0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

FIR滤波器代码及仿真设计

CHANBAEK 来源:FPGA自学笔记分享 作者:FPGA自学笔记分享 2023-06-02 12:36 次阅读

上文 FPGA数字信号处理之滤波器2_使用dsp48e1的fir滤波器设计完成了结构设计:

图片

根据这一结构,假定要设计一个满速率的fir滤波器,滤波器系数为:[3,13,27,58,62,204,47,546,233,1465,3260,3260,1465,233,546,47,204,62,58,27,13,3],滤波器总共22个系数,对称结构,所以有效系数11个。

以输入数据为自加数为例,根据结构可以得到数据摆放格式如下,clk0时刻的计算公式为:(500+521)*c0+(501+520)*c1+......+(510+511)*c10;clk1时刻的计算公式为:(501+522)*c0+(502+521)*c1+......+(511+512)*c10;....

图片

据此,设计fir代码如下:

代码设置三个参数,数据位宽、系数个数、系数增益,其中系数个数决定代码中乘法器的个数及代码的处理时延,系数增益是系数给数据带来的增益,在数据输出的时候要通过截位截掉。

// ============================================================
// File Name: cm_fir_top
// VERSION  : V1.0
// DATA     : 2023/3/4
// Author   : FPGA干货分享
// ============================================================
// 功能:fir滤波器代码
// coef = 
// delay : 4+C_COEF_NUM*2
// ============================================================




`timescale 1ns/100ps
module cm_fir_top #(
    parameter                           C_DATA_WIDTH     = 16    ,
    parameter                           C_COEF_NUM       = 11    , ///有效系数个数
    parameter                           C_COEF_CUT_NUM   = 12    ) ///四舍五入使用的0.5大小
(
    input  wire                         I_sys_clk                , /// 工作时钟 
    input  wire                         I_rst_in                 , /// 复位 
    input  wire [C_DATA_WIDTH-1:0]      I_data_in                , /// 数据输入
    output reg  [C_DATA_WIDTH-1:0]      O_data_out                 /// 数据输出
);


// ============================================================
// 内部参数
// ============================================================
localparam  C_COEF_05 = 2**C_COEF_CUT_NUM ;


// ============================================================
// 变量
// ============================================================
reg     [C_DATA_WIDTH-1:0]      S_data_in[C_COEF_NUM*2-1:0] ;
wire    [17:0]                  S_coef[C_COEF_NUM-1:0]      ;
wire    [47:0]                  S_pcout[C_COEF_NUM-1:0]     ;
wire    [47:0]                  S_dsp_out[C_COEF_NUM-1:0]   ;

然后就是主代码,使用assign给系数赋值,然后根据系数个数缓存输入数据,用于fir滤波器的卷积操作。随后例化第一个dsp,U0_cm_dsp48e1,该滤波器作为级联滤波器组的开头乘法器,没有级联输入,但是使用C端口作为假四舍五入预加的输入,随后使用generate根据滤波器系数个数生成级联dsp组,最后将最后一级滤波器的输出进行截位,得到最终结果。

// ============================================================
// main code
// ============================================================
assign S_coef[0 ] =  18'd3     ;
assign S_coef[1 ] =  18'd13    ;
assign S_coef[2 ] = -18'd27   ;
assign S_coef[3 ] = -18'd58   ;
assign S_coef[4 ] =  18'd62    ;
assign S_coef[5 ] =  18'd204   ;
assign S_coef[6 ] = -18'd47   ;
assign S_coef[7 ] = -18'd546  ;
assign S_coef[8 ] = -18'd233  ;
assign S_coef[9 ] =  18'd1465  ;
assign S_coef[10] =  18'd3260  ;


always@(posedge I_sys_clk)
    S_data_in[0] <= I_data_in ;




genvar i;
generate for(i=1;i< C_COEF_NUM*2;i=i+1)
    begin
        always@(posedge I_sys_clk)
            S_data_in[i] <= S_data_in[i-1];
    end
endgenerate




cm_dsp48e1 #(
    .C_DATA_WITH_A      (C_DATA_WIDTH                   ),
    .C_DATA_WITH_B      (18                             ),
    .C_DATA_WITH_C      (32                             ),
    .C_DATA_WITH_D      (C_DATA_WIDTH                   )
)
U0_cm_dsp48e1(
    .I_CLK              (I_sys_clk                      ) , // clk
    .I_RST              (I_rst_in                       ) , // RST
    .I_A                (S_data_in[0]                   ) , // [29:0] 
    .I_B                (S_coef[0 ]                     ) , // [17:0] 
    .I_C                (C_COEF_05                      ) , // [47:0] 
    .I_D                (S_data_in[C_COEF_NUM*2-1]      ) , // [24:0] 
    .I_PCIN             (48'd0                          ) , // [47:0] 只能直连PCOUT
    .I_ALUMODE          (4'd0                           ) , // [3:0] 
    .I_INMODE           (5'b00101                       ) , // [4:0] 
    .I_OPMODE           (7'b0110101                     ) , // [6:0]  C + (A+D)*B
    .O_P                (                               ) , // [47:0]
    .O_PCOUT            (S_pcout[0]                     )   // [47:0] 只能直连PCIN
    );




genvar j;
generate for(j=1;j< C_COEF_NUM;j=j+1)
    begin


        cm_dsp48e1 #(
            .C_DATA_WITH_A      (C_DATA_WIDTH                   ),
            .C_DATA_WITH_B      (18                             ),
            .C_DATA_WITH_C      (32                             ),
            .C_DATA_WITH_D      (C_DATA_WIDTH                   )
        )
        U1_cm_dsp48e1(
            .I_CLK              (I_sys_clk                      ) , // clk
            .I_RST              (I_rst_in                       ) , // RST
            .I_A                (S_data_in[2*j]                 ) , // [29:0] 
            .I_B                (S_coef[j ]                     ) , // [17:0] 
            .I_C                (32'd0                          ) , // [47:0] 
            .I_D                (S_data_in[C_COEF_NUM*2-1]      ) , // [24:0] 
            .I_PCIN             (S_pcout[j-1]                   ) , // [47:0] 只能直连PCOUT
            .I_ALUMODE          (4'd0                           ) , // [3:0] 
            .I_INMODE           (5'b00101                       ) , // [4:0] 
            .I_OPMODE           (7'b0010101                     ) , // [6:0] PCin + (A+D)*B
            .O_P                (S_dsp_out[j]                   ) , // [47:0]
            .O_PCOUT            (S_pcout[j]                     )   // [47:0] 只能直连PCIN
            );


    end
endgenerate


always@(posedge I_sys_clk)
    O_data_out <= S_dsp_out[C_COEF_NUM-1][C_COEF_CUT_NUM+1+:C_DATA_WIDTH] ;




endmodule

仿真tb如下,可使用自加数或者单音作为输入:

// ============================================================
// File Name: cm_fir_top
// VERSION  : V1.0
// DATA     : 2023/3/4
// Author   : FPGA干货分享
// ============================================================
// 功能:fir滤波器代码
// delay : 20clk
// ============================================================




`timescale 1ns/100ps
module tb_cm_fir_top ;
    parameter                           C_DATA_WIDTH     = 16    ;
    parameter                           C_COEF_NUM       = 11    ; ///有效系数个数
    parameter                           C_COEF_CUT_NUM   = 12    ; ///四舍五入使用的0.5大小


    reg                                 I_sys_clk                ; /// 工作时钟 
    reg                                 I_rst_in                 ; /// 复位 
    reg         [C_DATA_WIDTH-1:0]      I_data_in                ; /// 数据输入
    wire        [C_DATA_WIDTH-1:0]      O_data_out               ; /// 数据输出,从start开始连续输出,位宽按照最大能力输出


    reg [31:0]      S_clk_cnt ;

