当前位置:   article > 正文

FIR滤波器_fir滤波器原理图

fir滤波器原理图

1.原理

FIR滤波器是非递归型滤波器的简称,又叫有限长单位冲激响应滤波器。带有常系数的FIR滤波器是一种LTI(线性时不变)数字滤波器。冲激响应是有限的意味着在滤波器中没有发反馈。长度为N的FIR输出对应于输入时间序列x(n)的关系由一种有限卷积和的形式给出,具体形式如下:

                                                             

直接形式FIR滤波器图解:

                                                       

上式表达的是一个N-1阶的FIR滤波器,它有N个抽头(系数)。因此有N个乘法器,N-1个累加器组成。每一个抽头需要消耗逻辑资源的乘法器累加器( Mac )单元。

输入信号是有时间性的,随着时间的改变而改变,FIR滤波器最终的输出是各个时刻的输入乘以相应的权重(系数),然后进行叠加输出:

           


FIR数字滤波器“移动平均数”为例子:

“移动平均数”就是按我们事先设定的信号个数将输入信号加以平均。譬如,如果我们按每4个信号就做一次平均,那么这个4点的“移动平均数”滤波器就如下图所示:

                             

下图是经过11点和51点“移动平均数”滤波器过滤的信号图:

                                       

“移动平均数”滤波器的频率响应如下图所示:

                                       

如上图所示,随着点数的增加,滚降(ROLLOFF)变陡了,但对旁瓣(sidelobe,衰减部分)的高低影响不大。但是如果我们考虑对滤波器的每个系数采用不同的权重(加权),而不是像“移动平均数”滤波器那样,用相同的权重(1/4,对4点“移动平均数”滤波器来说),那么可以期待旁瓣的大小会大大的降低。

对系数采用不同权重的滤波器,我们可以用下面的数学公式来表达:

                              

2.FPGA实现fir滤波器

2.1在MATLAB中输入fdatool即可打开滤波器设计工具,如图7所示。里面可以设置滤波器的类型,采样频率,截止频率等。本设计设置的参数如图所示。

然后将此滤波器系数导出,然后用以下命令将系数放大、取整:

>> Num=round(Num*256)//将系数放大并取整

num=[ 5    17    43    63    63    43    17     5]; 

本设计用于仿真的输入波形是2个正弦波叠加而成,分别是5HZ、45HZ。

  1. Fs = 1000; %采样频率决定了两个正弦波点之间的间隔
  2. N = 256; %采样点数
  3. N1 = 0 : 1/Fs : N/Fs-1/Fs;
  4. s = cos(5*2*pi*N1) + cos(45*2*pi*N1) ;%
  5. fidc = fopen('mem.txt','wb'); %将结果写入mem.txt文件,便于modesim使用
  6. for x = 1 : N
  7. A = round(s(x)*20);%放大
  8. if (A >= 0)
  9. bin_x = dec2bin(A, 8); % 正数的反码和补码都和原码一样,转换位8
  10. fprintf(fidc,'%s\n',bin_x);
  11. else
  12. bin_x = dec2bin(2^8 + A, 8);
  13. fprintf(fidc,'%s\n',bin_x);
  14. end
  15. end
  16. fclose(fidc);

