FIR数字滤波器在FPGA中怎么设计与实现

浏览量:9
时间: 2026-08-19 09:56:57

Linux设备树dts源码终端界面

本文概述

FIR滤波器是FPGA数字信号处理中最基础也是最常见的模块,属于面试高频考点。FIR的核心是乘加运算,输入信号经过延迟抽头,每个抽头乘以系数后求和得到输出。FPGA中常用的实现结构有直接型、转置型和分布式算法三种:直接型结构直观易理解,转置型更适合高速时钟,分布式算法用查找表代替乘法器可以节省DSP资源。设计FIR需要关注系数量化、位宽增长、流水线级数和资源利用率之间的平衡。

核心要点速览

  • FIR = 有限长单位脉冲响应,核心公式 y(n) = Σ h(k) × x(n-k)

  • 三种常用结构:直接型、转置型、分布式算法(DA)

  • 系数一般用MATLAB或Python设计,需量化为定点数

  • 输出位宽 = 输入位宽 + 系数字宽 + log2(N阶数)

  • 选择结构要看:阶数、采样率、DSP资源、输入位宽

面试题:你在FPGA里做过FIR滤波器吗?怎么设计的?用了什么结构?
面试官
你在FPGA里做过FIR滤波器吗?简单说说怎么做的。
做过的。我之前在一个信号采集项目里做过一个32阶的低通FIR滤波器,采样率20MHz,用Verilog实现的。整体思路是先在MATLAB里设计滤波器系数,量化后在FPGA里用转置型结构实现。

一、面试官考察点

理论基础

  • FIR和IIR的区别

  • FIR的线性相位特性

  • 抽头系数的含义

硬件实现

  • 常用实现结构

  • 资源和速度权衡

  • 位宽增长处理

工程经验

  • 系数设计和量化

  • 实际调试问题

  • 仿真验证方法

二、回答思路

第一部分:FIR的基本原理

在说FPGA实现之前,先把FIR的原理说清楚。FIR是有限长单位脉冲响应滤波器,意思是单位脉冲响应的长度是有限的。输出等于输入和单位脉冲响应的线性卷积。

简单说就是:输入信号经过一串延迟寄存器,每个延迟抽头的信号乘以对应的滤波器系数,所有乘积加起来就是输出。阶数等于抽头数减一,阶数越高,滤波器的过渡带越陡,性能越好,但需要的乘法器和资源也越多。

面试官
FIR和IIR有什么区别?为什么选FIR?
主要有几个区别。第一,FIR没有反馈,永远稳定,不会振荡;IIR有反馈,设计不好可能不稳定。第二,FIR可以做到严格的线性相位,信号通过滤波器所有频率成分延迟一样,不会有相位失真;IIR的相位是非线性的。第三,同样的性能指标,IIR需要的阶数少很多,FIR阶数多。

选FIR主要是因为稳定和线性相位,在数字通信、图像处理这些对相位敏感的场合必须用FIR。而且FPGA里乘法器很多,做多阶FIR也不是问题。

第二部分:系数设计

FIR的系数不是拍脑袋定的,是用专门的滤波器设计工具算出来的。我一般用MATLAB的fdatool或者filterDesigner,或者Python的scipy.signal.firwin函数。

设计滤波器的时候要先确定几个指标:滤波器类型(低通、高通、带通、带阻)、采样率、截止频率、通带纹波、阻带衰减。然后选设计方法,常用的有窗函数法和等波纹法。窗函数法简单直观,等波纹法在同样阶数下性能更好。

设计出来的系数是浮点数,FPGA里不能直接用,需要量化成定点数。量化的时候要考虑量化位数对滤波器性能的影响,位数太少的话通带纹波和阻带衰减都会变差。我一般先量化成16位,仿真看效果行不行,不行就加位数。量化的方式也有讲究,一般用四舍五入比直接截位误差小。

第三部分:FPGA实现结构

FPGA里实现FIR,常用的结构有三种,各有适用场景:

