链路训练过程详解:速率、宽度、比特与符号锁定
说真的,链路训练这玩意儿,看着协议里几十页的流程图,一开始很容易懵。但拆开来看,其实就是四个核心步骤:比特锁定、符号锁定、速率协商、宽度协商。它们串起来,才让一根PCIe链路从“死”变“活”。
我习惯把这四个阶段比作两个人打电话。比特锁定是“听到声音了”,符号锁定是“听懂了你说的每一个字”,速率协商是“咱们说快点儿还是慢点儿”,宽度协商是“咱俩用一条线还是多条线聊”。这么一想,是不是好理解多了?
1. 比特锁定:从“噪声”中找到“信号”
链路刚复位时,收端看到的就是一堆随机电平。你得先找到COM序列(Comma Sequence),它是8b/10b编码里特有的同步头。说白了,COM是一个特定波形,就像你在收音机里调频时听到的“滴滴”声。
我个人经验,比特锁定出问题最常见的原因就是PLL压控振荡器没锁住。我记得有一次做板级调试,链路死活起不来,示波器一看,RX端时钟抖得跟心电图似的。最后发现是电源纹波串进了PLL的模拟供电。
- COM检测:在比特流里匹配特定的10位序列(K28.5)。匹配不到就说明链路不通。
- 时钟恢复:锁相环锁定输入数据边沿,产生同频同相采样时钟。
- 时间窗:协议规定,必须在最多1024个UI内完成比特锁定,否则宣告训练失败。
调试小技巧:用逻辑分析仪抓COM序列,看它是否周期出现(约每1000个UI一次)。连续16个UI没检测到COM,基本可以判定比特锁定失败。
2. 符号锁定:给“比特”分组
比特锁定之后,你有了连续的数据流,但还不对。因为PCIe用8b/10b编码,每10个比特才组成一个符号。你得知道哪10个比特是同一组。这就是符号锁定做的事。
符号锁定靠的是K码(控制码)。K28.5是特殊的控制符号,它的10位编码跟数据不一样。一旦连续收到3个正确的K28.5,收端就知道“哦,从这里开始对齐”。
嗯,这里要注意。符号锁定后,收端就能识别TS1和TS2序列了。TS1/TS2是训练集,里面携带了大量信息——速率请求、链路宽度、序号等等。符号锁定没做好,后面TS1/TS2识别全是乱码。
3. 速率协商:从Gen1到Gen5的“讨价还价”
速率协商可能是四个阶段里最微妙的。它的起点永远是Gen1(2.5GT/s)。两边先用这个“最低共同语言”开始聊,用TS1和TS2互发消息。
你看,TS1里的某个比特位标记着“速率标识符”。发端写一个速率值(比如010代表Gen2),收端看到了,回复同样速率的TS1。这就叫握手确认。
我遇到过一个大坑:某个老款FPGA当作RC,跟Endpoint之间做速率协商。Gen1和Gen2都OK,但一到Gen3就崩。查了很久才发现是FPGA的Tx EQ(发送均衡)初始化数据有问题,Gen3需要的去加重参数没配好。说白了,高速率下信号质量不够,收端根本解不出正确的TS1。
速率协商的强制步骤:
- 发送端在Gen1速率下发送TS1,携带目标速率。
- 收端在Gen1下接收TS1,确认速率请求。
- 两端同步切换到新速率(必须同时切换,有保护时间)。
- 在新速率下重新进行比特锁定和符号锁定。
- 如果失败,回退到Gen1重新开始。
| PCIe代际 | 比特率 | 速率协商特点 | 常见故障点 |
|---|---|---|---|
| Gen1 | 2.5 GT/s | 无需EQ协商 | COM序列质量差 |
| Gen2 | 5.0 GT/s | 需去加重(De-emphasis) | 去加重系数不匹配 |
| Gen3 | 8.0 GT/s | 需Tx/Rx EQ协商 | EQ系数收敛失败 |
| Gen4/5 | 16.0/32.0 GT/s | 复杂EQ + 前向纠错 | 接收端眼图闭合 |
避坑指南:我曾经在一个Gen4项目中,所有硬件参数都是对的,但速率协商总是超时。最后抓信号发现,是PCIe参考时钟的PPM(百万分之几)偏差超过了300ppm。协议要求是±300ppm以内。你说这算不算“死于公差”?
4. 宽度协商:把多条lane“黏”在一起
速率定下来了,接下来要决定用几条lane。x1、x2、x4、x8、x16,选哪个?
宽度协商的核心在于lane映射和lane合并。每个TS1序列里都包含“链路序号”和“lane序号”。发端告诉收端:“这是我编号0的lane,这是我编号1的lane……”收端收到所有lane的序号后,才能把它们组合成一个完整的链路。
你可能想问:如果某条lane坏了怎么办?协议里有个叫Lane-to-Deskew的机制。坏lane上的数据会丢失,收端通过跨lane的同步头(SKP符号)来重新对齐。说到SKP,这玩意儿在Gen3/4里特别重要——它用于补偿不同lane之间的时钟偏移。
我实际测试时发现,宽度协商最常出问题的是差分对极性反转。你想想看,如果P和N接反了,收端看到的信号直流分量完全反相。虽然PCIe的RX有极性反转检测,但如果PCB设计时不注意,还是可能引入额外的延迟甚至误码。
- lane序号分配:发送端在TS1中声明每一条lane的序号(0~15)。
- 跨lane对齐:通过SKP有序集调整各lane间的相位差。
- 宽度降级:如果某条lane训练失败,链路可以降级使用(例如x8降为x4)。
快速检查方法:用示波器同时看所有lane的COM序列。如果某条lane上的COM脉冲明显偏窄或偏宽,大概率极性反了,或者PCB走线不匹配。
总结一下四个锁定的关系
比特锁定是最底层的物理层同步,好比你要先能开机;符号锁定是数据链路层的对齐,好比你要能认出汉子;速率协商是两边商量用多快的速度跑;宽度协商是决定用几条车道。没有前一步,后一步就无从谈起。
很多人调试时只盯着“链路是否进入L0状态”,忽略了中间哪一步卡住了。我建议下次看训练失败时,先查比特锁定(COM序列有没有?),再查符号锁定(K码对齐没有?),顺着流程往下走。90%的问题都能在前两步找到线索。
好了,链路训练的四步走,咱们算是掰开揉碎了讲了一遍。希望以后你碰到链路不起来的板子,心里能有个清晰的排查路径。