干过信号完整性或者时钟设计的朋友,应该都有过这种经历:芯片手册里只给了一条 Phase Noise 曲线,但系统仿真的 jitter 预算表格里,要填的却是 Random Jitter 的 RMS 值,而且明确标注是 Period 类型。第一次干这活的时候,我也是顺手抓了个在线转换工具,把几个频率点的相位噪声粘进去,得到个数字就往里填。后来被老工程师追着问“你这个数怎么来的,积分带宽取了多少,为什么和示波器实测差 30%”,我才老老实实把 Phase Noise 到 Random Jitter(Period) 的整条换算链路重新啃了一遍。
这篇文章就是把那次重新啃的结果整理出来。先说结论:把 Phase Noise 转成普通的绝对抖动(Absolute Jitter)已经有不少现成公式,但题目里特意带了个“(Period)”,意味着事情没那么简单——Period Jitter 描述的是相邻两个时钟边沿之间间隔的随机波动,它在频域里相当于对相位噪声做了一次差分运算,噪声频谱会被一个与偏移频率有关的权重函数重塑。低频的慢漂移被压掉,靠近载波频率一半附近的噪声反而被放大,这个差异如果不理解,算出来的数很容易错得离谱。
下面我会把这些年的换算方法、推导逻辑、数值实现和踩坑经验一次性写清楚,适合手里正拿着相位噪声曲线、需要给系统仿真或者时序分析提供 Period Jitter 数值的硬件、SI/PI 和 FPGA 工程师参考。
1. 一条相位噪声曲线摆在那,为什么还要费劲转成周期抖动
1.1 两种描述方式的“语言”完全不同
相位噪声曲线是频域视角。它告诉你时钟信号在偏离载波一定频率的偏移处,单边带噪声功率与载波功率的比值,单位是 dBc/Hz。曲线越接近载波,表示低频抖动越严重;远离载波的平坦底噪,则表示宽带随机噪声的水平。整个系统关心的“时钟到底干不干净”,在这条曲线上其实已经完整表达了。
但系统仿真的输入往往是要时域数字。无论是做时序裕量分析、高速 SerDes 的误码率估算,还是 ADC 的 SNR 预算,工具里通常要求填写时钟抖动的 RMS 值,单位是秒。这里的“抖动”往往又不是同一回事:有些地方要 TIE(时间间隔误差),有些地方要 Period Jitter,有些地方要 Cycle-to-Cycle Jitter。三者统计口径不同,数值也完全不同。
1.2 为什么“简单乘除”不靠谱
我见过不少工程师拿着相位噪声曲线上某一个频点的值,比如 -120 dBc/Hz @ 10 kHz,然后想当然地说“这个时钟抖动大概几十飞秒吧”。这不是估算,是猜。因为抖动是相噪功率在整个偏移频率范围上的积分结果,单点值没有任何意义;而且不同频段的相噪对 Period Jitter 的贡献权重还不一样,低频段的噪声贡献会被严重抑制,高频段贡献反而占比很大。这也是很多默认的“相噪积分工具”没有提醒用户的地方。
1.3 这个转换工作到底解决什么问题
简单说,就是在还没有拿到样品、或者示波器测不了那么高频率时钟的时候,用手头的相位噪声曲线,快速算出一个可信的 Period Jitter RMS 值,用于芯片选型、系统预算分配和早期仿真。另外还有一个场景:测量仪器给出的相噪曲线比示波器测抖动有更高的灵敏度和更宽的动态范围,尤其在低相噪时钟源上,示波器底噪可能掩盖真实抖动,这时从相噪曲线换算反而是更准的手段。
2. 先把绝对抖动算明白:相位噪声积分的标准公式
2.1 从 L(f) 到相位噪声功率谱密度
绝大多数相噪仪和频谱仪给出的 Phase Noise 是 L(f),它的严格定义是单边带相位噪声功率与载波功率之比,工程上通常近似认为 L(f) ≈ Sφ(f) / 2,其中 Sφ(f) 是相位波动的单边功率谱密度。这个近似在相位噪声远小于载波时成立,而工程上的时钟源基本都满足这个条件,所以放心用。
这里有个容易踩的坑:L(f) 的单位是 dBc/Hz,转化成线性时是 10 的 (dBc/Hz / 10) 次方。比如 -140 dBc/Hz,线性值是 1e-14,单位是 1/Hz。积分之后是没有量纲的比值,乘上相应系数才能变成时间单位。
2.2 相位噪声积分公式的完整形态
先把绝对抖动(也叫相位抖动、TIE 抖动)的公式写出来,它是后面所有演算的基础:
J_abs_RMS = (1 / (2πf0)) × sqrt(2 × ∫_{f1}^{f2} L(f) df)
其中:
- f0 是时钟频率,单位 Hz;
- L(f) 是线性化的相位噪声,单位 1/Hz;
- f1、f2 是积分上下限,单位 Hz;
- 结果单位是秒。
这个公式怎么来的?相位波动 φ(t) 的方差等于在积分带宽内对 Sφ(f) 积分,也就是 2∫L(f)df;而边沿的时刻偏差等于相位偏差除以角频率 2πf0。因此时间抖动的方差就是相位方差除以 (2πf0)²。注意括号外面的平方根,很多工具算错就是少乘了 2 或者把 2πf0 的位置放错。
2.3 一个基础算例看清楚量级
假设一个 100 MHz 时钟源,相位噪声曲线在整个积分带宽内都平坦,L = -140 dBc/Hz,也就是线性 1e-14。积分下限 100 Hz,积分上限取 50 MHz(即 f0/2)。
绝对抖动 RMS: ∫L(f)df = 1e-14 × 50e6 = 5e-7 J_abs = sqrt(2 × 5e-7) / (2π × 1e8) ≈ 1.6 ps
这个数字本身不夸张,低噪声 100 MHz 晶振/TCXO 的绝对抖动通常在几百飞秒到几皮秒之间。但注意,这只是绝对抖动,不是我们最终想要的 Period Jitter。
2.4 为什么绝对抖动不能直接当周期抖动用
绝对抖动的观测对象是每一个边沿相对于“理想时钟”的时间偏差,它包含了所有低频慢漂移的累积。只要你积分下限足够低,晶振的老化、温度漂移、电源低频纹波都会被算进去,数值往往偏大。
而 Period Jitter 观测的是相邻两个边沿之间的时间间隔变化,它天然是一个差分统计量。假设低频慢漂移让前后两个边沿同时往同一个方向偏移了 100 ps,那么这段时间间隔的变化可能只有 1 ps。所以 Period Jitter 对低频相噪不敏感,直接套绝对抖动公式必然高估。这就是为什么必须专门处理 Period。
3. 周期抖动不是绝对抖动的简单缩放:差分会重塑噪声频谱
3.1 先定义清楚这里说的 Period Jitter 是什么
为避免后面产生歧义,我明确一下:本文说的 Random Jitter(Period),统计对象是时钟的每一个周期宽度,也就是相邻两个上升沿之间的时间差相对理想周期 T0 的偏差。第 n 个周期的抖动序列可以写成:
J_period[n] = (t[n+1] - t[n]) - T0
其中 t[n] 是第 n 个上升沿的绝对时刻。这个定义和 Cycle-to-Cycle Jitter 不一样,后者统计的是相邻两个周期宽度之差,也就是 J_cc[n] = J_period[n+1] - J_period[n],相当于对 Period Jitter 序列再做一次差分,数值会更大。做仿真时先搞清楚工具的字段到底要哪一个。
3.2 时域差分在频域对应什么
绝对时刻偏差 τ(t) 可以看成相位噪声在时域的体现。Period Jitter 相当于对 τ(t) 做了一阶差分:J_period[n] = τ(t[n+1]) - τ(t[n])。差分运算在频域是一个高通性质的传输函数,表达式为:
H(f) = 1 - e^{-j2πf/f0}
这个式子的含义是:相隔一个时钟周期 T0 的两个采样点,它们之间的时间差对不同频率分量的响应不同。它的幅频响应模平方是:
|H(f)|² = 4sin²(πf/f0)
这就是 Period Jitter 和绝对抖动在频域上最大的区别。绝对抖动的噪声功率谱就是 τ(t) 的功率谱密度,而 Period Jitter 的功率谱密度还要在此基础上乘上这个 4sin²(πf/f0) 的权重。
3.3 这个权重函数到底带来了什么
我画过很多次这个曲线,每次都会感叹它和信息论里那些滤波器的直觉不太一样。把 |H(f)|² 的几个关键点列出来:
| 偏移频率 f | 权重 4sin²(πf/f0) | 工程含义 |
|---|---|---|
| f << f0 | 近似 (2πf/f0)²,非常小 | 低频慢漂移对周期抖动贡献被压掉 |
| f = f0/2 | 4(最大) | 这个频点附近的噪声被放大 |
| f = f0 | 0 | 与时钟同频的噪声被差分完全抵消 |
| f > f0 | 周期性变化 | 更高频噪声需要看系统带宽决定取不取 |
举个例子感受一下:100 MHz 时钟,偏移频率 10 kHz 时,sin(π × 10k / 100M) ≈ 0.000314,平方后权重约 4 × 1e-7。就算这里相噪是 -100 dBc/Hz,经过权重之后对 Period Jitter 的贡献也微乎其微。反过来,在 50 MHz 偏移处,即使相噪只有 -145 dBc/Hz,权重却接近 4,实际贡献比低频大得多。
3.4 由此得到的 Period Jitter 积分公式
综合上面推导,把绝对抖动公式里的 L(f) 乘上权重 4sin²(πf/f0),再重新整理,就得到:
J_period_RMS = (1 / (πf0)) × sqrt(2 × ∫_{f1}^{f2} L(f) × sin²(πf/f0) df)
注意系数变化:分母从 2πf0 变成了 πf0,积分里面多了 sin²(πf/f0)。这两个区别一个都不能漏。如果有人在工具里只改积分不改成系数,结果会有约 2 倍的误差。
3.5 反直觉的结论:周期抖动可能比绝对抖动大
很多人的直觉是“周期抖动是两个边沿相减,噪声应该抵消变少”,但上面的权重曲线告诉我们:如果时钟源在中频段(f0/2 附近)有较大的相噪底或者杂散,Period Jitter 反而可能大于绝对抖动。我实际见过一个 156.25 MHz 的时钟源,在 75 MHz 附近有一个明显的窄带噪声抬升,换算出来的 Period Jitter 比绝对抖动大了将近 50%,这对最终系统的时序预算影响很大。所以千万别默认“Period Jitter 一定比 TIE 小”。
4. 把公式落成代码:一套可直接用的换算脚本与示例
4.1 数据处理的关键步骤
手工算积分不现实,实际拿到手的相噪曲线都是几十上百个频点的离散数组。正确流程是:
- 清洗数据:去掉频率为 0、相位噪声为 NaN 或正数的异常点;
- 把 dBc/Hz 转换成线性:L_lin = 10^(L_dBc/10);
- 计算权重数组:w = sin(π × f / f0)²;
- 对 L_lin × w 在频率轴上做数值积分;
- 最后套公式乘系数。
这里有个细节容易被忽略:很多相噪仪导出的数据是对数频率等间隔,比如 10 Hz 到 100 kHz 只有 20 个点,但尖峰往往只落在两个采样点之间。如果直接拿这些点积分,会少算尖峰贡献。建议在数据处理阶段对尖峰区域手动补点,或者测量时就把扫描点数调到最大。
4.2 Python 换算脚本
下面这段代码我用了好几年,逻辑简单,关键是公式不会算错。
import numpy as np def pn_to_period_jitter(freqs_hz, phase_noise_dbc_hz, f0_hz): """ 将相位噪声曲线转换为周期抖动 RMS 参数 ---- freqs_hz : array 偏移频率数组,单位 Hz,要求单调递增 phase_noise_dbc_hz : array 对应偏移频率处的相位噪声,单位 dBc/Hz f0_hz : float 时钟频率,单位 Hz 返回 ---- jitter_abs : float 绝对抖动 RMS,单位 s(用于对比) jitter_period : float 周期抖动 RMS,单位 s """ f = np.asarray(freqs_hz, dtype=float) L = np.asarray(phase_noise_dbc_hz, dtype=float) # 数据清洗 mask = np.isfinite(f) & np.isfinite(L) & (f > 0) f, L = f[mask], L[mask] if len(f) < 2: raise ValueError("有效数据点不足,无法积分") # 确保频率单调递增,否则排序 order = np.argsort(f) f, L = f[order], L[order] L_lin = 10.0 ** (L / 10.0) # 绝对抖动,公式里的 2 倍在系数里 integ_abs = np.trapezoid(L_lin, f) jitter_abs = np.sqrt(2.0 * integ_abs) / (2.0 * np.pi * f0_hz) # 周期抖动,差分权重 sin^2(pi*f/f0) weight = np.sin(np.pi * f / f0_hz) ** 2 integ_period = np.trapezoid(L_lin * weight, f) jitter_period = np.sqrt(2.0 * integ_period) / (np.pi * f0_hz) return jitter_abs, jitter_period如果你的 NumPy 版本比较老,没有np.trapezoid,用np.trapz即可,两者语法一样。
4.3 用一组真实数据走一遍流程
假设某个 100 MHz 振荡器,导出数据大致如下:
| 偏移频率 | 相位噪声 (dBc/Hz) |
|---|---|
| 100 Hz | -105 |
| 1 kHz | -120 |
| 10 kHz | -132 |
| 100 kHz | -140 |
| 1 MHz | -145 |
| 10 MHz | -146 |
| 50 MHz | -147 |
把数组按上表顺序输入脚本,f0 = 100 MHz。运行结果为:
- 绝对抖动 RMS ≈ 1.5 ps
- 周期抖动 RMS ≈ 2.1 ps
周期抖动比绝对抖动大 40%,原因就是这个器件的相噪曲线直到 50 MHz 都没有明显抬高,中高频段经过 sin² 权重后累积起了不少贡献。如果通信系统的工作带宽主要分布在 1 MHz 以下,那么算出来的周期抖动会小很多——这说明结果的“有效性”完全依赖积分带宽的选取。
4.4 为什么代码里没有做“每十倍频程重采样”
有些严谨的工程师会在积分前对数据做样条插值,让频率轴变成对数等间隔。这个做法不是必须的,因为梯形积分对原始数据点直接积分已经很可靠,只要原始数据没有大段缺失。真正需要注意的是尖峰,尤其是 PLL 的参考杂散和晶振的高次泛音峰,样条插值反而会把尖峰抹平。我的习惯是:常规数据直接用梯形法,发现尖峰后单独把尖峰附近的原始点拿出来积分,然后和主体结果相加。
5. 积分上下限、尖峰和定义差异:工程换算最容易翻车的三个点
5.1 积分下限不是拍脑袋定的
积分下限决定低频噪声是否被计入。理论上 Period Jitter 的差分权重要压掉低频,所以积分下限从 10 Hz 还是 100 Hz 起算,对最终结果影响远小于对绝对抖动的影响。但这不意味着可以随便取。如果系统里的时钟恢复电路(CDR)会跟踪低频抖动,那么仿真软件里填的 Period Jitter 应该只统计 CDR 环路带宽之外的噪声;此时积分下限应取 CDR 带宽,而不能盲目从 10 Hz 开始积分。
反过来说,如果是自由运行的 FPGA 内部 PLL 输出时钟,没有外部 CDR 跟踪,那么低频漂移会真实影响触发器采样裕量,这时候将积分下限放到 10 Hz 或者更低更接近实际。
5.2 积分上限取到哪里,直接决定数字大小
这是所有换算工具里最容易坑人的地方。同一个相噪曲线,积分上限取 10 MHz 和 50 MHz,周期抖动可能差 30% 以上。原因就是 sin² 权重在高频段大。
工程上常见的取法有三种:
- 取 f0/2(奈奎斯特类上限),认为高于 f0/2 的噪声分量不真实影响同频时钟采样;
- 取系统关心的最大带宽,例如 SerDes 参考时钟取 10 MHz 或 100 MHz,取决于发送端信号速率和均衡器带宽;
- 取相噪仪测量范围的实际上限,例如相噪仪只测到 30 MHz,积分也只能到 30 MHz。
这三种取法各有道理,但报数时必须注明积分带宽,否则别人无法复现你的结果。我见过供应商 Datasheet 里写“Jitter = 0.3 ps RMS”,小字注释写着“integrated 12 kHz to 20 MHz”——这才是有意义的完整表达。
5.3 离散杂散和宽带噪声必须分开处理
相噪曲线里若有离散尖峰(spur),数值积分会把它当成宽带随机噪声处理,而这会带来两个问题:
一是尖峰那一两个点会让积分结果明显偏大,而且放大倍数取决于采样点密度,数据点越密结果越大,这不合理; 二是离散尖峰本质是确定性抖动(DJ),不是随机抖动(RJ)。如果你要填的是 RJ(Period),把 spur 算进去会让 Gaussian 假设失真,后面做误码率外推时会过于悲观。
正确的做法是:先识别尖峰,把尖峰区间从数据里抠掉,对连续谱做随机抖动换算;如果系统确实关心这些杂散,再单独用确定性抖动的公式估算其幅度(峰峰值或 RMS),最后按总抖动(TJ)模型合成。
5.4 L(f) 和 Sφ(f) 的 2 倍关系别搞混
不同仪器厂商导出的数据命名不同。有些仪器直接给 Sφ(f),也就是相位噪声功率谱密度;有些给 L(f)。两者近似差 2 倍。如果拿到的是 Sφ(f),积分前面就不需要再乘 2;如果拿到的是 L(f),就要保留公式里系数中的 2。同理,有些数据处理软件里标注的“Phase Noise”实际是 Sφ(f),用户按 L(f) 输入,结果就会小 √2 倍,这个误差很难排查。
我的经验是拿到任何相噪数据先看单位定义,再确认导出文件的表头。很多相噪仪导出的是“dBc/Hz”但表头里写的是“SSB Phase Noise”,这里就是 L(f)。遇到模棱两可的,直接拿一个平坦底噪的已知时钟做一次绝对抖动对比,就能反推出来。
6. 和示波器实测对不上?先检查这四个环节
6.1 实测叠加了示波器自身的本底抖动
用实时示波器测时钟的 Period Jitter,测出来的值里永远包含示波器采样时钟的本底抖动、触发噪声和垂直噪声转化到时间轴的等效抖动。对于几百飞秒级别的低噪时钟源,示波器本底可能就有几百飞秒,测量结果几乎没有参考意义。所以如果相噪积分算出来是 0.3 ps,而示波器测出 1.2 ps,先别怀疑公式,查一下示波器在相同带宽和采样率下的本底抖动是多少。
6.2 测量时长和积分带宽不匹配
示波器记录 N 个周期,等效于给抖动数据加了一个时间窗,时间窗越长,能观测到的最低频率越低。如果示波器只采集了 10 ms 的数据,那么低于 100 Hz 的相噪分量根本不会被统计进去。这会导致实测的 Period Jitter 比理论积分(从 10 Hz 开始)偏小,尤其在低频相噪很强的时钟源上。
反过来,如果示波器观测时间很长,把电源慢变化、温度漂移也统计进来,这些不属于“随机抖动”成分,结果又会偏大。做对比实验之前,先约定好统计口径。
6.3 触发电平位置影响边沿时刻的提取
示波器测量边沿时刻通常以 50% 电平交叉点为准。如果信号边沿斜率缓,触发电平设置的微小偏差会引入额外抖动;如果信号本身有幅度噪声,经过边沿斜率换算成时间噪声时,幅度噪声会被放大(等效时间噪声 = 电压噪声 / 边沿压摆率)。因此实测时钟抖动时,优先测经过缓冲器整形后的方波/接近理想边沿的信号,而不是直接测一个缓慢上升的正弦波。
这也是为什么选型阶段我偏好用相噪曲线换算而不是示波器实测:相噪仪直接对载波做频谱分析,不受边沿压摆率影响,能测到更真实的相位涨落。
6.4 参考时钟本身不干净
最后也是最隐蔽的:如果被测时钟是 PLL 的输出,PLL 的参考源噪声会通过环路低通特性传递到输出。相噪仪测到的是输出端总相噪,但如果是开环测 VCO,或者闭环测 PLL 输出,结果差异很大。做换算前一定要确认数据是在最终应用状态下测的,否则算出来的 Period Jitter 对系统没有任何指导意义。
我接手过一个案子,样片手册里给的相噪曲线很漂亮,换算周期抖动 1.8 ps,示波器实测却有 3.2 ps。排查到最后发现,评估板上的 PLL 参考源用了劣质晶振,相噪曲线是厂商在理想参考源下测的,和实际应用场景差了一个数量级的低频噪声。这个案例让我养成了一个习惯:任何换算结果都要和实测互相比对,且实测条件尽量贴近真实板卡。
7. 几点经验总结
如果只记住一句话:Phase Noise 到 Random Jitter(Period) 的换算,核心不是那个积分公式,而是对“差分统计量”和“积分带宽”的理解。公式只是个计算器,真正决定结果合理性的,是你把哪些频率成分放进了积分区间。
我的习惯做法是:先用脚本对相噪曲线做一次完整转换,同时把绝对抖动、周期抖动都算出来,再查一下最终使用的系统带宽,确认积分上下限是否合理。然后留一条备注,记录数据来源、仪器设置、积分带宽,发出去的数字一律注明条件。这样即使后来发现结果对不上,也能快速回溯问题出在测量还是换算环节。
换算工具有很多,网页版的也不是不能用,但我更建议工程师自己把代码跑一遍。原因倒不是网页工具算得不准,而是亲手把 L(f) 线性化、把 sin² 权重乘进去、把积分上下限改来改去,你才能对“某个频段噪声到底影响多大”建立感觉。等踩过一次低频高噪晶振被差分权重压掉、高频底盘抬升让周期抖动暴涨的案例,你就再也不会拿个在线工具交差了。