这是一个非常经典的 FPGA 数字信号处理问题。32 位相位累加器能实现 mHz(毫赫兹)级别的频率分辨率,其核心原因在于利用了"溢出"的数学特性和巨大的二进制位数比。
下面我们分步拆解,并用 GNSS 诱骗的实际参数代入计算。
一、NCO 的基本原理:相位累加器
NCO 的核心是一个寄存器(相位累加器),它在每个系统时钟周期(sys_clk)加上一个固定的数值(频率控制字,FCW)。当累加器溢出(超过最大值)时,它回到 0,形成一个周期。
+-----------+
| Phase |
sys_clk --> Accumulator| --> [取高位] --> 查表(RAM) --> 波形
| |
+-----------+
^
| (每次加 FCW)
数学公式
设:
-
fclk= 系统时钟频率(例如 100 MHz)
-
N= 相位累加器的位宽(例如 32 bits)
-
FCW= 频率控制字(我们要写入的整数)
输出频率 fout的计算公式:
fout=2NFCW×fclk
这个公式的含义是:每 2N个时钟周期,累加器转了一圈(溢出一次),这就形成了一个频率。
二、为什么 32 位能做到 mHz 级分辨率?
关键在于分母 232这个巨大的数字。
1. 计算分辨率(Frequency Resolution)
频率分辨率(Δf)是指 FCW 每增加 1,输出频率的最小变化量。
Δf=2Nfclk
代入实战参数:
-
fclk=100 MHz=100×106 Hz
-
N=32
Δf=232100×106=4,294,967,296100×106≈0.02328 Hz
结果:约 23 mHz(毫赫兹)。
这意味着,我们可以通过调整 FCW,将输出频率精确地控制在 0.023 Hz 的倍数上。这对于 GNSS 所需的微小多普勒牵引来说,精度绰绰有余。
2. 对比:如果是 16 位累加器会怎样?
Δf16=216100×106=65,536100×106≈1525.9 Hz
如果是 16 位,频率调节步长高达 1.5 kHz,这对于 GNSS 载波(1575.42 MHz)来说简直是"狂奔",根本无法锁定。
三、在 GNSS 慢牵引(Slow Pull-off)中的应用
现在我们回到之前的 GAN 诱骗场景,看看这个 23 mHz 的精度意味着什么。
1. 控制 L1 载波(1575.42 MHz)
我们需要生成 GPS L1 载波。假设 FCW 为 X:
1575.42×106=232X×100×106
X=1001575.42×232≈67,627,206
这是一个整数。由于分辨率是 0.023 Hz,我们可以非常精确地锁定在 1575.42 MHz,误差极小。
2. 控制多普勒牵引(最关键)
在 Slow Pull-off 中,我们需要让频率缓慢变化。假设我们要实现 0.5 m/s 的牵引速度。
-
多普勒频移公式:Δf=−cv⋅fcarrier
-
v=0.5 m/s
-
fcarrier=1.57542×109 Hz
-
c=3×108 m/s
Δf=−3×1080.5×1.57541×109≈−2.625 Hz
结论:我们需要在 L1 载波的基础上,增加或减少大约 2.6 Hz 的频率偏移。
用 32 位 NCO 如何实现?
我们只需要改变 FCW 的值。
ΔFCW=fclkΔf×232=100×1062.625×4,294,967,296≈112.7
取整为 113。也就是说,我们只需要把 FCW 增加 113,频率就会增加 2.625 Hz。
精度验证:113 * 0.02328 Hz ≈ 2.630 Hz。误差仅为 0.005 Hz,对于接收机 PLL 来说完全不可察觉。
四、相位截断(Phase Truncation)带来的杂散
虽然累加器是 32 位,但我们通常不会用全部的 32 位去查表(RAM 没那么大)。
假设我们只取高 10 位作为 ROM 地址:
-
累加器位宽:32 bits
-
查表位宽:10 bits
-
截断位数:22 bits
这会导致相位截断误差,在频谱上表现为杂散(Spurs)。为了掩盖 GAN 生成的虚假信号,这些杂散必须足够低,不能比真实卫星信号的噪声底高太多。
解决方法:
-
增加 LUT 深度:尽量用高位宽(如 12~14 位)。
-
抖动(Dithering):在累加器低位人为加入随机噪声,将杂散能量扩散成白噪声,降低单频杂散的峰值。这对 GNSS 欺骗非常重要,因为真实卫星信号是非常纯净的。
五、总结
此文由 怡心湖 编辑,若您觉得有益,欢迎分享转发!:首页 > 常识论 » NCO 频率分辨率的计算(为什么 32bit 累加器能精确到 mHz 级别)