3. 训练序列的作用与分类归纳总结

做CXL链路训练,说白了就是在物理层上“握手”。握手用的数据包,就是训练序列(Training Sequence,TS)。每家协议都有自己的一套握手暗号,CXL的这套序列,我当年刚接触时觉得又臭又长,后来踩过一次坑才明白——每一个字段都在解决一个真实的物理难题。

CXL 链路训练序列与状态机流程 Detect 检测接收器 Polling TS0: 位锁定/极性反转 Configuration TS1/TS2: 宽度协商 L0 TS3: 均衡 Recovery TS4: 重训练 L2 低功耗状态 要点说明 TS0 在 Polling 阶段完成初始同步和极性反转;TS1/TS2 在 Configuration 阶段协商链路宽度; TS3 在进入 L0 前做自适应均衡;TS4 在 Recovery 阶段触发重训练。

3.1 训练序列的核心作用

训练序列不是一条完整的报文,而是一组固定模式的数据块。CXL 物理层靠它们完成五件事:

  1. 初始同步——位锁定、字节对齐、符号锁定。没有正确对齐,后面全是乱码。
  2. 极性反转——通道正负信号可能接反,训练序列里用特定比特模式告诉对方“你反了”。
  3. 通道对齐——多条 Lane 之间的歪斜(skew)必须消除,否则数据跨 Lane 传输会串位。
  4. 链路宽度协商——两端决定用 x4、x8 还是 x16,以及哪些 Lane 坏了需要降级。
  5. 均衡与状态转换——调整发射器和接收器的滤波器,让信号质量达标,然后转入正常 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 挂掉再查方便多了。