4. Detect状态:电气空闲检测、接收器检测、发送器初始化
Detect状态,说白了就是链路训练的第一步握手。我刚开始接触PCIe时,总觉得这步很简单——不就是检测一下对面有没有设备吗?后来踩过几次坑才明白,Detect阶段要是没做好,后面整个链路都别想跑起来。
这个状态的核心任务有三个:电气空闲检测、接收器检测、发送器初始化。咱们一个一个说。
4.1 电气空闲检测(Electrical Idle Detection)
电气空闲,就是链路上没有信号跳变的状态。你想想看,两个设备刚上电,谁都不知道对方在不在,总得先听听线上有没有动静吧?
检测电路其实挺巧妙的。它通过比较差分信号线上的共模电压来判断。正常情况下,差分对的两根线电压是相反的。但空闲时,两根线都会被拉到同一个共模电平上。
关键参数:
- 电气空闲退出阈值:通常为50-175mV
- 电气空闲进入阈值:通常低于50mV
- 检测时间窗口:约10ms(具体取决于Gen版本)
我在项目中遇到过一个问题:某款FPGA作为RC(根复合体),死活检测不到EP(端点设备)的电气空闲退出。查了两天才发现,是PCB走线的AC耦合电容焊反了方向。嗯,这种低级错误,说出来都是泪。
4.2 接收器检测(Receiver Detection)
接收器检测,说白了就是看看对面有没有接上。PCIe规范里规定,发送端会发出一个检测脉冲,然后测量反射回来的信号。
为什么能测出来?因为接收器端有终端电阻(通常50Ω对地)。有终端电阻时,反射回来的信号幅度会明显不同。没有终端电阻(即没接设备),反射信号就大得多。
实战技巧:
我曾经调试过一个板子,接收器检测总是失败。后来发现是接收端的AC耦合电容容值选错了。规范要求75-200nF,我手头只有10nF的,想着凑合用...结果就是检测不到。所以,别在耦合电容上省钱。
接收器检测的流程大致如下:
- 发送端发出一个窄脉冲(约2个UI宽度)
- 等待反射信号稳定(约4个UI)
- 采样反射电压,与参考阈值比较
- 判定接收器是否存在
4.3 发送器初始化(Transmitter Initialization)
检测到接收器之后,就该初始化发送器了。这一步主要是设置发送器的电气参数,比如摆幅、预加重、去加重等。
我记得第一次做PCIe Gen3的板子时,发送器初始化总是超时。后来用示波器一看,眼图简直惨不忍睹——眼高不够,眼宽也不够。调了半天预加重的系数才搞定。
注意:
发送器初始化时,千万不要直接上满摆幅。规范要求先以低摆幅(约400mV)开始,等链路稳定后再逐步调整到目标摆幅(800mV-1.2V)。否则可能引起严重的信号反射,导致链路训练失败。
4.4 眼图与信号完整性考量
说到信号完整性,眼图是最直观的衡量工具。一个健康的眼图,应该像一只睁开的眼睛——上下对称,中间开阔。
在Detect阶段,虽然数据速率还没起来,但发送器初始化时的信号质量直接决定了后续链路能否稳定。我一般会在发送器初始化完成后,先抓一帧眼图看看。
| 眼图参数 | PCIe Gen3要求 | 实测经验值 |
|---|---|---|
| 眼高 | ≥100mV | ≥150mV(更安全) |
| 眼宽 | ≥0.4 UI | ≥0.5 UI |
| 抖动(RJ) | ≤0.15 UI | ≤0.1 UI |
| 抖动(DJ) | ≤0.2 UI | ≤0.15 UI |
为什么会关注这些?因为Detect阶段要是信号质量不好,后面进入Polling、Configuration阶段时,误码率会急剧上升。我见过一个案例,某款SSD在Gen3模式下频繁掉盘,最后定位到就是发送器初始化时的预加重系数没调好,导致眼图闭合。
避坑指南:
我曾经在调试时发现,同样的PCB设计,不同批次的板材做出来眼图差异很大。后来才意识到,PCB的介电常数和损耗因子对高速信号影响巨大。所以,做PCIe设计时,建议优先选用低损耗板材(如M6、M7级别)。
4.5 实战中的常见问题
总结一下我在Detect阶段踩过的坑:
- 电气空闲检测失败:检查AC耦合电容、检查共模电压是否正常
- 接收器检测失败:检查终端电阻、检查PCB走线阻抗(100Ω差分)
- 发送器初始化超时:检查预加重系数、检查电源纹波
- 眼图质量差:检查PCB走线长度、检查过孔数量、检查参考时钟抖动
嗯,Detect状态看似简单,但每个细节都可能成为瓶颈。我的建议是:在硬件设计阶段就把信号完整性仿真做扎实,别等到板子打回来再抓瞎。
这张图把Detect状态的三个核心步骤串起来了。你想想看,从电气空闲检测开始,到接收器检测,再到发送器初始化,每一步都环环相扣。哪一步出了问题,链路训练都会卡住。
最后说一句:眼图是信号完整性的照妖镜。别嫌麻烦,每次调试都抓一下眼图,能帮你省下大量排查时间。