1. 从一块眼图塌掉的载板说起:这五种器件到底在链路里管什么
前阵子帮朋友看一块 PCIe 5.0 的载板,主控到插槽之间走了大约 18 英寸的走线,中间还过了两个连接器。板子能枚举、能识别设备,但一跑带宽测试就掉速,误码率高得离谱。抓眼图一看,32 GT/s 下眼高几乎压成一条线,UI 只有 31.25 ps 的窗口里抖得没法看。他把链路里堆了一堆料——Redriver 也加了、时钟 Buffer 也换了、Driver 也调了,问题依旧。最后发现根本原因不在这些器件本身,而是他压根没分清 Retimer、Redriver、Buffer、Switch、Driver 各自在链路里扮演什么角色,把该用 Retimer 的位置塞了个 Redriver。
这件事让我觉得有必要把这几个经常被混为一谈的名词掰开讲清楚。PCIe的信号链其实是一条从发送端到接收端的"高速运输线",Retimer、Redriver、Buffer、Switch、Driver 都是这条线上不同职能的"工种"。有的负责重新整形数据,有的只是把信号再推一把,有的负责分发参考时钟,有的负责扩展拓扑,有的负责源端驱动。名字听着像亲戚,内核差异却是一个量级。这篇文章适合做硬件设计、信号完整性、板级调试、FPGA 高速接口的人看,也适合刚接触PCIe链路、对着 BOM 表发懵的朋友。
先把结论摆在前面:Retimer是"协议感知 + 时钟恢复"的重定时器,能洗掉抖动;Redriver是纯模拟的线性均衡放大器,能补损耗但洗不掉抖动;Buffer通常指时钟或信号的缓冲分发,本身不做均衡;Switch是协议层的端口扩展器件,代价是延迟和枚举复杂度;Driver一般指时钟或信号的驱动器,负责把参考时钟或信号推到足够的强度。搞清这五者的边界,选型和排错才有方向。
2. 信道的账要先算明白:奈奎斯特频率和损耗预算
2.1 每一代 PCIe 的奈奎斯特频率都不是随便定的
要判断链路需不需要加器件、加哪种器件,第一步是把损耗预算算清楚。很多人上来就翻 BOM,其实应该先看信道在奈奎斯特频率处的插入损耗。PCIe各代的数据率不同,对应的奈奎斯特频率也不同,这个频率决定了板材和走线的损耗有多难缠。
| 代际 | 数据率 | 编码 | 奈奎斯特频率 | 单 UI |
|---|---|---|---|---|
| Gen1 | 2.5 GT/s | 8b/10b | 1.25 GHz | 400 ps |
| Gen2 | 5.0 GT/s | 8b/10b | 2.5 GHz | 200 ps |
| Gen3 | 8.0 GT/s | 128b/130b | 4 GHz | 125 ps |
| Gen4 | 16 GT/s | 128b/130b | 8 GHz | 62.5 ps |
| Gen5 | 32 GT/s | 128b/130b | 16 GHz | 31.25 ps |
| Gen6 | 64 GT/s | PAM4 / 1b1b | 32 GBd 符号率 | 31.25 ps |
这张表里最关键的列是奈奎斯特频率和单 UI。UI 越窄,留给抖动、码间干扰、反射的余量就越小。Gen3 时代 125 ps 的窗口还算宽裕,到了 Gen5 只剩 31.25 ps,任何一点抖动或损耗过冲都可能把眼图压死。Gen6 更狠,用了 PAM4,虽然符号率还是 32 GBd,但要同时看三只眼,信噪比要求比 NRZ 高得多。
2.2 FR4 板材在 8 GHz 以上是灾难
普通 FR4 在 4 GHz 处的插入损耗大约是 0.3 到 0.5 dB/inch,到了 8 GHz 会涨到 0.7 到 1 dB/inch,16 GHz 时更是直奔 1.5 dB/inch 甚至更高。也就是说,一段 10 英寸的 FR4 走线在 Gen5 的奈奎斯特频率上可能吃掉十几 dB。而规范给的通道损耗参考预算,Gen3 大约 22 dB、Gen4 大约 28 dB、Gen5 大约 36 dB,都是含连接器和封装的整体值。超过这个量级,光靠调整走线和换板材已经救不回来,就得考虑往链路里加器件。
这里有个常见的误区:很多人以为只要插槽能识别设备就没问题,其实枚举成功只是低频握手过了,高频的链路训练和误码测试完全是另一回事。我有次见到一块板子,Gen4 下能跑满,切到 Gen5 直接掉到 Gen1,就是因为 Gen5 的奈奎斯特频率上损耗超标,链路自适应训练失败后退回了低速率。所以评估信道损耗,一定要按目标速率去算,不能拿低代际的经验套。
2.3 一个粗略的估算思路
没有仿真条件的时候,可以用一个粗略的办法估:先量出走线长度、连接器数量,乘以对应频率下的单位损耗,再加上封装和过孔的近似损耗,得到总的插入损耗估算值。如果这个值和规范预算的差距在 10 dB 以内,通常靠源端去加重加接收端均衡能扛过去;超过 15 dB,就要认真考虑 Redriver 或 Retimer 了。这个估算不精确,但能帮你快速判断"要不要加器件"这个方向性问题。真正的判据还是 S 参数仿真加实测眼图,后面会专门讲。
3. Retimer 和 Redriver:名字像兄弟,内核差一个量级
3.1 Redriver 的线性均衡:能放大,但洗不掉抖动
Redriver 的本质是一个模拟的线性均衡器,典型结构是 CTLE(连续时间线性均衡)加上预加重或去加重。它把输入信号按频率做增益补偿,高频衰减得厉害就多给点增益,低频本来就够就少给点。整个过程是线性的、连续的、不做判决的,信号从输入到输出几乎是"原样放大加整形"。
它的优点是延迟极低,通常在几百皮秒量级,功耗和成本都很友好,配置也简单,很多 Redriver 连寄存器都不用配,上电即用。但它的致命短板也在这里:因为它不做采样和判决,输入信号里带的随机抖动、确定性抖动、码间干扰会被一起放大并继续往下传。换句话说,Redriver 是把"已经脏了的水"再过滤一下,但没有换一桶干净水。链路本身的抖动预算如果已经被前面几段走线吃掉大半,Redriver 帮不了你。
我一般把 Redriver 用在损耗中等、抖动还没失控的场景。比如 Gen4 以下、走线十来英寸、连接器一两个,源端去加重加上接收端均衡本来就能过,只是余量薄,加个 Redriver 补个几 dB 就稳了。这种场合用 Retimer 是杀鸡用牛刀,还会白白增加延迟和成本。
3.2 Retimer 的 CDR:重新采一次,抖动到这里为止
Retimer 则是完全不同的量级。它内部有CDR(时钟数据恢复)模块,从进来的信号里恢复出时钟,然后用这个恢复的时钟对数据重新采样、重新判决、重新发送。关键就在"重新"这两个字上:抖动传到 Retimer 这里就被截断了,因为输出是用本地恢复出来的干净时钟重新打出去的,前面累积的抖动不会再往后传。
Retimer 通常还是协议感知的,会参与PCIe链路的训练过程,理解 LTSSM 的状态机,在均衡协商阶段配合做 Tx 和 Rx 的均衡参数调整。这意味着它不只是个物理层器件,还涉及一部分协议栈逻辑,需要固件、需要配置、需要通过 SMBus 或 I2C 加载参数。延迟上,Retimer 会比 Redriver 高,通常增加的延迟在纳秒量级,但在 PCIe 的延迟预算里是可以接受的。
功耗和成本是 Retimer 的代价。一颗 Gen5 Retimer 的功耗可能到几瓦,价格也远高于 Redriver。所以它不是无脑堆料的选择,而是当信道损耗和抖动预算确实撑不住、又不想换更高等级板材时,才值得上的方案。跨板、背板、长线缆、多连接器这些场景,Retimer 几乎是标配。
3.3 两者放在一起对比才看得清
| 维度 | Redriver | Retimer |
|---|---|---|
| 工作方式 | 模拟线性均衡 | 采样判决后重发 |
| 是否恢复时钟 | 否 | 是(CDR) |
| 抖动传递 | 会累积传递 | 被截断 |
| 延迟 | 几百 ps | 纳秒量级 |
| 功耗 | 低 | 较高 |
| 成本 | 低 | 高 |
| 配置复杂度 | 简单,常免配置 | 需要固件与寄存器配置 |
| 适用场景 | 中等损耗、抖动尚可控 | 长距离、高损耗、抖动吃紧 |
一句话记忆:Redriver 补损耗不补抖动,Retimer 既补损耗又洗抖动,代价是延迟、功耗和复杂度。选型时先看信道损耗,再看抖动余量,两个指标都紧张才上 Retimer。
4. Buffer 和 Driver:最容易忽略,也最容易翻车
4.1 时钟 Buffer 分发的从来不只是频率
很多人一听到Buffer就想到数据缓冲,但在 PCIe 语境里,最常说的 Buffer 是参考时钟缓冲器。一块板子上主控、插槽、Retimer、Switch 往往都需要 100 MHz 的参考时钟,不可能每个都从晶振单拉一根线,于是就用时钟 Buffer 把一路时钟扇出成多路,同时做阻抗匹配和电平转换。
问题在于,时钟 Buffer 分发的从来不只是频率,还有抖动。Buffer 本身如果附加抖动(additive jitter)太大,或者电源纹波抑制做得差,它就会把供电上的噪声调制到时钟上,再传给下游每一个器件。PCIe 对参考时钟的抖动要求很严,尤其是 Gen5 以后,时钟的相位抖动直接吃掉接收端的时序余量。我见过一个案例,整条链路数据侧做得很干净,就是跑不稳,最后查到是时钟 Buffer 的电源去耦没做好,换了个低附加抖动的型号立刻就好。
4.2 Driver 负责把信号推到足够的强度
Driver这个词有点泛,在时钟链路里它指时钟驱动器,负责把参考时钟推到足够的幅度和边沿速率;在信号链里它有时也指源端的发送驱动能力。PCIe 的发送端本身就有可配置的驱动强度和去加重,规范里定义了一组 Tx 均衡预设(Gen3 时代是 P0 到 P9,Gen4 之后是更细的系数协商),发送端通过调整去加重和预加重来补偿信道的高频损耗。
这里有个实操点:源端去加重不是越大越好。去加重调过头会造成过冲,接收端反而更难判决。链路训练时会做发送端和接收端的均衡协商,最终落在一个双方都能接受的参数组合上。调试时如果发现眼图有严重过冲,先别急着加 Redriver,回头看看源端预设是不是配得太激进。这个坑我在 Gen4 的 FPGA 链路上踩过,把预设从高档降到中档,眼图立刻就开了。
4.3 AC 耦合电容和端接这些细节别轻视
PCIe 的发送端是 AC 耦合的,每条 lane 上串着耦合电容,规范要求通常在 100 nF 量级。这个电容的位置、容值、封装寄生都会影响高频响应。位置应该尽量靠近发送端还是接收端,不同代际和不同设计有讲究,放错位置会让阻抗不连续点落在最难受的地方。端接方面,接收端的差分端接电阻、共模电压匹配,也是眼图塌陷的常见原因。
还有一个经常被混淆的概念是 PCIe 物理层内部的弹性缓存(elastic buffer)。它和我们在板上加的 Buffer 完全是两码事。弹性缓存存在于接收端的物理层内部,用来做跨时钟域的数据传递——接收端从数据流里恢复出的时钟和本地时钟之间有频偏,弹性缓存通过插入或删除一些填充符号来吸收这个频差。之前有人专门聊过弹性缓存怎么搞定跨时钟域,那讲的是链路内部的机制,不是外部器件。把这两个 Buffer 混为一谈,讨论就会跑偏。
5. PCIe Switch:扩展拓扑的代价不只是延迟
5.1 Switch 内部其实是一组虚拟桥
PCIe Switch和前面几种器件的层次完全不同。Retimer、Redriver、Buffer、Driver 基本都在物理层或时钟层面工作,而 Switch 是协议层的器件,内部实现了一组虚拟的 PCI-to-PCI 桥,每个下游端口对外看起来都是一个独立的桥设备。主机枚举的时候,会看到 Switch 的上游端口和各个下游端口,每个端口下面挂的设备都有自己独立的配置空间。
这意味着 Switch 不只是"把一路信号分成几路"那么简单,它参与整个PCIe 枚举过程,负责路由配置读写、转发事务层包、维护各端口的链路状态。好处是它能扩展出远超根端口数量的设备,还能做热插拔、错误隔离。代价是它给每一跳都引入了额外的延迟,转发本身也要消耗时间和功耗。
5.2 延迟、功耗和枚举复杂度是三道坎
Switch 带来的延迟在几十纳秒量级,对大多数存储和网卡场景可以接受,但对延迟敏感的实时采集、低延迟网络就不一定了。功耗上,一颗多端口 Gen5 Switch 可能十几瓦,散热和供电都得重新规划。枚举复杂度更是个隐形坑:Switch 下游挂的设备多了,配置空间映射、BAR 分配、总线号分配都会变复杂,有些老固件或者特殊设备在 Switch 后面就是枚举不出来。
我在 FPGA 多卡场景里见过典型的麻烦:主机根端口下面挂 Switch,Switch 下挂四张 FPGA 卡,单卡测试都正常,四卡同时上电就出现部分卡枚举失败。最后查出来是上电时序和 Switch 的配置加载顺序对不上,Switch 固件还没加载完,下游卡就急着训练链路,导致端口状态乱掉。所以用 Switch 一定要把上电复位时序、固件加载顺序、时钟就绪时序排清楚,不能只看功能对不对。
5.3 NTB 和多主机场景是另一层玩法
Switch 里还有个进阶功能叫非透明桥(NTB),用于多主机共享同一组下游设备。普通透明桥是把下游设备映射到同一个主机地址空间,NTB 则允许两个主机各自独立地看到对方后面的设备,中间通过地址翻译窗口通信。这个功能在做多主机冗余、双控存储、异构计算时很有用,但配置复杂,地址窗口划分、门铃中断、内存映射都要仔细设计。没搞清 NTB 的机制就贸然上,很容易出现两个主机互相抢设备或者地址冲突的问题。
6. 选型决策:把场景、损耗、验证手段串成一条线
6.1 一个可以照着走的决策顺序
面对一条链路要不要加器件、加什么,我通常按这个顺序走:
- 先按目标代际算出奈奎斯特频率,估信道插入损耗,和规范预算对比。
- 损耗在预算内且有余量,什么都不加,靠收发端均衡解决。
- 损耗略超预算、抖动余量还够,优先考虑 Redriver,便宜、低延迟、免配置。
- 损耗明显超标、或者走线长、连接器多、抖动吃紧,上 Retimer。
- 需要扩展端口数量,才引入 Switch,并接受它的延迟和枚举复杂度。
- 时钟分发和驱动强度的问题,用 Buffer 和 Driver 解决,别指望它们去补数据链路的损耗。
这个顺序的核心逻辑是:能不加就不加,能用模拟解决就不上协议器件,延迟、功耗、成本、复杂度都是要付的账。很多设计一上来就堆 Retimer,结果发现瓶颈根本在时钟抖动或者端接,白花钱。
6.2 常见组合方案对照
| 场景 | 典型方案 | 说明 |
|---|---|---|
| 板内短距、损耗低 | 仅收发端均衡 | 最省,靠规范内的均衡能力 |
| 板内中距、损耗略高 | 源端去加重 + Redriver | 低延迟、成本友好 |
| 跨板 / 背板 / 线缆 | Retimer | 需要洗抖动、参与链路训练 |
| 多设备扩展 | Switch | 协议层扩展,注意延迟 |
| 多路时钟分发 | 时钟 Buffer | 关注附加抖动与电源 |
| 时钟驱动能力不足 | 时钟 Driver | 关注边沿和幅度 |
6.3 验证手段要把仿真和实测结合起来
选完器件不代表就完事了。S 参数仿真用来预判、实测眼图用来定案,两者缺一不可。仿真阶段把走线、过孔、连接器、器件的模型都串起来,看通道的插入损耗、回波损耗、串扰,确认在奈奎斯特频率上还有多少余量。实测阶段用误码测试仪或者协议分析仪跑不同速率、不同温度、不同码型,看误码率和眼图余量。
这里提醒一句:常温跑通不等于全温区跑通。高速链路的损耗和抖动对温度敏感,很多问题在高温或者低温下才暴露。我建议验证时至少覆盖高低温两个角落,尤其是用了 Retimer 或 Redriver 的链路,器件本身的性能也会漂。温度一上去误码率变差,往往是均衡参数或者器件偏置没在温漂范围内设计好。
7. 实测踩坑记录:几个真金白银换来的经验
7.1 Retimer 固件没加载,链路表现和没加一样
我碰到过一次印象很深的坑:板子上了 Gen5 Retimer,硬件焊接、供电、参考时钟都正常,但链路一直不稳定,甚至不如不加。查了半天发现 Retimer 的固件根本没加载成功,它处于一种"直通"的默认状态,内部均衡没生效。后来排查是配置总线的一根上拉电阻阻值不对,导致配置接口通信异常,固件加载指令没被正确接收。教训是:协议器件一定要确认固件/配置真的生效了,不能只看链路能不能通。
7.2 均衡设置过冲,眼图反而变差
第二个坑是均衡参数调过头。为了压住高频损耗,把源端去加重和 Redriver 的高频增益都拉满,结果眼图上的过冲非常明显,接收端的眼高反而更低。均衡的本质是在补偿和引入失真之间找平衡,不是增益越大越好。正确的做法是看接收端判决点的眼图,而不是发射端或中继点的波形。调试均衡,永远以最末端接收端的眼图为准。
7.3 时钟 Buffer 的电源没去耦干净,整条链路遭殃
前面提到的时钟 Buffer 电源问题,值得再强调一次。时钟路径上的任何噪声都会转化为相位抖动,而相位抖动会直接吃掉高速链路的时序余量。Buffer 的电源脚旁边一定要放足够且位置合理的高频去耦电容,供电走线要短、要宽、要干净。有条件的话给时钟链路单独供电或者加低噪声稳压,收益非常明显。这个细节在原理图上看起来不起眼,实测阶段却经常是决定成败的那一环。
7.4 把 Retimer 和 Switch 的参考时钟搞混
还有一个配置层面的坑:Switch 和 Retimer 往往都需要参考时钟,但它们的时钟需求不一定是同一路。如果为了省事用同一个时钟 Buffer 的输出同时喂 Switch 和 Retimer,要特别确认两边的时钟要求是否兼容,包括频率、电平标准、抖动预算。我见过把参考时钟接错、导致 Switch 训练到一半就反复重训的情况,最后追到时钟树上才发现接的是不匹配的那一路。
7.5 AC 耦合电容位置放错,阻抗不连续
最后一个高频设计的老毛病:AC 耦合电容的位置。它本质上是一段阻抗不连续,放得好影响小,放得不好就在最敏感的频段制造反射。一般建议尽量靠近发送端,配合接收端的端接和均衡去吸收这个不连续。走线阻抗要严格控制在目标值,过孔尽量减少,换层要加回流过孔。这些基本功在 Gen3 时代还能含糊,到了 Gen5 就是生死线。
这几种器件的关系说白了就是:Driver 管源头发力,Buffer 管时钟分发,Redriver 补损耗,Retimer 补损耗加洗抖动,Switch 管拓扑扩展。把它们放在链路的不同位置去理解,选型和排错就不会再乱。我自己现在做链路评估,第一步永远是算奈奎斯特频率上的损耗预算,然后再决定往哪一层加什么,这个习惯帮我省了太多返工。