2.verilog

  1. module fir(clk,rst,din,dout,ordy);
  2. input clk;
  3. input rst;
  4. input [7:0] din;
  5. output [15:0] dout;
  6. output ordy;
  7. //matlab fir生成系数 * 256 该滤波器采样率为100Hz,截止频率为10Hz
  8. parameter coeff1=8'd5,coeff2=8'd17,coeff3=8'd43,coeff4=8'd63,coeff5=8'd63,coeff6=8'd43,coeff7=8'd17,coeff8=8'd5;
  9. //8个寄存器
  10. reg signed [7:0] sample_1;
  11. reg signed [7:0] sample_2;
  12. reg signed [7:0] sample_3;
  13. reg signed [7:0] sample_4;
  14. reg signed [7:0] sample_5;
  15. reg signed [7:0] sample_6;
  16. reg signed [7:0] sample_7;
  17. reg signed [7:0] sample_8;
  18. reg [18:0] dout;
  19. reg ordy;
  20. //输入数据,移位寄存
  21. always @(posedge clk )
  22. begin
  23. if(rst)
  24. begin
  25. sample_1 <= 8'd0;
  26. sample_2 <= 8'd0;
  27. sample_3 <= 8'd0;
  28. sample_4 <= 8'd0;
  29. sample_5 <= 8'd0;
  30. sample_6 <= 8'd0;
  31. sample_7 <= 8'd0;
  32. sample_8 <= 8'd0;
  33. end
  34. else
  35. begin
  36. sample_1 <= din;
  37. sample_2 <= sample_1;
  38. sample_3 <= sample_2;
  39. sample_4 <= sample_3;
  40. sample_5 <= sample_4;
  41. sample_6 <= sample_5;
  42. sample_7 <= sample_6;
  43. sample_8 <= sample_7;//8个周期完成移位
  44. end
  45. end
  46. //调用ip,执行乘法
  47. wire [15:0] p[8:1];
  48. mult_8 u1 (
  49. .CLK(clk), // input wire CLK
  50. .A(sample_1), // input wire [7 : 0] A
  51. .B(coeff1), // input wire [7 : 0] B
  52. .P(p[1]) // output wire [15 : 0] P 设置pipline stage 为3,表示3级延时
  53. );
  54. mult_8 u2 (
  55. .CLK(clk), // input wire CLK
  56. .A(sample_2), // input wire [7 : 0] A
  57. .B(coeff2), // input wire [7 : 0] B
  58. .P(p[2]) // output wire [15 : 0] P
  59. );
  60. mult_8 u3 (
  61. .CLK(clk), // input wire CLK
  62. .A(sample_3), // input wire [7 : 0] A
  63. .B(coeff3), // input wire [7 : 0] B
  64. .P(p[3]) // output wire [15 : 0] P
  65. );
  66. mult_8 u4 (
  67. .CLK(clk), // input wire CLK
  68. .A(sample_4), // input wire [7 : 0] A
  69. .B(coeff1), // input wire [7 : 0] B
  70. .P(p[4]) // output wire [15 : 0] P
  71. );
  72. mult_8 u5 (
  73. .CLK(clk), // input wire CLK
  74. .A(sample_5), // input wire [7 : 0] A
  75. .B(coeff5), // input wire [7 : 0] B
  76. .P(p[5]) // output wire [15 : 0] P
  77. );
  78. mult_8 u6 (
  79. .CLK(clk), // input wire CLK
  80. .A(sample_6), // input wire [7 : 0] A
  81. .B(coeff6), // input wire [7 : 0] B
  82. .P(p[6]) // output wire [15 : 0] P
  83. );
  84. mult_8 u7 (
  85. .CLK(clk), // input wire CLK
  86. .A(sample_7), // input wire [7 : 0] A
  87. .B(coeff7), // input wire [7 : 0] B
  88. .P(p[7]) // output wire [15 : 0] P
  89. );
  90. mult_8 u8 (
  91. .CLK(clk), // input wire CLK
  92. .A(sample_8), // input wire [7 : 0] A
  93. .B(coeff8), // input wire [7 : 0] B
  94. .P(p[8]) // output wire [15 : 0] P
  95. );
  96. //加法第一级
  97. wire [16:0] s1 [4:1];//加法器的延时为2
  98. add_16 a1 (
  99. .A(p[1]), // input wire [15 : 0] A
  100. .B(p[2]), // input wire [15 : 0] B
  101. .CLK(clk), // input wire CLK
  102. .S(s1[1]) // output wire [16 : 0] S
  103. );
  104. add_16 a2 (
  105. .A(p[3]), // input wire [15 : 0] A
  106. .B(p[4]), // input wire [15 : 0] B
  107. .CLK(clk), // input wire CLK
  108. .S(s1[2]) // output wire [16 : 0] S
  109. );
  110. add_16 a3 (
  111. .A(p[5]), // input wire [15 : 0] A
  112. .B(p[6]), // input wire [15 : 0] B
  113. .CLK(clk), // input wire CLK
  114. .S(s1[3]) // output wire [16 : 0] S
  115. );
  116. add_16 a4 (
  117. .A(p[7]), // input wire [15 : 0] A
  118. .B(p[8]), // input wire [15 : 0] B
  119. .CLK(clk), // input wire CLK
  120. .S(s1[4]) // output wire [16 : 0] S
  121. );
  122. //加法第二级
  123. wire [17:0] s2 [2:1];
  124. add_17 a21 (
  125. .A(s1[1]), // input wire [16 : 0] A
  126. .B(s1[2]), // input wire [16 : 0] B
  127. .CLK(clk), // input wire CLK
  128. .S(s2[1]) // output wire [17 : 0] S
  129. );
  130. add_17 a22 (
  131. .A(s1[3]), // input wire [16 : 0] A
  132. .B(s1[4]), // input wire [16 : 0] B
  133. .CLK(clk), // input wire CLK
  134. .S(s2[2]) // output wire [17 : 0] S
  135. );
  136. //加法第三级
  137. wire [18:0] s3;
  138. add_18 a31 (
  139. .A(s2[1]), // input wire [17 : 0] A
  140. .B(s2[2]), // input wire [17 : 0] B
  141. .CLK(clk), // input wire CLK
  142. .S(s3) // output wire [18 : 0] S
  143. );
  144. //计数
  145. reg [4:0] counter;
  146. always @(posedge clk)
  147. begin
  148. if(rst)
  149. begin
  150. counter <= 5'd0;
  151. dout <= 19'd0;
  152. ordy <= 1'b0;
  153. end
  154. else if(counter == 17)
  155. begin
  156. dout <= s3;
  157. ordy <= 1'b1;
  158. end
  159. else
  160. begin
  161. dout <= 19'd0;
  162. counter <= counter + 1'b1;
  163. end
  164. end
  165. endmodule

由于抽头系数N=8,滤波的效果不是太好,可以采用更高阶数的fir滤波器,这里只是做个演示,有何错误之处还请指教!!

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小蓝xlanll/article/detail/154509?site
推荐阅读
相关标签
  

闽ICP备14008679号