3. 训练序列的作用与分类归纳总结
做CXL链路训练,说白了就是在物理层上“握手”。握手用的数据包,就是训练序列(Training Sequence,TS)。每家协议都有自己的一套握手暗号,CXL的这套序列,我当年刚接触时觉得又臭又长,后来踩过一次坑才明白——每一个字段都在解决一个真实的物理难题。
3.1 训练序列的核心作用
训练序列不是一条完整的报文,而是一组固定模式的数据块。CXL 物理层靠它们完成五件事:
- 初始同步——位锁定、字节对齐、符号锁定。没有正确对齐,后面全是乱码。
- 极性反转——通道正负信号可能接反,训练序列里用特定比特模式告诉对方“你反了”。
- 通道对齐——多条 Lane 之间的歪斜(skew)必须消除,否则数据跨 Lane 传输会串位。
- 链路宽度协商——两端决定用 x4、x8 还是 x16,以及哪些 Lane 坏了需要降级。
- 均衡与状态转换——调整发射器和接收器的滤波器,让信号质量达标,然后转入正常 L0 状态。
我个人习惯把训练序列比作“链路训练的敲门砖”——每块砖都敲在特定的状态机门环上,敲错了门不开,敲慢了门自动关上。
3.2 训练序列分类详解
CXL 规范定义了五种训练序列:TS0、TS1、TS2、TS3、TS4。注意,PCIe 也有 TS1/TS2,但 CXL 扩展了字段含义,并在 TS0 和 TS3 中加了独有内容。下表归纳了它们的差异:
| 类型 | 主要用途 | 关键字段 | 出现阶段 |
|---|---|---|---|
| TS0 | 位锁定、符号锁定、极性反转、链路初始化 | Polarity, Symbol Lock, Lane Number | Polling |
| TS1 | 通道对齐、去歪斜、SKP 有序集同步 | SKP, Lane Alignment, Receiver Detect | Configuration |
| TS2 | 链路宽度协商、降级 Lane 识别 | Width, Lane Swap, Equalization Hint | Configuration |
| TS3 | 自适应均衡、发射器去加重、接收器补偿 | Eq Preset, Filter Coefficients, Precursor | 即将进入 L0 前 |
| TS4 | 重训练、链路恢复、错误恢复 | Recovery Reason, Retrain Count | Recovery |
你想想看,每种训练序列都有固定字段结构。比如 TS0 的 Polarity 字段,我曾经在一个项目里发现两端信号线交叉了,但软件没检测出来,结果链路一直复位。后来硬件同事直接在板子上量,才发现是 PCB 走线绕反了——但通过 TS0 的极性反转机制,物理层其实可以自动纠正。所以,不要小看那一个 bit。
⚠️ 容易混淆的点:TS1 和 TS2 在 PCIe 基础版里也有,但 CXL 扩展了其中的 Reserved 字段用于“链路切换信息”和“CXL 协议版本协商”。如果你的仿真环境还按纯 PCIe 解析,会漏掉关键信息,导致训练无法完成。
3.3 训练序列的发送规则与交互流程
训练序列不是乱发的,每个状态都有严格的时序要求:
- 发送频率:在 Polling 和 Configuration 阶段,发送端必须连续发送 TS0/TS1/TS2 直到接收到对端的对应序列或超时。
- 超时门限:CXL 规定了每个状态的最大驻留时间(例如 Configuration 最多 2 μs)。超了直接转 Recovery。
- 序列转换:只有收到特定序列且字段匹配,状态机才允许切换。例如从 Polling 到 Configuration,必须先收到 TS0 的确认(TS0 ordered set 的 Loopback? 这里简化)。
- SKP 插入:TS1 和 TS2 之间会穿插 SKP 有序集用于时钟补偿,这属于物理层自动完成,但你做调试时需要知道。
举个例子,TS2 的 Width 字段决定了最终链路宽度。如果一端支持 x16,另一端只支持 x4,那么 TS2 交互后会协商为 x4。我记得有一次 debug,发现训练总是卡在 TS2,后来抓 trace 看到宽度字段里“upstream 写的是 0”(代表 x4),但 downstream 一直发 x16,两边没法达成一致——其实是 driver 配错了寄存器。
调试小技巧:用逻辑分析仪抓取训练序列时,重点关注 TS2 的 Width 和 Lane Number 字段。如果你的板子连接器少焊了一排 pin,这里就能看出异常。
3.4 实战中的注意事项
理论说完了,我分享几个实际碰到的问题:
- 极性反转不要全靠训练序列——它只能纠正 Lane 级别的正负交换,没法处理 Lane 顺序错乱。Lane 映射需要在 PCB 设计时就确认好。
- TS3 的均衡参数不是越强越好——我曾经调过一组系数,让眼图在接收端看起来超级干净,结果发现远端串扰反而变大了。CXL 建议先用默认预设,再用 training 微调。
- Recovery 阶段的 TS4 重试次数——规范允许连续重试 3 次,超过后转入 L2 或触发错误上报。如果你的产品在高温下频繁进 Recovery,多半是 TS3 阶段的均衡没做好,而不是链路硬件坏了。
说到底,训练序列是链路的第一道关卡。关关过了,后面的数据传输才顺。我个人习惯在芯片 bring-up 早期专门写个脚本,轮询每个状态的训练序列计数,一旦发现 TS0/TS1/TS2 的重传率超过 1%,立刻标记异常——这比等 L0 挂掉再查方便多了。