尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

零基础看懂 FPGA 实现 IIR 滤波器:大白话 + 手算实例 + 代码全拆解

零基础看懂 FPGA 实现 IIR 滤波器:大白话 + 手算实例 + 代码全拆解
📅 发布时间:2026/6/19 8:01:22

做数字信号处理的同学,刚接触 FPGA 实现 IIR 滤波器时,总会被一堆专业名词砸晕 —— 差分方程、零点极点、定点化、符号扩展、算术右移…… 看着代码好像每个关键字都认识,凑一起就不知道在干啥。

这篇文章彻底抛开晦涩术语,用生活类比 + 逐行代码拆解 + 手算实例,带你从零搞懂 IIR 滤波器的 FPGA 实现逻辑,看完就能对应到自己的工程代码里。

一、先搞懂:IIR 滤波器到底是啥?

1. 滤波器:一个 “信号筛子”

你可以把滤波器想象成一个信号筛子:

  • 输入是一段混杂了杂音的信号(比如人声 + 高频电流杂音)
  • 输出是筛掉杂音后的干净信号
  • 我们常说的「低通滤波器」,本质就是留下低频的有效信号,筛掉高频的噪声干扰。

2. FIR 与 IIR 的核心区别:有没有 “回头路”

两种最常见的数字滤波器,核心差异就在有没有反馈机制:

  • FIR 滤波器:只有一条 “向前走” 的通路,信号从左边进,一层一层过筛子,直接从右边输出,没有回头路。优点是绝对稳定,不会 “炸机”;缺点是要想滤波效果好,得堆很多层 “筛子”,非常占用 FPGA 资源。
  • IIR 滤波器:多了一条 “回头路”—— 把输出的一部分,再送回输入端重新参与运算(这个机制就叫反馈)。优点是只用很少几层 “筛子”,就能实现很强的滤波效果,省资源;缺点是反馈比例没调好的话,信号会越放越大,最终发散失控。

一句话总结:IIR = 带循环反馈的信号筛子,用更少资源实现更强滤波。

3. 专业名词大白话对照表

把所有劝退人的术语全部翻译成日常表达,对照着看再也不懵:

表格

专业名词大白话解释
差分方程IIR 的 “计算公式”:当前输出 = 一部分当前 + 历史输入 - 一部分历史输出
零点系数 b前向通路(输入侧)每层筛子的 “松紧比例”,决定输入信号的权重占比
极点系数 a反馈通路(输出回传侧)每层筛子的 “松紧比例”,决定反馈信号的权重占比
延迟单元 z⁻¹就是一个 “寄存格子”,把上一个时刻的数值存起来,下一拍再拿出来用,在 FPGA 里就是寄存器
直接 I 型先走完所有前向筛子,再走反馈回路,两条通路完全分开,结构最直白易懂
定点化FPGA 算小数很麻烦,于是把所有小数系数先放大 N 倍变成整数,算完再缩小 N 倍还原,这个过程就叫定点化
缩放因子定点化里放大 / 缩小的那个倍数,常见的是 2 的整数次幂,比如典型代码里常用 512(2 的 9 次方)
符号扩展负数在 FPGA 里用补码表示,两个位数不一样的负数相加减,要把短位数的符号位复制补齐,否则会算错正负
右移实现除法除以 2 的 n 次方,直接把二进制数往右挪 n 位就能实现,比专门做除法器省超多资源,是 FPGA 设计的必用技巧

二、代码逐行拆解:直接 I 型 IIR 的硬件逻辑

我们以一段典型的直接 I 型 IIR 顶层代码为例,拆成模块逐个讲,完全对应上面的 “筛子” 类比。

1. 两个子模块:两套独立的筛子

代码里例化了zero和pole两个模块,分别对应前向通路和反馈通路:

verilog

zero U0(.Xin(Din), .Xout(Xout)); // 前向筛子:处理输入信号 pole U1(.Yin(Yin), .Yout(Yout)); // 反馈筛子:处理反馈回来的历史输出
(1)zero 模块(前向通路 / 零点)
  • 核心功能:把「当前输入、上一拍输入、上上拍输入……」分别乘以对应的 b 系数,然后全部累加,得到前向通路的加权总和Xout。
  • 以二阶为例,运算逻辑就是:Xout = b0*当前输入 + b1*上一拍输入 + b2*上上拍输入
  • 为什么输出位宽比输入宽?因为 12 位的输入乘以系数、再累加,数值会变大,位数不够就会溢出出错,所以中间运算必须用更宽的位宽预留余量。
