FPGA实现并行低通FIR滤波器
设计一个15阶(长度为16)的具有线性相位低通FIR滤波器,采用布拉克曼窗函数设计,截止频率为500HZ,抽样频率为2000HZ;采用FPGA实现并行低通FIR滤波器,系数的量化位数为12比特,输入数据位数为12比特,输出数据位数为29比特,系统时钟为2000HZ。
设计思路:本例与上一例参数相同,所采用的数据、MATLAB程序及仿真方式并没有差别。因此此章只给出FPGA实现滤波器的方法。其它设计思路相同,详情参考利用FPGA实现全串行低通FIR滤波器_小小低头哥的博客-CSDN博客。
1.采用Verilog HDL语言设计并行低通FIR滤波器
module My_FirFullSerial(
input clk, //输入时钟 频率为2KHZ
input rst, //复位信号
input signed[11:0] Xin, //输入数据,频率为2KHZ
output signed[28:0] Yout //输出数据
);
//将各个寄存器清零
reg signed [11:0] Xin_reg[15:0];
reg [ 3:0] i;
always @(posedge clk or negedge rst)
if(!rst) begin
for(i=0;i<15;i=i+1)
Xin_reg[i] <= 12'd0;
end
else begin
for(i=0;i<15;i=i+1)
Xin_reg[i+1] <= Xin_reg[i];
Xin_reg[0] <= Xin;
end
//将对称系数的输入数据相加,同时将对应的滤波器系数送入乘法器
//为了进一步提高运算速度,零外增加了一级寄存器
reg signed [12:0] Add_reg[7:0]; //长度为滤波器长度的一半 因为是两个系数相加,所以位宽增加了一位
reg [3:0] j;
always @(posedge clk or negedge rst)
if(!rst) begin
for(j=0;j<8;j=j+1)
Add_reg[j] <= 12'd0;
end
else begin
for(j=0;j<8;j=j+1)
Add_reg[j] <= {Xin_reg[j][11],Xin_reg[j]} + {Xin_reg[15-j][11],Xin_reg[15-j]};
end
//得出结果,简便起见就直接用✖,不用乘法器IP核了 不过实际过程中推荐使用IP核
reg signed[24:0] Mout[7:0];
reg [ 3:0] k;
wire signed[11:0] coe[7:0];
assign coe[0] = 12'h000;
assign coe[1] = 12'hffd;
assign coe[2] = 12'h00f;
assign coe[3] = 12'h02e;
assign coe[4] = 12'hf8b;
assign coe[5] = 12'hef9;
assign coe[6] = 12'h24e;
assign coe[7] = 12'h7ff;
always @(posedge clk or negedge rst)
if(!rst) begin
for(k=0;k<8;k=k+1)
Mout[k] <= 12'd0;
end
else begin
for(k=0;k<8;k=k+1)
Mout[k] <= Add_reg[k] * coe[k];
end
//将滤波器系数与输入数据的乘法结果累加,并输出滤波后的结果
//与串行结构不同,此处在一个时钟周期内直接将所有乘法器结果相加
reg signed [28:0] sum;
reg signed [28:0] yout;
reg [ 3:0] L;
always @(posedge clk or negedge rst)
if(!rst) begin
sum <= 29'd0;
yout <= 29'd0;
end
else begin
yout <= sum;
sum = 29'd0;
for(L=0;L<8;L=L+1)
sum = sum + Mout[L];
end
assign Yout = yout;
endmodule
2.总结
并行结构是指并行的实现滤波器的累计运算,具体来讲,就是并行的将具有对称系数的输入数据进行相加,然后采用多个乘法器并行地实现系数与数据的乘法运算,最后将所有的乘积结果相加输出。这种结构具有最高的运行速率,由于不需要累加运算,因此系数时钟频率可以与数据输出的时钟频率一致。但是代价确实使用到了成倍的硬件资源。
另外,参考了这篇文章Quartus II13.0设置Testbench步骤 实现了上个例子没有理解的.vt文件,自己创建了.vt文件并利用modesim仿真成功。最终使用MATLAB仿真FPGA滤波后的输出数据,如图1所示,只剩下200HZ频率的信号。因此FPGA程序应该是编译成功。