m基于FPGA的FIR低通滤波器实现和FPGA频谱分析,包含testbench和滤波器系数MATLAB计算程序

212 阅读3分钟

1.算法仿真效果

本系统进行了Vivado2019.2平台的开发,Vivado2019.2仿真结果如下:

 

整体仿真结果如下:

 

d68b7af5de2e45e7e25790d4ec7a46c9_watermark,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=.jpg

 

放大看,滤波效果如下:

 

bd6327e6b4b5f83d2c587afd67f5e5f0_watermark,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=.jpg

 

对应的频谱如下:

 

2a3734e0027c556d7a4b98166e1157d8_watermark,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=.jpg

 

FPGA的RTL结构如下:

 

7184ead18957cbe890acb0f0e36f5740_watermark,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=.jpg

 

最后用matlab对比仿真,结果如下:

 

3e441e92d90b807313f51c5c5301b588_watermark,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=.jpg

  4ef7d9fad8d5ae7f1b1ad2f229ebfe6f_watermark,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=.jpg

可以看到,FPGA的滤波效果和频谱分析与matlab的结果一致。

 

2.算法涉及理论知识概要

       基于FPGA(Field-Programmable Gate Array,现场可编程门阵列)的数字低通滤波器实现和FPGA频谱分析是数字信号处理领域的重要应用,广泛应用于通信、音频处理、图像处理等多个行业。数字低通滤波器旨在允许低频信号通过而衰减高频信号,是信号处理中基础且重要的组件之一。其设计通常基于时域采样定理和滤波器设计理论,常见的实现方法有IIR(无限脉冲响应)滤波器和FIR(有限脉冲响应)滤波器。

 

b24d59579f29c43528f4e4f3876544ee_watermark,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=.png

 

       在FPGA上实现FIR滤波器,主要通过配置硬件逻辑资源(如查找表LUTs、触发器等)来实现上述卷积运算。具体步骤包括:

 

系数存储:滤波器系数h[k]被存储在FPGA的块RAM中。

并行处理:利用FPGA的并行处理能力,将输入信号序列分块处理,每一块与滤波器系数进行并行卷积。

流水线设计:为了提高处理速度,设计中通常采用流水线技术,即每个运算步骤在不同的时钟周期完成,从而实现连续数据流处理。

      频谱分析是将信号从时域转换到频域,以观察其频率组成的技术。在FPGA上实现频谱分析,最常见的方式是使用离散傅里叶变换(DFT)或其快速版本——快速傅里叶变换(FFT)。

 

4883fb81cc8dcddb2faa0c25c54e78e7_watermark,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=.png

 

3.Verilog核心程序 ``timescale 1ns / 1ps

//

// Company:

// Engineer:

//

// Create Date: 2024/05/27 21:38:45

// Design Name:

// Module Name: test

// Project Name:

// Target Devices:

// Tool Versions:

// Description:

//

// Dependencies:

//

// Revision:

// Revision 0.01 - File Created

// Additional Comments:

//

//

 

 

module test();

 

reg i_clk;

reg i_rst;

wire signed[15:0]o_x;

wire signed[15:0]o_y;

reg i_before_fft1;                 

reg i_last_fft1;   

reg i_enable1;  

wire             o_enable1;  

wire             o_enable2;  

wire signed[63:0]o_abs_ifft1;

wire signed[63:0]o_abs_ifft2;

 

tops tops_U(

.i_clk (i_clk),

.i_rst (i_rst),

.o_x   (o_x),

.o_y   (o_y),

.i_before_fft1  (i_before_fft1),

.i_last_fft1    (i_last_fft1),

.i_enable1      (i_enable1),

.o_enable1      (o_enable1),

.o_enable2      (o_enable2),

.o_abs_ifft1    (o_abs_ifft1),

.o_abs_ifft2    (o_abs_ifft2)

);

 

initial

begin

i_clk=1'b1;

i_rst=1'b1;

#100

i_rst = 1'b0;

end

always #5 i_clk=~i_clk;

reg [19:0]cnts2;

always @(posedge i_clk or posedge i_rst)

begin

     if(i_rst)

     begin

     cnts2        <= 20'd0;

     i_before_fft1<=1'b0;

     i_enable1    <=1'b0;

     i_last_fft1  <=1'b0;

     end

else begin

          if(cnts2==20'd25000)

          cnts2  <= cnts2;

          else

          cnts2  <= cnts2 + 20'd1;

          if(cnts2==20'd0)

          begin

             i_before_fft1<=1'b1;

             i_enable1    <=1'b0;

             i_last_fft1  <=1'b0;

          end

          if(cnts2==20'd1)

          begin

             i_before_fft1<=1'b1;

             i_enable1    <=1'b0;

             i_last_fft1  <=1'b0;

          end

          if(cnts2==20'd2)

          begin

             i_before_fft1<=1'b1;

             i_enable1    <=1'b0;

             i_last_fft1  <=1'b0;

          end

          if(cnts2==20'd3)

          begin

             i_before_fft1<=1'b1;

             i_enable1    <=1'b0;

             i_last_fft1  <=1'b0;

          end

          

          if(cnts2==20'd4)

          begin

             i_before_fft1<=1'b0;

             i_enable1    <=1'b0;

             i_last_fft1  <=1'b0;

          end

          if(cnts2>=20'd5 & cnts2<=20'd4+2047)

          begin

             i_before_fft1<=1'b0;

             i_enable1    <=1'b1;

             i_last_fft1  <=1'b0;

          end

          

          if(cnts2==20'd4+2048)

          begin

             i_before_fft1<=1'b0;

             i_enable1    <=1'b1;

             i_last_fft1  <=1'b1;

          end

          

          if(cnts2>20'd4+2048)

          begin

             i_before_fft1<=1'b0;

             i_enable1    <=1'b0;

             i_last_fft1  <=1'b0;

          end

     

     

     

     end

end

 

 

 

endmodule

00_065m`