基于Verilog语言的FIR滤波【程序和理解】

本文分享了一个简单的FIR滤波器设计过程,适合FPGA初学者。通过MATLAB设计8阶低通FIR滤波器,导出滤波器系数,并在QuartusII中编写Verilog代码实现。详细介绍了系数量化、滤波器结构及延时链、加法和乘法器的Verilog实现,最后讨论了根据输入数据位宽调整设计的方法。
摘要由CSDN通过智能技术生成

一直想找一个简单、清晰、明了的fir滤波器的设计,终于找到了一个可以应用的,和大家分享一下,有助于FPGA新手入门。

1.说道fir滤波器,滤波系数肯定是最重要的,因为后面程序中涉及到滤波系数问题,所以先来介绍,此处使用matlab来辅助求出。

①打开matlab中的start,toolbox,filter design,filter design & Analysis Tool,具体位置见下图。

基于Verilog语言的FIR滤波【程序和理解】

②选择想要涉及的滤波器类型,本次以8阶fir滤波器为例。

设计参数:低通fir滤波器,采样精度是根据自己的输入数据来的,本例为25MHz,通过频率2MHz,截止频率8MHz,可以在specify order处选择几阶滤波器。

基于Verilog语言的FIR滤波【程序和理解】
③把滤波器数据导出,选择export,在随后弹出的框中再次点击Export(本步骤可以改变数据的变量名),就可以看到命名为Num的滤波器系数出现在目录里。

基于Verilog语言的FIR滤波【程序和理解】

基于Verilog语言的FIR滤波【程序和理解】

④在matlab框中输入指令Num=Num'

可以看到如下结果,这个就是滤波器的系数了,新建一个txt文件,命名如图,把滤波器系数复制进去。

基于Verilog语言的FIR滤波【程序和理解】

⑤编写matlab程序,进行系数量化。

运行下面一段程序,生成的COF就是最后的量化数据,记录这组数据。

clc;
clear all ;
load COFFICIENT.dat;%加载系数
a1=COFFICIENT(1:1:length(COFFICIENT));
width = 16;%数据宽度8位
% 量化滤波器系数
COF  = round(a1 .* (2^(width-1) - 1));%量化正弦波形数据并取整

基于Verilog语言的FIR滤波【程序和理解】

2.在quartusII中建立一个工程,新建一个fir_filter模块,把我们计算出来的滤波器系数写在程序里面

基于Verilog语言的FIR滤波【程序和理解】
整体程序如下:

`timescale 1 ns / 1 ns

module fir_filter
               (
                i_fpga_clk ,
                i_rst_n    ,
                i_filter_in,
                o_filter_out
                );

input                   i_fpga_clk  ; //25MHz
  input                   i_rst_n     ;
  input   signed      [7:0] i_filter_in ; //数据速率25Mh
  output  signed      [7:0] o_filter_out; //滤波输出

//==============================================================
//8阶滤波器系数,共9个系数,系数对称
//==============================================================
  wire signed[15:0] coeff1 = 16'd239 ;
  wire signed[15:0] coeff2 = 16'd1507;
  wire signed[15:0] coeff3 = 16'd4397;
  wire signed[15:0] coeff4 = 16'd7880;
  wire signed[15:0] coeff5 = 16'd9493;

//===============================================================
//    延时链
//===============================================================
reg signed [7:0] delay_pipeline1 ;
reg signed [7:0] delay_pipeline2 ;
reg signed [7:0] delay_pipeline3 ;
reg signed [7:0] delay_pipeline4 ;
reg signed [7:0] delay_pipeline5 ;
reg signed [7:0] delay_pipeline6 ;
reg signed [7:0] delay_pipeline7 ;
reg signed [7:0] delay_pipeline8 ;

always@(posedge i_fpga_clk or negedge i_rst_n)
       if(!i_rst_n)
                begin
                    delay_pipeline1 <= 8'b0 ;
                     delay_pipeline2 <= 8'b0 ;
                     delay_pipeline3 <= 8'b0 ;
                     delay_pipeline4 <= 8'b0 ;
                     delay_pipeline5 <= 8'b0 ;
                     delay_pipeline6 <= 8'b0 ;
                     delay_pipeline7 <= 8'b0 ;
                     delay_pipeline8 <= 8'b0 ;
                end
       else
                begin
                    delay_pipeline1 <= i_filter_in     ;
                     delay_pipeline2 <= delay_pipeline1 ;
                     delay_pipeline3 <= delay_pipeline2 ;
                     delay_pipeline4 <= delay_pipeline3 ;
                     delay_pipeline5 <= delay_pipeline4 ;
                     delay_pipeline6 <= delay_pipeline5 ;
                     delay_pipeline7 <= delay_pipeline6 ;
                     delay_pipeline8 <= delay_pipeline7 ;
                end
     
//================================================================
//加法,对称结构,减少乘法器的数目
//================================================================
reg signed [8:0] add_data1 ;
reg signed [8:0] add_data2 ;
reg signed [8:0] add_data3 ;
reg signed [8:0] add_data4 ;
reg signed [8:0] add_data5 ;

always@(posedge i_fpga_clk or negedge i_rst_n) //x(0)+x(8)
       if(!i_rst_n)                                   
           add_data1 <= 9'b0 ;
       else
           add_data1 <= i_filter_in + delay_pipeline8 ;

always@(posedge i_fpga_clk or negedge i_rst_n) //x(1)+x(7) 
       if(!i_rst_n)                                        
           add_data2 <= 9'b0 ;                             
       else                                                
           add_data2 <= delay_pipeline1 + delay_pipeline7 ;

always@(posedge i_fpga_clk or negedge i_rst_n) //x(2)+x(6) 
       if(!i_rst_n)                                        
           add_data3 <= 9'b0 ;                             
       else                                                
           add_data3 <= delay_pipeline2 + delay_pipeline6 ;


always@(posedge i_fpga_clk or negedge i_rst_n) //x(3)+x(5) 
       if(!i_rst_n)                                        
           add_data4 <= 9'b0 ;                             
       else                                                
           add_data4 <= delay_pipeline3 + delay_pipeline5 ;

always@(posedge i_fpga_clk or negedge i_rst_n) //x(4) 
       if(!i_rst_n)                                        
           add_data5 <= 9'b0 ;                             
       else                                                
           add_data5 <= {delay_pipeline4[7],delay_pipel

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值