(2)pole 模块(反馈通路 / 极点)
  • 核心功能:把「上一拍输出、上上拍输出……」分别乘以对应的 a 系数,然后全部累加,得到反馈通路的加权总和Yout。
  • 以二阶为例,运算逻辑就是:Yout = a1*上一拍输出 + a2*上上拍输出
  • 为什么位宽比 zero 模块更宽?因为反馈是循环累加的,数值会持续堆叠,动态范围更大,需要更多的位数防止溢出。

2. 核心反馈环路:混合 + 缩放还原

这三行是 IIR 滤波器的灵魂,对应反馈、定点化还原的完整逻辑:

verilog

wire signed [25:0] Ysum = {{5{Xout[20]}},Xout} - Yout; // 减法:前向总和 - 反馈总和 wire signed [25:0] Ydiv = {{9{Ysum[25]}},Ysum[25:9]}; // 除法:除以512,还原定点缩放 assign Yin = rst ? 'd0 : Ydiv[11:0]; // 结果回传+输出
第一步:符号扩展 + 减法求和

verilog

{{5{Xout[20]}},Xout}

这行就是符号扩展操作:

  • Xout是 21 位,Yout是 26 位,位宽不同的有符号数不能直接相加减;
  • 把Xout的最高位(符号位,0 代表正数、1 代表负数)复制 5 次,拼接在高位,把 21 位补成 26 位;
  • 补位后正负属性不变,负数运算才不会出错。

完成位宽对齐后,执行减法:前向加权和 - 反馈加权和,对应 IIR 差分方程的核心逻辑:

当前运算结果 = 输入加权和 - 历史输出加权和

第二步:算术右移 = 定点化还原

verilog

{{9{Ysum[25]}},Ysum[25:9]}

这行是算术右移 9 位,等价于有符号数除以 2⁹ = 512。

为什么要除以 512?这就是定点化的 “还原操作”:

  • 前面 zero 和 pole 模块里的 b、a 系数,原本是小数(比如 0.1、0.2);
  • FPGA 做整数运算效率最高,所以设计时把所有系数都乘以 512,转成整数参与运算;
  • 全部运算完成后,再把结果除以 512,还原成真实的物理数值。

这里同样做了符号扩展,保证负数右移时高位补 1,不会出现正负错乱。

第三步:截位输出 + 反馈回传

verilog

assign Yin = rst ? 'd0 : Ydiv[11:0]; assign Dout = Yin;
  • 复位时强制输出 0,让所有寄存器初始状态为 0,避免上电状态混乱;
  • 正常工作时,从 26 位的运算结果里截取低 12 位,作为最终结果;
  • 这个结果兵分两路:一路送回pole模块输入端,参与下一拍的反馈运算(这就是 IIR 的 “循环” 本质);另一路直接作为整个滤波器的输出。

三、手算一遍:一阶 IIR 实例,彻底搞懂运算逻辑

光看代码抽象,我们用一个最简单的一阶 IIR 举例子,数字全部凑成整数,跟着算一遍就全通了。

例子设定

  • 滤波公式:y[n] = 0.5*x[n] + 0.5*y[n-1](一阶低通,实现信号平滑效果)
  • 定点化规则:缩放因子选 2(2 的 1 次方),所有系数乘以 2 转成整数:
    • 零点系数 b0 = 0.5 × 2 = 1
    • 极点系数 a1 = -0.5 × 2 = -1
  • 输入序列:x = [4, 0, 0, 0, 0] (第一个时刻输入 4,之后全为 0,也就是冲激信号)
  • 初始状态:第 0 拍之前的输出 y [-1] = 0

逐拍手算过程(定点整数版)

  1. 第 0 拍(n=0),输入 x [0]=4

    • 前向加权和:1 × 4 = 4
    • 反馈加权和:(-1) × y [-1] = (-1) × 0 = 0
    • 运算总和:4 - 0 = 4
    • 除以 2 还原缩放:4 ÷ 2 = 2
    • 本拍输出 y [0] = 2
  2. 第 1 拍(n=1),输入 x [1]=0

    • 前向加权和:1 × 0 = 0
    • 反馈加权和:(-1) × y [0] = (-1) × 2 = -2
    • 运算总和:0 - (-2) = 2
    • 除以 2 还原缩放:2 ÷ 2 = 1
    • 本拍输出 y [1] = 1
  3. 第 2 拍(n=2),输入 x [2]=0

    • 前向加权和:1 × 0 = 0
    • 反馈加权和:(-1) × y [1] = (-1) × 1 = -1
    • 运算总和:0 - (-1) = 1
    • 除以 2 还原缩放:0.5 → 整数截位后为 0
    • 本拍输出 y [2] = 0