initial
    begin
        I_sys_clk    = 'd1;
        I_rst_in     = 'd1;
        I_data_in    = 'd0;
        S_clk_cnt    = 'd0;

        #1000;
        I_rst_in     = 'd0;


    end

always #1 I_sys_clk = ~I_sys_clk;





always @(posedge I_sys_clk) 
    S_clk_cnt <= S_clk_cnt + 'd1;


/// 自加数
always @(posedge I_sys_clk)
    I_data_in <= I_data_in + 'd1;

///单音
// always @(posedge I_sys_clk)
    // I_data_in <= $sin(2*3.14*S_clk_cnt/512)*8192;


cm_fir_top #(
    .C_DATA_WIDTH               ( C_DATA_WIDTH          )  ,
    .C_COEF_NUM                 ( C_COEF_NUM            )  , ///有效系数个数
    .C_COEF_CUT_NUM             ( C_COEF_CUT_NUM        )  ) ///四舍五入使用的0.5大小
cm_fir_top(
    .I_sys_clk                  ( I_sys_clk             )  , /// 工作时钟 
    .I_rst_in                   ( I_rst_in              )  , /// 复位 
    .I_data_in                  ( I_data_in             )  , /// 数据输入
    .O_data_out                 ( O_data_out            )    /// 数据输出,从start开始连续输出,位宽按照最大能力输出
);






endmodule

使用自加数仿真对数如下:

输入输出:

图片

dsp输入数据摆放:

图片

python或者Excel计算的结果:

图片

使用单音仿真结果如下:

