当前位置: 首页 > news >正文

FPGA实现CIC抽取滤波器

FPGA实现CIC抽取滤波器

  • 一、什么是CIC滤波器
    • (一)CIC滤波器原理和结构
    • (二)最大位宽计算
  • 二、CIC抽取滤波器FPGA实现
    • (一)Verilog代码
    • (二)仿真分析

一、什么是CIC滤波器

(一)CIC滤波器原理和结构

CIC(级联积分梳状)滤波器,它是一种高效的多速率信号处理滤波器,是一种无乘法器的线性相位FIR滤波器。常用于数字下变频(DDC)和数字上变频(DUC)中。CIC滤波器的主要优点是不需要乘法器,结构简单,仅由加法器、减法器和寄存器组成。CIC滤波器是FIR滤波器的一种,可以只使用积分器和梳状器来实现,没有了FIR的乘法操作,实现非常的简单并且大大节约了资源。
CIC滤波器有三种工作模式:抽取滤波器(最常用)、插值滤波器和单纯滤波器。

  • 抽取滤波器: 数据流由高速输入变为低速输出,主要应用于数字下变频以及降低采样率的系统中。其结构如下图所示:

在这里插入图片描述

  • 插值滤波器: 数据流由低速输入变为高速输出,主要应用于数字上变频以及提升采样率的系统中。其结构如下图所示:
    在这里插入图片描述
  • 单纯滤波器: 数据流速率不变,积分器和梳状器都工作在同一个采样率下,主要应用于移动平均滤波。

前面提到CIC滤波器主要由积分器和梳状器组成,积分器状态方程如下:
在这里插入图片描述
梳状器状态方程如下:
在这里插入图片描述
其中N为抽取倍数(抽取因子),什么意思呢?举个例子输入信号采样率为100MHz,如果抽取因子为10,那么降采样之后的信号速率就是100MHz / 10 = 10MHz。也就是说F_out = F_in / 抽取因子。
由于单级CIC的第一旁瓣阻带衰减是固定的13.46dB,无法很好的抑制旁瓣,因此可以通过级联的方式来提升抑制效果,根据实际旁瓣抑制需求可以实现单级、二级、三级、四级、五级、六级等多级CIC。
可以把CIC滤波器想象成一个多层过滤系统:

  • 一级(N=1):像一层纱网,能过滤掉一些大颗粒杂质,但一些小颗粒和细微的杂质还能通过。
  • 二级(N=2):在纱网后面再加一层更密的滤布,过滤效果更好。
  • 五级(N=5):相当于经过了五层不同精度的过滤,最后得到的液体非常纯净。

级数N越高,滤波效果越好,但系统的“阻力”也会相应增加(对应到FPGA就是资源消耗和位宽增长)。在数字下变频等应用中,N=5 或 N=6 是非常常见的选择,它在性能和资源之间取得了很好的平衡。

假设数据以Fs(假设100MHz)的频率输入滤波器,那数据先通过3级的积分滤波器一直进行累加。假如我们希望得到Fs的10分频的采样数据,那就将积分滤波器的最后一级输出以Fs/N(10MHz)的频率进入梳状滤波器,梳状滤波器其实是微分运算,即当前值减去上一次的值。经过3次的梳状滤波器,最后1级的结果即为抽取的数值。
在这里插入图片描述

(二)最大位宽计算

上面提到CIC滤波器中计算存在加减法操作,因此我们需要考虑到计算过程中信号位宽的问题,这是CIC实现中最需要关注的问题。由于积分器的累加效应,内部数据位宽会随着级数N线性增长。

最大位宽计算公式如下:

B_max = B_in + N * ceil(log2(R * M))

ceil()–向上取整函数

  • B_in:输入位宽
  • R:抽取/插值因子
  • M:差分延迟(通常为1)

举个例子:假设 B_in=16位, R=64, M=1, ceil(log2(64)) = 6。

  • 当 N=3 时,最大位宽 = 16 + 3*6 = 34位
  • 当 N=5 时,最大位宽 = 16 + 5*6 = 46位
  • 当 N=6 时,最大位宽 = 16 + 6*6 = 52位