你看,只输入了一个 4,输出是 2、1、0…… 慢慢衰减下去,这就是 IIR “无限冲激响应” 的含义 —— 输入消失了,输出还在慢慢变化,理论上永远不会绝对归零。

工程里的高阶 IIR 代码,逻辑和这个手算例子完全一致,只是阶数更高、位宽更大、缩放因子更大而已。

四、FPGA 设计 IIR 的完整步骤(通俗版)

搞懂原理后,完整的工程设计流程也很好理解:

  1. 定需求:明确滤波目标、采样率、输入输出位宽、通带阻带衰减等指标
  2. 算系数:用 MATLAB 的 Filter Designer 等工具,输入需求算出浮点格式的 b、a 系数
  3. 定点化:选择合适的缩放因子,把小数系数量化为整数,同时规划好每一级运算的位宽
  4. 搭结构:划分前向、反馈通路,用寄存器做延迟、乘法器乘系数、加法器做累加
  5. 防溢出:中间运算位宽留足余量,输出端可增加饱和逻辑防止溢出反转
  6. 写代码 + 仿真:编写 Verilog 代码,输入测试信号验证滤波效果与精度

五、初学者常见疑问解答

1. 为什么用减法不用加法?

标准 IIR 传递函数的分母形式是1 + a1 z⁻¹ + ...,移项整理成差分方程后,反馈项就是减法形式,因此硬件里用减法实现。

2. 为什么一定要定点化?不能直接算小数吗?

FPGA 也可以实现浮点运算,但浮点运算器资源占用极大、运行速度慢。滤波器这类需要高速、重复运算的模块,全行业都采用定点整数方案,性价比最高。

3. 定点截位会不会算错?精度够吗?

截位确实会引入微小的量化误差,但只要缩放因子选取得当、中间位宽预留充足,误差完全在可接受范围内,音频处理、工业控制、传感器信号采集等绝大多数场景都能满足要求。

写在最后

IIR 滤波器看似复杂,本质就是 “前向加权 + 反馈加权 + 缩放还原” 的循环逻辑。只要理解了反馈的意义、定点化的原因、每一行代码对应的运算,就能从 “能跑就行” 进阶到 “知道为什么这么写”。

如果是刚入门 FPGA 数字信号处理,建议先从一阶、二阶 IIR 入手,手写代码 + 仿真对比 MATLAB 结果,上手会非常快。

相关新闻

  • MC68VZ328 UART与PWM寄存器深度解析与驱动开发实战
  • 2026老Windows WMA格式免费在线转换保姆级教程:即转即播全攻略 - 时时资讯
  • 2026年6月市政水务在线ORP仪主要品牌排行榜:技术实力、市场格局与场景化选型深度分析 - 仪表品牌榜

最新新闻

  • 揭秘XOutput:让老旧游戏手柄在PC游戏中完美工作的终极解决方案
  • 2026兰州黄金回收白银回收铂金回收门店实测|本地正规实体老店无套路门店推荐 - 中安检金银铂钻回收
  • 滁州来安县大型罐体吸污抽粪处理工地混杂污水,重载车辆抽泥浆清运基坑沉淀淤泥沙土 - 天堂海洋
  • 2026达州黄金回收白银回收铂金回收门店+工商公安双备案+中检认证商家推荐 - 诚金汇钻回收公司
  • 上电考试-言语之路
  • RK3288_Android7.1:从驱动适配到事件上报,打通ES8388音频全链路

日新闻

  • 5分钟掌握Python进化算法:Geatpy高性能优化工具完全指南
  • Microchip 24AA044 EEPROM选型与应用全指南:从参数解析到实战编程
  • 华为的鸿蒙到底有多牛?为什么称作遥遥领先?

周新闻

  • 3步解锁iOS设备:applera1n激活锁绕过完全指南
  • 39 2026 人工智能证书终极盘点,普通人选 AI 证书可以从这些方向入手
  • Redis 暴露公网有多危险?从端口检查到补救步骤

月新闻

  • 【总结】入门篇:50句话让你记住架构核心概念
  • WeChatMsg技术方案解析:实现Mac微信数据自主管理的完整解决方案
  • WeChatMsg:革新性微信数据备份方案,打造你的专属数字记忆库

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号