2. 链路层初始化训练流程简介
CXL 链路层的初始化训练,说白了就是让两边的设备在物理连接建立之后,相互认识一下,然后协商好怎么干活。这个过程不是一锤子买卖,而是一个状态机驱动、逐级递进的握手过程。
我第一次调 CXL 链路时,以为只要上电复位,链路就能自动跑起来。嗯,后来发现想法太天真。链路训练涉及多个子阶段,任何一步卡住,整个链路就起不来。今天咱们就把这个流程拆开,看看每一步具体做了什么。
链路训练的核心目标
说到底,链路层初始化的目的就是三件事:
- 建立位锁定 —— 让收发两端的时钟和数据对齐
- 完成块对齐 —— 找到 FLIT 的边界
- 交换能力信息 —— 告诉对方我能支持多宽、多快、哪些功能
这三件事做完,数据才能可靠传输。咱们一个一个看。
训练阶段概览
CXL 链路层训练通常遵循一个固定的阶段顺序。我习惯把它分成四个大阶段:
| 阶段 | 名称 | 主要动作 |
|---|---|---|
| Phase 0 | Reset & Detect | 复位,检测对端是否存在 |
| Phase 1 | Bit & Block Lock | 位锁定,块同步 |
| Phase 2 | Link Training | 交换训练序列,协商宽度和速率 |
| Phase 3 | Link Up | 确认链路就绪,进入正常运行 |
注意啊,这些阶段不是线性的。实际硬件中,有些阶段会有回退重试的机制。比如位锁定失败,就得重新从 Phase 0 开始。
关于训练序列:训练期间收发的是特定的有序集合(Ordered Sets),不是普通数据。CXL 定义了 TS1、TS2 等训练序列,和 PCIe 的玩法很像,但细节有差异。
链路训练状态机(LTSSM)
每个 CXL 端口内部都有一个链路训练与状态机(LTSSM)。它控制着端口在不同状态之间跳转。状态机设计得好不好,直接影响链路上电速度和稳定性。
下面这张图把核心状态和转移画出来了:
各阶段详解
Reset & Detect
上电或硬件复位后,端口进入 Detect 状态。这个阶段的工作很简单:
- 释放所有内部状态
- 等待对端也完成复位
- 检测接收器上是否有信号存在
避坑:有些芯片的复位时序有严格要求,复位信号保持时间不够,端口可能卡在 Detect 不动。我曾经遇到过一块 FPGA 的 CXL IP,复位拉低时间不够 100us,死活检测不到对端。调整复位时序后问题消失。
Bit & Block Lock
进入 Polling 状态后,两边开始发送训练序列。接收端做的事情包括:
- 通过时钟数据恢复(CDR)电路锁定数据流中的时钟相位
- 搜索训练序列的特征模式(比如 COM 字符)
- 一旦找到连续多个正确的训练序列,就宣布位锁定
- 再从位流中识别出块边界(Block Lock)
经验之谈:我个人习惯在这个阶段多检查眼图。如果信号质量不好,位锁定就会反复失败。链路训练里的很多“灵异问题”,根因都在物理层信号完整性上。
Link Training
位锁定和块对齐搞定后,进入 Configuration 阶段。这是训练的核心部分:
| 子步骤 | 动作 | 关键参数 |
|---|---|---|
| 宽度协商 | 双方报告自己的物理宽度,协商出共同支持的最大宽度 | x4, x8, x16 |
| 速率协商 | 交换支持的速率,选择最优的公共速率 | 16GT/s, 32GT/s |
| 能力交换 | 传输链路层能力集(比如支持的虚拟通道数、CRC 模式等) | VN 数量、ARI |
有意思的是,宽度协商可以降级。比如另一端是 x16,你这端只支持 x8,链路就自动降为 x8。速率协商也是一个道理。
注意:配置阶段对时序要求很严。每个训练序列必须在规定时间内响应,超时会触发 Recovery。我以前调试一个板子时,发现对端响应总是慢几微秒,最后查出来是中间 retimer 芯片的延迟超标了。
Recovery 与异常处理
任何阶段出了问题时,LTSSM 都会跳转到 Recovery 状态。Recovery 不是一个失败状态,它是一种容错机制:
- 尝试重新做块对齐和宽度协商
- 如果成功,就回到正常状态继续工作
- 如果连续失败,才回退到 Detect 再次从头开始
我见过不少团队在 Recovery 处理上踩坑,比如 Recovery 阈值设得太小,导致链路抖动频繁。阈值设得太大,又会让链路卡在恢复过程里。这个值需要根据实际链路质量和可靠性要求来调。
链路就绪确认
所有训练通过后,链路进入 L0 状态。此时才真正可以传输 FLIT 数据。但注意:L0 不意味着一切完美。它只是说明链路层训练完成了基础握手。后续上层协议(比如 CXL.mem、CXL.cache)还要继续做自己的初始化。
小结一下今天的内容:
- 链路层训练是一个状态机驱动的过程,分 Detect → Polling → Configuration → L0 四步
- 位锁定和块对齐是数据传输的前提,信号质量不佳会导致反复失败
- 宽度和速率协商在 Configuration 阶段完成,支持自动降级
- Recovery 状态处理各种异常,设计好阈值能提升链路稳定性
说实话,链路层训练看起来不复杂,但实际调试时坑不少。尤其是多板互联、通过 retimer 或交换机的情况,时序、信号完整性、协商策略都可能出问题。后面几章咱们会深入到具体的案例中,看看这些坑是怎么踩进去、又怎么爬出来的。