差别

这里会显示出您选择的修订版和当前版本之间的差别。

到此差别页面的链接

两侧同时换到之前的修订记录 前一修订版
后一修订版
前一修订版
fpga滤波器实现 [2020/07/22 14:19]
zili
— (当前版本)
行 1: 行 1:
-### FPGA滤波器实现 
-\\ 
- 
-#### FPGA滤波器实施概述 
-我协助我的一位研究生进行了一些有关FPGA滤波器实现的定向研究。她的任务是了解并实现FPGA硬件上的几种类型的过滤器。设计的所有滤波器均为15阶滤波器,并使用16位定点数学运算。然后检查了过滤器的性能和资源使用情况。她关于研究的最终演讲可以在下面查看:\\ 
- 
-[[https://​www.eetree.cn/​wiki/​_media/​filter_implementation_on_a_fpga_board_xueyan_lu_06152017.pdf|FPGA滤波器实现]]\\ 
- 
-研究项目期间创建的Verilog源文件如下。\\ 
-\\ 
- 
-#### FIR滤波器 
-FIR滤波器是四个滤波器中最简单,最快的。它利用了预加器的对称性。而且,使用加法器树来最小化组合路径延迟。\\ 
-{{ ::​fir_filter.png |}} 
- 
-##### FIR_Filter.v ​ 
-<code verilog> 
- 
-`define FILT_LENGTH 16 
- 
-module FIR_Filter( 
-    input  clk, 
-    input  en, 
-    input  [15:0]din, 
-    output [15:0]dout 
-    ); 
-  
-    reg signed [15:​0]coeff[`FILT_LENGTH/​2-1:​0];​ //Filter coefficients. 
-    reg signed [15:​0]delay_line[`FILT_LENGTH-1:​0];​ //Input delay line. 
-    wire [31:​0]accum;​ //​Accumulator for output filter calculation. ​   ​ 
-    integer i; //​Initialization integer. 
-    genvar c;  //Delay line generation variable. 
-    
-    reg signed [16:​0]preadd_regs[7:​0];​ //Save calc after preadd. 
-    reg signed [31:​0]mult_regs[7:​0]; ​  //​Save calc after multiplication. 
-    reg signed [31:​0]tree1_regs[3:​0]; ​ //Save calc after first layer of adder tree. 
-    reg signed [31:​0]tree2_regs[1:​0]; ​ //Save calc after first layer of adder tree. 
-    reg signed [31:​0]treeout_reg; ​     //Save calc after complete. 
-    
-    //assign dout = treeout_reg[31:​16];​ 
-    ​ 
-    //Calculate value in the accumulator. 
-    assign accum = (delay_line[0] + delay_line[15]) * coeff[0] + 
-                   ​(delay_line[1] + delay_line[14]) * coeff[1] + 
-                   ​(delay_line[2] + delay_line[13]) * coeff[2] + 
-                   ​(delay_line[3] + delay_line[12]) * coeff[3] + 
-                   ​(delay_line[4] + delay_line[11]) * coeff[4] + 
-                   ​(delay_line[5] + delay_line[10]) * coeff[5] + 
-                   ​(delay_line[6] + delay_line[9]) ​ * coeff[6] + 
-                   ​(delay_line[7] + delay_line[8]) ​ * coeff[7]; 
- 
-    //Assign upper 16-bits to output. 
-    assign dout = accum[31:​16];​ 
-      ​ 
-    initial begin    
-        //Load the filter coefficients. 
-        coeff[0] = 16'​d2320;​ 
-        coeff[1] = 16'​d4143;​ 
-        coeff[2] = 16'​d4592;​ 
-        coeff[3] = 16'​d7278;​ 
-        coeff[4] = 16'​d8423;​ 
-        coeff[5] = 16'​d10389;​ 
-        coeff[6] = 16'​d11269;​ 
-        coeff[7] = 16'​d12000;​ 
-                  
-        //​Initialize delay line. 
-        for(i = 0; i < `FILT_LENGTH;​ i = i+1'​b1) begin 
-            delay_line[i] = 16'd0; 
-        end 
-        ​ 
-        //​Initialize the preadder regs. 
-        for(i = 0; i < 8; i = i+1'​b1) begin 
-            preadd_regs[i] = 17'd0; 
-        end 
-                ​ 
-        //​Initialize the multiplier regs. 
-        for(i = 0; i < 8; i = i+1'​b1) begin 
-            mult_regs[i] = 32'd0; 
-        end 
-        ​ 
-        //​Initialize the first layer of the adder tree regs. 
-        for(i = 0; i < 4; i = i+1'​b1) begin 
-            tree1_regs[i] = 32'd0; 
-        end 
-        ​ 
-        //​Initialize the second layer of the adder tree regs. 
-        for(i = 0; i < 2; i = i+1'​b1) begin 
-            tree2_regs[i] = 32'd0; 
-        end        ​ 
-        ​ 
-        //​Initialize the adder tree output reg. 
-        treeout_reg = 32'd0; 
-    end 
-    ​ 
-    //Advance the data through the delay line every clock cycle. 
-    generate 
-        for (c = `FILT_LENGTH-1;​ c > 0; c = c - 1) begin: inc_delay 
-            always @(posedge clk) begin 
-                if(en) delay_line[c] <= delay_line[c-1];​ 
-            end 
-        end 
-    endgenerate 
-    ​ 
-    //Update with input data. 
-    always @(posedge clk) begin 
-        if(en) delay_line[0] <= din; 
-    end 
-endmodule 
- 
-</​code> ​ 
-\\ 
- 
-##### filter_top.v 
-<code verilog> 
- 
-module filter_top( 
-    input clk, 
-    input [7:0]sw, 
-    output [7:0]JA 
-    ); 
-        ​ 
-    wire [15:0]tout; //The output of the tone lookup table. 
-    wire [15:0]fout; //The output of the FIR filter. 
-    wire [15:0]mout; //Selected output. 
-    wire en;         //​Clock enble. 
-    wire clk_out; ​   //264MHz System clock. 
-    ​ 
-    assign en = 1'b1; 
-    ​ 
-    clk_wiz_0 cw (.clk_in1(clk),​ .clk_out1(clk_out));​ 
-    //clk_en ce(.clk(clk_out),​ .en(en)); 
-    ToneGen tg(.clk(clk_out),​ .en(en), .dout(tout));​ 
-    FIR_Filter ff(.clk(clk_out),​ .en(en), .din(tout), .dout(fout));​ 
-    ​ 
-    //Choose filtered or unfiltered output based on sw0. 
-    assign mout = sw[0] ? fout : tout; 
-    ​ 
-    //Take only the upper 8 bits and make it unsigned. 
-    //assign JA = mout[15:8] + 8'​d128;​ 
-    assign {JA[3:0], JA[7:4]} = mout[15:8] + 8'​d128;​ 
-    ​ 
-endmodule 
- 
-</​code> ​ 
-\\ 
- 
- 
- 
-