Gen4 均衡系数:定义与规范

讲均衡系数之前,我先说个我自己的经历。刚做 Gen4 项目那会儿,我总觉得系数嘛,随便写个值调一下就行,结果板子死活 link 不上。后来发现,系数的范围、步长、编码方式,规范里掰得清清楚楚,漏一个细节就翻车。这节咱们就把这些硬骨头啃下来。

系数范围——别超出边界

Gen4 标准里,均衡系数分发送端(Tx)和接收端(Rx)。我这里重点讲 Tx 去加重系数,因为它在训练中来回协商,最容易出问题。

  • 最小系数:通常对应最大去加重,例如 -12 dB 衰减。换算成数字域,是 -127 LSB(1 LSB = 0.094 dB 左右)。
  • 最大系数:无去加重,即 0 dB,对应 0 LSB。有时候也允许一点点预加重,但 Gen4 里很少用到正方向。
  • 实际可取范围:-127 ~ 0,单位 LSB。注意,有些芯片内部支持 +127,但标准交互时只发负值。
我曾经踩过的坑:用了一个支持到 +64 的芯片,结果对端 Preset 回复里根本不认正值,直接导致训练失败。最后我强制把系数 clamp 到 [-127,0] 才解决。所以,协议范围内能发的值才是有效的,别信 datasheet 上写的“支持范围”。

步长——非均匀还是均匀?

Gen4 均衡系数的步长可不是随便定的。很多人以为和 ADC 一样,每 1 LSB 对应固定 dB 步长。其实不然。

系数分段 LSB 步长(dB) 典型应用场景
-6 dB 以内(轻度去加重) 0.5 dB / LSB 短通道、低损耗链路
-6 dB ~ -12 dB(中重度去加重) 1.0 dB / LSB 长通道、高损耗背板
-12 dB 以下(极少使用) 2.0 dB / LSB 极端损耗链路

为什么要这么设计?我琢磨过,核心原因是 人耳感知(不对,是链路均衡)对近端误差更敏感。轻度去加重时,零点几个 dB 的偏差就可能导致眼图闭合;重度去加重时,信号眼本来就小,允许更大误差。步长非均匀,是性价比最高的编码方式。

编码方式——二进制补码 + 偏移映射

Gen4 均衡系数在寄存器里用 8 位有符号二进制补码 表示,但实际物理值要经过一段映射表。直接补码的坑在于,0x80(-128)按协议是保留值,千万别发。

关键编码规则:

  • 有效范围:-127(0x81)到 0(0x00),以及 +1(0x01)到 +127(0x7F)——虽然 Tx 很少用正值。
  • 寄存器写入时,直接放补码;读取时也是补码,但实际链路协商会用 Preset 索引 来间接推导系数,而不是直接读补码值。
  • 编码表格在 PCIe Base Spec 的表 4-X 里(具体号记不清了),我建议手边常备那份表。

配合一个实际例子。比如你想设置去加重 3.5 dB,对应物理值约 -37 LSB(计算:3.5 ÷ 0.094 ≈ 37.2)。补码就是 0xDB。嗯,这里要注意,如果芯片内部的 LSB 精度和协议不一致,还得乘个缩放因子。我一般直接查 Preset,省心。

寄存器字段布局

Gen4 把所有均衡相关的系数收在 PCIe Extended Capability – Equalization Control 里。每个 Lane 单独有一个 Tx 系数寄存器,格式如下:

Bit 位 | 名称              | 描述
7      | Sign              | 1: 负数(补码符号位)
6:1    | Magnitude[5:0]    | 幅度值(6 bit)
0      | Reserved          | 必须置 0

更常见的做法是把 8 位整体看作补码。但上面这种拆分方式,在调试时很有用——我可以用 bit mask 单独看符号位有没有搞错。记得有一次同事写了个 bug,符号位和幅度反了,结果 –1 变成了 –63,眼图直接塌了。

实战避坑:系数协商的边界

训练过程中,端到端会交换系数 Preset 值(0~10),而不是直接传系数补码。我建议你做链路层设计时,一定要把 Preset 和实际系数的映射表固化成一个数组,别现场算。为什么?

  • 性能:每个 Preset 对应的系数是固定的,计算一次就行。
  • 一致性:避免浮点误差——我亲眼见过两个芯片商的算出来的系数差了 1 LSB,然后不停切换 Preset,死循环了。
  • 合规:Gen4 标准要求 Preset 具体系数必须匹配规范中的数值表,不允许自己设计。
我的个人习惯:在 FPGA 验证阶段,用一个 SPI 命令让 CPU 把映射表 dump 出来,比对两边是否一致。这样做一次,后面就不用再怀疑系数本身了。

一张图看懂均衡系数规范

下面这个 SVG 框架图,把系数范围、步长非均匀、编码方式、寄存器布局串在一起。画的时候我特意把“我踩过的坑”也标上去了——也算是给各位提个醒。

Gen4 均衡系数规范框架 均衡系数规范总览 系数范围 -127 LSB ~ 0 LSB 步长 非均匀 0.5/1.0/2.0 dB 编码方式 8位补码 0x81~0x00 寄存器字段 Bit7:符号 | Bit[6:1]:幅度 Reserved 必须为0 Preset 间接映射 Preset 0~10 对应固定系数 避免浮点误差 常见陷阱 0x80 保留值 符号幅度搞反 💡 不要自己发明系数映射,严格遵循 Gen4 规范表 Preset 协商比直接传补码更安全

小结一下

均衡系数不是什么玄学,就是一本规范账:范围不能越界、步长靠分段表格、编码用补码。但每一个细节都可能成为你调试时的拦路虎。我建议你把这节讲的三个要点——范围、步长、编码——当成 checklist,每次写代码前过一遍。嗯,这样基本就能避免我在开头说的那种“死活 link 不上”的尴尬了。