直接型

  • 结构最直观,跟公式对应

  • 输入延迟链 + 乘法器 + 加法树

  • 阶数高时输入扇出大

  • 加法树路径长,不利于高速

  • 适合低阶、低速场景

转置型

  • 输入同时到所有乘法器

  • 乘法结果经寄存器链累加

  • 关键路径短,容易跑高速

  • 每个加法器后插寄存器

  • 适合高阶、高速场景

分布式(DA)

  • 用查找表代替乘法器

  • 省DSP资源,只用BRAM

  • 适合系数固定、位宽不大

  • 串行处理,采样率受限

  • 可以多级展开提升速度

我之前那个项目用的是转置型结构,因为采样率20MHz,时钟要跑在100MHz以上,转置型时序更容易收敛。而且32阶的话,用32个DSP乘法器也不算多,资源是够的。

转置型FIR的Verilog代码大概是这样的结构:

module fir_transposed ( input clk, input rst_n, input signed [15:0] din, output reg signed [31:0] dout ); // 32阶滤波器系数(量化后的16位定点数) parameter signed [15:0] COEFF [0:31] = '{ 16'h0012, 16'h0034, ... // 32个系数 }; // 32个乘法输出 + 32个前馈寄存器链 reg signed [31:0] add_chain [0:31]; genvar i; generate for (i = 0; i < 32; i = i + 1) begin : fir_tap always @(posedge clk) begin if (i == 0) add_chain[i] <= din * COEFF[i]; else add_chain[i] <= add_chain[i-1] + din * COEFF[i]; end end endgenerate always @(posedge clk) dout <= add_chain[31]; endmodule

这是一个简化的示意代码,实际项目中还要考虑复位、输出截位、系数对称性优化等。

第四部分:位宽和截位

FIR滤波器有一个很重要的问题就是位宽增长。假设输入是N位,系数是M位,N阶滤波器,乘法器输出就是N+M位,加法树加完之后最多再增加log2(N)位。所以输出位宽大约是N+M+log2(N)。32阶16位输入16位系数的话,输出大约是16+16+5=37位,一般用40位或者直接用DSP的输出位宽。

但最后输出一般不需要这么多位,要截位。截位的时候要注意不能截得太狠导致信噪比不够。通常做法是先算好需要的输出位宽,然后根据增益和噪声要求决定截几位。截位方式有直接截位和四舍五入,四舍五入误差小一点但逻辑稍微复杂。

三、追问环节

面试官
如果系数是对称的,可以怎么优化?
线性相位FIR的系数是对称的,也就是第k个系数等于第N-k个系数。这个特性可以用来减少乘法器的数量。

具体做法是:先把对称的两个输入加起来,再乘以一个系数,这样乘法器的数量就减少了一半。比如32阶对称FIR,本来要32个乘法器,现在只要16个就够了,节省一半DSP资源。

不过要注意,先加后乘虽然省了乘法器,但加法器的位宽会多一位,而且路径上多了一个加法器的延迟,时序上要考虑一下。

追问2:什么是半带滤波器?有什么优势?

半带滤波器是一种特殊的FIR滤波器,它的通带和阻带关于二分之一采样频率对称,而且近一半的抽头系数是零。因为有很多零系数,所以实际需要的乘法器数量大约只有普通FIR的一半,资源利用率高很多。

半带滤波器常用在2倍抽取或插值的场合,比如多速率信号处理中的半带抽取器、半带插值器。配合2倍采样率变化,每两个采样点算一次,进一步减少计算量。如果做多级降采样,第一级常用半带滤波器,效率很高。

追问3:如果采样率很高,单时钟周期算不完怎么办?

如果采样率太高或者阶数太多,一个时钟周期算不完,有几个优化方向。第一个是加流水线,在加法树中间插寄存器,把长路径拆短,这样可以跑更高的时钟频率。转置型结构本身就是部分流水线的。

第二个是用全并行结构,就是每个抽头一个乘法器,一拍出结果,速度最快但用的乘法器也最多。第三个是串行结构,用一个乘法器时分复用,多个抽头共用一个乘法器,几拍算完一个输出,省资源但速度慢。

