1、主要内容
这里主要是借助 Matlab 和 ModelSim 等软件做 FIR 滤波器的仿真,当仿真结果正确时,在将程序下载到 FPGA 中做实时测试。
2、实验平台
Matlab7.1 + ModelSim6.3
参考书籍:数字信号处理的 FPGA 实现(第二版)
3、实现步骤
假设为 N 阶滤波器:
(1)根据滤波器的指标,利用 Matlab 计算出响应参数,共有 N 个;
(2)利用这些响应参数,采用分布式算法的 FIR 滤波器,用 ModelSim 仿真实现;
a. 移位:这里采用移位寄存器,将串行输入转换为并行数据;
b. 降阶:由于 FIR 滤波器的对称性,将相同响应参数的输入叠加;
c. 分割:由于 FIR 滤波器的线性特性,将 DA 表分割,这样可以大大缩小 DA 表的规模;
d. 查表:这里通过查表的,得到各个中间值;
e. 叠加:将各个中间值叠加,得到最终结果;
(3) 最后将这些结果跟 Matlab 仿真所得结果进行比对,若差别不大,则进一步用硬件做测试。
一些需要注意的地方:
假设是 N 阶 16 位的滤波器,则滤波器抽头数量是 N,滤波器的响应参数也是 N 个。对 a 步骤的理解,这里是将输入的数据,按照并行排列,而每一个数据是按照由低到高逐位输入,如下形式:
第一个数据:1111 1001 0100 0001
第二个数据:0101 1011 0001 1110
第三个数据:1001 0000 1110 1111
…
…
第 N 个数据:1001 0001 1010 1001
4. 例 1 3 阶 FIR 滤波器设计
这里对应 FIR_DA 工程文件夹。
下面是主程序:
//********************************************************* // IEEE STD 1364-1995 Verilog file: dafsm.v // Author-EMAIL: www.sunev.cn //********************************************************* module FIR (clk, x_in0, x_in1, x_in2, y, p, table_out, x0, x1, x2, count); //--> Interface input clk; input [2:0] x_in0, x_in1, x_in2; output [5:0] y, p, table_out; output x0, x1, x2; output count; reg [5:0] y; reg [2:0] x0, x1, x2; wire [2:0] table_in,table_out ; reg [5:0] p; // temporary register reg [0:0] state = 0; reg [2:0] count; // Counts the shifts assign table_in[0] = x0[0]; assign table_in[1] = x1[0]; assign table_in[2] = x2[0]; always @(posedge clk) //----> DA in behavioral style begin case (state) 0 : begin // Initialization state <= 1; count <= 0; p <= 6'b0; x0 <= x_in0; x1 <= x_in1; x2 <= x_in2; end 1 : begin // Processing step if (count == 4) begin // Is sum of product done y <= p; // Output of result to y and state <= 0; // start next sum of product end else begin p <= {p[5],p[5:1]} + {1'b0,table_out,2'b00}; x0[0] <= x0[1]; x0[1] <= x0[2]; x1[0] <= x1[1]; x1[1] <= x1[2]; x2[0] <= x2[1]; x2[1] <= x2[2]; count <= count + 1; state <= 1; end end endcase end case3 LC_Table0 ( .clk(clk), .table_in(table_in), .table_out(table_out) ); endmodule
通过 dagen 程序生成的 case3 程序:
//********************************************************* // IEEE STD 1364-1995 Verilog file: case3.v // Author-EMAIL: www.sunev.cn //********************************************************* module case3 (clk, table_in, table_out); input clk; input [2:0] table_in; // Three bit output [2:0] table_out; // Range 0 to 6 reg [2:0] table_out = 3'b0; // This is the DA CASE table for // the 3 coefficients: 2, 3, 1 always @(posedge clk) begin case (table_in) 0 : table_out = 0; 1 : table_out = 2; 2 : table_out = 3; 3 : table_out = 5; 4 : table_out = 1; 5 : table_out = 3; 6 : table_out = 4; 7 : table_out = 6; default : ; endcase end endmodule
Modelsim 所用的测试程序:
module FIR_tb ; reg [2:0] x_in2 ; wire [5:0] y ,p ; wire [2:0] count; wire [2:0] x0, x1, x2; wire [2:0] table_out; reg [2:0] x_in0 ; reg clk ; reg [2:0] x_in1 ; FIR DUT ( .count(count), .x0(x0), .x1(x1), .x2(x2), .x_in2 (x_in2 ) , .y (y ) , .p(p), .table_out(table_out), .x_in0 (x_in0 ) , .clk (clk ) , .x_in1 (x_in1 ) ); initial begin #0 x_in0 <= 4'b0000; x_in1 <= 4'b0000; x_in2 <= 4'b0000; clk <= 0; #0 x_in0 <= 4'b0001; x_in1 <= 4'b0011; x_in2 <= 4'b0111; end always #10 clk <= ~clk; endmodule
Modelsim 仿真结果:
5、结论
该篇笔记主要讲述了 FPGA 实现 FIR 滤波器的步骤,并以一个简单的例子实现了 3 阶滤波器的设计。
扫码关注尚为网微信公众号
原创文章,作者:sunev,如若转载,请注明出处:https://www.sunev.cn/embedded/12.html