3. 均衡化系数更新协议概述归纳总结
好,咱们今天把这套均衡化系数更新协议捋一捋。说实话,我刚接触PCIe Gen3的时候,也被这套握手流程搞得有点晕。但后来发现,它其实就是一套很严谨的“沟通机制”,确保发送端和接收端能在高速下对上话。
3.1 为什么需要系数更新?
说白了,信号在PCB上跑快了以后,会变形。眼图闭合、抖动变大,这都是高频损耗带来的问题。均衡化就是给信号做“整形”,让接收端能看清。
但问题来了——每个板卡的走线长度、材料特性都不一样。没法用一套固定的均衡参数包打天下。所以协议规定:在链路训练的特定阶段,双方必须交换均衡化系数。我习惯把这个过程叫作“链路双方的相互适配”。
核心思想: 发送端调整信号的幅度和预加重(Preshoot/De-emphasis),接收端反馈是否收到干净的眼图。来回几次,直到双方都满意。
3.2 系数更新发生的时机
不是任何时候都能改系数的。它只发生在两个明确的状态里:
- Recovery.RcvrLock:链路从低功耗或错误中恢复时。
- Recovery.Equalization:专门用来协商Gen3/Gen4均衡化系数的状态。
嗯,这里有个坑。我记得有一次,我在调试一块Gen4的Retimer芯片,就是因为在Recovery状态里没处理好EQ系数更新的时序,导致链路反复进入Recovery,就是上不去L0。后来发现是接收端的系数准备好信号给晚了。
3.3 协议流程的五步走
协议把这个过程拆成了5个阶段。你对照着下面这张图看,会更清楚。
3.4 系数的具体协商内容
你想想看,光说“调整系数”,到底调什么?协议定义了三个参数:
| 系数名称 | 影响范围 | 常见值范围 |
|---|---|---|
| Preshoot | 信号跳变前的高频预补偿 | 0 ~ 6 dB |
| De-emphasis | 信号跳变后的低频衰减 | -3.5 ~ -12 dB |
| Coefficient (直流增益) | 信号的总体幅度 | 0.95 ~ 1.05 |
⚠️ 注意: 这三个系数在更新时,必须保证乘积(Pres x Coeff x Demp)近似为1。我曾经碰到过有人把Preshoot拉到6dB,但忘了降增益,结果信号直接饱和了,接收端根本解不出来。
3.5 硬件实现中的几个要点
3.5.1 连续的系数更新模式
协议支持两种模式:
- 单独更新(Independent):每次只更新一个系数。
- 连续更新(Continuous):发送端可以连续发出多个TS1,每次更新一个不同系数。
我个人建议,在硬件设计时,如果FSM(有限状态机)资源允许,尽量用连续模式。我在一款Gen4交换芯片的项目里,就是靠连续模式把链路协商时间从200μs降到了80μs。效率提升很明显。
3.5.2 接收端的眼图监测
接收端在做评估时,不能光看“有没有信号”。它需要知道自己是否能可靠地采样到0和1。协议要求接收端有一个内部眼图扫描器。如果你在做芯片验证,记得检查这个模块是否按照协议要求锁定了“眼高”和“眼宽”阈值。
3.6 超时与重试机制
协议很聪明,它考虑到链路环境可能变化(比如温度升高导致损耗变大)。所以它设定了:
- 如果在24ms内没有完成均衡化(即没有进入L0),则链路会重新冷复位。
- 每次系数更新请求的超时时间在20μs左右(取决于具体实现)。
有一次我在实验室调一块CPU和FPGA的互联,发现每次跑到Recovery.EQ就卡死。后来追了逻辑分析仪,才发现是FPGA侧在发送TS1时,没能按时把“准备好”位置1。这就是典型的接收端超时问题。
💡 避坑指南: 调试LTSSM状态机时,先抓Recovery状态里的TS1/TS2序列。看发出请求的一方是否在等待对方响应。绝大多数EQ问题都出在“响应方没干活”或者“响应方干了活但发送方没看到”。
3.7 总结一下
均衡化系数更新,其实就是一段有监督的对话:
- 发问:发送端问“我要不要调一下参数?”
- 许可:接收端说“等等,我告诉你调成多少。”
- 执行:发送端按指令改好系数。
- 确认:接收端看看效果,行就过,不行就重来。
这套机制保证了PCIe Gen3/Gen4在千变万化的板级环境下,依然能稳定工作在8GT/s或16GT/s。你理解了这5步,后面再讲具体寄存器配置和状态机跳转,就会轻松很多。