第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 这三个核心子状态抽象成下面的流程图。箭头上的条件就是咱们测试时要重点检查的信号。
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的训练测试,我建议按以下顺序搭建环境:
- 强制进入Configuration.LinkWidth:先保证LTSSM走到这个状态,再触发FRL使能。
- 发送FTI帧:用DWORD级的码型发生器,输出带正确Guard的训练帧。
- 模拟接收端响应:在FPGA或VIP里做一个状态机,按上面的图跳转。
- 抓取FTS帧的Payload:重点核对Link Number和Lane Number,这俩错了会导致链路分叉。
- 验证超时机制:延时返回或故意丢帧,看LTSSM是否回退到Detect。
为什么强调要在Payload里核对Link Number?我记得第一次搭建FRL测试时,没注意这东西,导致误把不同IC的通道数混在一起,链路一进入Data Flow就丢包。说白了,测试项一定要覆盖参数交换的完整性验证。
小结:FRL训练序列并不复杂,核心就是“检测-参数交换-确认”三段式。你只要抓住Training Header的前两个bit(0b00=FTI, 0b01=FTS, 0b10=FTC),再配合上面的超时表,迭代个两三轮就能稳定跑通。下一节我们会拿一个实际的测试日志来分析,看看失败的时候到底报了什么错误。
(注:按照课程安排,本章不预告后续内容。)