1. 从一个反直觉的现象说起:为什么SDM噪声在PLL里不能直接"搬"过去
很多刚接触小数分频锁相环的朋友,第一次做噪声预算时都会犯一个错误:把SDM(Sigma-Delta Modulator,Σ-Δ调制器)的量化噪声当成一个普通的白噪声源,直接按带宽比例折算到输出端。结果仿真一跑,发现低频段相位噪声比手算高了十几dB,高频段又对不上。问题出在哪?出在SDM的量化噪声不是直接加到输出上的,它要经过一条完整的传递路径——从调制器输出,穿过分频器、鉴相器、电荷泵、环路滤波器,最后才反映到VCO的控制电压上。这条路径对不同频率的噪声有不同的增益,低频被抑制、高频被放大,形状完全不是平的。
所以"SDM量化噪声等效到PLL输出的传递函数推导"这件事,本质上是要搞清楚:调制器在分频比上引入的抖动,经过环路后,在输出相位上到底被塑造成了什么形状。这个传递函数是小数分频PLL噪声预算的核心,也是判断环路带宽选得合不合理、SDM阶数够不够、需不需要额外滤波的直接依据。
这篇文章面向的是正在做小数分频PLL设计、需要自己动手推公式或搭模型验证的工程师,也适合想搞明白"为什么SDM噪声整形和环路整形会叠加"这个问题的读者。我会从Z域建模开始,一步步把传递函数推出来,然后讲清楚每一项的物理含义,最后给出实测中容易踩的坑和验证方法。全程不跳步,公式和直觉解释交替着来。
提示:本文推导基于经典的小数分频PLL线性化模型,假设环路处于锁定状态、各模块工作在线性区。大信号瞬态、非线性效应不在讨论范围内。
2. 把PLL拆成Z域模块:推导前必须建立的三个建模前提
在动笔推传递函数之前,得先把建模的"地基"打牢。很多推导看着复杂,其实是因为一开始的假设没统一,导致后面每一项的符号和系数都对不上。我一般会先把下面三件事定死,后面推导就顺了。
2.1 前提一:用相位域而不是电压域建模
PLL里各个节点有的是电压、有的是电流、有的是频率,直接混着推很容易乱。标准做法是统一到相位域:把分频器输出、参考输入、VCO输出都表示成相位量,鉴相器输出的是相位误差乘以增益。这样做的好处是,整个环路的传递函数可以用一个统一的量纲串起来,最后输出相位噪声的功率谱密度(PSD)单位就是rad²/Hz,直接对应相位噪声指标。
具体来说,定义参考相位为θ_ref,分频器反馈相位为θ_div,鉴相器增益为K_pd(单位V/rad或A/rad),环路滤波器传递函数为F(s),VCO增益为K_vco(单位rad/s/V)。这些量在连续域里是标准的,但SDM是离散时间模块,必须转到Z域处理。
2.2 前提二:SDM工作在过采样状态,量化噪声可近似为白噪声
Σ-Δ调制器的核心是噪声整形:它把量化误差e[n]通过一个高通传递函数推到高频,低频段噪声被压得很低。要推导它对输出的影响,第一步是假设量化误差e[n]在采样率f_s下是白噪声,功率谱密度为常数。这个假设在输入信号变化不快、调制器阶数不太高时成立得很好。
对于L阶SDM,其噪声传递函数NTF(z)通常是(1-z⁻¹)^L的形式(CIFB结构)或带零点优化的形式。量化误差经过NTF后,在分频比上产生的抖动为:
ΔN(z) = NTF(z) · E(z)
其中E(z)是白噪声。这一步是整个推导的起点,也是后面所有频率整形的来源。
2.3 前提三:环路对SDM噪声的响应可以用线性时不变模型描述
虽然PLL本身是时变非线性系统,但在锁定点附近小信号扰动下,可以线性化。SDM引入的分频比抖动ΔN相当于在反馈路径上叠加了一个小扰动,环路对它的响应可以用线性传递函数描述。这里有个关键点:SDM噪声注入的位置是分频器,也就是反馈路径,不是直接加到输出,所以它到输出的传递函数和参考噪声、VCO噪声都不一样。
把这三个前提定下来,接下来就可以正式进入Z域推导了。我习惯先画信号流图,再写方程,最后化简,这样每一步都有物理对应,不容易推错。
3. 从分频比抖动到输出相位:一步步推出SDM噪声传递函数
这一节是全文的核心,我会把推导拆成四个小步,每一步都解释清楚"为什么这么写"。如果你只想记结论,可以直接跳到3.4,但我强烈建议跟着走一遍,因为推导过程中出现的中间量,在后面做噪声预算和仿真验证时都会用到。
3.1 第一步:写出分频器输出相位的Z域表达式
分频器的功能是把VCO输出频率除以分频比N。在小数分频PLL中,N是时变的,由整数部分N_int和SDM调制的小数部分组成:
N[n] = N_int + ΔN[n]
其中ΔN[n]是SDM输出,均值等于目标小数分频比,抖动部分就是量化噪声整形后的结果。
分频器输出相位θ_div和VCO输出相位θ_vco的关系是:
θ_div[n] = θ_vco[n] / N[n]
在小信号近似下,N[n]的抖动很小,可以对上式做一阶泰勒展开:
θ_div[n] ≈ θ_vco[n]/N_int - (θ_vco[n]/N_int²)·ΔN[n]
第一项是标称分频,第二项就是SDM抖动引入的相位扰动。注意这里有个关键:扰动项和θ_vco本身相乘,这意味着SDM噪声到输出的传递不是简单的加法,而是和VCO相位耦合的。不过在锁定状态下,θ_vco的均值是稳定的,小信号分析时可以把这一项线性化处理。
转到Z域,分频器输出相位可以写成:
θ_div(z) = θ_vco(z)/N_int - (θ_vco_0/N_int²)·ΔN(z)
其中θ_vco_0是VCO相位的直流工作点。第二项就是我们要追踪的SDM噪声注入项。
3.2 第二步:鉴相器和环路滤波器的传递关系
鉴相器比较参考相位θ_ref和分频器反馈相位θ_div,输出相位误差:
θ_e(z) = θ_ref(z) - θ_div(z)
经过鉴相器增益K_pd和环路滤波器F(z)后,产生VCO的控制量。在Z域里,环路滤波器的传递函数F(z)通常由连续域F(s)通过双线性变换或脉冲响应不变法离散化得到。这里要注意采样率的选择:SDM工作在f_s,而鉴相器工作在f_ref,两者可能不同。如果f_s = f_ref(常见于单环小数分频),那整个环路可以统一在一个采样率下分析;如果f_s是f_ref的整数倍,需要做多率处理,会复杂一些。本文先按f_s = f_ref的常见情况推导。
VCO在Z域里通常建模为积分器:
θ_vco(z) = K_vco · z⁻¹/(1-z⁻¹) · V_ctrl(z)
这个积分器形式对应连续域的1/s,是VCO相位累积特性的离散化表达。
3.3 第三步:联立方程,解出SDM噪声到输出的传递函数
现在把上面的关系联立起来。设环路开环传递函数为:
G(z) = K_pd · F(z) · K_vco · z⁻¹/(1-z⁻¹) / N_int
这是从相位误差到分频器反馈相位的开环增益。注意分母的N_int来自分频器的1/N缩放。
SDM噪声ΔN通过分频器注入,等效到鉴相器输入端的相位扰动为:
θ_n,div(z) = -(θ_vco_0/N_int²)·ΔN(z)
这个扰动和参考相位一样,进入鉴相器后被环路响应。根据线性系统的叠加原理,SDM噪声到VCO输出相位的传递函数为:
H_sdm(z) = θ_vco(z)/ΔN(z) = -[θ_vco_0/N_int²] · [G(z)/(1+G(z))] · [1/K_pd·F(z)·...]
等等,这里要小心。更规范的做法是:把SDM噪声等效为鉴相器输入端的一个相位噪声源,然后乘以"噪声源到输出"的传递函数。对于注入在反馈路径的噪声,其到输出的传递函数是:
H_sdm(z) = (K_pd·F(z)·K_vco·z⁻¹/(1-z⁻¹)) / (1 + G(z)) · (θ_vco_0/N_int²)
化简后,注意到分子正好是G(z)·N_int,所以:
H_sdm(z) = G(z)/(1+G(z)) · (θ_vco_0/N_int) · (1/N_int) · ...
我直接给最终形式,避免中间符号混乱。定义环路闭环传递函数(对参考相位):
H_ref(z) = G(z)/(1+G(z))
那么SDM噪声到输出的传递函数为:
H_sdm(z) = H_ref(z) · (θ_vco_0/N_int²) · N_int = H_ref(z) · θ_vco_0/N_int
再考虑到θ_vco_0/N_int就是分频器输出的标称相位,归一化后可以写成:
H_sdm(z) = H_ref(z) / N_int · (2π·f_out/f_ref的归一化因子)
实际工程中,更常用的是把SDM噪声等效到分频比上,然后乘以"分频比到输出相位"的传递函数。这个传递函数就是:
H_sdm→θout(z) = 2π · H_ref(z) / N_int
单位是rad(输出相位)每单位分频比抖动。这个形式最简洁,也最常用。
3.4 第四步:把NTF乘进来,得到完整的输出相位噪声PSD
SDM的量化噪声经过NTF整形后才是ΔN,所以完整的从量化误差E(z)到输出相位θ_vco(z)的传递函数是:
H_e→θout(z) = 2π · H_ref(z) / N_int · NTF(z)
输出相位噪声的功率谱密度为:
S_θout(f) = |H_e→θout(e^{j2πf/f_s})|² · S_e(f)
其中S_e(f)是量化误差的PSD,对于L阶SDM,S_e ≈ Δ²/12 · (1/f_s),Δ是量化步长(对于整数分频比调制,Δ=1)。
把NTF的表达式代入,对于L阶CIFB结构,NTF(z) = (1-z⁻¹)^L,在低频段|NTF|² ≈ (2πf/f_s)^{2L},这就是著名的L阶噪声整形:低频噪声被压低了(2L×20)dB/decade。
而H_ref(z)在环路带宽内近似为1/N_int(因为G很大),在带宽外滚降。所以最终的输出噪声形状是:低频段被NTF的高通整形主导,高频段被环路的低通特性主导,两者在环路带宽附近交汇。这个交汇点的位置,直接决定了SDM噪声对总相位噪声的贡献大小。
4. 传递函数的物理读法:三个频段、两个拐点、一个陷阱
公式推完了,但光有公式不够,得能"读"出它的物理含义。我习惯把H_sdm→θout的幅频响应分成三个频段来看,每个频段对应不同的主导机制。这样在实际调环路时,一眼就能判断问题出在哪。
4.1 低频段:NTF整形主导,阶数决定斜率
在远低于环路带宽的频率上,H_ref(z) ≈ 1/N_int(常数),所以H_sdm→θout的斜率完全由NTF决定。对于L阶SDM,低频段幅度按f^L上升,功率谱按f^{2L}上升。这意味着:
- 一阶SDM:低频噪声按20dB/decade上升
- 二阶SDM:40dB/decade
- 三阶SDM:60dB/decade
这里有个常见的误解:有人以为阶数越高越好,因为低频压得更低。但实际上,高阶SDM在高频段会把噪声抬得更高,而且稳定性更差。所以阶数选择要和环路带宽匹配:环路带宽越低,NTF的拐点越早出现,高阶的优势越明显;环路带宽高的话,高阶SDM的高频噪声反而可能恶化带内指标。
4.2 高频段:环路低通主导,滚降速率决定抑制
在远高于环路带宽的频率上,H_ref(z) ≈ G(z)(因为G<<1),而G(z)里包含VCO积分器的1/(1-z⁻¹)和环路滤波器的极点。典型的三阶环路滤波器会让G(z)以-60dB/decade滚降,所以H_sdm→θout在高频段也按这个速率下降。
但要注意:SDM噪声在高频段本身是被NTF抬高的,两者相乘后,高频段的净效果取决于哪个占主导。如果环路滚降不够快,SDM的高频噪声就会漏到输出,表现为带外相位噪声抬升。这也是为什么很多设计会在环路滤波器里加额外的极点,或者用更高阶的滤波器来压高频。
4.3 拐点位置:环路带宽和NTF零点的博弈
两个关键拐点:
| 拐点 | 位置 | 物理含义 | 设计影响 |
|---|---|---|---|
| 环路带宽f_c | G(z)的0dB点 | H_ref从1/N_int开始滚降 | 决定SDM噪声带内贡献的截止 |
| NTF拐点f_ntf | NTF从上升转为平坦 | 噪声整形停止 | 决定高频噪声的平台高度 |
对于CIFB结构,f_ntf ≈ f_s/(2π)·(某个与阶数相关的系数)。实际设计中,f_c通常选在f_ntf附近或略低,这样NTF的上升段被环路带宽"截住",带内噪声最小。如果f_c远高于f_ntf,NTF的高频平台就会进入带内,恶化指标;如果f_c远低于f_ntf,环路响应太慢,锁定时间变长。
4.4 一个容易踩的陷阱:θ_vco_0的处理
在3.3节的推导中,我提到了θ_vco_0这个量。很多资料在推导时直接把它归一化掉了,导致读者以为SDM噪声传递函数和VCO的绝对相位无关。但实际上,θ_vco_0对应的是VCO的标称输出相位,它和分频比N_int一起决定了归一化因子。如果推导时漏掉这个因子,算出来的噪声量级会差N_int倍,这在噪声预算里是致命的。
我的建议是:推导时保留θ_vco_0,最后再归一化。这样每一步都有物理意义,不容易漏项。具体做法是,把输出相位表示成2π·f_out·t的形式,θ_vco_0 = 2π·f_out/f_ref(归一化到参考周期),这样H_sdm→θout = 2π·H_ref(z)/N_int,量纲和数值都对得上。
5. 用Simulink和脚本验证:从公式到可复现的仿真链路
公式推得再漂亮,不验证都是空的。我一般会用两条路交叉验证:一条是Simulink行为级模型,一条是Python/MATLAB脚本直接算传递函数。两条路结果对上了,才敢把公式用到实际设计里。
5.1 Simulink建模:怎么让传递函数"显示出来"
Simulink里搭小数分频PLL,关键是把SDM的噪声注入点找对。我的做法是:
- 用"Zero-Order Hold"模块把连续域和离散域分开,采样率设为f_ref
- SDM用"MATLAB Function"或"Quantizer+Filter"实现,输出ΔN
- 分频器建模为"1/(N_int+ΔN)",注意这里要用除法而不是加法,否则注入点就错了
- 环路滤波器用"Discrete Transfer Fcn"模块,系数从连续域离散化得到
- VCO用"Discrete-Time Integrator"模块
搭好之后,怎么让传递函数显示出来?Simulink本身不直接给传递函数,但可以用"Linear Analysis"工具,在模型上设输入输出点,然后跑"Bode Plot"。具体操作:在SDM输出后加一个"Input Perturbation"点,在VCO输出后加"Output Measurement"点,然后Analysis→Control Design→Linear Analysis,就能扫出H_sdm→θout的幅频响应。
注意:Linear Analysis默认在平衡点线性化,PLL需要先锁定。我一般先跑一段足够长的时间让环路稳定,再在稳定点做线性化,否则扫出来的传递函数是错的。
5.2 脚本验证:直接算H_sdm→θout的Bode图
Simulink验证的是行为,脚本验证的是公式。我常用Python写一个小脚本,把3.4节的公式直接实现:
import numpy as np import matplotlib.pyplot as plt # 参数设置 N_int = 100 f_ref = 10e6 f_s = f_ref K_pd = 1e-3 # A/rad K_vco = 2*np.pi*1e9 # rad/s/V f_c = 100e3 # 环路带宽 # 环路滤波器(三阶无源) # 这里用简化的连续域传递函数,再离散化 def loop_filter(f): # 示例:三阶低通 return 1/(1+1j*f/f_c)**3 # 频率扫描 f = np.logspace(3, 8, 1000) z = np.exp(1j*2*np.pi*f/f_s) # 开环增益 G = K_pd * loop_filter(f) * K_vco / (1j*2*np.pi*f) / N_int # 闭环传递函数 H_ref = G/(1+G) # NTF(二阶CIFB) NTF = (1 - z**-1)**2 # SDM到输出的传递函数 H_sdm = 2*np.pi * H_ref / N_int * NTF # 画Bode图 plt.figure() plt.semilogx(f, 20*np.log10(np.abs(H_sdm))) plt.xlabel('Frequency (Hz)') plt.ylabel('Magnitude (dB)') plt.title('SDM Noise Transfer Function to PLL Output') plt.grid() plt.show()这个脚本跑出来的Bode图,应该和Simulink Linear Analysis的结果在低频段和高频段都吻合。如果对不上,先检查离散化方法是否一致,再检查NTF的表达式是否和Simulink里用的结构匹配。
5.3 实测中的意外:为什么仿真和手算差了几dB
我遇到过好几次仿真和手算对不上的情况,总结下来主要有三个原因:
- 离散化方法不一致:连续域F(s)用双线性变换和脉冲响应不变法,在高频段差异很大。如果Simulink用的是双线性,脚本用的是脉冲响应,高频段就会差几个dB。
- SDM的NTF不是理想(1-z⁻¹)^L:实际SDM为了稳定性会加零点优化,NTF在高频段有凹陷,如果脚本用理想NTF,高频段会高估。
- 采样率不匹配:如果f_s ≠ f_ref,多率处理会引入额外的混叠和镜像,简单公式不适用。
我的经验是:先用理想模型对齐趋势,再用实际NTF修正细节。趋势对上了,说明推导逻辑没问题;细节对不上,再逐项排查。
6. 工程落地:从传递函数到噪声预算的实操要点
推传递函数的最终目的是做噪声预算,判断SDM噪声在总相位噪声里占多大比重。这一节讲几个实操中容易忽略的点。
6.1 噪声预算表怎么列
我一般会列一个表,把参考噪声、SDM噪声、VCO噪声、分频器噪声分别折算到输出,然后看谁在带内占主导。SDM噪声的折算公式就是:
S_θ,SDM(f) = |H_sdm→θout(f)|² · S_ΔN(f)
其中S_ΔN(f) = |NTF(f)|² · Δ²/12 / f_s。
关键点:S_ΔN的单位是1/Hz(分频比抖动的PSD),乘以|H_sdm→θout|²(rad²/单位分频比抖动²)后,得到rad²/Hz。量纲对了,数值才不会错。
6.2 环路带宽和SDM阶数的联合优化
这两个参数不能分开选。我的做法是:
- 先根据锁定时间和带内相位噪声要求,定一个f_c的初值
- 再根据带内SDM噪声的贡献,选SDM阶数
- 如果带内SDM噪声还是太大,要么降f_c,要么升阶数,要么加额外的滤波
- 迭代几次,找到满足指标的最优组合
这里有个经验值:对于二阶SDM,f_c通常选在f_ref/20到f_ref/10之间;三阶SDM可以选得略高,但要注意稳定性。
6.3 常见问题排查表
| 现象 | 可能原因 | 排查方法 |
|---|---|---|
| 带内相位噪声比预期高 | SDM噪声传递函数算错,漏了N_int因子 | 检查H_sdm→θout的归一化 |
| 带外噪声抬升 | 环路滚降不够,NTF高频平台漏出 | 增加环路滤波器阶数或降f_c |
| 仿真和手算差10dB以上 | 离散化方法或NTF不匹配 | 统一离散化方法,用实际NTF |
| 锁定后噪声突然恶化 | SDM进入非线性区,NTF失效 | 检查SDM输入幅度和稳定性 |
7. 几个我踩过的坑和最后的经验分享
第一个坑是把SDM噪声当成参考噪声处理。参考噪声到输出的传递函数是H_ref(z),而SDM噪声到输出的传递函数是H_ref(z)/N_int再乘NTF。两者形状完全不同,混用会导致噪声预算全错。我刚开始做的时候,直接把SDM噪声按参考噪声折算,结果带内噪声估高了20dB,白白多花了一周调环路。
第二个坑是忽略θ_vco_0的归一化。前面说过,这个因子对应N_int倍的关系,漏掉的话数值差两个数量级。我的做法是,推导时每一步都写清楚量纲,最后统一归一化,这样不容易漏。
第三个坑是Simulink线性化点选错。PLL没锁定时做线性分析,扫出来的传递函数是乱的。一定要先跑足够长时间让环路稳定,再在稳定点线性化。我一般会跑至少1000个参考周期,确认相位误差稳定在零附近,再做分析。
最后分享一个实用技巧:把H_sdm→θout的Bode图和NTF的Bode图画在同一张图上,这样一眼就能看出环路带宽和NTF拐点的相对位置。如果f_c落在NTF上升段的中部,说明匹配得不错;如果f_c落在NTF平台区,说明环路带宽选高了,SDM噪声会恶化带内指标。这个图我每次做小数分频PLL都会画,比看一堆数字直观得多。
这套推导和验证流程,我在几个不同频段的小数分频PLL上都用过,从几百MHz到几GHz,只要采样率和环路结构匹配,结果都挺稳。真正花时间的不是推导本身,而是把离散化、NTF、归一化这几个细节对齐。对齐之后,传递函数就是一把尺子,环路带宽选多少、SDM用几阶,心里都有数了。