可以看到,级数每增加一级,位宽就会显著增加,消耗更多的寄存器、逻辑和布线资源。
级数N对滤波器性能的影响:
1、阻带抑制(抗混叠/抗镜像性能)
这是增加级数最主要的目的。N越高,阻带衰减越大,滤波器对带外信号的抑制能力就越强。在频谱上看,旁瓣的幅度会显著降低。这对于抽取器来说,意味着能更好地防止混叠;对于插值器来说,意味着能更好地抑制镜像。

2、通带衰减(副作用)
这是增加级数带来的主要代价。N越高,通带内的衰减也越严重。这意味着我们想要的信号,尤其是通带边缘的信号,也会被显著衰减。为了补偿这种通带衰减,通常需要在CIC滤波器后面级联一个补偿FIR滤波器。

二、CIC抽取滤波器FPGA实现

(一)Verilog代码

以下CIC滤波器代码参数:
级数:3
抽取因子:16

`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 2025/10/13 15:11:49
// Design Name: 
// Module Name: cic_down_sample
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////module cic_down_sample#(parameter   DATA_IN_WIDTH   =   8       ,parameter   DATA_OUT_WIDTH  =   8       ,parameter   CIC_FACTORS     =   16      ,   //  抽取因子parameter   MAX_WIDTH       =   20          //  最大位宽
)(input                                   clk                 ,input                                   rstn                ,input   signed  [DATA_IN_WIDTH-1:0]     data_in             ,input                                   data_in_valid       ,output  signed  [DATA_OUT_WIDTH-1:0]    data_out            
);wire    signed  [MAX_WIDTH-1:0] add_data_0      ;
wire    signed  [MAX_WIDTH-1:0] add_data_1      ;
wire    signed  [MAX_WIDTH-1:0] add_data_2      ;
reg     signed  [MAX_WIDTH-1:0] data_0          ;
reg     signed  [MAX_WIDTH-1:0] data_1          ;
reg     signed  [MAX_WIDTH-1:0] data_2          ;reg             [4:0]           cnt_div         ;
reg                             sample_flag     ;   //  采样标志reg     signed  [MAX_WIDTH-1:0] comb_in         ;
wire    signed  [MAX_WIDTH-1:0] add_comb_0      ;
wire    signed  [MAX_WIDTH-1:0] add_comb_1      ;
wire    signed  [MAX_WIDTH-1:0] add_comb_2      ;
reg     signed  [MAX_WIDTH-1:0] comb_0          ;
reg     signed  [MAX_WIDTH-1:0] comb_1          ;
reg     signed  [MAX_WIDTH-1:0] comb_2          ;//  积分器
always @(posedge clk or negedge rstn) beginif(!rstn)begindata_0 <= 'd0   ;data_1 <= 'd0   ;data_2 <= 'd0   ;endelse begindata_0 <= add_data_0    ;data_1 <= add_data_1    ;data_2 <= add_data_2    ;end
endassign  add_data_0  =   {{12{data_in[7]}},data_in}  +   data_0  ;
assign  add_data_1  =   add_data_0                  +   data_1  ;
assign  add_data_2  =   add_data_1                  +   data_2  ;//  降采样处理
always @(posedge clk or negedge rstn) beginif(!rstn)begincnt_div <= 'd0  ;endelse if(cnt_div == CIC_FACTORS - 1)begincnt_div <= 'd0  ;endelse begincnt_div <= cnt_div + 1  ;end
end
always @(posedge clk or negedge rstn) beginif(!rstn)beginsample_flag <= 1'b0  ;endelse if(cnt_div == CIC_FACTORS - 1)beginsample_flag <= 1'b1  ;endelse beginsample_flag <= 1'b0  ;end
end
//  梳状器
always @(posedge clk or negedge rstn) beginif(!rstn)begincomb_in <= 'd0  ;endelse if(sample_flag)begincomb_in <= add_data_2  ;end
end
always @(posedge clk or negedge rstn) beginif(!rstn)begincomb_0 <= 'd0   ;comb_1 <= 'd0   ;comb_2 <= 'd0   ;endelse if(sample_flag)begincomb_0 <=  comb_in      ;comb_1 <=  add_comb_0   ;comb_2 <=  add_comb_1   ;end
endassign  add_comb_0 = comb_in    -   comb_0  ;
assign  add_comb_1 = add_comb_0 -   comb_1  ;
assign  add_comb_2 = add_comb_1 -   comb_2  ;assign data_out = add_comb_2[19:12]    ;//endmodule

顶层文件:

`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 2025/10/13 15:45:40
// Design Name: 
// Module Name: cic_top
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////module cic_top(input               sysclk                 ,input               sysrstn                                  
);wire                    m_axis_data_tvalid  ;
wire    signed  [7:0]   m_axis_data_tdata   ;
wire    signed  [7:0]   data_out            ;dds_compiler_0 dds (.aclk                 ( sysclk            ),                                // input wire aclk.m_axis_data_tvalid   ( m_axis_data_tvalid),    // output wire m_axis_data_tvalid.m_axis_data_tdata    ( m_axis_data_tdata ),      // output wire [7 : 0] m_axis_data_tdata.m_axis_phase_tvalid  (                   ),  // output wire m_axis_phase_tvalid.m_axis_phase_tdata   (                   )    // output wire [31 : 0] m_axis_phase_tdata
);cic_down_sample#(.DATA_IN_WIDTH  (   8      ),.DATA_OUT_WIDTH (   8      ),.CIC_FACTORS    (   16     ),   //  抽取因子.MAX_WIDTH      (   20     )    //  最大位宽
)u_cic_down_sample(/*input                                */.clk                 ( sysclk               ),/*input                                */.rstn                ( sysrstn              ),/*input   signed  [DATA_IN_WIDTH-1:0]  */.data_in             ( m_axis_data_tdata/*{~m_axis_data_tdata[7],m_axis_data_tdata[6:0]}*/    ),/*input                                */.data_in_valid       ( m_axis_data_tvalid   ),/*output  signed  [DATA_OUT_WIDTH-1:0] */.data_out            ( data_out             )
);
endmodule

