1 .原理
FIR滤波器是非递归滤波器的简称,也称为有限长度单位脉冲响应滤波器。 具有常数系数的FIR滤波器是LTI (线性时变)数字滤波器。 冲激响应有限,意味着滤波器中没有发送反馈。 长度为n的FIR输出与输入时间序列x(n )相对应的关系由有限卷积和的形式给出,具体形式如下。
直接FIR滤波器的图解:
上式是N-1阶FIR滤波器,具有n个抽头(系数)。 因此,由n个乘法器、N-1个累加器组成。 每抽头占用逻辑资源乘法器累加器( Mac )单元。
输入信号具有时间性,随时间的经过而变化。 FIR滤波器的最终输出乘以与各时刻的输入对应的权重(系数)后重叠输出。
FIR数字滤波器“移动平均”示例:
“移动平均”是指用预先设定的信号数对输入信号进行平均。 例如,如果对四个信号中的每一个取平均值,则这四个“移动平均”滤波器如下图所示。
下图为11点和51点“移动平均”滤波器滤波后的信号图。
“移动平均”滤波器的频率响应如下图所示。
如上图所示,随着点数的增加,滚降变得陡峭,但对旁瓣(旁瓣)衰减部分)的高低影响不大。 然而,如果考虑采用与“移动平均”滤波器相同的权重(对于1/4、4个点的“移动平均”滤波器来说),而是针对滤波器的每个系数而不同的权重)加权,则可以期待旁瓣的大小大幅降低
对于系数使用不同权重的滤波器,可以用以下公式表示:
2 .利用2.FPGA实现fir滤波器
2.1在MATLAB中键入fdatool可打开过滤器设计工具,如图7所示。 可以设定滤波器的类型、采样频率、截止频率等。 本设计中设定的参数如图所示。
然后导出此滤波器系数,并使用以下命令放大和整形系数:
num=round(num*256 ) /增大系数进行调整
num=[ 5 17 43 63 63 43 17 5];
本设计中用于模拟的输入波形由2个正弦波重叠而成,分别为5HZ、45HZ。
Fs=1000; %采样频率决定两个正弦波点之间的间隔N=256。 %采样点数N1=0 : 1/Fs : N/Fs-1/Fs; s=cos(5*2*pi*N1 ) cos (45 *2* pi * n1 ); %FIDC=fopen(‘mem.txt ‘,’ wb ‘ ); 将%结果写入mem.txt文件,使modesim易于使用forx=1:na=round(s(x ) *20 )。 %放大if(a=0) thDGS_x=deC2thDGS(a,8 ); %正数的反码和补码都与原码相同,变换位8位的fprintf(FIDC,’ %s\n ‘,thdgs_x )。 ELSEthDGS_x=DEC2thDGS(2^8a,8 ); frintf(FIDC,’ %s\n ‘,thdgs_x ); 结束关闭(fidc; 2.verilog
模块fir (clk、rst、din、dout、ordy ); 输入时钟; 输入Rst; input [7:0] din; output [15:0] dout; 输出订单; //matlab fir生成系数* 256该滤波器的采样率为100Hz,截止频率为10Hzparametercoeff1=8’d5,coeff2=8’d17,coeff3=8’d43,coeeff reg signed [7:0] sample_2; reg signed [7:0] sample_3; reg signed [7:0] sample_4; reg signed [7:0] sample_5; reg signed [7:0] sampl
e_6; reg signed [7:0] sample_7; reg signed [7:0] sample_8; reg [18:0] dout; reg ordy; //输入数据,移位寄存 always @(posedge clk ) begin if(rst) begin sample_1 <= 8’d0;sample_2 <= 8’d0;sample_3 <= 8’d0;sample_4 <= 8’d0;sample_5 <= 8’d0;sample_6 <= 8’d0;sample_7 <= 8’d0;sample_8 <= 8’d0; endelse begin sample_1 <= din;sample_2 <= sample_1;sample_3 <= sample_2;sample_4 <= sample_3;sample_5 <= sample_4;sample_6 <= sample_5;sample_7 <= sample_6;sample_8 <= sample_7;//8个周期完成移位 end end //调用ip,执行乘法 wire [15:0] p[8:1]; mult_8 u1 ( .CLK(clk), // input wire CLK .A(sample_1), // input wire [7 : 0] A .B(coeff1), // input wire [7 : 0] B .P(p[1]) // output wire [15 : 0] P 设置pipline stage 为3,表示3级延时); mult_8 u2 ( .CLK(clk), // input wire CLK .A(sample_2), // input wire [7 : 0] A .B(coeff2), // input wire [7 : 0] B .P(p[2]) // output wire [15 : 0] P); mult_8 u3 ( .CLK(clk), // input wire CLK .A(sample_3), // input wire [7 : 0] A .B(coeff3), // input wire [7 : 0] B .P(p[3]) // output wire [15 : 0] P); mult_8 u4 ( .CLK(clk), // input wire CLK .A(sample_4), // input wire [7 : 0] A .B(coeff1), // input wire [7 : 0] B .P(p[4]) // output wire [15 : 0] P); mult_8 u5 ( .CLK(clk), // input wire CLK .A(sample_5), // input wire [7 : 0] A .B(coeff5), // input wire [7 : 0] B .P(p[5]) // output wire [15 : 0] P); mult_8 u6 ( .CLK(clk), // input wire CLK .A(sample_6), // input wire [7 : 0] A .B(coeff6), // input wire [7 : 0] B .P(p[6]) // output wire [15 : 0] P); mult_8 u7 ( .CLK(clk), // input wire CLK .A(sample_7), // input wire [7 : 0] A .B(coeff7), // input wire [7 : 0] B .P(p[7]) // output wire [15 : 0] P); mult_8 u8 ( .CLK(clk), // input wire CLK .A(sample_8), // input wire [7 : 0] A .B(coeff8), // input wire [7 : 0] B .P(p[8]) // output wire [15 : 0] P); //加法第一级 wire [16:0] s1 [4:1];//加法器的延时为2 add_16 a1 ( .A(p[1]), // input wire [15 : 0] A .B(p[2]), // input wire [15 : 0] B .CLK(clk), // input wire CLK .S(s1[1]) // output wire [16 : 0] S); add_16 a2 ( .A(p[3]), // input wire [15 : 0] A .B(p[4]), // input wire [15 : 0] B .CLK(clk), // input wire CLK .S(s1[2]) // output wire [16 : 0] S); add_16 a3 ( .A(p[5]), // input wire [15 : 0] A .B(p[6]), // input wire [15 : 0] B .CLK(clk), // input wire CLK .S(s1[3]) // output wire [16 : 0] S); add_16 a4 ( .A(p[7]), // input wire [15 : 0] A .B(p[8]), // input wire [15 : 0] B .CLK(clk), // input wire CLK .S(s1[4]) // output wire [16 : 0] S); //加法第二级 wire [17:0] s2 [2:1]; add_17 a21 ( .A(s1[1]), // input wire [16 : 0] A .B(s1[2]), // input wire [16 : 0] B .CLK(clk), // input wire CLK .S(s2[1]) // output wire [17 : 0] S); add_17 a22 ( .A(s1[3]), // input wire [16 : 0] A .B(s1[4]), // input wire [16 : 0] B .CLK(clk), // input wire CLK .S(s2[2]) // output wire [17 : 0] S); //加法第三级 wire [18:0] s3; add_18 a31 ( .A(s2[1]), // input wire [17 : 0] A .B(s2[2]), // input wire [17 : 0] B .CLK(clk), // input wire CLK .S(s3) // output wire [18 : 0] S); //计数 reg [4:0] counter; always @(posedge clk) begin if(rst) begin counter <= 5’d0; dout <= 19’d0; ordy <= 1’b0;end else if(counter == 17) begin dout <= s3; ordy <= 1’b1;end else begin dout <= 19’d0; counter <= counter + 1’b1; end endendmodule
由于抽头系数N=8,滤波的效果不是太好,可以采用更高阶数的fir滤波器,这里只是做个演示,有何错误之处还请指教!!