发 帖  
原厂入驻New
[经验]

单级CIC滤波器Verilog设计

2020-9-28 09:36:54  291 FPGA 滤波器 Verilog
分享
1
本文将详细介绍使用Verilog HDL设计单级CIC滤波器的方法。
CIC滤波器
多速率信号处理系统中最主要的还是滤波器的设计:抽取和内插后不能产生频谱混叠、占用资源少、运算速度快。上一篇介绍了多速率FIR滤波器,与其相比,CIC(Cascaded Integrator Comb,积分梳状)滤波器运算速度快、占用资源少、工作频率高(因为CIC只使用加法器、减法器和寄存器),在多速率信号处理系统中应用更广泛。
●频谱特性
CIC本质上其实就是一种特殊的FIR滤波器(系数都为1)。本文不用理论推导的方式,从频谱图出发更直观地观察体会CIC滤波器的特点。我们使用matlab的FDATOOL工具观察CIC滤波器的频谱。

点击最左边的小按钮,中间选择CIC滤波器,右边级数(Number Of Sections)设置为1,表示单级CIC滤波器。这里设置为对25MHz的Fs进行25倍抽取。可以看到第一旁瓣的衰减为13.46dB(事实上这是一个固定的值,与CIC滤波器阶数无关),这个阻带衰减远远不能满足通常的设计要求,通过级联的方式可以提高阻带衰减,在下一篇介绍多级CIC滤波器时再详细说明。
●阶数与倍数的关系
CIC滤波器通常用于抗混叠抽取/内插滤波器(抽取与内插结构见本文开头的链接)。考虑抽取/内插的过程、CIC滤波器的特性(系数为1的特殊FIR滤波器)以及FIR滤波器的实现结构,就会发现,当CIC滤波器的阶数与内插/抽取的倍数相同时,其结构更利于FPGA实现。比如抽取时,只需要将D个数据组成一组,相加作为一个输出即可(即同时完成了滤波与抽取)。
结合下面的实例理解(设CIC滤波器阶数与抽取倍数都为5):

完整的抽取过程为:CIC作为抗混叠滤波,由于系数为1,y1=x1+x2+…+x5,y2=x2+x3+…+x6,等等;得到滤波输出后,再每隔4个点(即D-1个)取一个值输出,完成5倍抽取。而这个过程恰好等效于将原始数据每5个分为一组,每组的数据分别相加作为一个输出。由此可见:当CIC滤波器与抽取倍数相同时,可以大大节省资源、减小运算量。
同理,当使用CIC完成内插滤波时,设CIC滤波器阶数与内插倍数都为5:

完整的内插过程为:每两个数据之间插入4个零值(I-1个),完成5倍内插,之后使用CIC做低通滤波,由于CIC滤波器的系数为1,滤波后的插值0变为前一个原始数据值。这个过程恰好等效于直接在两个数据之间插入前一个数据值。由此可见:当CIC滤波器与内插倍数相同时,也可以节省资源和运算。

CIC抽取滤波器的FPGA设计与仿真
使用50MHz采样率对0.25MHz的信号进行采样,由五阶CIC滤波器进行5倍抽取,将采样率降至10MHz。根据上文的介绍,设计的Verilog HDL代码如下:
`timescale 1ns / 1ps
//-------------------------------------------------------------
//  单级CIC抽取滤波器,滤波器阶数与抽取倍数相同
//-------------------------------------------------------------
module SingleCIC_Decimation
(
    input clk,    //50MHz系统时钟
    input rst,    //复位信号
    input signed [9:0] din,    //采样数据,速率为50MHz
    output tvalid,             //输出数据有效信号
    output signed [12:0] dout  //5倍抽取后数据,速率为10MHz
);


reg tvalid_reg;
reg [2:0] cnt;      //抽取控制计数器
reg signed [12:0] sum, dout_reg;


always @ (posedge clk or posedge rst)
    if (rst) begin
        cnt <= 'd0; tvalid_reg <= 1'b0;
        sum <= 'd0; dout_reg <= 'd0;
    end
    else begin
        if (cnt == 4) begin   //每隔4个数据
            tvalid_reg <= 1'b1;
            dout_reg <= sum + din;   //得到输出结果
            cnt <= 'd0;
            sum <= 'd0;
        end
        else begin
            tvalid_reg <= 1'b0;
            sum <= sum + din;     //累加
            cnt <= cnt + 1'b1;
        end
    end


assign dout = dout_reg;
assign tvalid = tvalid_reg;


endmodule

使用MATLAB生成一个0.25MHz的单频信号,写入txt文件。编写testbench读取txt文件对信号抽取滤波
Vivado中仿真结果如下图所示:

可以看到输出数据速率为输入数据速率的1/5,每当有新数据输出时,tvalid信号会置高1个时钟周期。将信号设置为analog显示方式:

可以看到经过抽取滤波后,数据速率降低,但信号频率没有改变。

CIC内插滤波器的FPGA设计与仿真
使用10MHz采样率对0.25MHz的信号进行采样,由五阶CIC滤波器进行5倍内插,将采样率提高至50MHz。根据上文的介绍,内插比抽取甚至更容易理解,设计起来也非常简单,设计的Verilog HDL代码如下:
`timescale 1ns / 1ps
//-------------------------------------------------------------
//  单级CIC内插滤波器,滤波器阶数与抽取倍数相同
//-------------------------------------------------------------
module SingleCIC_Interpolation
(
    input clk,    //50MHz系统时钟
    input rst,    //复位信号
    input signed [9:0] din,    //采样数据,速率为10MHz
    output signed [9:0] dout   //5倍内插后数据,速率为50MHz
);


reg signed [9:0] dout_reg;


always @ (posedge clk or posedge rst)
    if (rst)  dout_reg <= 'd0;
    else dout_reg <= din;     


assign dout = dout_reg;


endmodule
Vivado中仿真结果如下图所示:

从结果看输入与输出是完全一样的,但实际意义不同,输入数据的速率为10MHz(每5个时钟周期输入一个数据),输出数据的速率为50MHz(每个时钟周期都输出一个数据)。

相关经验

评论

高级模式
您需要登录后才可以回帖 登录 | 注册

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

站长推荐 上一条 /7 下一条

快速回复 返回顶部 返回列表