第3章:链路初始化与Detect状态机制
3.1 先从物理层握手开始
链路初始化,说白了就是LTSSM把两个PCIe设备拉到一起的过程。从上电复位开始,到链路能传输数据,全靠这套状态机在运作。
我记得第一次调试PCIe链路时,系统死活Link Up不上。翻来覆去查Code,最后发现是Detect阶段的电气参数没配好。从那以后,我对LTSSM的初始化细节就再也不敢马虎了。
LTSSM的初始化从Detect状态开始。这个状态的目的很简单——检测对端有没有设备。但实际做起来,要考虑的细节可不少。
3.2 Detect状态:如何知道对面有人?
Detect状态分为两个子状态:Detect.Quiet和Detect.Active。先静默,再试探,这是硬件通用的套路。
核心目标:通过发送周期性的Electrical Idle Exit Sequences(EIES),检测接收端是否看到连续的阻抗变化。如果看到,说明对面有设备。
我曾经遇到过一个Case:某款FPGA作为Endpoint,在Detect.Quiet阶段发呆太久,导致Root Port检测超时。后来发现是PHY层的复位逻辑没对齐。这个坑,我印象很深。
Detect.Quiet
在Detect.Quiet状态下,发送端保持电气空闲(Electrical Idle)。接收端则开启接收检测电路(Rx Detection Circuit),监控线路上的阻抗变化。
- 持续时间:至少12ms,但具体由SoC的PHY实现决定。
- 关键操作:发送端不主动驱动线路,接收端被动监听。
- 退出条件:检测到对端设备的接收器阻抗,或者超时进入下一步。
我的习惯:在仿真时,我会把Rx Detection Circuit的模型换成真正的负载模型,而不是简单的开路/短路。否则容易漏掉Receiver Detection的时序问题。
Detect.Active
Detect.Quiet完毕,状态机跳入Detect.Active。这个阶段,发送端开始主动发送EIES序列。EIES说白了就是一串特定的差分翻转信号,用来验证对面是不是真的在侦听。
- EIES序列长度:Gen1中至少需要发送2个TS1序列。Gen3/Gen4会变成更复杂的Ordered Set。
- 检测结果:如果对端收到了EIES并回应正确的TS1,说明链路存在。如果收不到,则重试或进入Disable状态。
| Detect子状态 | 持续时间 | 发送端动作 | 接收端动作 |
|---|---|---|---|
| Detect.Quiet | ≥12ms | 保持Electrical Idle | 主动检测接收器阻抗 |
| Detect.Active | 连续发送EIES,直到收到回应 | 发出TS1序列 | 等待接收TS1,然后回送TS1 |
3.3 从Detect走向Polling
Detect成功不等于万事大吉。它只告诉你对面有接收器。但双方的通道宽度、数据速率、链路编号还没对齐。这些是Polling和Configuration阶段要干的活。
不过,如果你在Detect阶段发现链路始终无法进入Polling,先别急着怀疑后端逻辑。我个人习惯先检查PHY层的PLL锁定状态。PLL不稳,Detect.Active发出的EIES会被抖掉,对面根本看不到。
曾经踩过的坑:做过一个GaN功放验证板,PCIe走线长度超出Spec规定10%。结果在Detect.Active阶段,EIES信号衰减太大,对端收不到。后来加了一级Repeater才搞定。记住,Detect阶段的灵敏度和信号完整性高度相关。
3.4 链路初始化全流程速览
为了帮助大家建立整体认识,我画了一张链路初始化的状态转换图。从Detect开始,到L0结束,中间每一步都有对应的测试点和调试方法。
这张图其实是个简化版。实际FSM里还有Loopback、Recovery、Hot Reset这些旁路状态。但在初始化这条主线上,Detect、Polling、Configuration、L0就是四个关键锚点。
Detect阶段的具体参数
你可能会问我,Detect到底要测多久?答案不固定,但PCIe Spec给了清晰的时间约束。
- Detect.Quiet 最小时间: 12 ms (这是Gen1/Gen2的标准。Gen4/Gen5有更短的替代方案,但不常用).
- Detect.Active 持续期: 最多可以连续发送512个TS1序列,之后如果没回应,LTSSM会认为对端不存在,重新回到Detect.Quiet.
- 退出条件: 只要在Detect.Active期间收到一个有效的TS1序列,立即跳转到Polling.
调试小技巧:在仿真中,我会在Detect.Active后加一个硬件断点,监控接收到的TS1序列数量。如果收不到,检查PHY的CDR(时钟数据恢复)是否锁定。没锁定,EIES序列就是废的。
3.5 实际项目中的Detect问题案例
我在维护一个老式服务器平台时,碰过一件怪事:某批次PCIe SSD插入主机后,系统偶尔识别不到。换槽位又正常。用逻辑分析仪抓Detect阶段的波形,发现Root Port发送的EIES序列在Slot与SSD之间有反射。因为连接器的寄生电容太大,EIES的第一个沿被削平了。对端的Receiver Detection电路误判为电气空闲,直接忽略。
解决方案也简单:在PHY侧调整EIES的驱动强度,让上升沿更快。或者,在PCB布局时给差分对加个小串阻。这类问题在高速设计里很常见,根源往往就是信号完整性,不是LTSSM逻辑有Bug。
3.6 本章小结
Detect状态是LTSSM的门神,也是整个链路训练的基础。从Detect.Quiet到Detect.Active,每一步都涉及PHY层的电气特性和状态机的同步。我个人总结了一个三字诀:静、发、收。先静默(Quiet)等对端准备好,再发(Active)EIES试探,最后收(Receive)TS1确认。顺序错了,或者时序跑了,链路就别想起来。
如果你在项目里遇到链路初始化失败,先从Detect阶段查起。查看PHY的Rx Detection电路是否使能、CDR是否锁定、EIES的幅度是否达标。很多时候,问题就出在这些看起来简单的环节上。