(二)仿真分析

级数:3 抽取因子:16
在这里插入图片描述
级数:3 抽取因子:8
在这里插入图片描述
可以看到抽取因子越小或级数越小时,CIC抽取滤波器输出波形约平滑,因此需要有必要时级联一个补偿FIR滤波器。

http://www.dtcms.com/a/492430.html

相关文章:

  • 深圳快速网站制作哪家快wordpress自适应设置宽度
  • qq临时会话网站搜索引擎网站推广法 怎么做
  • 国内可以做的国外兼职网站高端网站建设论坛
  • 网站广告策划wordpress如何使用
  • 网站品牌推广公司最新被百度收录的网站
  • 19. Linux free命令、awk命令
  • NewStarCTF2025-Week2-Pwn
  • 网站建设5个why分销网站怎么做
  • 永州做网站的公司河南省建设厅执业资格注册中心网站
  • 3-C++中类大小影响因素
  • 广州外贸网站公司新零售网络推广方案
  • mybatis返回map对象,在线程内将getkey值后赋值给stirng,会线程卡死问题
  • 【北邮-本科-通信原理】第五章关于HDB3编码的C++实现
  • 酒类网站建设方案案酷玛网站建设
  • 晋江网站建设联系电话销售渠道都有哪些
  • 商务网站建设策划书2000字做汽车团购的网站有哪些
  • 网站的域名空间思茅网站建设
  • 定西市网站建设企业wordpress网站缩
  • 黑河做网站公司wordpress标签管理系统
  • RunnableParallel
  • 做网站要学什么c语言如何在手机上运行wordpress
  • 建设农产品网站总结ppt三明市建设局网站
  • 好的网站建设哪家好随州网站建设价格
  • 可信验证网站深圳高端网站设计公司
  • 深入理解 Rust 的类型系统:内存布局、Trait 与类型推理
  • how to Disable SMPL(Sudden Momentary Power Loss) feature
  • 性能测试实战:JMeter全攻略
  • 淘宝客网站建设视频教程制作企业网站的
  • Furtherance,一个隐私友好的时间追踪工具
  • 网站开发和设计人员的岗位要求个人网站做论坛