Verilog CIC 滤波器设计(代码自取)
前言:积分梳状滤波器(CIC,Cascaded Integrator Comb),一般用于数字下变频(DDC)和数字上变频(DUC)系统。CIC 滤波器结构简单,没有乘法器,只有加法器、积分器和寄存器,资源消耗少,运算速率高,可实现高速滤波,常用在输入采样率最高的第一级,在多速率信号处理系统中具有着广泛应用。
1. DDC 原理
DDC 主要由本地振荡器(NCO) 、混频器、滤波器等组成,如下图所示。
DDC 将中频信号与振荡器产生的载波信号进行混频,信号中心频率被搬移,再经过抽取滤波,恢复原始信号,实现了下变频功能。
中频数据采样时,需要很高的采样频率来确保 ADC(模数转换器)采集到信号的信噪比。经过数字下变频后,得到的基带信号采样频率仍然是 ADC 采样频率,所以数据率很高。此时基带信号的有效带宽往往已经远小于采样频率,所以利用抽取、滤波进行数据速率的转换,使采样率降低,避免资源的浪费和设计的困难,就成为 DDC 不可缺少的一部分。
而采用 CIC 滤波器进行数据处理,是 DDC 抽取滤波部分最常用的方法。
2.带通采样定理
3. DDC 频谱搬移
例如一个带宽信号中心频率为 60MHz,带宽为 8MHz, 则频率范围为 56MHz ~ 64MHz,m 的可取值范围为 0 ~ 7。取 m=1, 则采样频率范围为 64MHz ~ 112MHz。
取采样频率为 80MHz,设 NCO 中心频率为 20 MHz,下面讨论复信号频谱搬移示意图。
(1)考虑频谱的对称性,输入复信号的频谱示意图如下:
(2)80MHz 采样频率采样后,56~64MHz 的频带被搬移到了 -24~ -16MHz 与 136 ~ 144MHz(高于采样频率被滤除)的频带处,-64~ -56MHz 的频带被搬移到 -144~ -136MHz(高于采样频率被滤除)与 16~24MHz 的频带处。
采样后频带分布如下:
(3)信号经过 20MHz NCO 的正交电路后, -24~ -16MHz 的频带被搬移到 -4~4MHz 与 -44~ -36MHz 的频带处,16~24MHz 的频带被搬移到 -4~4MHz 与 36~44MHz 的频带处,如下所示。
(4)此时中频输入的信号已经被搬移到零中频基带处。
-44~ -36MHz 和 36~44MHz 的带宽信号是不需要的,可以滤除;-4~4MHz 的零中频信号数据速率仍然是 80MHz,可以进行抽取降低数据速率。而 CIC 滤波,就是要完成这个过程。
上述复习了很多数字信号处理的内容,权当抛 DDC 的砖,引 CIC 的玉。
4.CIC 滤波器原理
多级 CIC 滤波器
单级 CIC 滤波器的阻带衰减较差,为了提高滤波效果,抽取滤波时往往会采用多级 CIC 滤波器级联的结构。
实现多级直接级联的 CIC 滤波器在设计和资源上并不是最优的方式,需要对其结构进行调整。如下所示,将积分器和梳状滤波器分别移至一组,并将抽取器移到梳状滤波器之前。先抽取再进行滤波,可以减少数据处理的长度,节约硬件资源。
当然,级联数越大,旁瓣抑制越好,但是通带内的平坦度也会变差。所以级联数不宜过多,一般最多 5 级。
5.CIC 滤波器设计
设计说明
CIC 滤波器本质上就是一个简单的低通滤波器,截止频率为采样频率除以抽取倍数后的一半。输入数据信号仍然是 7.5MHz 和 250KHz,采样频率 50MHz。抽取倍数设置为 5,则截止频率为 5MHz,小于 7.5MHz,可以滤除 7.5MHz 的频率成分。设计参数如下:
输入频率: 7.5MHz 和 250KHz
采样频率: 50MHz
阻带: 5MHz
阶数: 1(M=1)
级数: 3(N=3)
//3 stages integrator
module integrator#(parameter NIN = 12,parameter NOUT = 21)(input clk ,input rstn ,input en ,input [NIN-1:0] din ,output valid ,output [NOUT-1:0] dout) ;reg [NOUT-1:0] int_d0 ;reg [NOUT-1:0] int_d1 ;reg [NOUT-1:0] int_d2 ;wire [NOUT-1:0] sxtx = {{(NOUT-NIN){1'b0}}, din} ;//data input enable delayreg [2:0] en_r ;always @(posedge clk or negedge rstn) beginif (!rstn) beginen_r <= 'b0 ;endelse beginen_r <= {en_r[1:0], en};endend//integrator//stage1always @(posedge clk or negedge rstn) beginif (!rstn) beginint_d0 <= 'b0 ;endelse if (en) beginint_d0 <= int_d0 + sxtx ;endend//stage2always @(posedge clk or negedge rstn) beginif (!rstn) beginint_d1 <= 'b0 ;endelse if (en_r[0]) beginint_d1 <= int_d1 + int_d0 ;endend//stage3always @(posedge clk or negedge rstn) beginif (!rstn) beginint_d2 <= 'b0 ;endelse if (en_r[1]) beginint_d2 <= int_d2 + int_d1 ;endendassign dout = int_d2 ;assign valid = en_r[2];endmodule
抽取器设计
抽取器设计时,对积分器输出的数据进行计数,然后间隔 5 个数据进行抽取即可。
module decimation#(parameter NDEC = 21)(input clk,input rstn,input en,input [NDEC-1:0] din,output valid,output [NDEC-1:0] dout);reg valid_r ;reg [2:0] cnt ;reg [NDEC-1:0] dout_r ;//counteralways @(posedge clk or negedge rstn) beginif (!rstn) begincnt <= 3'b0;endelse if (en) beginif (cnt==4) begincnt <= 'b0 ;endelse begincnt <= cnt + 1'b1 ;endendend//data, validalways @(posedge clk or negedge rstn) beginif (!rstn) beginvalid_r <= 1'b0 ;dout_r <= 'b0 ;endelse if (en) beginif (cnt==4) beginvalid_r <= 1'b1 ;dout_r <= din;endelse beginvalid_r <= 1'b0 ;endendendassign dout = dout_r ;assign valid = valid_r ;endmodule
梳状器设计
梳状滤波器就是简单的一阶 FIR 滤波器,每一级的 FIR 滤波器对数据进行一个时钟延时,然后做相减即可。因为系数为 ±1,所以不需要乘法器。
module comb#(parameter NIN = 21,parameter NOUT = 17)(input clk,input rstn,input en,input [NIN-1:0] din,input valid,output [NOUT-1:0] dout);//en delayreg [5:0] en_r ;always @(posedge clk or negedge rstn) beginif (!rstn) beginen_r <= 'b0 ;endelse if (en) beginen_r <= {en_r[5:0], en} ;endendreg [NOUT-1:0] d1, d1_d, d2, d2_d, d3, d3_d ;//stage 1, as fir filter, shift and add(sub), //no need for multiplieralways @(posedge clk or negedge rstn) beginif (!rstn) d1 <= 'b0 ;else if (en) d1 <= din ;endalways @(posedge clk or negedge rstn) beginif (!rstn) d1_d <= 'b0 ;else if (en) d1_d <= d1 ;endwire [NOUT-1:0] s1_out = d1 - d1_d ;//stage 2always @(posedge clk or negedge rstn) beginif (!rstn) d2 <= 'b0 ;else if (en) d2 <= s1_out ;endalways @(posedge clk or negedge rstn) beginif (!rstn) d2_d <= 'b0 ;else if (en) d2_d <= d2 ;endwire [NOUT-1:0] s2_out = d2 - d2_d ;//stage 3always @(posedge clk or negedge rstn) beginif (!rstn) d3 <= 'b0 ;else if (en) d3 <= s2_out ;endalways @(posedge clk or negedge rstn) beginif (!rstn) d3_d <= 'b0 ;else if (en) d3_d <= d3 ;endwire [NOUT-1:0] s3_out = d3 - d3_d ;//tap the output data for better displayreg [NOUT-1:0] dout_r ;reg valid_r ;always @(posedge clk or negedge rstn) beginif (!rstn) begindout_r <= 'b0 ;valid_r <= 'b0 ;endelse if (en) begindout_r <= s3_out ;valid_r <= 1'b1 ;endelse beginvalid_r <= 1'b0 ;endendassign dout = dout_r ;assign valid = valid_r ;endmodule
顶层例化
按信号的流向将积分器、抽取器、梳状器分别例化,即可组成最后的 CIC 滤波器模块。
梳状滤波器的最终输出位宽一般会比输入信号小一些,这里取 17bit。当然输出位宽完全可以与输入数据的位宽一致。
module cic#(parameter NIN = 12,parameter NMAX = 21,parameter NOUT = 17)(input clk,input rstn,input en,input [NIN-1:0] din,input valid,output [NOUT-1:0] dout);wire [NMAX-1:0] itg_out ;wire [NMAX-1:0] dec_out ;wire [1:0] en_r ;integrator #(.NIN(NIN), .NOUT(NMAX))u_integrator (.clk (clk),.rstn (rstn),.en (en),.din (din),.valid (en_r[0]),.dout (itg_out));decimation #(.NDEC(NMAX))u_decimator (.clk (clk),.rstn (rstn),.en (en_r[0]),.din (itg_out),.dout (dec_out),.valid (en_r[1]));comb #(.NIN(NMAX), .NOUT(NOUT))u_comb (.clk (clk),.rstn (rstn),.en (en_r[1]),.din (dec_out),.valid (valid),.dout (dout));endmodule
testbench
testbench 编写如下,主要功能就是不间断连续的输入 250KHz 与 7.5MHz 的正弦波混合信号数据。输入的混合信号数据也可由 matlab 生成,具体过程参考《并行 FIR 滤波器设计》一节。
module test ;parameter NIN = 12 ;parameter NMAX = 21 ;parameter NOUT = NMAX ;reg clk ;reg rstn ;reg en ;reg [NIN-1:0] din ;wire valid ;wire [NOUT-1:0] dout ;//=====================================// 50MHz clk generatinglocalparam T50M_HALF = 10000;initial beginclk = 1'b0 ;forever begin# T50M_HALF clk = ~clk ;endend//============================// reset and finishinitial beginrstn = 1'b0 ;# 30 ;rstn = 1'b1 ;# (T50M_HALF * 2 * 2000) ;$finish ;end//=======================================// read cos data into registerparameter SIN_DATA_NUM = 200 ;reg [NIN-1:0] stimulus [0: SIN_DATA_NUM-1] ;integer i ;initial begin$readmemh("../tb/cosx0p25m7p5m12bit.txt", stimulus) ;i = 0 ;en = 0 ;din = 0 ;# 200 ;forever begin@(negedge clk) beginen = 1 ;din = stimulus[i] ;if (i == SIN_DATA_NUM-1) begini = 0 ;endelse begini = i + 1 ;endendendendcic #(.NIN(NIN), .NMAX(NMAX), .NOUT(NOUT))u_cic (.clk (clk),.rstn (rstn),.en (en),.din (din),.valid (valid),.dout (dout));endmodule // test
6.仿真结果
由下图仿真结果可知,经过 CIC 滤波器后的信号只有一种低频率信号(250KHz),高频信号(7.5MHz)被滤除了。
但是波形不是非常完美,这与设计的截止频率、数据不是持续输出等有一定关系。
此时发现,积分器输出的数据信号也非常的不规则,这与其位宽有关系。
为了更好的观察积分器输出的数据,将其位宽由 21bit 改为 34bit,仿真结果如下。
此时发现,CIC 滤波器的数据输出并没有实质性的变化,但是积分器输出的数据信号呈现锯齿状,也称之为梳状。这也是梳状滤波器名字的由来。
Verilog CIC 滤波器设计(代码自取)相关推荐
- 基于MATLAB FDATOOL的CIC滤波器设计
级联积分梳状(CIC)滤波器是一种被广泛应用于软件无线电中,可以实现抽取或者插值的高效滤波器.它主要用于降低或提高采样率.CIC滤波器的主要特点是,仅利用加法器.减法器和寄存器,占用资源少,实现简单且 ...
- m基于FPGA和MATLAB的数字CIC滤波器设计和实现
目录 1.算法概述 2.仿真效果预览 3.MATLAB/FPGA部分代码预览 4.完整MATLAB/FPGA程序 1.算法概述 CIC滤波器由一对或多对积分-梳状滤波器组成,在抽取CIC中,输入信号依 ...
- 基于FPGA的CIC滤波器设计(2)——以数字上下变频为例讲解
多级CIC滤波器理论与设计 项目简述 多级CIC滤波器 多级CIC滤波器的抽取操作 多级CIC滤波器的内插操作 多级CIC滤波器的抽取的MATLAB实现 多级CIC滤波器的抽取的MATLAB结果 多级 ...
- IIR滤波器设计代码(巴特沃斯+脉冲响应不变法/双线性变换法) Matlab代码
引言 说实话我感觉自己滤波器不算学到位了,一般来说我是需要把整个过程都弄得非常清楚,但是这个模拟滤波器设计是真的麻烦,至少我现在不确定以后会从事DSP相关的内容,就没有对细节考量,但或许也没谁会对它去 ...
- FPGA数字信号处理(十六)单级CIC滤波器Verilog设计
该篇是FPGA数字信号处理的第16篇,选题为多速率信号处理系统中常用的CIC滤波器.本文将详细介绍使用Verilog HDL设计单级CIC滤波器的方法.接下来几篇会介绍多级CIC滤波器的Verilog ...
- m基于FPGA的积分梳状CIC滤波器verilog设计
目录 1.算法描述 2.仿真效果预览 3.verilog核心程序 4.完整FPGA 1.算法描述 积分梳状滤波器,是指该滤波器的冲激响应具有如下形式: 其物理框图如图所示: 可见,CIC滤波器是由两部 ...
- FIR滤波器设计(包括Verilog HDL设计以及MATLAB设计)
FIR滤波器设计 滤波器原理:滤波器就是对特定的频率或者特定频率以外的频率进行消除的电路,被广泛用于通信系统和信号处理系统中.从功能角度,数字滤波器对输入离散信号的数字代码进行运算处理,以达到滤除频带 ...
- 如何利用CIC滤波器、CIC补偿滤波器和半带滤波器设计一个高频数字抽取滤波器
设计了采样频率为640 MHz.过采样率为64的高频数字抽取滤波器.该数字抽取滤波器由CIC(Cascaded Integrator Comb)滤波器(降16倍).CIC补偿滤波器(降2倍)和半带滤波 ...
- 【CIC滤波器】基于MATLAB/FPGA的数字CIC滤波器的设计
FPGA代码: module down(i_clk,//输入时钟i_rst,//输入复位信号i_M, //抽取值i_data,//输入信号o_data,//输出信号r_clk);input i_clk ...
- 基于fpga的fir滤波器设计,通过matlab代码设计滤波器参数,最终通过fpga实现
基于fpga的fir滤波器设计,通过matlab代码设计滤波器参数,最终通过fpga实现,modelsim仿真,最后在开发板上实现,两路adc采集的掺杂高频信号经过低通滤波器之后,由dac输出,由si ...
最新文章
- 一维数组求平均值c语言编程软件,c语言编程:用数组名作函数参数,编写一个对一维数组求平均值的函数,并在主函数中调用它...
- 综述:光流估计从传统方法到深度学习
- CentOS6.8 安装/升级Python2.7.x,并安装最新setuptools、pip、fabric程序总结
- crawler_爬虫开发的曲线图
- 局部变量和成员变量的初始值问题
- 【GitLab】与idea的搭配
- Typescript学习;Typescript总结;Typescript 的数据类型有哪些?
- linux网卡IO,浅谈Linux 网络 I/O 模型简介(图文)
- yolov5的flask部署python调用
- B+Tree及其创建过程
- python形参中传入两个实参_C语言学习第3篇---形参-实参概念剖析
- 放心了!邮政、顺丰和京东基本全部复工
- Qt界面美化 QSS
- 图片上传的ajax代码,一个伪ajax图片上传代码的例子
- 《Python密码学编程》——2.6 本书的文本换行
- 计算机组成与设计---硬件/软件接口---计算机概要与技术
- java将数字转换成大写_Java中金额数字转换为大写数字
- 得物 × StarRocks:潮流网购社区的极速 OLAP 实践
- JDK8 源码包 外加注释
- Unity 人形动画、动画切割、Animator