精华内容
下载资源
问答
  •  文中基于多速率数字信号处理原理,设计了用于数字下变频技术的CIC抽取滤波器。通过分析CIC滤波器的原理及性能参数,利用MATLAB设计了符合系统要求的CIC滤波器,并通过FPGA实现了CIC滤波器的设计
  • 基于MATLAB FDATOOL的CIC滤波器设计

    千次阅读 热门讨论 2018-05-27 22:21:36
    CIC滤波器的主要特点是,仅利用加法器、减法器和寄存器,占用资源少,实现简单且速度高。CIC滤波器是数据通信的常用模块,一般应用于数字下变频(DDC)和数字上变频(DUC)系统,随着数据传输率的不断增加,级联梳状...

    级联积分梳状(CIC)滤波器是一种被广泛应用于软件无线电中,可以实现抽取或者插值的高效滤波器。它主要用于降低或提高采样率。CIC滤波器的主要特点是,仅利用加法器、减法器和寄存器,占用资源少,实现简单且速度高。

    CIC滤波器是数据通信的常用模块,一般应用于数字下变频(DDC)和数字上变频(DUC)系统中,随着数据传输率的不断增加,级联梳状滤波器(CIC)的应用变得非常重要,CIC滤波器仅利用加法器、减法器和寄存器的特点,所以非常适用工作在高采样率下。数字下变频(DDC)中,CIC滤波器起着重要的作用,它主要用对于采样速率的抽取,同时具有低通滤波器的特性。

    滤波器的Z变换为:

     


    积分器I




     


    1 积分器的结构图

    疏状滤波器C:

     


     

    D是延时因子,是滤波器的一个重要参数,可以用来控制滤波器的频率响应,决定零点的位置。D可以是任意正整数,但是D越大,会导致带内主瓣的衰减过大,所以通常取12



    单级CIC滤波器的的结构图



     

    N级内插滤波器



    N级抽取滤波器

     

    衰减:滤波器为单级时,第一旁瓣与主瓣的比值:

     



    为四级滤波器时,第一旁瓣与主瓣的比值:

     


     

    中间变量的位扩展:

    从而在输入信号位数为Bin的情况下,滤波输出的最大可能位数为:

     


    R为抽取或插值因子,N滤波器级数。


    2.matalab分析CIC插值滤波器频谱

    打开matlab,选择左下角的“start”,“toolboxes”—“filterDesign”—“fdatool

    打开fadtool界面:

     

    设计(25/24)MHz采样率、24倍插值、4CIC滤波器的频谱图,如下:

     


    由上图可以见,主瓣大概40KHz,通带只有30KHz

     

    2、用matlab程序sin_1MHz_gen.m生成正弦波波形表,改变变量f0=1.5e6可以生成不同频率的波形。把第一个周期的波形数据存入signal_1m.dat文件中,存入的数据个数为Fs/Fo的最小正整数之比的分子,比如Fs=25MHzFo=0.3MHz,Fs/Fo=250/3(Fs=25/24MHz),则存入文件signal_1m.dat的波形数据个数为开头的250个数据。相应的signal_gen0.v中的语句if(i0<50)相应的改为if(i0<250)仿真时signal_1m.dat放在仿真目录下

     

    3、用sin_1MHz_gen.m产生1MHz正弦波信号,并把数据hex_sin_data的前25个数据存入signal_1m.dat文件,相应的signal_gen0.v中的语句if(i0<50)相应的改为if(i0<25)

    仿真的波形如下图:



    由图可见数据速率变高了,变为了25MHz,同时对信号也起了衰减作用

     

    4、用sin_1MHz_gen.m产生0.1MHz正弦波信号(f0=0.1e6Fs/Fo=125/12,把数据hex_sin_data的前125个数据存入signal_1m.dat文件,相应的signal_gen0.v中的语句if(i0<25)相应的改为if(i0<125)

    仿真的波形如下图:



    CIC对信号旗衰减左右。

    5、用sin_1MHz_gen.m产生1MHz正弦波信号(f0=0.01e6Fs/Fo=625/6,把数据hex_sin_data的前625个数据存入signal_1m.dat文件,相应的signal_gen0.v中的语句if(i0<50)相应的改为if(i0<625)

    仿真的波形如下图:



     

    由此可见CIC滤波器对带内的信号也是具有小的衰减

    由此可见CIC适合作为窄带低通滤波器。部分代码如下:


    //==========================================================================
    `timescale 1ns/1ps

    module   cic_dec_arithmetic
       (
    //sys_signal
       input          i_fpga_clk      ,//25MHz
       input          i_rst_n         ,
    //input    
       input   [7:0] i_cic_data      ,  //输入的数据
       
       output  [7:0] o_cic_data      

        );
       
       
    //=============================== main=============================
    //==================================================================
    //1.                      积分器例化                
    //==================================================================
    //--CIC0
       wire  [26:0] integral_data    ;//位扩展,防止累加溢出,8+4*log2(24)=27
       
    multilevel_integrator   u0_multilevel_integrator
       (
    //sys_signal
       .i_fpga_clk                (i_fpga_clk       ),//25MHz
       .i_rst_n                   (i_rst_n          ),           
    //input
       .i_integral_data           (i_cic_data      ),
    //output   
       .o_integral_data           (integral_data   )
        );
       

           
    //==================================================================                                                                           
    //2.                   24倍抽取,当然抽取率也可以取1                                    
    //==================================================================
    wire  [26:0] dec24_data    ;
    wire         dec24_fp      ;

    cic_dec24   u0_cic_dec24
       (
    //sys_signal
       .i_fpga_clk       ( i_fpga_clk   ),//25Mhz
       .i_rst_n          (i_rst_n     ),                        
    //input                                          
       .i_data           ( integral_data),

       .o_data           ( dec24_data  ),
       .o_fp             ( dec24_fp   )
        );
       
    //==================================================================                                                                           
    //3.                     派生滤波器                                     
    //==================================================================
    multilevel_der_filter   u0_multilevel_der_filter
       (
    //sys_signal
       .i_fpga_clk            ( i_fpga_clk   ),//25MHz
       .i_rst_n               (i_rst_n      ),                       
    //input
       .i_data        

    展开全文
  • 设定低通滤波器的采样频率为112MHz,信号带宽为30MHz,,那么对于同相与正交分量分别具有15MHz带宽,因此低通滤波器的通频带为15MHz,参数配置如下(在MATLAB中调用fdatool函数) ...

    FDATool界面左下侧排列了一组工具按钮,其功能分别如下所述:
    ● 创建多速率滤波器(Create a Multirate Filter)
    ● 滤波器转换(TransForm Filter)
    ● 设置量化参数(Set Quantization Parameters)
    ● 实现模型(Realize Model)
    ● 零极点编辑器(Pole-zero Editor)
    ● 导入滤波器(Import Filter)
    ● 设计滤波器(Design Filter)

    一、低通滤波器
    设定低通滤波器的采样频率为112MHz,信号带宽为30MHz,,那么对于同相与正交分量分别具有15MHz带宽,因此低通滤波器的通频带为15MHz,参数配置如下(在MATLAB中调用fdatool函数)
    在这里插入图片描述
    滤波器界面介绍网址https://www.cnblogs.com/sunev/archive/2011/11/22/2258426.html
    二、CIC滤波器
    1、用MATLAB实现
    当采用N级CIC滤波器级联时,主瓣电平A0与旁瓣电平A1的差值可表示
    在这里插入图片描述
    采用5级CIC滤波器级联,主瓣电平A0与旁瓣电平A1的差值为
    在这里插入图片描述
    在这里插入图片描述
    在5级CIC滤波器中,内插因子设为30,采样速率设为3.125MHz。
    2、用simulink实现

    三、低通有限冲激响应(Fir)滤波器
    1、用fdatool工具
    滤波器类型(Filer Type)为低通(Low Pass)
    设计方法(Design Method)为FIR,采用窗函数法(Window)
    滤波器阶数(Filter order)定制为19(注意这里输入的数值是所要设计的滤波器的阶数减 1,本设计是20阶滤波器)
    窗口类型为Kaiser,Beta为5
    采样频率Fs为3125kHz,截止频率Fc为5kHz
    最后单击Design Filter图标,让MATLAB计算FIR滤波器系数并作相关分析(在 FDATool 工具界面中,点击 File 选择 Export,在弹出窗口中点击 Export,即可在 MATLAB 中生成所设计的滤波器的抽头系数)
    在这里插入图片描述
    在这里插入图片描述
    2、用MATLAB代码
    恺撒窗(Kaiser Window) 
    调用格式:w=kaiser(n,beta),根据长度 n 和影响窗函数旁瓣的β参数产生一个恺撒窗w。
    fir1(n,Wn,Window),n 为阶数、Wn 是截止频率(如果输入是形如[W1 W2]的矢量时,本函数将设计带通/带阻滤波器。
    [H,W ] = freqz(b,a,n)返回n点复频响应矢量H和n点的频率向量w。b和a为系统传递函数的分子和分母的系数向量。如果n没有指定,默认为512。

    b = fir1(19,0.04,kaiser(20,5));
    [h1,w1]=freqz(b,1);  
    plot(w1/pi,20*log10(abs(h1))); 
    axis([0,1,-70,5]); 
    grid on;
    xlabel('归一化频率/p') ;
    ylabel('幅度/dB') ;
    

    在这里插入图片描述

    展开全文
  • 单级CIC滤波器的主瓣衰减并不是很理想。所以需要采用多级CIC滤波器。 1.多级CIC滤波器系统函数可写为:在根据抽取器(内插器)与线性系统(滤波器)可以位置互换的原则,可以得到一下的框图: 从图可以看出,...

    以下内容来自:数字滤波器的MATLAB与FPGA实现--杜勇

    单级CIC滤波器的主瓣衰减并不是很理想。所以需要采用多级CIC滤波器。

    1.多级CIC滤波器系统函数可写为:在根据抽取器(内插器)与线性系统(滤波器)可以位置互换的原则,可以得到一下的框图:

     

    从图中可以看出,多级CIC可以由3个模块组成,积分模块,抽取模块,梳状模块。

    2.接下来还有的就是各个模块的字位宽问题。

    WI是CIC中间处理过程字位宽,Win是输入数据字位宽,N是CIC滤波器阶数,M是抽取因子,D是滤波器级数

    数据滤波器的最终输出位宽

     

    仿真代码:https://download.csdn.net/download/qian_123456/12178297

    仿真结果:

     

    展开全文
  • 单级CIC滤波器理论与设计项目简述多级CIC滤波器多级CIC滤波器的抽取操作多级CIC滤波器的内插操作多级CIC滤波器的抽取的MATLAB实现 项目简述 我们上一篇博客对CIC滤波器的理论与实现进行了详细的介绍,相信同学们从前...

    项目简述

    我们上一篇博客对CIC滤波器的理论与实现进行了详细的介绍,相信同学们从前一篇博客可以进行相应的学习。但是CIC滤波器本质上就是 低通滤波器。为什么如此常用,只是因为CIC滤波器构成简单不需要乘法器,运行速度快,在通信中的上下变频中非常常用。当然CIC滤波器可是使用低通滤波器来实现,但是资源利用率不高。

    本次项目我们将使用多级CIC滤波器进行抽取与插值操作,这样做的目的主要是为了提高阻带衰减,是有用信号的占比更大。但是提高阻带衰减的同时会降低通带衰减,这些特点也就决定了CIC滤波器在数字上下变频中的应用,因为该应用中信号的抽样频率远大于有用信号的频率。学习这一篇博客的时候一定要先学习上一篇博客,否则会导致概念不明白。

    多级CIC滤波器

    根据上一篇文章我们关于CIC滤波器严格的计算,可以发现单级CIC滤波器的第一旁瓣电平衰减固定为 13.46dB,且与滤波器的阶数无关。然而,这个 阻带衰减通常不满足实际中的要求,所以会把多个简单的CIC滤波器进行级联,所以称为 多级CIC滤波器
    不过增加CIC滤波器的级数也有不利的影响:通带衰减也随着增加。换句话说,对于给定的通带衰减要求,多 级CIC滤波器的通带范围会随着级数的增加而不断变窄,通带衰减也会随之增加。滤波器的设计不仅要考虑阻带误差容限,还要考虑通带误差容限,设计多级CIC滤波器时要注意考虑这个问题。这里再次强调CIC滤波器就是低通滤波器,至于为什么不使用其他的低通滤波器,而使用CIC滤波器,主要是因为结构简单。

    其实,CIC滤波器大多应用于 抗混叠抽取/内插滤波器,也是因为上述的原因。因为在抗混叠应用中,有效信号频带往往远小于采样率,因此总可以设计出同时满足通带和阻带要求的CIC滤波器。

    多级CIC滤波器的抽取操作

    常见信号的抽取操作如下图:
    在这里插入图片描述
    从上面我们可以看出一般先进行抗混叠滤波再进行抽取。这事抗混叠滤波就可以使用如下CIC多级滤波器进行级联。
    在这里插入图片描述
    上面的图是一级CIC,如果感觉阻带衰减不满足要求,那么可以进行多级CIC滤波器的级联。

    理论上多级CIC滤波器可以直接由多个单级CIC滤波器级联得到,但根据 Noble恒等式(“先进行抽取或者插值,再进行线性滤波”与“先进行线性滤波,再进行抽取或者插值”这两者是可以等价的) 。这个公式特别重要也是CIC滤波器在抗混叠滤波器应用如此广泛的另一个原因。所以根据这个原理,当抽取时,我们把抽取操作放到CIC滤波器积分与梳状之间。假设抽取个数与CIC滤波器的阶数相同,那么级联的梳状滤波器正好变成一阶,如下图:
    在这里插入图片描述
    在这里插入图片描述
    多级CIC抽取的整个级联图倍简化成上面图形,所以CIC滤波器在抽取中才会那么常用。

    多级CIC滤波器的内插操作

    上面我们我们已经介绍了CIC滤波器在抽取中的优点以及特殊结构。接下来我们将介绍CIC滤波器在内插中的优点及特殊结构。
    常见的内插操作如下:
    在这里插入图片描述
    从上面我们可以看出一般先进行内插再进行抗混叠滤波。这时抗混叠滤波就可以使用如下CIC多级滤波器进行级联。
    在这里插入图片描述
    上面的图是一级CIC,如果感觉阻带衰减不满足要求,那么可以进行多级CIC滤波器的级联。

    同样,利用 Noble恒等式,我们可以将内插操作放到梳状滤波器与积分滤波器的中间。假设内插的个数与梳状滤波器的阶数相同,那么将内插操作插入到梳状滤波器之后,便可以将梳状滤波器化简为1阶滤波器。从而减少硬件资源量,变化之后的图形如下图:
    在这里插入图片描述

    多级CIC滤波器的抽取的MATLAB实现

    我们实现的功能是,采样率1MHz,信号2.5KHz的正弦波进行采样,然后将采样之后的信号进行4倍抽取。在这个程序中,我们使用的是3级4阶CIC滤波器级联进行滤波操作。最后对比两个结果。我们严格按照变形之后的图形,即经过Noble恒等式变形之后的图形进行编写MATLAB代码:

    close all
    clear all
    clc
     
    %set system parameter
    fs = 2500;    %The frequency of the local oscillator signal
    Fs = 1000000;   %sampling frequency
    N =  24;         %Quantitative bits
    L = 50000000;
     
    %Generating an input signal
    t =0:1/Fs:(1/Fs)*(L-1);          %Generating the time series of sampling frequencies
    sc =sin(2*pi*fs*t);        %a sinusoidal input signal that produces a random starting phase
     
    b =[1,-1];%integerator
    a =[1,-1];%comb 
     
    %comb
    c1=filter(1,b,sc);
    c2=filter(1,b,c1);
    c3=filter(1,b,c2);
     
    y = downsample(c3,4);
     
    %integerater
    i1 =filter(a,1,y);
    i2 =filter(a,1,i1);
    i3 =filter(a,1,i2);
    sf = i3;
     
     
     
    figure(1),
    subplot(211),stem(t(1:1600),sc(1:1600));
    xlabel('时间(t)','fontsize',8);
    ylabel('幅度(dB)','fontsize',8);
    title('sc','fontsize',8);
    subplot(212),stem(t(1:400),sf(1:400));
    xlabel('时间/4(t)','fontsize',8);
    ylabel('幅度(dB)','fontsize',8);
    title('sf','fontsize',8);
    

    相信大家经过MATLAB代码与博客理论之间的学习,可以很容易学会CIC滤波器在信号抽取上面的实现。

    多级CIC滤波器的抽取的MATLAB结果

    我们将上面的MATLAB文件进行运行,结果如下:
    在这里插入图片描述
    从上面的结果可以看出我们成功实现了CIC抽取操作。
    在这里插入图片描述

    多级CIC滤波器的内插的MATLAB实现

    我们实现的功能是,采样率0.25MHz,信号2.5KHz的正弦波进行采样,然后将采样之后的信号进行4倍内插。在这个程序中,我们使用的是3级4阶CIC滤波器级联进行滤波操作。我们的内插操作也是按照前面Noble恒等式变形之后的图形进行的程序**。这里需要注意一下,上一篇博客关于单级CIC滤波器的内插操作,我们没有按照变形之后的图像操作,只是把CIC当成了一个简单的低通滤波器来进行信号处理。但是抽取部分吗是严格按照变形之后的图形进行的。**,代码如下:

    close all
    clear all
    clc
     
    %set system parameter
    fs = 2500;    %The frequency of the local oscillator signal
    Fs = 250000;   %sampling frequency
    L = 81920;
     
    %Generating an input signal
    t =0:1/Fs:(1/Fs)*(L-1);          %Generating the time series of sampling frequencies
    sc =sin(2*pi*fs*t);        %a sinusoidal input signal that produces a random starting phase
     
    b =[1,-1];%comb
    a =[1,-1];%integerator
     
    %comb
    c1=filter(b,1,sc);
    c2=filter(b,1,c1);
    c3=filter(b,1,c2);
     
    y = upsample(c3,4);
     
    %integerater
    i1 =filter(1,a,y);
    i2 =filter(1,a,i1);
    i3 =filter(1,a,i2);
    sf = i3;
     
     
     
    figure(1),
    subplot(211),stem(t(1:320),sc(1:320));
    xlabel('时间(t)','fontsize',8);
    ylabel('幅度(dB)','fontsize',8);
    title('sc','fontsize',8);
    subplot(212),stem(t(1:1280),sf(1:1280));
    xlabel('时间*4(t)','fontsize',8);
    ylabel('幅度(dB)','fontsize',8);
    title('sf','fontsize',8);
    

    同样从上面的MATLAB代码,相信大家可以很容易的学会基于CIC滤波器的内插操作。

    多级CIC滤波器的内插的MATLAB结果

    在这里插入图片描述
    从上面的结果可以看出,我们实现的基于CIC滤波器的内插操作成功实现。

    多级CIC滤波器的抽取的FPGA实现

    由于积分运算会导致数据位宽扩展,首先需要确定积分器的输出数据位宽。可以借助如下公式,当输入信号为Bin位时,积分器最大可能输出位数为:
    在这里插入图片描述
    R为抽取/插值倍数,D为滤波器级数,N为滤波器阶数。
    梳状滤波器模块设计与积分模块很相似,只不过是由寄存器和减法器组成的。该模块的输出即为整个CIC抽取滤波器的输出数据,位宽可由如下公式确定:
    在这里插入图片描述
    当然我们程序中使用的位宽稍大。
    我们此代码得书写严格按照我们博客上面给得结构,也与MATLAB的流程一摸一样,但是输出可以极大的缩小位宽,为了方便原因,我们不再调整。

    我们实现的功能是,采样率1MHz,信号2.5KHz的正弦波进行采样,然后将采样之后的信号进行4倍抽取。在这个程序中,我们使用的是3级4阶CIC滤波器级联进行滤波操作

    多级CIC滤波器的抽取的FPGA代码

    cic模块:

    `timescale 1ns / 1ps
    // *********************************************************************************
    // Project Name : OSXXXX
    // Author       : zhangningning
    // Email        : nnzhang1996@foxmail.com
    // Website      : 
    // Module Name  : cic.v
    // Create Time  : 2020-04-24 15:08:16
    // Editor       : sublime text3, tab size (4)
    // CopyRight(c) : All Rights Reserved
    //
    // *********************************************************************************
    // Modification History:
    // Date             By              Version                 Change Description
    // -----------------------------------------------------------------------
    // XXXX       zhangningning          1.0                        Original
    //  
    // *********************************************************************************
        
    module cic(
        //System Interfaces
        input                           sclk            ,
        input                           rst_n           ,
        //Communication Interfaces
        input                           rvalid          ,
        input           signed  [ 9:0]  din             ,
        output  reg                     tvalid          ,
        output  reg     signed  [33:0]  dout            
    );
     
    //========================================================================================\
    //**************Define Parameter and  Internal Signals**********************************
    //========================================================================================/
    wire    signed      [33:0]  din_x           ;     
    //积分器
    wire    signed      [33:0]  int_in1         ;
    wire    signed      [33:0]  int_in2         ;
    wire    signed      [33:0]  int_in3         ;
    reg     signed      [33:0]  int_r1          ;
    reg     signed      [33:0]  int_r2          ;
    reg     signed      [33:0]  int_r3          ;
    wire    signed      [33:0]  int_data        ;
    //抽取
    reg                 [ 2:0]  cnt             ;
    reg                         ext_valid       ;
    //梳状滤波器
    wire    signed      [33:0]  comb_din        ;      
    reg     signed      [33:0]  comb_r1         ;
    reg     signed      [33:0]  comb_r2         ;
    reg     signed      [33:0]  comb_r3         ;
    wire    signed      [33:0]  comb_in1        ;
    wire    signed      [33:0]  comb_in2        ;
    wire    signed      [33:0]  comb_in3        ;
    
    
    //========================================================================================\
    //**************     Main      Code        **********************************
    //========================================================================================/
    assign      din_x       =       rvalid == 1'b1 ? {{24{din[9]}},din}: din_x;
    assign      int_in1     =       int_r1 + din_x; 
    assign      int_in2     =       int_r2 + int_in1;
    assign      int_in3     =       int_r3 + int_in2; 
    assign      comb_din    =       ext_valid == 1'b1 ? int_in3 : comb_din;
    assign      comb_in1    =       comb_din - comb_r1;
    assign      comb_in2    =       comb_in1 - comb_r2;
    assign      comb_in3    =       comb_in2 - comb_r3; 
    
    always @(posedge sclk or negedge rst_n)
        if(rst_n == 1'b0)
            int_r1          <=      34'd0;
        else if(rvalid == 1'b1)
            int_r1          <=      int_in1;
        else 
            int_r1          <=      int_r1;
    
    always @(posedge sclk or negedge rst_n)
        if(rst_n == 1'b0)
            int_r2          <=      34'd0; 
        else if(rvalid == 1'b1)
            int_r2          <=      int_in2;
        else
            int_r2          <=      int_r2;        
    
    always @(posedge sclk or negedge rst_n)
        if(rst_n == 1'b0)
            int_r3          <=      34'd0; 
        else if(rvalid == 1'b1)
            int_r3          <=      int_in3;
        else
            int_r3          <=      int_r3;
              
    always @(posedge sclk or negedge rst_n)
        if(rst_n == 1'b0)
            cnt             <=      3'd0;
        else if(rvalid == 1'b1 && cnt == 'd3) 
            cnt             <=      3'd0;
        else if(rvalid == 1'b1)
            cnt             <=      cnt + 1'b1;
        else 
            cnt             <=      cnt;
    
    always @(*)
        if(rvalid == 1'b1 && cnt == 'd3)
            ext_valid       <=      1'b1;
        else
            ext_valid       <=      1'b0;
    
    always @(posedge sclk or negedge rst_n)
        if(rst_n == 1'b0)
            comb_r1         <=      34'd0;
        else if(ext_valid == 1'b1)
            comb_r1         <=      int_in3;
        else 
            comb_r1         <=      comb_r1;
    
    always @(posedge sclk or negedge rst_n)
        if(rst_n == 1'b0)
            comb_r2         <=      34'd0;
        else if(ext_valid == 1'b1)
            comb_r2         <=      comb_in1;
        else
            comb_r2         <=      comb_r2;
                
     always @(posedge sclk or negedge rst_n)
        if(rst_n == 1'b0)
            comb_r3         <=      34'd0;
        else if(ext_valid == 1'b1)
            comb_r3         <=      comb_in2;
        else
            comb_r3         <=      comb_r3;   
    
    always @(posedge sclk or negedge rst_n)
        if(rst_n == 1'b0)
            dout            <=      'd0;
        else if(ext_valid == 1'b1)
            dout            <=      comb_in3;
        else
            dout            <=      dout;
            
    always @(posedge sclk or negedge rst_n)
        if(rst_n == 1'b0)
            tvalid          <=      1'b0;
        else 
            tvalid          <=      ext_valid;
        
    
    endmodule
    
    

    多级CIC滤波器的抽取的FPGA测试代码

    tb模块:

    `timescale 1ns / 1ps
    // *********************************************************************************
    // Project Name : OSXXXX
    // Author       : zhangningning
    // Email        : nnzhang1996@foxmail.com
    // Website      : 
    // Module Name  : tb.v
    // Create Time  : 2020-04-24 16:00:12
    // Editor       : sublime text3, tab size (4)
    // CopyRight(c) : All Rights Reserved
    //
    // *********************************************************************************
    // Modification History:
    // Date             By              Version                 Change Description
    // -----------------------------------------------------------------------
    // XXXX       zhangningning          1.0                        Original
    //  
    // *********************************************************************************
    
    module tb();
    reg                 sclk            ;
    reg                 rst_n           ;
    wire                rvalid          ;
    wire        [ 7:0]  din             ;
    wire                tvalid          ;
    wire        [12:0]  dout            ;     
    
    initial begin
        sclk            =           1'b0;
        rst_n           <=          1'b0;
        #(1000);
        rst_n           <=          1'b1;
    end
    always      #(500)       sclk        =           ~sclk;
    
    dds_compiler_0 dds_compiler_0_inst (
      .aclk                         (sclk                       ),                              // input wire aclk
      .m_axis_data_tvalid           (rvalid                     ),  // output wire m_axis_data_tvalid
      .m_axis_data_tdata            (din                        )    // output wire [7 : 0] m_axis_data_tdata
    );
    
    cic cic_inst(
        //System Interfaces
        .sclk                       (sclk                       ),
        .rst_n                      (rst_n                      ),
        //Communication Interfaces
        .rvalid                     (rvalid                     ),
        .din                        ({{2{din[7]}},din}          ),
        .tvalid                     (tvalid                     ),
        .dout                       (dout                       )
    );
    
    
    endmodule
    
    

    上面我们为了方便起见使用了DDS IP来产生正弦波信号,详细的IP定制步骤可以查看我们前面的DDS的文章。

    多级CIC滤波器的抽取的FPGA仿真结果

    进行运行结果如下:
    在这里插入图片描述
    放大的局部信息:
    在这里插入图片描述
    从上面的运行结果中可以看出,我们成功实现了原始信号的四抽取。如果要实现更高倍数的抽取,只需要对代码中稍作修改即可。

    多级CIC滤波器的内插的FPGA实现

    同样这里梳状滤波器、积分滤波器的输入输出位宽满足多级CIC滤波器的抽取时候的条件。本次实验选取的位宽依旧有很大剩余,这是为了计算的简洁性,但是做学术的时候绝对不可以出现这样的情况。**

    我们实现的功能是:采样率0.25MHz,信号2.5KHz的正弦波进行采样,然后将采样之后的信号进行4倍内插。在这个程序中,我们使用的是3级4阶CIC滤波器级联进行滤波操作

    多级CIC滤波器的内插的FPGA代码

    这里废话不多说,直接给出相应的代码供大家学习,这里需要注意我们使用的结构是经过Noble恒等式优化之后的结构,整个过程与MATLAB仿真完全一摸一样。
    CIC_inter模块:

    `timescale 1ns / 1ps
    // *********************************************************************************
    // Project Name : OSXXXX
    // Author       : zhangningning
    // Email        : nnzhang1996@foxmail.com
    // Website      : 
    // Module Name  : CIC_inter.v
    // Create Time  : 2020-04-24 20:20:56
    // Editor       : sublime text3, tab size (4)
    // CopyRight(c) : All Rights Reserved
    //
    // *********************************************************************************
    // Modification History:
    // Date             By              Version                 Change Description
    // -----------------------------------------------------------------------
    // XXXX       zhangningning          1.0                        Original
    //  
    // *********************************************************************************
    
    module CIC_inter(
        //System Interfaces
        input                   sclk            ,
        input                   rst_n           ,
        //Communication Interfaces
        input                   rvalid          ,
        input           [ 9:0]  din             ,
        output  wire            tvalid          ,
        output  wire    [33:0]  dout            
    );
     
    //========================================================================================\
    //**************Define Parameter and  Internal Signals**********************************
    //========================================================================================/
    wire    signed      [33:0]  din_x           ;     
    //积分器
    wire    signed      [33:0]  int_in1         ;
    wire    signed      [33:0]  int_in2         ;
    wire    signed      [33:0]  int_in3         ;
    reg     signed      [33:0]  int_r1          ;
    reg     signed      [33:0]  int_r2          ;
    reg     signed      [33:0]  int_r3          ;
    wire    signed      [33:0]  int_data        ;
    wire    signed      [33:0]  int_din         ;  
    //抽取
    reg                 [ 2:0]  cnt             ;
    reg                         intr_valid      ;
    //梳状滤波器    
    reg     signed      [33:0]  comb_r1         ;
    reg     signed      [33:0]  comb_r2         ;
    reg     signed      [33:0]  comb_r3         ;
    wire    signed      [33:0]  comb_in1        ;
    wire    signed      [33:0]  comb_in2        ;
    wire    signed      [33:0]  comb_in3        ;
    //========================================================================================\
    //**************     Main      Code        **********************************
    //========================================================================================/
    assign      din_x       =       rvalid == 1'b1 ? {{24{din[9]}},din} : 34'd0;
    assign      int_in1     =       int_r1 + int_din; 
    assign      int_in2     =       int_r2 + int_in1;
    assign      int_in3     =       int_r3 + int_in2; 
    assign      comb_in1    =       din_x - comb_r1;
    assign      comb_in2    =       comb_in1 - comb_r2;
    assign      comb_in3    =       comb_in2 - comb_r3;
    assign      int_din     =       rvalid == 1'b1 ? comb_in3 : 34'd0;
    assign      dout        =       int_in3;
    assign      tvalid      =       intr_valid;
    
    always @(posedge sclk or negedge rst_n)
        if(rst_n == 1'b0)
            comb_r1         <=      34'd0;
        else if(rvalid == 1'b1)
            comb_r1         <=      din_x;
        else 
            comb_r1         <=      comb_r1;
    
    always @(posedge sclk or negedge rst_n)
        if(rst_n == 1'b0)
            comb_r2         <=      34'd0;
        else if(rvalid == 1'b1)
            comb_r2         <=      comb_in1;
        else
            comb_r2         <=      comb_r2;
                
     always @(posedge sclk or negedge rst_n)
        if(rst_n == 1'b0)
            comb_r3         <=      34'd0;
        else if(rvalid == 1'b1)
            comb_r3         <=      comb_in2;
        else
            comb_r3         <=      comb_r3; 
        
    always @(posedge sclk or negedge rst_n)
        if(rst_n == 1'b0)
            cnt             <=      3'd0;
        else if(cnt == 'd3)
            cnt             <=      3'd0;
        else if(rvalid == 1'b1)
            cnt             <=      3'd1;
        else 
            cnt             <=      cnt + 1'b1;
    
    always @(*)
        if(rvalid == 1'b1)
            intr_valid      <=      1'b1;
        else if(cnt > 0)
            intr_valid      <=      1'b1;
        else
            intr_valid      <=      1'b0;
            
    always @(posedge sclk or negedge rst_n)
        if(rst_n == 1'b0)
            int_r1          <=      34'd0;
        else if(intr_valid == 1'b1)
            int_r1          <=      int_in1;
        else 
            int_r1          <=      int_r1;
    
    always @(posedge sclk or negedge rst_n)
        if(rst_n == 1'b0)
            int_r2          <=      34'd0; 
        else if(intr_valid == 1'b1)
            int_r2          <=      int_in2;
        else
            int_r2          <=      int_r2;        
    
    always @(posedge sclk or negedge rst_n)
        if(rst_n == 1'b0)
            int_r3          <=      34'd0; 
        else if(intr_valid == 1'b1)
            int_r3          <=      int_in3;
        else
            int_r3          <=      int_r3;
        
    
    endmodule
    
    

    仔细读一下代码再结合前面的理论相信大家可以学会CIC滤波器在内插时候的操作。

    多级CIC滤波器的内插的FPGA测试代码

    tb模块:

    `timescale 1ns / 1ps
    // *********************************************************************************
    // Project Name : OSXXXX
    // Author       : zhangningning
    // Email        : nnzhang1996@foxmail.com
    // Website      : 
    // Module Name  : tb.v
    // Create Time  : 2020-04-24 16:00:12
    // Editor       : sublime text3, tab size (4)
    // CopyRight(c) : All Rights Reserved
    //
    // *********************************************************************************
    // Modification History:
    // Date             By              Version                 Change Description
    // -----------------------------------------------------------------------
    // XXXX       zhangningning          1.0                        Original
    //  
    // *********************************************************************************
    
    module tb();
    reg                 sclk            ;
    reg                 rst_n           ;
    wire                rvalid          ;
    wire        [ 7:0]  din             ;
    reg                 clk_250k        ;
    reg                 clk_1m          ;
    reg         [ 8:0]  cnt_250k        ;
    reg         [ 8:0]  cnt_1m          ; 
    wire                tvalid          ;
    wire        [33:0]  dout            ; 
    reg                 CIC_inter_valid ;
    reg         [ 2:0]  cnt             ;  
    
    initial begin
        sclk            =           1'b0;
        rst_n           <=          1'b0;
        #(1000);
        rst_n           <=          1'b1;
    end
    always      #(10)       sclk        =           ~sclk;
    
    always @(posedge sclk or negedge rst_n)
        if(rst_n == 1'b0)
            cnt_250k        <=      9'd0;
        else if(cnt_250k == 'd99)
            cnt_250k        <=      9'd0;
        else 
            cnt_250k        <=      cnt_250k + 1'b1;
    
    always @(posedge sclk or negedge rst_n)
        if(rst_n == 1'b0)
            clk_250k        <=      1'b0; 
        else if(cnt_250k == 'd99)
            clk_250k        <=      ~clk_250k;
        else
            clk_250k        <=      clk_250k;
    
    always @(posedge sclk or negedge rst_n)
        if(rst_n == 1'b0)
            cnt_1m          <=      9'd0; 
        else if(cnt_1m == 'd24)
            cnt_1m          <=      9'd0;
        else 
            cnt_1m          <=      cnt_1m + 1'b1;
    
    always @(posedge sclk or negedge rst_n)
        if(rst_n == 1'b0)
            clk_1m          <=      1'b0; 
        else if(cnt_1m == 'd24)
            clk_1m          <=      ~clk_1m;
        else
            clk_1m          <=      clk_1m;
              
    always @(posedge clk_1m or negedge rst_n)
        if(rst_n == 1'b0)
            cnt             <=      3'd0;
        else if(cnt == 'd3 && rvalid == 1'b1) 
            cnt             <=      3'd0; 
        else if(rvalid == 1'b1)
            cnt             <=      cnt + 1'b1;
        else
            cnt             <=      cnt;
    
    always @(posedge clk_1m or negedge rst_n)
        if(rst_n == 1'b0)
            CIC_inter_valid <=      1'b0;
        else if(cnt == 'd3 && rvalid == 1'b1)
            CIC_inter_valid <=      1'b1;
        else
            CIC_inter_valid <=      1'b0;
       
    
    dds_compiler_0 dds_compiler_0_inst (
      .aclk                         (clk_250k                   ),                              // input wire aclk
      .m_axis_data_tvalid           (rvalid                     ),  // output wire m_axis_data_tvalid
      .m_axis_data_tdata            (din                        )    // output wire [7 : 0] m_axis_data_tdata
    );
    
    
    CIC_inter CIC_inter_inst(
        //System Interfaces
        .sclk                       (clk_1m                     ),
        .rst_n                      (rst_n                      ),
        //Communication Interfaces
        .rvalid                     (CIC_inter_valid            ),
        .din                        ({{2{din[7]}},din}          ),
        .tvalid                     (tvalid                     ),
        .dout                       (dout                       )
    );
    
    
    endmodule
    
    

    正弦波的产生我们同样使用了DDS IP核。

    多级CIC滤波器的内插的FPGA仿真结果

    CIC滤波器内插结果如下:
    在这里插入图片描述
    放大后的细节如下:
    在这里插入图片描述
    由上图可知,我们成功实现了基于CIC滤波器的内插操作。

    参考文献

    [1]、FPGADesigner——CSDN博主

    [2]、长弓的坚持——CSDN博主

    [3]、行州人——CSDN博主

    [4]、FPGA开源工作室——CSDN博主

    总结

    在查找一些资料的时候,发现一些博主只给出部分代码,其实这样别人根本看不懂,只有给出整个工程代码才易于知识的传播。创作不易,认为文章有帮助的同学们可以关注、点赞、转发支持。为行业贡献及其微小的一部分。或者对文章有什么看法或者需要更近一步交流的同学,可以加入下面的群:
    在这里插入图片描述

    展开全文
  • 我是一个刚接触滤波器和卫星信号解调的工程人员,前一段时间购买了由你主笔出版的《数字滤波器的Matlab与FPGA实现》一书,对我有很大的启发和帮助。 现在我有一些问题想向你请教,希望你能百忙之抽出宝贵的时间...
  • highspeedlogic算法仿真---CIC滤波器

    千次阅读 2020-08-24 19:40:41
    这个CIC滤波器的频率特性,如果上图,上图和梳子比较相似。所以称为梳状滤波器。 这个是CIC抽取滤波器,如图可以看到,每2个点抽取一个点,达到抽取效果。 这个是CIC内插滤波器,如图可以看到,每2个点插入...
  • 我是一个刚接触滤波器和卫星信号解调的工程人员,前一段时间购买了由你主笔出版的《数字滤波器的Matlab与FPGA实现》一书,对我有很大的启发和帮助。 现在我有一些问题想向你请教,希望你能百忙之抽出宝贵的时间...
  • 燕唐 宁何颖子 (桂林电子科技大学信息与通信学院广西桂林541004 摘 要抽取滤波器是常用于降低乏调制器采样率的数字滤波器详细讨论了音频乏ADC抽取滤波器的设 计方法,即确定了系统流程,深入地研究了CIC滤波器的
  • 这是多速率信号处理一种结构简单的滤波器,只需要加法器和寄存器即可实现,可以灵活设置抽取因子和插值因子,并且CIC是一种基于零点和极点相消FIR滤波器CIC是由积分器和梳状滤波器组成。积分器可表示为(太...
  • MATLAB与FPGA设计滤波器2-1

    千次阅读 2017-07-31 10:00:44
    matlab的fdatool设计滤波器,导出参数,然后在FPGA中设计滤波器的方法。 1、设计fir插值滤波 2、设计半带滤波器 3、CIC滤波器 4、频谱相关 111111111111111111111111111111111111111111111111111 1、设计fir...
  • 本文首先介绍了Δ-Σ模数转换器的基本理论,并针对Δ-Σ模数转换器提出了梳状滤波器的设计,通过Δ-Σ模数转换器的特性,本文选用CIC积分梳状滤波器作为设计方法。对CIC积分梳状滤波器在理论上做了详细的研究,并...
  • 3 补偿滤波器的设计  从图3 可以看出,CIC 滤波器幅频特性曲线在通带内并不平坦,在通带内信号被衰减.为了克服这一缺点,可加入补偿滤波器,它的幅频特性正好与CIC 滤波器相反,完成对频率响应的补偿,从而扩展了...
  • 该本图书的新版《数字滤波器的MATLAB与FPGA实现——Xilinx/VHDL版》及《数字滤波器的MATLAB与FPGA实现——Altera/Verilog版(第2版)》均已修订了该部分内容,设计中不需要再涉及到计算多级CIC滤波器中间字长的问题...
  • 同时,由于CIC滤波器的通带性能实在太差,所以中间还要加上一级PFIR滤波器以平滑滤波器的通带性能。而众所周知用FPGA从事算法的开发是一件难度比较大的工作,而Xilinx公司开发的System Generator工具为算法的快速...
  • CIC设计

    千次阅读 2020-09-01 18:32:17
    这个CIC滤波器的频率特性,如果上图,上图和梳子比较相似。所以称为梳状滤波器。 这个是CIC抽取滤波器,如图可以看到,每2个点抽取一个点,达到抽取效果。 这个是CIC内插滤波器,如图可以看到,每2个点插入...
  • 在多级级联积分梳状(CIC滤波器的设计中,充分运用置换原则以优化各级级数并采用非递归结构实现方式,同时将多相结构运用到补偿滤波器与半带滤波器,获得电路功耗与面积的明显降低。将∑- Δ调制器输出信号作为...
  •  15.3直Ⅰ、Ⅱ型IIR滤波器的MATLAB相关函数  15.4直Ⅰ、Ⅱ型结构的MATLAB实现  15.5级联型结构  15.6一阶、二阶子滤波器  15.7一阶、二阶子滤波器的MATLAB实现 [1] 15.8并联型结构  15.9级联/并联型结构的...
  • 在多级级联积分梳状(CIC滤波器的设计中,充分运用置换原则以优化各级级数并采用非递归结构实现方式,同时将多相结构运用到补偿滤波器与半带滤波器,获得电路功耗与面积的明显降低。将∑- Δ调制器输出信号作为...
  • 15.3 直Ⅰ、Ⅱ型IIR滤波器的MATLAB相关函数 15.4 直Ⅰ、Ⅱ型结构的MATLAB实现 15.5 级联型结构 15.6 一阶、二阶子滤波器 15.7 一阶、二阶子滤波器的MATLAB实现 15.8 并联型结构 15.9 级联/并联型结构的MATLAB实现 ...
  • 宽带短波信道模拟器是一种运用...然后,阐述了数字下变频的数控振荡器、CIC 滤波器、半带滤波器和低通滤波器的实现方法。最后,结合Matlab 算法仿真技术,不依赖FPGA 的IP 核,设计并实现了基于FPGA 的数字下变频。
  • 然后,阐述了数字下变频的数控振荡器、CIC 滤波器、半带滤波器和低通滤波器的实现方法。最后,结合Matlab 算法仿真技术,不依赖FPGA 的IP 核,设计并实现了基于FPGA 的数字下变频。功能与时序仿真结果表明: 基于...
  • 分析了在抽取和内插中采用抗混叠滤波器CIC,HB,多相滤波器组等,提出一种128倍多级抽取器设计方案,通过在MATLAB中建模,并编写verilog HDL代码,在ModelSim中进行仿真,仿真结果验证了这一结构合理性。

空空如也

空空如也

1 2
收藏数 26
精华内容 10
关键字:

matlab中cic滤波器的设计

matlab 订阅