CIC(级联积分梳状)滤波器是FPGA多速率信号处理中的常用滤波方法,关键在于无需任何乘法器,仅靠加法器、减法器和寄存器就能实现高效的抽取(降采样)或插值(升采样)。
从原理结构、位宽计算、FPGA实现架构以及关键设计技巧四个维度,深度解析CIC滤波器在FPGA中的实现。
一、 CIC滤波器的数学与结构原理
CIC滤波器的传递函数由积分器(I)和梳状(C)两部分组成。假设抽取/插值因子为R ,梳状延迟为M (通常M=1或2),级数为N。
积分器:是一个理想的累加器,传递函数$ H_I(z) = \frac{1}{1 - z^{-1}} $。在时域就是$ y[n] = y[n-1] + x[n] $。
梳状器:是一个差分器,传递函数$ H_C(z) = 1 - z^{-RM} $。在时域就是$ y[n] = x[n] - x[n-RM] $。 根据Nobel恒等式,在多速率系统中,可以先进行滤波再进行抽取,等效于在低速率下进行滤波。这为FPGA实现提供了极大的优化空间。
二、 抽取CIC的FPGA实现架构
对于抽取(降采样,速率➗R ),为了降低梳状部分的运行频率、节省资源,必须将梳状部分放在抽取操作之后。架构图:
高频输入 fs
│
▼
┌─────────┐ ┌─────────┐ ┌─────┐ ┌─────────┐ ┌─────────┐
│ 积分器1 │────>│ 积分器2 │ ── ... ─>│ R抽取 │────>│ 梳状器1 │────>│ 梳状器2 │──> 低频输出 fs/R
│ y=y+x │ │ y=y+x │ │ 降频 │ │y=x-x[-M]│ │y=x-x[-M]│
└─────────┘ └─────────┘ └─────┘ └─────────┘ └─────────┘
(工作在fs) │
【降采样点】
工作逻辑:
积分阶段(高速):前N级积分器工作在输入采样率fs下,每个时钟周期执行一次累加。
降采样:积分器输出的数据,每隔R个时钟周期抓取一个,传递给后续模块。
梳状阶段(低速):后N级梳状器工作在降采样后的低频 fx/R 下。因为M通常为1,梳状器仅需一个深度为1的寄存器(延迟一个低频时钟周期),然后做减法。
三、 插值CIC的FPGA实现架构
对于插值(升采样,速率*R),原理与抽取对称,必须将梳状部分放在插值操作之前。架构图:
低频输入 fs/R
│
▼
┌─────────┐ ┌─────────┐ ┌─────┐ ┌─────────┐ ┌─────────┐
│ 梳状器1 │────>│ 梳状器2 │────>│ R插值 │ ── ... ─>│ 积分器1 │────>│ 积分器2 │──> 高频输出 fs
│y=x-x[-M]│ │y=x-x[-M]│ │ 插零 │ │ y=y+x │ │ y=y+x │
└─────────┘ └─────────┘ └─────┘ └─────────┘ └─────────┘
(工作在fs/R) │
【在此处插入R-1个零】
工作逻辑:
梳状阶段(低速):输入信号先经过N级梳状滤波,工作在低频fs/R。
插零升频:在两个有效数据之间插入R-1个零,数据率提升为 R·fs。
积分阶段(高速):积分器工作在高频fs下。由于输入含有大量的0,积分器实际上是在保持前值,只有遇到非零数据时才发生累加。
四、 FPGA实现中位宽计算
CIC滤波器在FPGA实现中最容易忽略的就是位宽截断导致溢出。因为积分器不断累加,数据位宽会急剧增长。
1. 最大位宽计算公式
CIC滤波器全链路必须保证**无精度损失**(即不截断),其最大输出位宽由下式决定:
$$ B_{\max} = B_{in} + N \cdot \left\lceil \log_2(R \cdot M) \right\rceil $$
Bin:输入数据位宽
N:CIC级数
R:抽取/插值因子
M:梳状延迟(通常取1)
举例:输入16位,5级CIC(N=5),抽取因子32(R=32),M=1。
$$ B_{\max} = 16 + 5 \times \left\lceil \log_2(32) \right\rceil = 16 + 5 \times 5 = 41 $$
- 位。
2. 为什么绝对不能在中间截断?
在纯整数运算中,积分器一定会发生二进制溢出。只要保证全链路使用统一的位宽(即 Bmax),积分器的溢出会在梳状器的差分运算中自动抵消。如果在中间阶段随意截断高位,这种“溢出自抵消”特性就会被破坏,导致输出数据完全错误。
3. 输出截断策略
虽然中间不能截断,但最终输出往往不需要41位这么宽。FPGA中一般在最后一级梳状器输出之后进行截断(类似四舍五入),以匹配后续DSP系统的位宽。
五、 FPGA高级设计技巧与优化
1. 时钟使能替代多时钟域
在插值/抽取CIC中,存在快慢两种时钟。不要用MMCM/PLL生成两个不同频率的时钟,这会带来跨时钟域问题。
推荐解法:全局使用高频时钟fs,在低频模块(梳状或插值前)使用时钟使能信号。产生一个周期为R、脉宽为1个高频时钟的脉冲信号,作为低频模块的 CE(Clock Enable)。
2. 积分器复位清零
积分器内部有反馈回路,FPGA上电时寄存器初始值可能未知。必须提供同步复位信号,在数据流开始前将所有积分器的累加寄存器清零,否则初始直流偏移会永远无法消除。
3. 位宽优化
如果Bmax太大(如50位),而实际信号有效动态范围没那么宽,全程使用50位加法器会浪费逻辑资源。可以根据MATLAB的定点仿真,精确计算每一级实际需要的有效位宽,逐级丢弃最低有效位(LSB),这被称为Pruning技术。虽然这会引入截断噪声,但只要信噪比满足系统要求,就能大幅减少FPGA面积。
在FPGA中实现CIC滤波器,本质上是利用Nobel恒等式调整运算顺序,以低频处理换取低功耗,利用全精度加法器/减法器替代乘法器。
“积分在前梳状在后(抽取)、全精度计算防溢出、单时钟加使能控时序”
105