图片

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • FPGA
    +关注

    关注

    1602

    文章

    21317

    浏览量

    593154
  • 滤波器
    +关注

    关注

    158

    文章

    7330

    浏览量

    174771
  • FIR
    FIR
    +关注

    关注

    4

    文章

    137

    浏览量

    32724
  • 仿真设计
    +关注

    关注

    3

    文章

    90

    浏览量

    16733
  • 代码
    +关注

    关注

    30

    文章

    4555

    浏览量

    66750
收藏 人收藏

    评论

    相关推荐

    FIR滤波器FAQ原理简述

      1、FIR 滤波器是在数字信号处理(DSP)中经常使用的两种基本的滤波器之一,另一个为IIR滤波器。  2、FIR代表有限冲激响应(Fi
    发表于 09-24 16:05

    基于FPGA的FIR滤波器设计与实现

    DSPBuilder设计了一个4阶FIR滤波器,并用QuartusII进行硬件仿真,仿真结果表明设计FIR
    发表于 08-11 15:32

    串行结构的FIR滤波器设计(含文档 代码资料)

    使用verilog设计的FIR滤波器,该滤波器采用了串行结构,占用资源少。虽然FIR滤波器可以用IP核实现,但通过本
    发表于 04-14 15:20

    FIR滤波器的设计

    第一个问题的基础上,我是设置unsigned还是signed?3、滤波器的设计,我要给他什么样子的输入,仿真看得出什么样子的结果?部分代码如下
    发表于 05-09 14:18

    如何设计低通FIR滤波器

    此示例显示如何设计低通FIR滤波器。这里介绍的许多概念可以扩展到其他响应,如高通,带通等。FIR滤波器被广泛使用,因为它们具有强大的设计算法,以非递归形式实现时的固有稳定性,可以轻松实
    发表于 08-23 10:00

    基于FPGA的FIR滤波器IP仿真实例

    基于FPGA的FIR滤波器IP仿真实例 AT7_Xilinx开发板(USB3.0+LVDS)资料共享 腾讯链接:https://share.weiyun.com/5GQyKKc 百度网盘链接
    发表于 07-16 17:24

    怎么设计高阶FIR滤波器

    相对无限冲击响应(IIR)滤波器,有限冲击响应(FIR)能够在满足滤波器幅频响应的同时获得严格的线性相位特性,而数据通信、语音信号处理等领域往往要求信号在传输过程中不能有明显的相位失真,所以F
    发表于 08-23 06:39

    并行FIR滤波器Verilog设计

    宽的运算步进浪费资源而且也没有必要。在MATLAB中将滤波器系数量化为指定位宽,会改变滤波器的频率特性,因此需要做好仿真,确定量化后的系数也能满足FIR的设计需求。由上节可知FPGA最
    发表于 09-25 17:44

    为什么要使用FIR滤波器

    FIR滤波器如何定义?为什么要使用FIR滤波器
    发表于 04-06 07:48

    FIR滤波器的特性是什么

    数字滤波器的类型有FIR(有限长冲击与IIR(无限长。离散数字系统中,滤波器的表述为差分方程。FIRFIR基本特性:FIR 滤波器永远是稳定
    发表于 08-17 06:19

    fir滤波器的设计和实现

    使用iir滤波器相对fir滤波器可以在使用更小的阶数的情况下实现更好的效果。实验证明,可能20阶的iir效果堪比500阶左右的fir滤波器
    发表于 12-22 08:29

    什么是fir数字滤波器 什么叫FIR滤波器

    什么是fir数字滤波器 Part 1: Basics1.1 什么是FIR滤波器?FIR 滤波器
    发表于 01-16 09:42 1.6w次阅读

    高效FIR滤波器的设计与仿真-基于FPGA

    高效FIR滤波器的设计与仿真-基于FPGA 摘要:该文在介绍有限冲激响应(FIR)数字滤波器理论及常见实现方法的基础上,提出了一种基于FP
    发表于 01-16 09:56 1473次阅读
    高效<b class='flag-5'>FIR</b><b class='flag-5'>滤波器</b>的设计与<b class='flag-5'>仿真</b>-基于FPGA

    FIR滤波器的FPGA设计与实现

    ,结合MATLAB软件提供的专用数字滤波器设计工具包FDATOOL,以及QuartusⅡ软件提供的FIR核实现快速、便捷的设计FIR滤波器的几个具体实验,得出结论证实了熟练使用FDAT
    发表于 12-21 14:53 14次下载
    <b class='flag-5'>FIR</b><b class='flag-5'>滤波器</b>的FPGA设计与实现

    使用DSP设计和仿真FIR滤波器

    本文档的主要内容详细介绍的是使用DSP设计和仿真FIR滤波器包括了:dsp builder profile和基本设计流程和fir的设计过程及注意事项
    发表于 09-01 16:02 12次下载
    使用DSP设计和<b class='flag-5'>仿真</b><b class='flag-5'>FIR</b><b class='flag-5'>滤波器</b>