多彩编程 多彩编程MZPH · CODE BLOG
ARTICLE DETAIL

文章详情

深耕前端与后端开发技术的一线实战笔记与踩坑复盘。

PCIe Gen5协议升级与调试实战:从通道预算到链路训练

PCIe Gen5协议升级与调试实战:从通道预算到链路训练 1. PCIe Gen5 协议到底升级了什么PCIe Gen5 这两年在服务器、AI 加速卡、高端存储领域几乎是绕不开的话题。我最早接触它是在一块 FPGA 加速卡的项目上当时从 Gen3 直接跳到 Gen5踩的坑比想象中多得多。很多人以为 Gen5 就是带宽翻倍这么简单实际上协议层面的改动、信号完整性的要求、链路训练的复杂度跟 Gen3/Gen4 完全不是一个量级。这篇文章我打算把 PCIe Gen5 的协议内容、设计要求、以及实际调试中遇到的掉卡、降速、AER 报错等问题按我自己的理解完整梳理一遍适合做硬件设计、FPGA 开发、驱动调试、以及服务器运维的朋友参考。先说清楚 PCIe Gen5 的核心定位。它是 PCI-SIG 在 2019 年正式发布的规范单 Lane 速率从 Gen4 的 16 GT/s 提升到 32 GT/s编码方式仍然是 128b/130b跟 Gen3/Gen4 一致所以单 Lane 有效带宽大约是 32 × 128/130 ÷ 8 ≈ 3.938 GB/sx16 双向就是约 126 GB/s。这个数字看起来很爽但代价是信号频率到了 16 GHz 的 Nyquist 频率通道损耗、串扰、反射的控制难度陡增。协议层为了配合物理层也做了不少调整比如更严格的均衡训练、更细的 LTSSM 状态机、以及对 Flit Mode 的引入虽然 Flit Mode 是 Gen6 才全面铺开但 Gen5 已经为它做了铺垫。我见过太多项目在 Gen4 上跑得好好的一上 Gen5 就各种掉链路、降 Lane、AER 报错刷屏。根本原因往往不是协议没读懂而是设计阶段对通道预算、参考时钟、均衡策略的估算太乐观。所以下面我会从协议结构讲起再落到设计要求最后给一套可复现的调试方法。2. PCIe Gen5 协议分层结构拆解2.1 三层结构在 Gen5 下的变化PCIe 协议一直是经典的三层结构事务层Transaction Layer、数据链路层Data Link Layer、物理层Physical Layer。Gen5 没有推翻这个框架但每一层都有实质性的增强。事务层主要负责 TLPTransaction Layer Packet的组装和解析包括 Memory Read/Write、Configuration、Completion、Message 等类型。Gen5 在事务层最大的变化是对 TLP 处理延迟的要求更严因为链路速率翻倍后如果事务层成为瓶颈物理层的带宽优势就发挥不出来。实际设计中很多 FPGA 的 PCIe Hard IP 在 Gen5 下需要把 TLP 的接收缓冲和发送缓冲做得更深否则容易出现 backpressure 导致吞吐上不去。数据链路层负责 DLLPData Link Layer Packet的可靠传输包括 ACK/NAK 协议、CRC 校验、重传机制。Gen5 下重传的代价更高因为一次重传浪费的带宽更多所以链路层的重传窗口和超时参数需要重新调优。我在调试一块 Gen5 SSD 时发现默认的重传超时在长通道下会导致频繁 NAK后来把 ACK 延迟策略调整后才稳定下来。物理层是 Gen5 变化最大的地方。它分为逻辑物理层Logical PHY和电气物理层Electrical PHY。逻辑物理层负责 LTSSM 状态机、链路训练、Lane 对齐、加扰解扰等电气物理层负责 SerDes、均衡、时钟恢复。Gen5 的 LTSSM 状态比 Gen4 更复杂尤其是在 Recovery 和 Configuration 状态下的均衡协商流程。2.2 LTSSM 状态机在 Gen5 的关键路径LTSSMLink Training and Status State Machine是 PCIe 链路训练的核心。Gen5 的 LTSSM 有 11 个顶层状态其中跟 Gen5 强相关的是 Configuration、Recovery、Polling 这几个。在 Configuration 状态链路会协商 Link Width 和 Link Speed。Gen5 的协商是分阶段的先以 Gen1 建立链路然后逐级提速到 Gen2、Gen3、Gen4、Gen5。每一级提速都要重新做均衡训练。我实测过如果通道损耗太大链路可能在 Gen4 就卡住根本到不了 Gen5这时候 dmesg 里会看到 Link Speed downgraded 之类的提示。Recovery 状态是 Gen5 调试的重灾区。当链路出现误码或者需要重新均衡时会进入 Recovery。Gen5 的 Recovery 分为 Recovery.RcvrLock、Recovery.RcvrCfg、Recovery.Speed、Recovery.Equalization 等子状态。其中 Recovery.Equalization 是 Gen5 新增的重点它负责在高速下重新协商 TX/RX 的均衡系数Preset、FS、LF、Post-cursor 等。注意Gen5 的均衡训练不是一次性的链路在运行过程中如果误码率超标会重新进入 Recovery.Equalization。如果均衡参数没调好会出现训练成功但运行几分钟就掉链路的现象。2.3 Flit Mode 与 Gen5 的关系很多人把 Flit Mode 当成 Gen6 的特性其实 Gen5 规范里已经定义了 Flit Mode 的框架只是 Gen5 默认还是用非 Flit Mode即传统的 TLP/DLLP 结构。Flit Mode 的核心是把 TLP 和 DLLP 打包成固定长度的 Flit减少协议开销提高效率。Gen5 引入它是为了给 Gen6 的 PAM4 编码做过渡。在实际项目中如果你用的是支持 Flit Mode 的 IP可以尝试开启但要注意跟对端设备的兼容性。我遇到过一端开了 Flit Mode、另一端没开结果链路能训练成功但数据传不了的情况排查了很久才发现是模式不匹配。3. Gen5 设计要求从通道预算到电源完整性3.1 通道损耗预算怎么算Gen5 的通道损耗是最核心的设计约束。PCI-SIG 对 Gen5 的通道损耗要求是在 16 GHz 频率下Root Complex 到 Endpoint 的总插入损耗Insertion Loss不能超过 -36 dB。这个数字比 Gen4 的 -28 dB 严格了不少。实际设计中损耗来自几个部分PCB 走线损耗、连接器损耗、过孔损耗、线缆损耗。我一般按下面的经验值估算损耗来源Gen4 典型值Gen5 典型值备注PCB 走线-0.5 dB/inch-1.0 dB/inch取决于板材连接器-1.5 dB-2.5 dB普通连接器过孔-0.3 dB/个-0.6 dB/个取决于过孔设计线缆-1.0 dB/m-2.0 dB/m普通铜缆假设你的通道总长 8 inch用普通 FR4 板材光 PCB 走线就 -8 dB加上两个连接器 -5 dB再加几个过孔很容易就超过 -20 dB。所以 Gen5 设计必须用低损耗板材如 Megtron 6、M6G、TU-872 等并且尽量缩短走线、减少过孔。我个人的经验是Gen5 通道预算要留至少 6 dB 的余量因为实际板材的损耗会随温度、批次波动。如果预算卡得太死量产时良率会很难看。3.2 参考时钟与抖动要求Gen5 对参考时钟Refclk的抖动要求非常严。PCI-SIG 规定 Gen5 的 Refclk 相位抖动Phase Jitter在 16 GHz 下要小于 150 fs RMS12 kHz 到 20 MHz 积分范围。这个要求对晶振和时钟分配芯片的选型提出了很高要求。常见的做法是用低抖动的差分晶振如 100 fs RMS配合专用的时钟缓冲器。如果系统里有多个 PCIe 设备建议用时钟发生器Clock Generator统一分配避免各设备时钟不同源导致 CDRClock Data Recovery困难。提示Refclk 的走线要严格等长、差分阻抗控制在 100 欧姆并且远离高速信号和电源噪声源。我见过因为 Refclk 走线靠近 DC-DC 电源导致抖动超标、链路降速的案例。3.3 电源完整性与去耦设计Gen5 的 SerDes 功耗比 Gen4 高不少单 Lane 的功耗可能到 100 mW 以上x16 就是 1.6 W 以上。电源噪声会直接影响 SerDes 的抖动和均衡效果。去耦设计上我一般会在每个 SerDes 电源引脚附近放 0.1 uF 0.01 uF 的陶瓷电容并在电源平面附近放 10 uF 的钽电容或聚合物电容。电源平面的阻抗要控制在目标阻抗以下通常按下面的公式估算Z_target (V_ripple × V_supply) / (P_total × 0.5)假设电源 1.0 V允许纹波 3%总功耗 10 W那么 Z_target ≈ (0.03 × 1.0) / (10 × 0.5) 6 mΩ。这个阻抗在几十 MHz 到几百 MHz 范围内都要满足所以需要多级去耦配合。3.4 PCB 布局布线的硬性约束Gen5 的 PCB 设计有几条硬性约束违反了基本就等着掉链路差分对内的偏斜Intra-pair Skew控制在 5 mil 以内最好 2 mil。差分对间的偏斜Inter-pair Skew同一组 Lane 之间控制在 10 mil 以内。阻抗控制差分阻抗 85 欧姆PCIe 标准误差 ±10%。过孔设计尽量用背钻Back Drill减少 stubstub 长度控制在 10 mil 以内。参考平面差分对下方要有完整的参考平面避免跨分割。我踩过最大的坑是过孔 stub 没背钻Gen4 能跑Gen5 直接降速到 Gen3。后来加了背钻问题解决。所以 Gen5 设计一定要把过孔当回事。4. 实操Gen5 链路调试与问题排查4.1 枚举过程与链路训练日志解读PCIe 枚举过程是系统启动时 BIOS/UEFI 或 OS 扫描 PCIe 总线、分配资源的过程。Gen5 的枚举跟之前版本流程一样但链路训练的时间更长因为要逐级提速和均衡。在 Linux 下可以用lspci -vvv查看链路的详细状态。重点关注这几个字段LnkCap链路能力包括支持的 Speed 和 Width。LnkSta链路当前状态包括实际协商的 Speed 和 Width。DevSta设备状态包括 Correctable/Non-Fatal/Fatal Error 标志。如果 LnkSta 显示的速度低于 LnkCap说明链路降速了。这时候要看 dmesg 里的 AER 报错和 LTSSM 日志。我一般会用下面的命令抓取链路状态# 查看链路能力和状态 lspci -vvv -s 01:00.0 | grep -E LnkCap|LnkSta|DevSta # 查看 AER 错误统计 lspci -vvv -s 01:00.0 | grep -A 10 Advanced Error Reporting # 查看内核日志中的 PCIe 相关消息 dmesg | grep -i -E pcie|aer|link4.2 掉卡、降速、AER 报错的排查思路掉卡、降速、AER 报错是 Gen5 最常见的三类问题排查思路可以按下面的顺序来第一步确认物理层是否稳定。用示波器或误码仪测眼图看眼高、眼宽、抖动是否满足要求。如果眼图闭合说明通道损耗太大或均衡没调好。第二步检查链路训练日志。在 BIOS 里开启 PCIe 的详细日志或者在 Linux 下用setpci读取 LTSSM 状态寄存器。如果链路在 Recovery 状态反复跳转说明均衡协商有问题。第三步检查 AER 错误类型。Correctable Error 一般是信号质量问题Non-Fatal Error 可能是协议层问题Fatal Error 通常是链路断了。根据错误类型定位。第四步调整均衡参数。Gen5 的均衡参数可以通过 BIOS 或 IP 的寄存器配置。常见的参数包括 TX Preset、RX Preset、FS/LF 等。我一般会先用默认参数如果不稳定再逐级调整。下面是我整理的一个常见问题速查表问题现象可能原因排查方法解决思路链路降速到 Gen4/Gen3通道损耗大、均衡失败测眼图、看 LTSSM 日志换低损耗板材、调均衡参数运行中掉链路电源噪声、温度漂移测电源纹波、监控温度加强去耦、优化散热AER Correctable Error 刷屏信号质量差、误码率高看 AER 统计、测误码率优化通道、调均衡枚举失败、设备不识别Refclk 问题、复位时序测 Refclk、看复位信号换晶振、调复位时序带宽上不去TLP 处理瓶颈、DMA 配置测吞吐、看 DMA 寄存器加深缓冲、优化 DMA4.3 用仿真验证 Gen5 链路在流片或打板之前用仿真验证 Gen5 链路是很有必要的。常用的仿真工具包括 Cadence Sigrity、Ansys HFSS、Keysight ADS 等。仿真主要做两件事一是通道的 S 参数提取和眼图仿真二是 SerDes 的行为级仿真。我一般会先用 HFSS 提取通道的 S 参数然后导入 ADS 做眼图仿真。如果眼图余量不足就调整板材、走线、过孔设计重新仿真。这个过程可能要迭代好几轮。对于 FPGA 项目Xilinx 和 Altera 都提供了 Gen5 的 IP 和仿真模型。我建议在硬件回来之前先用仿真模型验证 LTSSM 的状态跳转和均衡流程这样能提前发现协议层的问题。4.4 实测经验从 Gen4 迁移到 Gen5 的注意事项如果你是从 Gen4 项目迁移到 Gen5有几个地方要特别注意板材要换Gen4 用的 FR4 在 Gen5 下损耗太大建议换 Megtron 6 或同等低损耗板材。连接器要换普通连接器在 Gen5 下损耗和串扰都超标要用高速连接器。Refclk 要升级Gen4 的晶振抖动可能不满足 Gen5 要求要换低抖动晶振。均衡策略要重调Gen4 的均衡参数在 Gen5 下不一定适用要重新调。散热要加强Gen5 的 SerDes 功耗更高散热设计要跟上。我做过一个从 Gen4 迁移到 Gen5 的项目硬件改了三版才稳定。第一版是板材没换链路只能到 Gen4第二版换了板材但连接器没换还是降速第三版全换了才跑到 Gen5。所以迁移不是简单换个 IP 就行硬件设计要全面升级。5. 热插拔、兼容性与系统级设计考量5.1 PCIe 热插拔功能的实现要点PCIe 热插拔Hot-Plug在服务器和存储领域很常见Gen5 下热插拔的实现跟之前版本基本一致但对信号完整性和电源时序的要求更高。热插拔的核心是Present Detect和Power Controller。Present Detect 用来检测设备是否插入Power Controller 用来控制槽位电源。在 Gen5 下由于速率高插拔瞬间的电源波动和信号毛刺更容易导致链路异常所以电源的软启动和去抖设计要更精细。软件层面Linux 下可以用pciehp驱动管理热插拔。我一般会配置下面的参数# 查看热插拔槽位 lspci -vvv | grep -i slot # 手动触发热插拔扫描 echo 1 /sys/bus/pci/slots/slot_number/power注意Gen5 热插拔时建议先断开链路再断电避免带电插拔导致 SerDes 损坏。虽然规范支持带电插拔但实际风险还是有的。5.2 兼容性问题的常见来源Gen5 的兼容性问题主要来自几个方面一是不同厂商的 IP 实现差异二是不同版本的规范解读差异三是不同设备的均衡策略差异。我遇到过最典型的兼容性问题是一端用 Preset 均衡另一端用 FS/LF 均衡结果协商失败。后来查规范才发现Gen5 的均衡协商流程里如果两端都支持多种均衡方式会按优先级协商。如果优先级配置不一致就会卡住。解决兼容性问题的思路是先用最保守的配置比如都用 Preset P4确保链路能起来再逐步优化。如果两端设备来自不同厂商建议先查双方的 Errata 和应用笔记看看有没有已知的兼容性问题。5.3 系统级设计从 Root Complex 到 EndpointGen5 的系统级设计要考虑整个链路从 Root Complex通常是 CPU 或 PCH到 Endpoint加速卡、SSD、网卡等。中间可能经过 Switch、Retimer、Redriver 等器件。Retimer 和 Redriver 在 Gen5 下很常见因为通道损耗大需要它们来补偿。Retimer 会重新生成信号对协议透明Redriver 只是放大信号不处理协议。选择时要根据通道损耗和预算来定。我一般会在通道损耗超过 -20 dB 时考虑加 Retimer。Retimer 的选型要注意支持 Gen5、支持所需的 Lane 数、以及跟 Root Complex 和 Endpoint 的兼容性。6. 我个人在 Gen5 项目中的几点体会做 Gen5 项目这几年最大的感受是协议要读透但光读协议不够必须结合实测。规范里写的都是理想情况实际通道的损耗、噪声、温度漂移都会让链路行为偏离预期。另外Gen5 的调试工具很重要。我常用的工具包括示波器测眼图、误码仪测误码率、协议分析仪抓 TLP/DLLP、以及厂商提供的调试软件如 Xilinx 的 IBERT、Keysight 的 PCIe 分析仪。这些工具能帮你快速定位问题比盲猜高效得多。最后分享一个小技巧Gen5 链路调试时建议先把链路固定在 Gen4 或 Gen3确认协议层没问题再逐步提速到 Gen5。这样能把物理层问题和协议层问题分开排查起来更有条理。如果一上来就冲 Gen5出了问题很难判断是物理层还是协议层的原因。这个领域后续还可以往 Gen6 的 PAM4 编码、Flit Mode 全面铺开、以及 CXL over PCIe 等方向扩展等我有新的项目经验再跟大家分享。
返回列表