第3章 FRL链路训练协议:Flit Rate Link训练序列的协议细节与帧结构

各位好,我是老罗。在PCIe 6.0的测试中,FRL链路训练是很多人头疼的环节。我自己第一次调试时,被Flit帧的时序搞得焦头烂额。今天咱们就把FRL的训练序列和帧结构拆开来看,说白了就是把协议里那些弯弯绕绕简化为可落地的逻辑。

3.1 训练序列的宏观流程

FRL训练发生在链路从Gen1~Gen5的传统模式切换到Flit模式之前。你可以把它看作一个“握手+对齐”的阶段。整个序列分为三大块:

  • Flit Training Init(FTI):发送端开始发送Flit训练序列,接收端检测到后进入对齐。
  • Flit Training Sequence(FTS):双方交换Flit训练帧,完成Symbol锁定、SKP对齐和参数协商。
  • Flit Training Complete(FTC):确认稳定后,进入Data Flow,开始传输真正的Flit数据。

嗯,这里要注意:FRL训练是 独立于传统LTSSM 的,但LTSSM在Configuration状态会判断是否启用了Flit模式。我之前在测试时发现,有些IP在Configuration结束后直接跳入FRL训练,根本不给传统TS序列留窗口——其实这是协议允许的快速路径。

3.2 Flit训练帧结构拆解

每个FRL训练帧由多个 Flit Training Block(FTB) 组成。我习惯把FTB看作一个定长的小包,你把它当成一个“迷你Flit”就行。结构如下表:

字段 长度(Symbol) 说明
Start Block Guard 2 特殊码型,用于识别帧起始
Training Header 1 指示帧类型(FTI / FTS / FTC 等)
Payload 8~16 协商参数、Link Number、Lane Number等
CRC-8 1 对整个FTB的保护
End Block Guard 2 结束标记,类似SKP序列

个人建议:分析协议时别纠结每个bit的含义,先盯着 Training Header 和 Payload 看。我做第一个FRL测试用例时,就因为在End Block Guard里找了半天对齐标记,后来才发现Start Block Guard才是真正的“哨兵”。

3.3 核心状态机:FRL Training Substate Machine

你别被PCIe Spec里几十页的状态图吓到。我把 FRL Training Init → FTS → FTC 这三个核心子状态抽象成下面的流程图。箭头上的条件就是咱们测试时要重点检查的信号。

FRL链路训练核心状态机(简化版) FTI Tx (发送端) 接收端检测到FTI 进入FTS 交换参数 FTC确认 Data Flow 超时重传 测试关注点: 1. FTI发送后,接收端必须在4个Flit时间内回复FTS。 2. 参数交换阶段的CRC校验失败会导致回到FTI。 3. FTC确认后不允许再看到FTS帧,否则链路会挂。

3.4 关键信号与超时参数

做一致性测试时,我最讨厌对着Spec翻超时值。下面我把FRL训练中 必须记住 的Timer和计数器列出来:

参数 规范值 测试方法
FTI_Timeout 4 μs 从发送FTI到收到FTS的时间
FTS_Count_Max 32 连续FTS帧数(超过则回退)
Param_Retry 3 参数交换重试上限
Wait_FTC 20 Flit 等待对方发送FTC的最大时间

曾经踩过的坑:我的一个客户在仿真的FRL训练中,总是卡在FTS阶段不前进。我查了半天,发现是他们的PHY在接收FTS时,把Start Block Guard认成了普通数据——因为时序仿真里Guard的抖动超标了。后来我们在测试中强制加了一个“Guard对齐窗口”,问题才解决。记住:训练帧的边界检测一定要留足裕量。

3.5 实战思路:如何构造FRL测试用例

如果你正在写FRL的训练测试,我建议按以下顺序搭建环境:

  1. 强制进入Configuration.LinkWidth:先保证LTSSM走到这个状态,再触发FRL使能。
  2. 发送FTI帧:用DWORD级的码型发生器,输出带正确Guard的训练帧。
  3. 模拟接收端响应:在FPGA或VIP里做一个状态机,按上面的图跳转。
  4. 抓取FTS帧的Payload:重点核对Link Number和Lane Number,这俩错了会导致链路分叉。
  5. 验证超时机制:延时返回或故意丢帧,看LTSSM是否回退到Detect。

为什么强调要在Payload里核对Link Number?我记得第一次搭建FRL测试时,没注意这东西,导致误把不同IC的通道数混在一起,链路一进入Data Flow就丢包。说白了,测试项一定要覆盖参数交换的完整性验证。

小结:FRL训练序列并不复杂,核心就是“检测-参数交换-确认”三段式。你只要抓住Training Header的前两个bit(0b00=FTI, 0b01=FTS, 0b10=FTC),再配合上面的超时表,迭代个两三轮就能稳定跑通。下一节我们会拿一个实际的测试日志来分析,看看失败的时候到底报了什么错误。

(注:按照课程安排,本章不预告后续内容。)