基于FPGA的FIR滤波器设计

一、MATLAB滤波器工具介绍

 

 二、设计实例

 

 

 三、编程思路

 

 四、仿真结果

 

 五、程序

  1 //=============================================================
  2 //
  3 // ---Author: 橘子哥哥
  4 // ---QQ    : 1073273114
  5 // ---Wechat: 15870894502
  6 // ---create:2022-04-26 10:53:12
  7 //
  8 //=============================================================
  9 `define COE_NUM            68 
 10 `define DAT_WIDTH          16
 11 `define COE_WIDTH          20
 12 module fir_filter(
 13     input   wire                  clk,
 14     input   wire                  rst_n,
 15     input   wire                  filter_vld,
 16     input   wire [`DAT_WIDTH-1:0] in_dat,
 17     output  wire [`DAT_WIDTH-1:0] out_dat
 18 );
 19 
 20 //*********************************假设这里是奇数阶,也就是有偶数个抽头系数,并且这偶数个抽头系数是对称的*********************************//
 21 //因为抽头系数多为小数,所以这里的抽头系数是乘以了1_048_576,最后将结果右移20位就得到正确结果了
 22 reg  [`DAT_WIDTH-1:0] in_reg  [`COE_NUM-1:0]; //暂存输入待滤波处理的数据
 23 wire [`COE_WIDTH-1:0] coe_reg [`COE_NUM/2-1:0]; //存放抽头系数
 24 wire [`COE_NUM/2-1:0] coe_reg_sign; //存放抽头系数的符号位
 25 wire [`DAT_WIDTH+`COE_WIDTH-1:0] coe_x_indat [`COE_NUM/2-1:0]; //存放x(n)*h(n)的结果
 26 wire [`DAT_WIDTH+`COE_WIDTH-1:0] coe_x_indat_sign [`COE_NUM/2-1:0]; //将x(n)*h(n)的结果根据h(n)的符号加上正负号
 27 
 28 wire [`DAT_WIDTH+`COE_WIDTH+`COE_NUM/2-1:0] out_dat_pre;//存放卷积的结果,还要右移20位
 29 
 30 //***************************设置抽头系数***************************//
 31 assign coe_reg[0]='d690;
 32 assign coe_reg_sign[0]=0;
 33 
 34 assign coe_reg[1]='d729;
 35 assign coe_reg_sign[1]=1;
 36 
 37 assign coe_reg[2]='d0;
 38 assign coe_reg_sign[2]=0;
 39 
 40 assign coe_reg[3]='d929;
 41 assign coe_reg_sign[3]=0;
 42 
 43 assign coe_reg[4]='d1097;
 44 assign coe_reg_sign[4]=1;
 45 
 46 assign coe_reg[5]='d0;
 47 assign coe_reg_sign[5]=0;
 48 
 49 assign coe_reg[6]='d1585;
 50 assign coe_reg_sign[6]=0;
 51 
 52 assign coe_reg[7]='d1914;
 53 assign coe_reg_sign[7]=1;
 54 
 55 assign coe_reg[8]='d0;
 56 assign coe_reg_sign[8]=0;
 57 
 58 assign coe_reg[9]='d2763;
 59 assign coe_reg_sign[9]=0;
 60 
 61 assign coe_reg[10]='d3293;
 62 assign coe_reg_sign[10]=1;
 63 
 64 assign coe_reg[11]='d0;
 65 assign coe_reg_sign[11]=0;
 66 
 67 assign coe_reg[12]='d4593;
 68 assign coe_reg_sign[12]=0;
 69 
 70 assign coe_reg[13]='d5377;
 71 assign coe_reg_sign[13]=1;
 72 
 73 assign coe_reg[14]='d0;
 74 assign coe_reg_sign[14]=0;
 75 
 76 assign coe_reg[15]='d7259;
 77 assign coe_reg_sign[15]=0;
 78 
 79 assign coe_reg[16]='d8381;
 80 assign coe_reg_sign[16]=1;
 81 
 82 assign coe_reg[17]='d0;
 83 assign coe_reg_sign[17]=0;
 84 
 85 assign coe_reg[18]='d11068;
 86 assign coe_reg_sign[18]=0;
 87 
 88 assign coe_reg[19]='d12680;
 89 assign coe_reg_sign[19]=1;
 90 
 91 assign coe_reg[20]='d0;
 92 assign coe_reg_sign[20]=0;
 93 
 94 assign coe_reg[21]='d16608;
 95 assign coe_reg_sign[21]=0;
 96 
 97 assign coe_reg[22]='d19030;
 98 assign coe_reg_sign[22]=1;
 99 
100 assign coe_reg[23]='d0;
101 assign coe_reg_sign[23]=0;
102 
103 assign coe_reg[24]='d25219;
104 assign coe_reg_sign[24]=0;
105 
106 assign coe_reg[25]='d290281;
107 assign coe_reg_sign[25]=1;
108 
109 assign coe_reg[26]='d0;
110 assign coe_reg_sign[26]=0;
111 
112 assign coe_reg[27]='d40768;
113 assign coe_reg_sign[27]=0;
114 
115 assign coe_reg[28]='d49389;
116 assign coe_reg_sign[28]=1;
117 
118 assign coe_reg[29]='d0;
119 assign coe_reg_sign[29]=0;
120 
121 assign coe_reg[30]='d80524;
122 assign coe_reg_sign[30]=0;
123 
124 assign coe_reg[31]='d114117;
125 assign coe_reg_sign[31]=1;
126 
127 assign coe_reg[32]='d0;
128 assign coe_reg_sign[32]=0;
129 
130 assign coe_reg[33]='d577569;
131 assign coe_reg_sign[33]=0;
132 
133 
134 
135 
136 assign out_dat=out_dat_pre>>20; //右移20位取得滤波后的结果
137 
138 always@(posedge clk or negedge rst_n)
139    if(!rst_n)
140       begin
141       in_reg[0]<='d0;
142       end
143    else if(filter_vld)
144         begin
145         in_reg[0]<=in_dat;
146         end
147    else 
148         begin
149         in_reg[0]<='d0;
150         end
151 
152 //将输出的值进行移位操作
153 genvar i;
154 generate
155   for(i=1;i<`COE_NUM;i=i+1)
156       begin : xnshift
157       always@(posedge clk or negedge rst_n)
158          if(!rst_n)
159             begin
160             in_reg[i]<='d0;
161             end
162          else if(filter_vld)
163               begin
164               in_reg[i]<=in_reg[i-1];
165               end
166          else 
167               begin
168               in_reg[i]<='d0;
169               end
170       end
171 endgenerate
172 
173 //例化乘法器,因为抽头系数存在对称性,所以只需要一半的乘法器
174 genvar j;
175 generate
176   for(j=0;j<`COE_NUM/2;j=j+1)
177       begin : mul_ope
178       mul_16bx20b inst_mul_16bx20b (
179         .CLK(clk),  // input wire CLK
180         .A(in_reg[j]+in_reg[`COE_NUM-1-j]),      // input wire [15 : 0] A
181         .B(coe_reg[j]),      // input wire [19 : 0] B
182         .P(coe_x_indat[j])      // output wire [35 : 0] P
183       );
184       end
185 endgenerate
186 
187 //将乘法器的结果加上符号位
188 genvar k;
189 generate
190   for(k=0;k<`COE_NUM/2;k=k+1)
191       begin : mul_sign 
192       assign coe_x_indat_sign[k]=coe_reg_sign[k]?(~coe_x_indat[k]+1):coe_x_indat[k];
193       end
194 endgenerate
195 
196 //累加和
197 assign out_dat_pre=coe_x_indat_sign[0]
198                   +coe_x_indat_sign[1]
199                   +coe_x_indat_sign[2]
200                   +coe_x_indat_sign[3]
201                   +coe_x_indat_sign[4]
202                   +coe_x_indat_sign[5]
203                   +coe_x_indat_sign[6]
204                   +coe_x_indat_sign[7]
205                   +coe_x_indat_sign[8]
206                   +coe_x_indat_sign[9]
207                   +coe_x_indat_sign[10]
208                   +coe_x_indat_sign[11]
209                   +coe_x_indat_sign[12]
210                   +coe_x_indat_sign[13]
211                   +coe_x_indat_sign[14]
212                   +coe_x_indat_sign[15]
213                   +coe_x_indat_sign[16]
214                   +coe_x_indat_sign[17]
215                   +coe_x_indat_sign[18]
216                   +coe_x_indat_sign[19]
217                   +coe_x_indat_sign[20]
218                   +coe_x_indat_sign[21]
219                   +coe_x_indat_sign[22]
220                   +coe_x_indat_sign[23]
221                   +coe_x_indat_sign[24]
222                   +coe_x_indat_sign[25]
223                   +coe_x_indat_sign[26]
224                   +coe_x_indat_sign[27]
225                   +coe_x_indat_sign[28]
226                   +coe_x_indat_sign[29]
227                   +coe_x_indat_sign[30]
228                   +coe_x_indat_sign[31]
229                   +coe_x_indat_sign[32]
230                   +coe_x_indat_sign[33];
231                    
232 
233 endmodule

 

posted @ 2022-04-27 16:32  橘子哥哥hym  阅读(510)  评论(1)    收藏  举报