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 权重适用场景
001.00默认全摆幅,无均衡
100.90.1轻微去加重
200.80.2中等去加重
70.10.80.1对称预加重
80.10.70.2常用 Gen4 起点
............其余见 Spec
小技巧:若接收端未主动请求特定 Preset,发送端默认使用 Preset 0。但 Preset 0 在高频下几乎没有预加重,信号失真大。建议在 Link Training 之前,强制发送端至少设置为 Preset 1 或 7。

Hints:接收端的“指点”

Hints 是接收端在 EQ Training 阶段发给发送端的“建议值”。它不强制,只是告诉发送端:“你这样调下去,我在我这边的眼图质量会更好。” Hints 里包含一个 4-bit 的 preset_hint 和一个 2-bit 的 coefficient_hint。

你想想看,接收端其实才是真正“看”到信号质量的。发送端盲调不仅低效,还可能跑偏。Hints 机制就是让接收端能快速引导发送端往正确方向走。我见过有人完全忽略 Hints,让发送端自己暴力遍历系数组合,结果链路训练时间飙到 30ms 以上。加上 Hints 后,通常 5ms 内就能收敛。

注意:Hints 并非强制,发送端可以无视它。但如果发送端不响应 Hints,接收端可能会反复请求同一个 Hints,导致训练超时。建议 PHY 实现中至少对 Hints 做“软响应”——即收到后调整搜索方向。

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 和接收端均衡要配合着看,不能只调一边。

PCIe EQ 参数核心关系图 发送端 Tx 接收端 Rx Preset (预置套餐) 协商后选定起始点 0~10 共11种 Hints 建议 接收端→发送端 preset_hint + coefficient_hint Coefficients 最终精细值 由 Preset 或搜索算法决定 范围:-128~127(常用 -63~63) pre-cursor main-cursor post-cursor Tx 侧内部参数 最终输出依赖此三值

上面这张图把四个参数的关系串起来了。Preset 和 Hints 是开机谈判时的“外交语言”,Coefficients 是最终落地的“实际值”,而三个 Cursor 就是 Coefficients 在时域上的具体分量。调试时按这个思路走,不会乱。

避坑经验: 调 Cursors 时一定要看归一化和。我曾经只调大 pre-cursor 和 main-cursor,忘了降低 post-cursor,结果发送端总输出幅度超出 PHY 最大额定值,信号直接削顶。建议每次改了系数后,用软件算出 |pre|+|main|+|post| 是否接近 1.0,偏差超过 5% 就得警惕。