FPGA coder · 数字接收机与信号处理 · 163
DDC 参数到底怎么选?中频、信号带宽、抽取倍率与混叠边界一次算清
做数字接收机时,常有人先打开 FIR Compiler,试着填一个“看起来合理”的抽取率;等到波形不对,再回头猜是 NCO 符号、滤波器截止频率,还是 FFT 标定出了问题。这样排查很费时间,因为这些参数本来就是一条链:中频决定 NCO,信号带宽决定通带,抽取率决定新奈奎斯特区,滤波器则要阻止带外信号折回来。
先把一个容易忽略的事实放在前面:数字混频只是搬动频谱,不会自动删除带外信号。抽取也不是“扔掉一些采样点”这么简单;在降采样之前没有足够的抗混叠滤波,原本分开的频率会在新采样率下重叠,后面再加 FIR 也分不开了。
图 1|从输入中频、NCO混频到两级抽取与频谱折叠的参数规划图1、先把输入信号写成频率区间
假设 ADC 是实采样,采样率为 100 MSPS;目标中频为 21.4 MHz,目标信号的总占用带宽为 2 MHz。这里“总带宽 2 MHz”指中心频率两侧各 1 MHz,因此 ADC 输入端的目标频段是:
ADC 的第一奈奎斯特区是 0~50 MHz,这个目标频段落在区间内。实际板卡还要先检查模拟输入带宽、前端抗混叠滤波、时钟抖动和 ADC 输入网络;如果模拟端已经把另一个频段混叠进 20.4~22.4 MHz,FPGA 里的 DDC 无法把它“还原出去”。
让 NCO 产生 21.4 MHz 的复数本振,与 ADC 实数样本相乘后,目标频段被搬到复基带:
f_bb = f_in - f_LO
因此目标信号变成 −1~+1 MHz。这里的频率是带符号的复频率,不要把它误读成只有 0~1 MHz 的实信号。复数 I/Q 能保留正、负频率的方向信息;若 I/Q 符号或 Q 路正负约定相反,频谱可能镜像,但带宽仍然是 2 MHz。
图 2|100 MSPS输入频段、复基带通带和最终5 MSPS抽取的折叠边界2、NCO 频率不是“填一个小数”就结束
以 32 位相位累加器为例,若 DDS 的相位更新时钟就是每个 ADC 样本一次,则相位增量字可以按下式计算:
PINC = round(f_LO / F_s × 2^N)
其中 f_LO 是 21.4 MHz,F_s 是 100 MHz,N 是相位累加器位数。实际输出频率为 PINC × F_s / 2^N,频率分辨率为 F_s / 2^N。如果 DDS 的配置不是每个有效样本更新一次,或者输入数据存在时钟使能、抽取、时分复用,就不能盲目把板上时钟当作公式里的采样率;应按 IP 配置和数据握手语义确认相位推进速度。
下面这段小脚本可以先算出相位增量和实际频率。综合后还要核对 IP 报告中的相位宽度、频率模式、符号和 PINC 接口配置。
from math import floorfs_adc = 100_000_000.0f_if = 21_400_000.0phase_width = 32pinc = floor(f_if / fs_adc * (1 << phase_width) + 0.5)f_actual = pinc * fs_adc / (1 << phase_width)f_error = f_actual - f_ifprint(f"PINC = {pinc}")print(f"f_actual = {f_actual:.6f} Hz")print(f"frequency error = {f_error:.6f} Hz")本例中 32 位相位累加器的频率步进约为 0.0233 Hz,量化误差远小于很多接收机的频率误差预算;但这不代表系统频率就一定这么准。ADC 采样时钟偏差、外部参考源误差和 NCO 时钟源误差都会按比例影响实际频率。若系统要跨板同步或精确测频,还要把参考时钟和校准纳入预算。
另一个容易踩的坑是“零中频一定最好”。如果有强直流泄漏、LO 馈通或 ADC 直流偏置,可以让 NCO 留一个小的残余频偏,把目标信号放在 f_res 附近。此时滤波器通带应覆盖 f_res ± B/2,抽取混叠计算也要以这个实际通带为准。
3、先从通带反推最终采样率
目标总带宽 B=2 MHz,理想情况下复基带至少要以不低于 2 MSPS 采样。但工程设计不能把通带边缘卡在奈奎斯特边界上:滤波器需要过渡带,信号频率可能有偏差,系数和时钟也有误差。因此本例给通带边缘留 100 kHz 保护量,设:
通带距离最终奈奎斯特边缘还有 1.4 MHz,滤波器可以把过渡带安排在这段范围内。若最终采样率只选 2 MSPS,那么奈奎斯特边缘恰好是 ±1 MHz,连信号边缘和滤波器过渡带都没有容纳空间,参数就不成立。
对复基带,检查条件可以写为:
F_out / 2 > F_p
本例是 2.5 MHz > 1.1 MHz。同时,若后级要做 FFT,还要检查频率分辨率 Δf=F_out/N_FFT、每帧观测时间 T=N_FFT/F_out、处理吞吐和延迟。比如 4096 点 FFT 在 5 MSPS 下,频率栅格约为 1.221 kHz,一帧观测时间约为 819.2 μs。采样率不只是“能不能装下信号”,也影响观察时间和实时处理预算。
4、抽取率要拆成每一级,而不是只看总倍率
本例选择总抽取倍率 20:
D_total = 4 × 5 = 20
于是 100 MSPS → 25 MSPS → 5 MSPS。一级 CIC 做 4 倍抽取,二级 FIR 做 5 倍抽取。这样选不是唯一答案,而是便于说明速率与滤波边界的关系。也可以选 2×10、5×4 或更多级组合;每一级都必须用自己的输入采样率、输出采样率和目标通带重新检查。
抽取后采样率可以直接计算:
F_s,out = F_s,in / R
多级时,总倍率是各级倍率的乘积。若抽取率是可编程的,软件改倍率时,必须同步更新后续滤波器系数、NCO/FFT 标定、DMA 帧长度和上位机显示;只改一个寄存器,常常会得到“波形还有、频轴全错”的现象。
5、混叠边界要按“会折到哪里”来算
最后一级 FIR 把 25 MSPS 降到 5 MSPS。抽取后的复频谱每隔 5 MHz 重复一次,频率会折回区间 −2.5~+2.5 MHz。一个输入频率 f 折回后的等效频率可按下面的包裹关系理解:
f_alias = ((f + F_out/2) mod F_out) - F_out/2
如果只关心最终 −1.1~+1.1 MHz 的目标通带,那么会直接折入这个通带的第一个正频率干扰区从:
F_out - F_p = 5.0 - 1.1 = 3.9 MHz
开始;也就是说,最终抽取前 3.9~6.1 MHz 附近的能量,会映射到目标复基带通带附近。负频率一侧也有对称的折叠区。若是多音、宽带噪声或调制信号,不能只测一个点,要对整个带外频谱和滤波器衰减积分/仿真。
这里有两个常被混为一谈的滤波器指标:
- 完整输出频带都要干净:保守地要求阻带从最终奈奎斯特边界附近,即不晚于 2.5 MHz 开始。这样折回到输出 ±2.5 MHz 任意位置的带外分量都会被压制。
- 只交付窄目标通带:理论上可以把重点阻带放在会折入 ±1.1 MHz 的 3.9 MHz 附近,但 2.5~3.9 MHz 的折叠能量会落在目标通带外的输出保护区。只有当后级确实不会使用该区域、没有更后级抽取,并且阻塞信号/数值溢出风险也评估过,才考虑这种放宽。
因此“截止频率取新采样率的一半”不是一句可以不看上下文的口号。要说清楚你保护的是完整输出奈奎斯特区,还是只保护指定信道;再根据通带、过渡带和阻带衰减写滤波器指标。
可以用下面的代码快速列出抽取后映射进目标通带的几个干扰区。k 是频谱重复次数;实际输入带宽有限时,再把超出输入 Nyquist 范围的区间删掉。
fs_out = 5.0 # MSPS,最终复采样率fp = 1.1 # MHz,目标通带边缘input_nyquist = 50 # MHz,示例输入频带上限print(f"完整输出频带边界: +/-{fs_out / 2:.3f} MHz")print(f"直接折入目标通带的首个正频率边界: {fs_out - fp:.3f} MHz")print("正频率 alias bands that map into +/-Fp:")for k in range(1, int(input_nyquist // fs_out) + 1): lo = k * fs_out - fp hi = k * fs_out + fp if lo <= input_nyquist: print(f"k={k}: {lo:.3f} .. {min(hi, input_nyquist):.3f} MHz")这段脚本只给出频率区间,不会替你判断某个阻塞信号是否真的存在,也不会给出所需阻带衰减。阻带指标要从最大带外信号、目标噪声底、允许的杂散和后级动态范围推出来。
6、CIC 负责省乘法器,但它不是“免费砖墙滤波器”
CIC 适合做较大的整数抽取:结构主要是积分器和梳状器,不需要每级乘系数,逻辑资源效率好。代价是通带下垂、有限阻带抑制和较大的内部位宽。一个常用的归一化幅频响应表达式是:
|H(f)| = |sin(π R M f/F_s) / (R M sin(π f/F_s))|^N
其中 R 是抽取倍率,M 是差分延迟,N 是级数。不同 IP 的缩放、增益补偿和舍入配置可能不同,公式适合先做频响估算,不应替代 IP 仿真。
本例若用 R=4、M=1、N=3,CIC 的第一零点在 25 MHz。目标通带边缘 1.1 MHz 处,下垂较小;但遇到强阻塞信号时,要把 23.9~26.1 MHz 这类可能折入最终目标通带的频段代入 CIC 频响,检查实际抑制度。CIC 第一零点附近可能压得很深,但离零点越远衰减不同,别只看“有零点”就认为足够。
CIC 的位宽也别漏算。未缩放 CIC 的最大直流增益为 (R×M)^N,对应增长位数约为:
G_bits = ceil(N × log2(R × M))
本例 R=4、M=1、N=3,最坏增长为 6 位。若 ADC 输出 14 位有符号数据,简单上界估算需要 20 位保存 CIC 增益;实际还要结合输入满量程、有效带宽、IP 输出截位/舍入和后续 FIR 的系数增益来定。截掉低位会改变噪声底,过早截掉高位则可能饱和或回绕。
一种常见分工是:CIC 先把采样率大幅降下来,再由 FIR 做通带补偿并提供可控的阻带衰减。若第一级有特别强的邻道阻塞,资源允许时可在 CIC 前加半带/FIR 预滤波,或把抽取拆成更温和的多级结构。选择时比较的不是“哪个 IP 看起来最简单”,而是乘法器、存储、时钟、延迟、阻带要求和定点误差的总账。
7、把参数写成一张可交接的设计表
频率规划至少要交代这些信息,否则不同人填 IP 时容易各自理解一套:
实际设计表还应加上最大邻道/阻塞信号电平、要求的阻带衰减、允许通带纹波、通带群时延、输出位宽、舍入模式、饱和策略、有效数据速率和复位后首个有效样本位置。把这些写进版本管理的参数文件,比只在 IP GUI 里留一组没人记得来历的数字可靠得多。
8、仿真和上板怎么验证,能更快定位问题
不要只喂一个“刚好在中心频点”的正弦。建议按顺序准备以下测试:
- 中心频点测试:输入 21.4 MHz 单音,确认输出落在 DC 附近;如果有意设置残余频偏,则应落在预期
f_res。 - 通带边缘测试:分别输入 20.4 MHz、22.4 MHz,检查通带幅度、频率偏差和 I/Q 方向;再在 ±1.1 MHz 处验证设计通带边缘。
- 阻带/混叠测试:在最终抽取前给 3.9~6.1 MHz 的复基带等效频率注入干扰,确认它们映射到目标带内时已满足衰减要求。还要按每一级抽取率检查
k×F_s,out ± F_p 的 alias bands。 - 强邻道测试:目标信号很小、邻道很强时观察是否出现通带污染、CIC/FIR 溢出或 FFT 杂散。滤波器有足够理论抑制度,不代表前面级的位宽和动态范围就一定够。
- 时序和吞吐测试:检查每个抽取级的有效节拍、
valid/ready 背压、帧边界和 FFT 的 TLAST。输入连续时,确认下游停顿不会丢样或把两帧拼在一起。
频谱仪或仿真模型的横轴要跟着每级采样率更新。100 MSPS、25 MSPS、5 MSPS 三处的奈奎斯特边界分别是 ±50、±12.5、±2.5 MHz;如果抓到数据后仍用 ADC 的采样率画最终 FFT,频谱位置当然会错。可以在数据流里同步携带抽取倍率版本、有效样本计数和帧起始标志,便于离线复算。
9、最容易出现的几种参数错误
- 把“带宽 2 MHz”理解成 ±2 MHz:先统一总带宽和单边带宽的定义。本例总带宽 2 MHz,基带是 −1~+1 MHz,不是 −2~+2 MHz。
- NCO 用错时钟:DDS 的相位更新速率与 ADC 数据速率不一致时,频率会按比例跑偏。检查 IP 的时钟、时钟使能和每周期输入样本数。
- 抽取后还用旧的采样率:FIR 的系数归一化频率、FFT 频轴、时间戳和 DMA 吞吐都要用新的采样率。
- 只看目标信号,不看阻塞信号:抽取前的强带外信号可能折回目标频带;仿真只放一根目标单音,会把这个问题藏起来。
- 把最终混叠边界套到每一级:每一级输出率不同,alias bands 也不同;逐级列出
k×F_s,out ± F_p,不能只检查最后一级。 - 忘记模拟混叠和数字混叠是两件事:ADC 前的模拟混叠发生在采样时,DDC 后的抽取混叠发生在数字降采样时,两处都要有对应的滤波/频率规划。
- CIC 位宽和缩放随手定:按最坏增益、目标信号范围和后级动态范围复核增长位数、截位点和舍入方式。
10、收尾:把 DDC 设计从“填参数”变成“可复核的频率预算”
每次搭 DDC,先回答四个问题:ADC 实际看到的目标频段在哪里?混频后目标复频带落在哪里?每一级抽取之后,采样率和奈奎斯特范围是多少?哪些带外分量会折进最终的目标通带,滤波器在这些频段能压到多少?
这些答案确定后,再选 CIC 级数、差分延迟、抽取倍率和 FIR 系数;然后用中心频点、通带边缘、alias bands 和强邻道逐项验证。参数因此不只是一次 IP 配置,而是一份能复算、能复测、能交接的接收机频率计划。
参考资料
- AMD DDS Compiler PG141:Phase Increment
- AMD DDS Compiler PG141:System Parameters
- AMD CIC Compiler PG140:General Design Guidelines
- AMD CIC Compiler PG140:CIC Decimator
- AMD FIR Compiler PG149:Polyphase Decimator
*文中的 100 MSPS、21.4 MHz、2 MHz 带宽及抽取结构均为说明计算方法的示例,不代表特定项目或板卡的实测结果。滤波器阻带、动态范围、时钟精度和安全裕量应由实际信号环境与系统指标确定。*