分布式算法FIR滤波器
目前FIR滤波器的实现方法有三种:利用单片通用数字滤波器集成电路、DSP器件和可编程逻辑器件实现。单片通用数字滤波器使用方便,但由于字长和阶数的规格较少,不能完全满足实际需要。使用DSP器件实现虽然简单,但由于程序顺序执行,执行速度必然不快。FPGA有着规整的内部逻辑阵列和丰富的连线资源,特别适合于数字信号处理任务,相对于串行运算为主导的通用DSP芯片来说,其并行性和可扩展性更好。但长期以来,FPGA一直被用于系统逻辑或时序控制上,很少有信号处理方面的应用,其原因主要是因为在FPGA中缺乏实现乘法运算的有效结构。现在这个问题得到了解决,使FPGA在数字信号处理方面有了长足的发展。
分布式算法(Distributed Arithmetic,DA)是一种已实现乘加运算为目的的运算方法。它与传统实现乘加运算算法的不同之处在于:执行部分积运算的先后顺序不同。简单地说,分布式算法在完成乘加功能时是通过将各输入数据每一对应位产生的部分积预先进行相加形成相应部分积,然后再对各部分积进行累加形成最终结果;而传统算法是等到所有乘积产生之后再进行相加来完成乘加运算的。与传统算法相比,分布式算法可极大地减少硬件电路规模,很容易实现流水线处理,提高电路的执行速度。
在实际中,不仅是对于滤波器方面,在卷积、相关、DFT等有乘累加运算的地方,都可以使用这种方法实现。DA设计的先决条件是滤波器的系数h[i]可以通过运算得到,那么在技术部分乘积项h[i]*x[n-1]就变成了一个常数乘法(也就是缩放)。DA算法的主要特点是,巧妙地利用查找表将固定系数的MAC运算转化为查表操作,其运算速度不随系数和输入数据位数的增加而降低,而且相对直接实现乘法器而言,在硬件规模上得到了极大的改善。
对于式(4)括号中的每一个乘积项都代表了输入变量的某一位与常量的二进制“与”操作,加号代表了算术和操作,指数因子对括号中的值加权。如果事先构造一个查找表,该表储存了括号中所有可能的组合值,就可以通过所有输入变量相对应的组合向量(xb[N-1], xb[N-2], … ,xb[0])对该表进行寻址。
本设计是使用Verilog实现一个8阶对称系数的FIR滤波器,其系数分别是41,132,341,510,341,132,41。
该本滤波器的输入为12比特,先把相同系数对应的数据相加,输入到DA滤波器的数据经过符号位的扩展后变成13比特。这样可以看成是一个4阶的FIR滤波器,减小了构造表的复杂度。
设计程序:
module fir1(clk,reset,fir_in,fir_in_reg,fir_out,divfre_count_4b,divfre13_clk);
parameter S0=1'd0; //初始状态
parameter S1=1'd1; //处理状态
input clk;
input reset;
input[11:0]fir_in;
output[12:0]fir_out;
output[11:0]fir_in_reg;
output[3:0]divfre_count_4b;
output divfre13_clk;
reg[12:0]fir_out;
reg[11:0]fir_in_reg;
reg[12:0]shift_buf[7:0];
reg[12:0]add_buf[3:0];
//reg[12:0]state_shift_buf[4-1:0];
reg[12:0]state_shift_buf0;
reg[12:0]state_shift_buf1;
reg[12:0]state_shift_buf2;
reg[12:0]state_shift_buf3;
wire[3:0]table_4b;
wire[11:0]table_out_12b;
reg[12:0]sum;
reg STATE;
reg[3:0]divfre_count_4b;
reg divfre13_clk;
integer i,j,k,l,m,n,p;
always@(posedge clk or negedge reset)
begin
if(!reset)
begin
divfre13_clk<=1'b0;
divfre_count_4b<=4'b0000; //14分频
end
else
begin
if(divfre_count_4b==13)
begin
divfre_count_4b<=4'b0000;
divfre13_clk<=1'b1;
end
else
begin
divfre_count_4b<=divfre_count_4b+1'b1; //计数
divfre13_clk<=1'b0;
end
end
end
always @(posedge clk or negedge reset) //数据输入
begin
if(!reset)
fir_in_reg<=12'b0000_0000_0000;
else
if(divfre13_clk)
fir_in_reg<=fir_in;
end
always @(posedge clk or negedge reset)
begin
if(!reset)
for(i=0;i<=7;i=i+1)
shift_buf[i]<=13'b0000_0000_00000;
else if(divfre13_clk)
begin
for(j=0;j<8-1;j=j+1)
shift_buf[j+1]<= shift_buf[j];
shift_buf[0]<={fir_in_reg[11],fir_in_reg};
end
end
always @(posedge clk or negedge reset)
begin
if(!reset)
for(k=0;k<=4-1;k=k+1)
add_buf[k]<=13'b0000_0000_00000;
else
if(divfre13_clk)
for(l=0;l<=3;l=l+1)
add_buf[l]<=shift_buf[l]+shift_buf[7-1];
end
always @(posedge clk or negedge reset) //有限状态机初始化,比特移位
begin
if(!reset)
begin
//for(m=0;m<=4-1;m=m+1)
//state_shift_buf[m]<=13'b0000_0000_00000;
state_shift_buf0<=13'b0000_0000_00000;
state_shift_buf1<=13'b0000_0000_00000;
state_shift_buf2<=13'b0000_0000_00000;
state_shift_buf3<=13'b0000_0000_00000;
STATE<=S0;
end
else
case(STATE)
S0:begin //初始状态
// for(n=0;n<=4-1;n=n+1)
//state_shift_buf[n]<= add_buf[n];
state_shift_buf0<=add_buf[0];
state_shift_buf1<=add_buf[1];
state_shift_buf2<=add_buf[2];
state_shift_buf3<=add_buf[3];
STATE<=S1;
end
S1:begin //处理状态
if(divfre_count_4b==4'b1101)
STATE<=S0;
else
begin
for(p=0;p<=11;p=p+1)
begin
state_shift_buf0[p]<=state_shift_buf0[p+1];
state_shift_buf1[p]<=state_shift_buf1[p+1];
state_shift_buf2[p]<=state_shift_buf2[p+1];
state_shift_buf3[p]<=state_shift_buf3[p+1];
end
STATE<=S1;
end
end
endcase
end
assign table_4b[0]=state_shift_buf0[0];
assign table_4b[1]=state_shift_buf1[0];
assign table_4b[2]=state_shift_buf2[0];
assign table_4b[3]=state_shift_buf3[0];
DA_table U_DA(
.table_in_4b(table_4b),
.table_out_12b(table_out_12b)
);
wire[26:0]sign_ex={table_out_12b[11],table_out_12b[11],table_out_12b[11],
table_out_12b[11],table_out_12b[11],table_out_12b[11],
table_out_12b[11],table_out_12b[11],table_out_12b[11],
table_out_12b[11],table_out_12b[11],table_out_12b[11],
table_out_12b[11],table_out_12b[11],table_out_12b[11],
table_out_12b};
always @(posedge clk or negedge reset)
begin
if(!reset)
sum<=27'b0;
else
if(divfre_count_4b==4'b0000)
sum<=27'b0;
else
if(divfre_count_4b==4'b1101)
sum<=sum-delta(sign_ex,divfre_count_4b-4'b0001);
else
sum<=sum+delta(sign_ex,divfre_count_4b-4'b0001);
end
always @(posedge clk or negedge reset)
begin
if(!reset)
fir_out<=27'b0;
else
if(divfre_count_4b==4'b0000)
fir_out<=sum; //滤波器输出
end
function[13-1:0]delta; //定义移位寄存器左移
input[13-1:0]IQ;
input[3:0]pipe;
begin
case(pipe)
4'b0000:delta=IQ;
4'b0001:delta={IQ[13-2:0],1'b0};
4'b0010:delta={IQ[13-3:0],2'b00};
4'b0011:delta={IQ[13-4:0],3'b000};
4'b0100:delta={IQ[13-5:0],4'b0000};
4'b0101:delta={IQ[13-6:0],5'b00000};
4'b0110:delta={IQ[13-7:0],6'b000000};
4'b0111:delta={IQ[13-8:0],7'b0000000};
4'b1000:delta={IQ[13-9:0],8'b00000000};
4'b1001:delta={IQ[13-10:0],9'b000000000};
4'b1010:delta={IQ[13-11:0],10'b0000000000};
4'b1011:delta={IQ[13-12:0],11'b00000000000};
4'b1100:delta={IQ[13-13:0],12'b000000000000};
//4'b1101:delta={IQ[13-14:0],13'b0000000000000};
//4'b1110:delta={IQ[13-15:0],14'b00000000000000};
//4'b1111:delta={IQ[13-16:0],15'b000000000000000};
default:delta=IQ;
endcase
end
endfunction
endmodule
module DA_table(table_in_4b,table_out_12b);
input [3:0] table_in_4b;
output [11:0] table_out_12b;
reg[11:0] table_out_12b;
always @(table_in_4b)
begin
case(table_in_4b)
4'b0000:table_out_12b=0;
4'b0001:table_out_12b=41;
4'b0010:table_out_12b=132;
4'b0011:table_out_12b=173;
4'b0100:table_out_12b=341;
4'b0101:table_out_12b=382;
4'b0110:table_out_12b=473;
4'b0111:table_out_12b=514;
4'b1000:table_out_12b=510;
4'b1001:table_out_12b=551;
4'b1010:table_out_12b=642;
4'b0011:table_out_12b=683;
4'b1100:table_out_12b=851;
4'b1101:table_out_12b=892;
4'b1110:table_out_12b=983;
4'b1111:table_out_12b=1024;
default:table_out_12b=0;
endcase
end
endmodule
为了可以方便的判断程序输出结果的正确性,我们在仿真时采用了几个简单的数据作为采样后的数据输入。分别采用:1,2,3作为输入,则经过三次计算对应的输出应为41,241,728,十六进制数为29h,D6h,28Dh。与乘累加方式FIR滤波算法得出的结果完全一致。
输入后的波形如下图:
分布式算法FIR滤波器相关推荐
- 【FPGA教程案例99】数据处理2——基于DA分布式算法的FIR滤波器FPGA实现
FPGA教程目录 MATLAB教程目录 ---------------------------------------- 本课程成果预览(带高频干扰的正弦滤波后恢复到标准的正弦) 目录 1.软件版本 ...
- 【DA算法】基于DA算法的FIR滤波器的FPGA实现
1.软件版本 quartusii 2.本算法理论知识 DA算法的主要特点是,巧妙地利用查找表将固定系数的MAC运算转化为查表操作,其运算速度不随系数和输入数据位数的增加而降低,而且相对直接实现乘法器而 ...
- fir fpga 不同截止频率_一种新的FIR滤波器系数量化方法
相对于模拟滤波器,数字滤波器具有高精度.高可靠性.可编程改变滤波特性.便于集成等一系列优点,并且理论上可实现近似理想频率特性的滤波性能.经典的数字滤波器主要包括有限脉冲响应(Finite Impuls ...
- FIR滤波器学习设计笔记
根据滤波器的冲激响应宽度,数字滤波器可以分为无限长冲激响应IIR和有限长冲激响应FIR两种类型.在实际应用中,FIR更普遍,下面主要以FIR滤波器为主. 一个N阶fir可以用持续时间有限的冲激响应来定 ...
- FIR数字滤波器的FPGA实现(一)-FIR滤波器基本原理
(一)FIR数字滤波器的FPGA实现-FIR滤波器基本原理 文章目录 (一)FIR数字滤波器的FPGA实现-FIR滤波器基本原理 1 FIR滤波器基本原理 1.1 FIR滤波器的结构及设计 1.1.1 ...
- fir抽取滤波器matlab,Xilinx FPGA之抽取FIR滤波器的实现
过去半年有几位客户请我帮助他们设计和实现数字下变频器所用的降采样(即"抽取")滤波器,这种滤波器在软件无线电与数据采集类应用中都很常见.这项工作即便对于经验丰富的设计师也不是一件小 ...
- (多图) 基于并行流水线结构的可重配FIR滤波器的FPGA实现
1 并行流水结构FIR的原理 在用FPGA或专用集成电路实现数字信号处理算法时,计算速度和芯片面积是两个相互制约的主要问题.实际应用FIR滤波器时,要获得良好的滤波效果,滤波器的阶数可能会显著增加,有 ...
- 【 FPGA 】FIR滤波器的采样速率与系统时钟速率不同时的资源消耗分析
目录 MATLAB操作 Vivado操作 MATLAB操作 在matlab中命令窗口中输入:filterDesigner,设计如下参数的带通滤波器: 在左侧第三个功能设置:Set quantizati ...
- 【 FPGA 】MATLAB 生成 FIR 滤波器的操作步骤(包括生成Verilog HDL代码以及仿真过程)
使用MATLAB生成滤波器有很多学问,这里只是作为初步的探索,和FPGA的更多结合,也正在探索中,相关博文例如:[ FPGA ]FIR滤波器目录,该专题目录正在记录我学习FIR滤波器的过程. MATL ...
最新文章
- C++知识点22——使用C++标准库(顺序容器list的初始化、赋值、访问、交换、添加、删除与迭代器失效)
- redhat7.1安装mysql_redhat7.1 安装mysql 5.7.10步骤详解(图文详解)
- .Net 中接口应用的知识点(排序)
- Spring,FetchType.LAZY和FetchType.EAGER什么区别?
- android圆图,Android实现圆形图片或者圆角图片
- Atitit 语言分类 形式语言 目录 1. 形式语言(英语:Formal language)是用精确的数学或机器可处理的公式定义的语言。	1 1.1. 形式语言理论是用数学方法研究自然语言(如英语
- Android布局基础知识
- CentOS7环境下MySQL升级
- 《Android框架揭秘》——2.6节小结
- 小学计算机课的微案例,全国中小学信息技术课程教学案例大赛获奖作品 趣味造型制作.doc...
- Jsoup爬虫以及防反爬
- 税务Ukey如何进行批量开票
- 刚接触Linux服务器,如何变成可视化的操作界面?
- 用python做蒙特卡洛仿真算法
- 华为手机自带的双系统模式,你知道吗?一部手机当两部使用
- 计算机专业y9000x,LEGION Y9000X笔记本U盘一键重装Win10专业版的教程
- 如何用东华大学的邮箱来在Cousera进行学生认证
- 隐枚举法求解0-1整数规划
- Unity打包exe生成的文件夹合并成单独的exe
- Bootstrap官网的Bootstrap 3 字体图标的使用测试