3. 确定性抖动(DJ)的分类

聊完抖动的总体分类,咱们得把镜头拉近,专门看看确定性抖动(DJ)。这东西说白了就是那些“有规律、可预测”的抖动。它不像随机抖动那样靠概率分布说话,它的来源特别清楚,你多半都能找到元凶。

我做了这么多年信号完整性,处理的DJ案例比RJ多得多。为什么?因为这玩意儿能治!找到根源,往往一个电容、一段走线就能解决。DJ按行为特征,主要分三类:周期抖动(PJ)、数据相关抖动(DDJ)和占空比失真(DCD)。咱们一个个掰开讲。

核心概念: DJ是有界的、可重复的抖动分量。它的峰值(Peak-to-Peak)不会随着测量次数无限增长,这和RJ完全相反。所以你测量DJ时,看到的极限值就是它的真实边界。

确定性抖动(DJ)分类体系 确定性抖动(DJ) 周期抖动(PJ) 来源:开关电源、时钟辐射 特征:频谱上有独立尖峰 数据相关抖动(DDJ) 包含:ISI、PWD 分量 特征:与数据码型强相关 占空比失真(DCD) 来源:电平阈值偏移 特征:高低电平宽度不等 三大分量频谱和时域特征各不相同 分离它们需要不同的测量和分析手段

3.1 周期抖动(PJ)

PJ,顾名思义,就是抖动在时间上呈现周期性。你把它放到频谱仪上看,会在特定的频率点上看到一个明显的尖峰。我个人习惯是先看电源噪声,开关频率往往是PJ的第一大源头。

实战技巧: 拿到一个PJ波形,先算它的周期。如果周期跟你板上的DC-DC开关频率一致,八九不离十就是电源耦合过来的。我碰到过最夸张的一次,PJ周期正好等于USB 2.0的帧周期,查了半天发现是USB连接器屏蔽没做好。

PJ的典型来源有哪些?

  • 开关电源纹波: 频率通常在几百kHz到几MHz。这个在射频和高速数字电路里特别常见。
  • 串扰: 邻近信号线的电磁耦合。如果那个干扰信号是周期性的,比如时钟线,那么被干扰的线上就会出现同频的PJ。
  • 锁相环(PLL)的参考杂散: 频率合成器生成的杂散信号,会直接给输出时钟“化妆”,抹上周期性的抖动。
  • 机械振动: 在精密测量场景下,风扇、甚至人的脚步声都能产生低频PJ。这个我以前不太信,直到亲眼看到实验室数据...

测量PJ有个关键点:带宽。如果你用示波器测PJ,带宽不够,那些高频PJ分量会被滤掉。你看到的反而只是一个平滑的“假信号”。

表里是我总结的PJ分类和排查优先级:

PJ 来源 典型频率范围 排查优先级
开关电源 100 kHz ~ 10 MHz 高(1st pass)
时钟串扰 25 MHz ~ 1 GHz 高(Layout 检查)
PLL 杂散 数 MHz ~ 数百 MHz 中(Spectrum 分析)
机械振动 < 1 kHz 低(需排除法)

3.2 数据相关抖动(DDJ)

DDJ,这个名字很直白:它跟数据本身有关。你发送不同的比特序列,抖动大小就不一样。常见的情景是,你发一串长“0”然后突然来一个“1”时,这个跳变沿的位置会偏离理想位置。为什么?因为信道有带宽限制。

DDJ在两个场景里特别棘手:一是高速串行总线(比如PCIe、USB、SATA)的预加重设计;另一个是记忆信道(有反射、有多个抽头的信道)。

DDJ又两个关键分量,咱们必须分开处理:

3.2.1 码间干扰(ISI)

ISI是最常见的DDJ分量。传输信道不是理想导体,有损耗、有反射。前一个信号的尾巴还没收完,后一个信号就来了——这就像两个人同时说话,互相干扰,边沿位置就漂了。

我记得有一次调试DDR4总线,跑PRBS7码型,眼图半睁半闭。换上PRBS31后,眼完全闭上了。这就是ISI在作怪。为什么?PRBS31里连续相同比特(CIT)更长,信道记忆效应更强,抖动自然更大。

