Detect 状态:链路训练的第一声问候
Detect 状态,说人话就是——你的 PCIe 设备在问:「嘿,对面有人吗?」
它是 LTSSM 的起点,也是整个链路训练的第一步。如果你在做板级调试时发现链路始终起不来,十有八九是卡在了这个状态。我遇到过好几次这种问题,每次排查到最后,原因往往简单到让人哭笑不得。
好,我们直接进入正题。
Detect 状态在干啥?
Detect 的核心任务听上去很简单:检测对端是否存在。但 PCIe 是个高速串行总线,收发是分开的,所以检测也得分开做——发送端和接收端各玩各的。
具体来说,Detect 要完成三件事:
- 发送端检测:TX 发出一个低电平脉冲,看 RX 端有没有反射回来
- 接收端检测:RX 侦测链路上是否有交流耦合电容,判断对端是否接入
- 阻抗匹配检查:确保终端电阻(通常是 50Ω)已经就位,否则信号反射会乱套
你想想看,如果这两端都不知道对方在不在,后面的 Polling、Configuration 根本没法谈。
Detect 的子状态机
Detect 内部还有三个小子状态,我习惯把它们叫做「三步走」:
| 子状态 | 行为 | 典型时间 | 退出条件 |
|---|---|---|---|
| Detect.Quiet | 静默等待,让链路上的电荷泄放干净 | ≥ 12ms | 定时器超时 |
| Detect.Active | 发送检测脉冲,判断对端是否存在 | 几个 μs | 检测完成 |
| Detect.Waiting | 等待对端进入 Detect 状态 | ≤ 12ms | 接收端检测到信号 |
物理层到底怎么「检测」的?
这部分有点底层,但我还是想讲讲,因为理解透了才能做调试。
PCIe 的物理层有两种检测机制,我分别说一下:
1. 接收检测(Receiver Detection)
这是在 TX 侧做的。TX 发出一个低幅度的脉冲(区别于正常工作时的差分信号),然后观察反射回来的信号。如果对端有接收器且终端电阻已经接上,反射回来的信号幅度和相位会不同。说白了,就是发出一个「探测声纳」,看回声是撞到墙(有设备)还是掉进黑洞(没设备)。
我记得有次在实验室,一个新手同事死活调不通链路,抓波形发现反射一直不对。我过去看了一眼,发现他的 SMA 线缆没接终端电阻——接收端是开路的,反射全回来了,逻辑分析仪以为对面有个设备,其实啥也没有。
2. 带内检测(In-Band Detection)
这是 RX 侧做的事。接收器在自己的引脚上检查是否有直流电压偏移——如果有交流耦合电容,说明对端是有源设备;如果什么都没有,那就是空载。带内检测的好处是不需要额外的管脚,省了成本,但也带来一个问题:检测阈值非常敏感。
PCIe 规范规定,接收检测的阈值电压是 50mV ~ 175mV。低于 50mV 会被认为没设备,高于 175mV 才会认为有设备。中间有个死区,这区间的信号是不确定的。
电气参数表(参考 PCIe Base 5.0)
有些参数在调试时经常需要查,我整理了一个精简版:
| 参数 | 最小值 | 典型值 | 最大值 | 单位 |
|---|---|---|---|---|
| 检测脉冲幅度 | 0.5 | 0.6 | 1.2 | V |
| 接收检测阈值 | 50 | 100 | 175 | mV |
| 交流耦合电容 | 75 | 100 | 200 | nF |
| 终端电阻 | 40 | 50 | 60 | Ω |
| Detect.Quiet 等待时间 | 12 | - | - | ms |
表格里的数据要记住几个关键的:电容值 100nF 左右,电阻 50Ω,等待时间至少 12ms。这些是硬件设计时的硬约束,错一个链路就起不来。
Detect 状态机的完整流程图
下面我用一张 SVG 图把整个 Detect 的流转逻辑画出来,方便你对照调试:
这张图把整个 Detect 的流程串起来了。你可以看到,从进入 Detect 开始,经过 Quiet 的等待期,到 Active 的检测期,再根据结果决定是回到起点重试,还是进入 Waiting 等待下一步。
很多工程师拿到测试报告,看到「卡在 Detect」就直接慌了。其实你先对照这张图,看看是卡在哪个子状态——如果一直卡在 Quiet,说明前一个状态(可能是 Polling 或 Configuration 失败退回)没有正常完成,链路有脏状态没清干净。如果卡在 Active,那大概率是物理层的问题,眼图没张开呗。
常见调试误区
说几个我在项目里踩过的坑:
最后的叮嘱
Detect 状态是整个链路训练中「最简单但也最容易被忽略」的一个环节。它不涉及复杂的均衡算法,也没有烦人的链路宽度协商,但它决定了链路能否走下去。
我个人习惯,拿到一块新板子做调试时,第一件事就是去读 PCIe 控制器的 LTSSM 状态寄存器,确认是否正常走出了 Detect。如果连续几次都卡在 Detect,我不会急着去调后面的参数,而是先拿万用表测一下链路的两端电阻、用示波器确认交流耦合电容的值——这些物理层的东西对了,Detect 自然就过了。
下一个状态是 Polling,那才是真正开始「握手」的地方。先把基础打牢,调试起来才能得心应手。