Detect 状态:电气空闲检测与接收器检测

Detect 状态,是 LTSSM 的起点,也是链路训练的“第一脚油门”。说白了,这个阶段要回答一个最基本的问题:对面到底有没有设备?

只要链路没建立,LTSSM 就会乖乖待在 Detect 状态里。它会反复做两件事:先检测电气空闲,再检测接收器是否存在。我刚开始接触 PCIe 的时候,觉得这步太简单了——不就看看有没有信号吗?后来踩了坑才发现,这里的细节远比想象中多。

2.1 为什么要先检测电气空闲?

你可能想问:设备刚上电,为什么不去直接握手,反而要先看电气空闲?

嗯,这里有个历史原因。PCIe 链路在设计时就考虑到了热插拔和电源管理。你想想看,如果一块卡刚刚插入,或者某个设备刚从低功耗模式唤醒,它发送器的输出可能还不稳定。这时候贸然去握手,容易产生误判。

电气空闲检测,其实是在确认一件事:对方发送器是否已经进入了稳定的静默状态?

我更愿意把它理解成一个“基线校准”的动作。检测逻辑会盯着接收差分管脚上的共模电压和摆幅。当这个电压稳定在 0V 到 175mV 之间,并且持续一段时间,我们就认为电气空闲成立了。

参数 规格要求 说明
差分摆幅阈值 < 65 mV 超过此值视为非空闲
共模电压范围 0 ~ 175 mV 需在稳定范围内
检测时间窗口 最小 10 µs 持续空闲才确认
退出条件 检测到翻转 信号跳变即退出

关键点:电气空闲检测不能太灵敏,也不能太迟钝。太灵敏容易被噪声误触发;太迟钝又会导致链路训练超时。

2.2 接收器检测:怎么知道对面有人?

确认电气空闲之后,接收器检测就登场了。这一步我习惯叫它“敲敲门”——发送器会发出一个弱信号,然后监听反射回来的东西。

具体的做法是这样的:发送器会在其差分对上施加一个很小的测试电压,然后观察接收端反射回来的电压变化。如果对面有接收器,它的等效输入阻抗(大概在 40Ω 到 6.5kΩ 之间)会吸收一部分能量,反射回来的信号特征就会明显不同。

我印象比较深的是,检测脉冲的摆幅非常小,通常只有几百毫伏。而且它不会持续太久,不然功耗就上去了。

个人经验:我建议在调试时重点关注接收器检测的“采样窗口”。如果你发现 Receiver Detection 一直失败,不妨先看看发送器的驱动强度是不是偏弱,或者链路长度是不是超标了。我在一个项目中遇到过链路跨了两块背板,结果检测脉冲全被损耗掉了,接收器死活检测不到。

2.3 Detect 状态的完整流程

Detect 状态内部实际上分了两个子状态:

  1. Detect.Quiet:发送器保持静默,等待电气空闲被确认。通常是 12ms 的超时保护。
  2. Detect.Active:发送器发出检测脉冲,然后采样反射信号,判断接收器是否存在。

如果检测成功,链路就会进入 Polling 状态,开始真正的速度协商。如果失败,它会回到 Detect.Quiet 重新来过。

Detect 状态机流转 Detect.Quiet 发送检测脉冲 判断结果 成功 进入 Polling 失败 超时机制:每次停留 Detect 最长时间约 12 ms 若超时仍未检测到,硬件自动回到 Detect.Quiet

2.4 接收器检测的常见陷阱

避坑指南:我曾经在调试一块 Gen3 的 retimer 卡时,发现它卡在 Detect 状态一直不往前走。抓了信号才看到,接收器检测脉冲的幅度不够,导致反射回来的信号始终是一个“开路”特征——说白了就是对面觉得没接东西。最后排查发现,是板上的 AC 耦合电容容值偏大,把检测脉冲的低频分量衰减得太厉害了。

这个地方容易出问题的还有几个:

  • 阻抗不连续:连接器、过孔、PCB 走线的阻抗跳变,会制造虚假反射,让接收器检测误以为对面有设备(或者没设备)。
  • 电源噪声耦合:检测脉冲本来就弱,如果电源纹波直接串到链路上,很容易淹没信号。
  • 温度漂移:接收器的输入阻抗会随温度变化。在高温下,有些芯片的输入阻抗会掉到规格下限以下,导致检测失败。

2.5 怎么看 Detect 是不是正常的?

拿到示波器或者逻辑分析仪,我通常会先看这几个东西:

观察点 正常表现 异常表现
电气空闲信号 差分对稳定在 0V 附近 有持续毛刺或低频振荡
检测脉冲 幅度 > 200 mV,宽度约 10 ns 幅值不足或波形畸变
反射信号 呈容性或阻性特征 呈开路特征(全反射)
状态机停留时间 10 µs ~ 1 ms 内完成 反复超时或立即退出

个人习惯:我一般会用 PCIe 分析仪把 LTSSM 的轨迹抓出来,看它在 Detect 状态停留了多长时间。如果每次都是 12ms 超时退出,那几乎可以确定是接收器检测失败了。这个时候别急着改软件,先拿示波器去戳一下检测脉冲,看看波形对不对。

嗯,Detect 状态看起来简单,但它决定了后续所有状态能不能跑起来。我见过很多链路训练卡死的问题,追根溯源都是 Detect 阶段埋下的雷。所以每次调试新板子,我都会先确保这一步走得稳当。