避坑指南: 我曾经用PRBS7测试,所有指标都通过。但换到实际应用码型(比如80b/10b编码)后,系统频繁丢包。原因就是PRBS7的长度不够,没有覆盖到信道的记忆深度。所以DDJ验证,我建议至少跑PRBS15以上。

3.2.2 脉冲宽度失真(PWD)

PWD跟数据上升沿和下降沿的不对称有关。如果上升沿慢、下降沿快,那么一个“0-1-0”脉冲的宽度和“1-0-1”的脉冲宽度就不一样了。注意,这里不是电平高低的问题,是斜率不一样。

这个分量在低功耗设计里尤其明显。我曾经用过一款28nm的FPGA,它内部驱动强度可配置。当设成“弱驱动”时,PWD一下子窜上来几十皮秒。嗯,这是个很容易被忽略的问题。

DDJ的分解,核心思想就是条件平均。你按照不同的数据比特模式(Pattern)把抖动标记分组,然后各组分别取平均。ISI分量取的是当前比特前后比特组合的平均;PWD取的是单个比特的前后沿差异。

// 一段伪代码:DDJ 分解核心逻辑
// 假设我们已经拿到了一长串跳变沿的时间误差 TIE[]
// 以及对应的数据流 bits[]

for each transition edge at time t:
    pattern = get_surrounding_bits(bits[], t, pre_bits=2, post_bits=2)
    // pattern 如 "001", "101", "010" 等
    DDJ_ISI[pattern] += TIE[t]
    count[pattern]++

for each pattern:
    DDJ_ISI[pattern] /= count[pattern]

// 分离 ISI:提取不同 pattern 的 TTE 均值
// 剩下的残差 = TIE - DDJ_ISI,包含 PJ、DCD 和 RJ

你想想看,这个思路并不复杂。但实际工程里,码型数量太大(比如5比特前后文就有2^5=32种),需要大量的数据点才能统计稳定。所以,我一般推荐用长伪随机码(PRBS)配合硬件累加器来做。

3.3 占空比失真(DCD)

DCD,这个最简单,但也最容易掉坑。它的表现很单一:时钟或数据信号的高电平宽度和低电平宽度不相等。结果就是,上升沿和下降沿的零点位置都发生了偏移——一个往右偏,一个往左偏。

DCD的来源基本上就两个:

  1. 接收端阈值电压偏移: 接收器的判决电平不是理想的Vdd/2,而是偏高或偏低了。这会导致“1”比“0”看起来更宽(或更窄)。
  2. 发射端驱动不平衡: 上升沿和下降沿的驱动强度不一样。PMOS和NMOS的尺寸不匹配就会有这个问题。

关键特征: DCD不会影响信号的周期,它只影响占空比。所以你测周期是准的,但1和0的宽度是错的。这在DDR系统中特别致命,因为DDR对DQ-DQS的时序关系非常敏感。

分离DCD的方法还挺巧妙。你先把TIE序列按符号(正或负)分成两组。因为DCD会让上升沿偏一个方向,下降沿偏另一个方向。然后你取这两组的均值,它们模值的差就是DCD的大小。

手算例子: 假设上升沿的TIE平均是+5 ps,下降沿的TIE平均是-3 ps。那么DCD分量 = (|5| + |-3|) / 2 = 4 ps。简单吧?但注意,这个假设了PJ和ISI已经被提前分离了,否则算出来的是“假DCD”。

实际项目里,我通常用“双直方图法”来验证DCD。即分别绘制上升沿和下降沿的TIE直方图,如果它们有明显的偏移,而且偏移量之差是常数,那就实锤了DCD。这个方法的好处是,即使有PJ存在,直方图的形状会变花,但两个直方图的相对偏移不会变。

最后,我给大家列个总结表,方便对比这三类抖动的“性格差异”:

抖动类型 来源 特征 频谱表现 典型对策
PJ 电源、耦合、干扰 周期性,有固定频率 离散尖峰 去耦、屏蔽、Layout优化
DDJ(ISI) 信道带宽、反射、损耗 与码型记忆相关 码率整数倍宽带噪声 均衡器(CTLE/DFE)
DDJ(PWD) 沿斜率不对称 高/低脉冲宽度不等 主要是低频成分 调整驱动级尺寸
DCD 阈值偏、驱动平衡差 上升/下降沿偏移方向相反 偶次谐波加强 校准阈值、优化驱动