Polling 状态:比特锁定、符号锁定与块锁定
讲 Polling 状态之前,我先说说我早年的一个经历。
有一次调试 Gen3 板卡,链路老是起不来。抓了无数 trace,最后发现是 Polling 阶段的比特锁定根本没完成。但示波器上看波形,信号明明在跳。你想想看,要是连最基本的 0/1 边界都分不清,后续的符号锁定和块锁定就全是空中楼阁。那次排查花了我整整三天,所以今天这段,我希望你一次性搞明白。
Polling 状态,说白了就是链路初始化的第一阶段,也是接收端第一次看到高速串行数据。发送端这时候不管三七二十一,先发 TS1 或者 TS2 有序集(具体看子状态)。接收端呢,则要在这个阶段完成三件事:比特锁定、符号锁定、块锁定。我习惯把这三件事称为“锁定的三连击”——一步没锁住,后面全白搭。
比特锁定:找到时钟的节拍
比特锁定的目标是什么?就是让接收端的时钟恢复电路(CDR)能跟发送端的比特流对上频率和相位。这是一个纯物理层的过程,跟协议没关系,只看电气信号。
你可以想象一下:双通道示波器上,一个通道接发端时钟,一个通道接接收数据,你手动调整时基,让两个波形稳定下来——CDR 就是在干这事,只不过它靠反馈环路自动完成。
我在项目中遇到过一种情况:链路跑在 Gen3(8 GT/s)时,PCB 走线太长导致信号衰减太大,CDR 始终没法锁定。怎么办?要么加 Re-timer,要么优化走线。没有别的捷径。
| 锁定阶段 | 输入数据 | 锁定标志 | 典型时长 |
|---|---|---|---|
| 比特锁定 | 模拟信号(连续 bit 流) | CDR 锁定指示 | 几微秒到几十微秒 |
| 符号锁定 | 已并行化的 bit 流 | COM 符号对齐 | 几十个符号周期 |
| 块锁定 | 符号流 | Valid EDB / CRC 校验 | 128 个符号周期 |
注意:比特锁定不依赖任何协议内容。换句话说,哪怕发的是全 0 或全 1,如果信号翻转频率足够,CDR 照样能工作。PCIe 为了保证这一点,在 Polling 阶段会强制发送特定有序集,保证数据有足够的翻转密度。
符号锁定:找到字符的边界
比特锁定搞定之后,接收端拿到了一串连续的 0 和 1。但问题来了:你怎么知道从哪一位开始是第一个符号?比如 8b/10b 编码下,一个符号占 10 个 bit。如果接收端切分的位置比发送端偏移了 2 bit,那么后面所有的符号都是错的。
符号锁定解决的就是这个问题。接收端在 bit 流中寻找特定的“锚点”符号——COM 符号(逗号符号)。COM 符号的 10b 编码是唯一的,无论它出现在 bit 流的什么位置,接收端只要检测到它的图案,就能反推出符号边界。
我个人习惯把 COM 符号理解为“尺子的刻度”。你在卷尺上看不到毫米线的时候,整把尺就没法用——COM 符号就是这个刻度。
符号锁定完成后,接收端就能正确地“切”出每一个符号。这个阶段还会同步做一件事——极性校正。PCIe 允许发送端在差分对上的极性任意交换,接收端通过检测符号的极性,在内部做自动翻转。如果符号锁定了但极性没校正对,后续的 TS1 有序集内容就会全部颠倒——这在调试时特别坑人,因为你抓到的数据全是反的。
块锁定:找到数据块的边界
块锁定只在 Gen3 及以上的 PCIe 版本存在。因为 Gen3 从 8b/10b 切换到了 128b/130b 编码,接收端的工作方式也变了。
在 128b/130b 编码下,数据按 130 bit 一个块传输,其中前 2 bit 是同步头(Sync Header),后 128 bit 是有效数据。块锁定的目标,就是找到每个块的起始位置——也就是这 2 bit 同步头在哪。
同步头只有两种合法值:01(数据块)和 10(有序集块)。接收端在符号锁定后的 bit 流中,以 130 bit 为窗口,检查每 130 bit 中前 2 bit 是否匹配 01 或 10。如果连续多个窗口都匹配,就认定块锁定成功。
块锁定完成之后,接收端就能正确地解析每一个块,知道哪一段是数据,哪一段是控制命令。这时候,Polling 状态的核心任务就算完成了。接下来链路就可以转入下一阶段——Polling.Configuration,做一些简单的配置事务交换,然后进入 Detect 或 Configuration。
- 比特锁定 → 符号锁定 → 块锁定(Gen3 及以上)
- 前一个锁定没完成,后面不可能成功
- 每个锁定阶段都有超时保护——规范建议在 48 ms 内完成所有锁定
下面我画了一张图,把这几个锁定的关系理一下。你扫一眼就能明白。
从图上你能看到:Polling 是一个严格的串行过程。比特锁定是基础,符号锁定是承上启下,块锁定则是 Gen3+ 的额外关卡。每个锁定阶段都有一套硬件状态机在背后运转,你不需要关心它的每个微状态,但必须知道它锁什么、锁多久、锁不上会怎样。
嗯,关于 Polling 状态的三级锁定,我们就聊到这。这块内容虽然基础,但如果你能理清“比特→符号→块”这条链,后续的 Equalization 协商就好理解多了——因为 Equalization 本质上也是在信号质量上做“锁定”,只不过维度和方式完全不同。