还有一种是多相分解,把一个N阶滤波器拆成M个相,每个相处理一部分系数,适合多速率系统。总之就是速度和资源的权衡,看项目更看重哪个。

追问4:你怎么验证FIR滤波器做的对不对?

我一般分几步验证。第一步是单元仿真,给一个已知的输入信号,比如冲激响应或者阶跃信号,看输出是不是跟MATLAB算的一致。第二步是频域验证,给一个正弦扫频信号,或者用白噪声输入,算输出的频谱,看滤波器的幅频响应对不对。第三步是上板验证,用信号发生器输入不同频率的正弦波,用逻辑分析仪抓输出波形,算增益,跟仿真结果对比。

还有一个方法是把MATLAB或者Python算出来的参考输出做成文件,仿真的时候逐点对比,这样最严谨。位宽量化的影响也可以在这个过程中验证,看量化后的效果跟浮点参考比差多少。

四、失分表达

错误说法
"FIR就是乘法加加法,很简单,调用IP核就行。"

面试官问的是你的设计能力,不是调用IP的能力。要能讲清原理、结构、参数选择的考量。

错误说法
"输出位宽跟输入一样就行,直接截位。"

要理解位宽增长的规律,知道怎么计算需要的位宽,截位也要有依据,不能想当然。

五、准备动作

理论准备

  • FIR原理和线性相位特性

  • 直接型和转置型的结构差异

  • 位宽增长的计算方法

动手准备

  • 用MATLAB或Python设计一个低通FIR

  • 写一个简单的FIR Verilog代码

  • 做一个简单的Testbench验证

项目准备

  • 准备一个FIR相关的项目案例

  • 说清楚指标、结构、资源和遇到的问题

  • 能画出结构框图更好

面试官你好,关于FIR滤波器的FPGA设计与实现,以上是我的理解和实际经验

要不要我具体讲一下分布式算法的实现思路?


声明:本网站所收集的部分公开资料来源于互联网,转载的目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。仅供学习交流使用,不构成商业目的。版权归原作者所有,如果您发现网站上有侵犯您的知识产权的作品,请与我们取得联系,我们会及时删除。侵权投诉
相关推荐HOT
PCB上晶振的EMC防护布局怎么做?硬件面试要从频域干扰讲到接地屏蔽

分类:硬件工程师面试题经验要求:中高级难度:中高级题型:EMC防护设计📖 本文概述晶振是PCB上常见的高辐射源之一,也是硬件工程师面试中EMC防护的高频考点。... 详情>>

2026-08-04 15:58:40
嵌入式工程师面试简历项目描述怎么写才吸引面试官?4种结构对比

分类:嵌入式工程师面试准备经验级别:中级难度:基础题型:简历准备📖 本文概述简历中的项目描述是面试官对你形成第一印象的关键。本文对比4种不同的项目描述方式,帮... 详情>>

2026-08-05 09:56:21
PCB发板前DFM检查清单有哪些?PCB工程师面试必考题

分类:PCB设计工程师面试经验级别:中级难度:★★★☆题型:发板前设计检查PCB设计工程师面试:发板前DFM检查本文概述PCB发板前DFM检查是保证板子可制造、... 详情>>

2026-08-08 15:14:59
高速连接器在PCB上的布局位置怎么确定?PCB面试要从信号入口讲到阻抗过渡

分类:PCB设计工程师面试题经验要求:中级难度:中高级题型:布局设计📖 本文概述高速连接器布局位置是PCB设计工程师面试高频题。本文从结构接口坐标定位、参考平... 详情>>

2026-08-04 15:59:25
实时系统的调度

(1)调度:给定一组实时任务和系统资源,确定每个任务何时何地执行的整个过程。 (2)抢占式调度:通常是优先级驱动的调度,如uCOS。优点是实时性好、反应快,调度... 详情>>

2024-03-12 16:23:05
开班信息