PCIe EQ 参数详解:Preset、Hints、Coefficients、Cursors
在我刚开始调 PCIe 链路那会儿,最头疼的就是 EQ 参数。一堆英文缩写——Preset、Hints、Coefficients、Cursors——看得人眼花。后来啃完 Base Spec 再上手调了两次,才理顺它们到底各管啥。
说白了,EQ 参数就是发送端和接收端之间的一套“密码本”。发送端怎么调整出信号的幅度和边沿?接收端又期望什么样的波形?都得靠这些参数来沟通。下面我一个一个拆开讲,也会带上我踩过的坑。
Preset 是“预置套餐”,Hints 是“接收端的建议”,Coefficients 是“最终的精细调节值”,而 Cursors 则是“Coefficients 的具体分量”。
Preset:快速上手的“预置套餐”
Preset 是 PCIe Base Spec 定义好的 11 种发送端配置(编号 0~10)。每种 Preset 对应一组固定的 pre-cursor / main-cursor / post-cursor 权重组合。Link Training 刚开始时,双方必先交换 Preset 能力,然后选定一个双方都能工作的 Preset 作为起点。
我个人习惯先看接收端支持哪些 Preset。很多芯片的 PHY 手册里会列出推荐的 Preset 值。比如,Gen4 常从 Preset 7 或 8 开始协商。我记得有一次调试,板子上电后链路就是上不去,用逻辑分析仪一看,发送端 Preset 是 0(全摆幅,无预加重),接收端根本没法锁定。后来把 Preset 改成 8,再结合后续系数微调,链路立马稳定了。
| Preset 编号 | pre-cursor 权重(典型) | main-cursor 权重 | post-cursor 权重 | 适用场景 |
|---|---|---|---|---|
| 0 | 0 | 1.0 | 0 | 默认全摆幅,无均衡 |
| 1 | 0 | 0.9 | 0.1 | 轻微去加重 |
| 2 | 0 | 0.8 | 0.2 | 中等去加重 |
| 7 | 0.1 | 0.8 | 0.1 | 对称预加重 |
| 8 | 0.1 | 0.7 | 0.2 | 常用 Gen4 起点 |
| ... | ... | ... | ... | 其余见 Spec |
Hints:接收端的“指点”
Hints 是接收端在 EQ Training 阶段发给发送端的“建议值”。它不强制,只是告诉发送端:“你这样调下去,我在我这边的眼图质量会更好。” Hints 里包含一个 4-bit 的 preset_hint 和一个 2-bit 的 coefficient_hint。
你想想看,接收端其实才是真正“看”到信号质量的。发送端盲调不仅低效,还可能跑偏。Hints 机制就是让接收端能快速引导发送端往正确方向走。我见过有人完全忽略 Hints,让发送端自己暴力遍历系数组合,结果链路训练时间飙到 30ms 以上。加上 Hints 后,通常 5ms 内就能收敛。
Coefficients:真正的“精密旋钮”
Coefficients 是发送端最终采用的 3 个抽头权重值:pre-cursor、main-cursor、post-cursor。每个系数的取值范围是 -128~127(实际用带符号整数表示),但有效范围通常被限制在 -63~63。发送端根据 Hints 或者自适应的搜索算法,在系数空间里寻找最优组合。
我调过的某块 FPGA 开发板上,发送端 PHY 只支持 -16~+15 的系数范围。第一次看寄存器时差点怀疑人生——怎么只有 32 步?后来才知道,低成本 PHY 通常会缩减系数位宽。这时候就别想着太大范围的精细调节了,配合 Preset 选一个合适的工作点更重要。
Cursors:pre-cursor、main-cursor、post-cursor
三个 Cursor 分别控制不同时间位置的幅度贡献:
- pre-cursor:影响当前符号之前的那个符号。主要用来补偿前一个 bit 对当前 bit 的串扰(码间干扰 ISI)。
- main-cursor:当前符号的主幅度,通常最大。可以看作是信号的基础摆幅。
- post-cursor:影响当前符号之后的那个符号。典型的“去加重”就是降低 post-cursor,让当前 bit 幅度增大,后一个 bit 幅度减小。
三者的关系满足归一化约束:|pre| + |main| + |post| = 1(实际实现中近似)。所以不能三个都往大了调,必须此消彼长。
“前小后大” —— 如果接收端眼图的上冲(overshoot)严重,适当增大 pre-cursor;如果下冲(undershoot)明显,增大 post-cursor。
别盲目调大 main-cursor,那会让预加重效果减弱。
我曾经遇到一个 case:链路跑 Gen4 16GT/s 时收端眼图水平开口只有 0.3 UI,怎么都过不了测试。接收端 Hints 反复指向某个方向,但发送端不搭理。后来我手动把 post-cursor 从 3 改成 6,pre-cursor 保持 0,main-cursor 从 63 降到 57,再调接收器的 CTLE 和 DFE,开口直接跳到 0.45 UI。所以说,Cursors 和接收端均衡要配合着看,不能只调一边。
上面这张图把四个参数的关系串起来了。Preset 和 Hints 是开机谈判时的“外交语言”,Coefficients 是最终落地的“实际值”,而三个 Cursor 就是 Coefficients 在时域上的具体分量。调试时按这个思路走,不会乱。