Detect 状态:链路训练的起跑线 —— 子状态与转换条件详解
Detect 是 LTSSM 链路训练的第一站。说白了,就是你的 PCIe 设备在问:“对面有人吗?”
别小看这个“打招呼”的动作。我做过十几个 PCIe 项目,一半的链路训练失败都卡在 Detect 阶段,而且问题往往很隐蔽——不是电气特性不对,就是时序窗口没踩准。所以这一章我们把 Detect 的三个子状态掰开揉碎,结合转换条件,把每个细节讲透。
三个子状态,逐个击破
Detect 状态内部有三个子状态:Detect.Quiet、Detect.Active 和 Detect.DeBounce。它们形成一个闭环,像雷达扫描一样反复确认对端是否存在。下面我按顺序拆解。
1. Detect.Quiet — “先听,再说”
进入 Detect 后,设备首先停留在 Quiet 子状态。此时发送器处于电气空闲(Electrical Idle),不发送任何数据;接收器则全力检测对端是否存在。
怎么检测?通过监视接收器差分信号的共模电压变化。如果对端已经上电并开始发送训练序列,接收器会感应到信号跳变。
这里有个关键参数:电气空闲退出检测阈值。不同 IP 核的阈值设定可能略有差异,我遇到过一块 FPGA 原型板,因为接收器参考电压偏了 50 mV,导致始终检测不到对端,一直卡在 Quiet。后来用示波器量了差分峰峰值才发现问题。
转换条件就两条:
- 检测到对端信号 → 跳转到 Detect.Active
- 定时器超时(通常 12 ms) → 也跳转到 Detect.Active(用于主动发送训练序列,尝试建立链接)
你想想看,如果一直没人回应,设备不能永远等下去,超时后它会主动“喊一嗓子”。
2. Detect.Active — “打招呼并听回应”
进入 Active 后,发送器开始发送训练序列(TS1 或 TS2),接收器同时继续监听对端信号。这个阶段有点像两个人在黑暗中互相喊话:“我在这里,你在吗?”
训练序列的发送频率和内容由 PCIe Base Spec 定义,但具体实现中要注意占空比和信号完整性。我调试过一次 Gen3 链路,发现 Active 阶段发送的 TS1 序列幅值只有规范要求的一半,导致对端无法正确识别,反复回退到 Quiet。最后查出是发送端驱动强度配置错了。
Active 状态的转换条件:
- 成功检测到对端的有效信号 → 进入 Detect.DeBounce
- 未检测到对端,或信号质量不合格 → 回到 Detect.Quiet
- 超时(通常也是 12 ms) → 回到 Detect.Quiet
嗯,这里要注意:从 Active 回到 Quiet 并不代表失败,只是重新开始一轮检测。LTSSM 设计有多次重试机制。
3. Detect.DeBounce — “确认不是噪声”
这个阶段是去抖动。对端信号可能因为反射、串扰或电源噪声产生毛刺,如果贸然进入下一状态,可能造成误判。DeBounce 的作用就是连续采样一段时间,确认信号是稳定的。
去抖动的时长没有硬性规定,通常在 2 ms 到 10 ms 之间,具体由芯片实现决定。我个人习惯把 DeBounce 窗口设得比规范最小值宽 20%,给信号完整性留点余量。
我曾经被去抖动时间坑过一次:某款国产交换芯片为了追求快速训练,把 DeBounce 窗口压缩到了 1 ms,结果在强电磁干扰环境下频繁误触发,链路反复掉线。后来我们把窗口调到 4 ms,问题迎刃而解。所以不要盲目追求“快”,稳定才是第一优先级。
转换条件:
- 信号持续稳定超过去抖动窗口 → 退出 Detect,进入 Polling 状态
- 信号中途丢失或出现毛刺 → 回到 Detect.Quiet,重新开始
关键要点
- Detect 是 LTSSM 训练的入口,所有链路训练都从这里起步
- 三个子状态形成一个“检测 → 发送 → 确认”的闭环
- 去抖动窗口是抗干扰的第一道防线,不要设得太短
- 超时回退是正常机制,不是错误
转换条件全景表
为了方便你在调试时快速查询,我把所有转换路径整理成表格。建议收藏这张表,项目里肯定用得上。
| 当前子状态 | 目标子状态 | 转换条件 | 典型超时 |
|---|---|---|---|
| Detect.Quiet | Detect.Active | 检测到对端信号,或定时器超时 | 12 ms |
| Detect.Active | Detect.DeBounce | 成功检测到对端有效信号 | — |
| Detect.Active | Detect.Quiet | 未检测到对端,或信号质量不达标 | 12 ms |
| Detect.DeBounce | Polling | 信号持续稳定超过去抖动窗口 | — |
| Detect.DeBounce | Detect.Quiet | 去抖动期间信号丢失或出现毛刺 | — |
| 任意子状态 | Detect.Quiet | 全局超时或链路复位触发 | 按实现定义 |
调试建议
我建议在仿真阶段就覆盖以下场景:
- 对端从未上电(卡在 Quiet,应触发超时重试)
- 对端信号幅值偏低(Active 阶段检测失败,回退)
- 去抖动窗口内注入毛刺(验证 DeBounce 的容错能力)
- 连续多次回退后的恢复机制
这些 case 我在项目里都踩过,提早验证能省下好几轮板级调试的时间。
避坑指南
我曾经在某个量产项目中遇到批量链路训练失败的问题。现象是 Detect 状态反复在 Active 和 Quiet 之间跳转,始终进不了 DeBounce。最后定位到是发送端共模电压偏了 80 mV,导致接收端信号检测逻辑误判。
排查方法很简单:用示波器量差分信号的眼图,重点关注共模电压和峰峰值。PCIe Gen3 规范要求差分峰峰值在 800 mV 到 1200 mV 之间,共模电压在 0 V 到 2 V 之间。只要有一项偏离,Detect 阶段就会出问题。
所以我的建议是:在板级调试时,先把 Detect 阶段的信号质量调到最优,再往下走。这个阶段的基础打不牢,后面的 Polling、L0 状态全是空中楼阁。