
Gen5的板子第一次上电在操作系统的PCIe枚举里能看到设备但LnkSta停在2.5GT/s——这个场景我印象太深了。你查电源、查参考时钟、查焊接全都没问题可链路就是不上高速。后来用协议分析仪抓了一遍Training Sequence才发现卡在Recovery.Equalization的Phase 1接收端要求的TX均衡系数发送端给不出来。那时候我意识到搞懂Phase 0到Phase 3这套均衡协商流程比对着原理图瞎猜问题要快得多。这篇文章就把PCIe Gen4/Gen5链路训练里的均衡协商完整拆开讲一遍LTSSM里它发生在哪、Phase 0到Phase 3每步到底在谈什么、实操中怎么观测和排查。适合正在调Gen4/Gen5板卡的硬件工程师、做FPGA上PCIe IP开发的同学以及被链路训练问题折磨的板级调试人员。1. 链路训练该看哪里LTSSM与均衡发生的位置1.1 LTSSM状态机链路谈判的全过程PCIe链路的建立和速率维护全靠物理层里一个叫LTSSMLink Training and Status State Machine的状态机。它负责的事情简单说就是一次“双边谈判”上电之后先确认对方在不在再确定链路多宽、多快最后进入正常收发数据的L0状态。整个状态机的主干状态包括Detect、Polling、Configuration、L0、Recovery、Loopback、Disabled、Hot Reset等。上电流程通常是Detect检测到对端阻抗变化确认有设备接入进入Polling阶段在最低速率2.5GT/s下通过TS1/TS2有序集交换信息再进入Configuration阶段确定链路宽度、通道映射、极性反转和通道反转全部确认无误后进入L0开始正常传TLP和DLLP。如果之后要改变速率、出现误码需要恢复或者链路需要重新训练状态机会从L0进入Recovery子状态。Recovery下面还有RcvrLock、Speed、Equalization、Configuration等子状态。速率切换到16GT/sGen4或32GT/sGen5时LTSSM必须在进入L0之前完成Recovery.Equalization这一步——也就是均衡协商。理解这个背景很重要均衡协商并不是一个独立的“训练流程”而是LTSSM走到Recovery或Configuration阶段后为了支持高速率而必须经历的物理层子状态。所以当你在调试时看到LTSSM在Recovery.Equalization里反复进出问题基本就锁定在信号质量或者均衡参数上。1.2 均衡为什么在Gen4/Gen5成了强制项Gen38GT/s其实就已经引入了均衡的概念但那时候信号速率还没那么极端均衡更像是一种可选优化。到了Gen4的16GT/s和Gen5的32GT/s情况完全变了。算一笔账Gen4一个UIUnit Interval即一个比特的时长是62.5psGen5直接砍半到31.25ps。理论上信号上升沿和下降沿的时间占UI的比例越来越大在FR4板材上Gen5基波16GHz处的插入损耗可以做到每英寸几dB甚至更高。信号从发送端走到接收端眼图基本是闭合的。接收端不能只靠自己的均衡器硬撑。CTLE和DFE能补偿一部分高频损耗但补偿越大、噪声放大越厉害而且接收端的动态范围有限。所以PCIe规范从Gen4开始把发送端均衡TX EQ变成了强制要求链路上每个lane的发送器都要根据接收端的反馈调节自己的预加重Preshoot、去加重De-emphasis和摆幅参数。但问题是每种PCB走线长度、板材、连接器的损耗特性都不一样没法用一套固定参数通吃。于是就有了均衡协商机制接收端根据实际看到的信号质量动态向发送端提出调整请求双方在Phase 0到Phase 3这四个阶段里来回试探最终收敛到一组能正常通信的参数。如果你做PCIe开发可以这样理解均衡协商的本质是发送端和接收端在“信号质量”这个问题上做一轮轮谈判。手机信号不好时你会走到窗边说话或者让对方大点声、慢点说——PCIe的均衡协商就是把这个过程自动化了。2. Phase 0到Phase 3均衡协商的四轮谈判2.1 Phase 0摸清底牌的Preset通告Phase 0是均衡协商的第一步目的很直接让接收端知道发送端当前用了什么参数建立一个协商起点。在这个阶段发送端会按照一个固定的预设参数Preset发送TS1训练序列。所谓Preset是PCIe规范里预定义的一组发送端均衡参数集合每个Preset对应不同的去加重、预加重和摆幅组合用于匹配不同损耗等级的信道。规范里定义了多个预设值比如P0到P10每一个都对应一组FSFull Swing全摆幅和LFLow Frequency低频参数。接收端会监听每个lane上的TS1解析出里面的均衡信息把发送端当前使用的Preset和FS/LF值记录下来同时初始化自己的接收端均衡检测逻辑。当所有lane都收到了足够多的TS1、完成了参数记录Phase 0就结束了。实操中的要点Phase 0相对简单很少出问题但它决定了后续协商的起点。如果发送端的默认Preset选择不合理接收端一开始就看到了一个“完全没法看”的信号后面Phase 1可能要好几个轮次的系数调整才能拉回来。另外Gen4和Gen5的Preset定义并不完全相同板卡和主机如果对Preset的解析不一致有时表现为Phase 0反复等待或者异常退出。2.2 Phase 1先把发送端调明白Phase 1是均衡协商的重头戏核心目标是让接收端“指挥”发送端把发送均衡参数调到可接受的范围。这个阶段接收端会根据自己测量的信号质量在TS1里向发送端发送系数请求。请求的对象是发送端三个关键均衡抽头前标Pre-cursor记为C-1、主标CursorC0、后标Post-cursorC1。接收端通过调节这三个抽头的相对幅度就能改变发送端的波形形状尽量补偿信道带来的码间干扰。举个例子如果接收端检测到高频分量衰减严重它会在TS1中请求发送端增加某个抽头的幅度百分比。协议规定了一套离散的调整步进发送端收到请求后下一次发送TS1时就会按新系数进行调整。接收端继续测量如果信号质量可以接受了就发一个“完成”标志给发送端Phase 1进入收尾。实际调试中最常见的问题就出在这里。接收端的系数请求是根据“当前信号不够好”触发的但如果发送端物理上已经无法再补偿比如电源余量不足、驱动能力到头了就会出现反复请求、系数无法收敛的情况。另一种情况是PCB损耗太严重接收端把所有系数都拉到极限还是不够最后只能宣告协商失败、触发降速。还有一个容易忽略的点不同lane的信号质量可能差异很大。虽然均衡协商是按lane独立进行的但最终链路速率是全局一致的。如果某一个lane始终无法收敛整个链路就会降速或者训练失败这就是为什么有些Gen5 x16插槽用了低速卡没问题插高速卡就出状况——某个lane拖了后腿。2.3 Phase 2接收端自适应打开Phase 1把发送端调好之后Phase 2轮到接收端自我优化了。这一阶段核心是让接收端的均衡器——CTLE连续时间线性均衡和DFE决策反馈均衡——根据实际信号自动收敛到最优配置。发送端在Phase 2会进入一种特殊的训练模式持续发送特定的训练序列这些序列专门用于接收端的自适应算法。接收端一边接收这些序列一边调整自己的CTLE增益曲线和DFE抽头系数目标是最大化眼高、眼宽并最小化误码率。DFE这块值得一提。DFE是一种非线性均衡器它能消除长尾的码间干扰但需要足够长的训练时间才能收敛。如果训练序列不合理或者信道环境过于恶劣DFE可能会收敛到局部最优而不是全局最优导致Phase 2耗时过长甚至超时。我在FPGA上调试PCIe IP时发现Phase 2的问题有时候藏在接收端的时钟恢复CDR上。32GT/s下一个UI只有31.25psCDR要从这么窄的信号窗口里恢复出采样时钟难度非常大。如果参考时钟的抖动超标、电源纹波大CDR锁相不稳接收端的均衡自适应算法就会跟着乱套表现为Phase 2里反复尝试DFE tap组合却始终找不到稳定解。2.4 Phase 3最终验收与进入L0Phase 3是整个均衡协商的验收环节目的很纯粹确认前面调出来的参数组合在真实工作条件下确实可靠。这时发送端会使用Phase 1里协商好的最终发射系数继续发TS1接收端也把RX均衡参数固定为Phase 2确定的最优值。双方用这套“谈好的参数”重新评估链路质量确认每个lane的信号质量满足协议要求。如果验收通过LTSSM会向L0状态迁移开始正常传输数据。如果验收不通过状态机不会一条路走到黑而是会重新尝试之前的Phase或者对目标速率进行降级比如从Gen5降到Gen4用更宽容的信号条件完成训练。很多人觉得Phase 3只是走个过场其实不然。Gen5时代很多“间歇性降速”问题都源于Phase 3验证时信号margin不够训练时能勉强通过但在实际数据流量下温度变化、电压波动、串扰这些因素一叠加信号质量就掉到了临界线以下触发错误恢复又回到Recovery状态重新训练。这就表现为链路速率忽高忽低。从我实际接触的案例看Phase 3暴露出的问题往往不是某一对参数没谈拢而是系统性的信号margin不足。这时候光靠调均衡参数是治标不治本要去查走线、过孔、连接器和板材损耗。3. 实操如何观测均衡协商是否正常3.1 从Linux配置空间读训练结果调板子第一步往往是在操作系统里看设备是否被正确枚举协商到了什么速率和宽度。Linux下最常用的就是lspci。先用lspci | grep -i pcie找到设备BDF号然后执行lspci -vvv -s [bus:dev.fn]。重点看LnkCap、LnkSta和DevSta这几项LnkCap设备本身支持的最大速率和最大宽度比如64GT/s就是Gen632GT/s是Gen516GT/s是Gen4。LnkSta当前实际协商到的速率和宽度。如果LnkCap是32GT/s但LnkSta只有8GT/s说明均衡协商没成功链路被降级了。DevSta和错误寄存器如果Correctable Error计数不断上涨说明链路虽然建立起来了但信号质量不好时不时在报错。除了lspci还可以直接读sysfs节点例如/sys/bus/pci/devices/0000:01:00.0/current_link_speed和negotiated_link_width脚本巡检时更方便。在UEFI环境下也可以用Shell里的pci命令扫设备看每个设备当前工作速率。很多平台的BIOS设置界面也会直接显示PCIe链路速率有些还会记录训练失败的日志。不过要提醒一句lspci只能看到“协商结果”看不到训练过程。如果链路协商到了Gen3而不是Gen5lspci能告诉你结果但不会告诉你卡在Phase几。想定位具体阶段得上协议分析仪。3.2 用协议分析仪抓TS1/TS2与EQ报文要真正看到Phase 0到Phase 3的现场协议分析仪是绕不开的工具。Keysight、Teledyne LeCroy等厂商都有支持Gen5的PCIe协议分析仪可以捕获物理层的有序集TS1/TS2、EIEOS并解码出均衡协商细节。抓包过程中的几个关键设置探测点尽量靠近被测设备端选在PCIe插槽或金手指附近用专用探棒连接。设置触发条件为Recovery.Equalization或“TS1 with EQ”这样能直接抓到协商过程而不必存下大量无关数据。抓包后重点看TS1里的均衡字段里面能看到Preset信息、系数请求对C-1、C0、C1的调整请求和完成标志。实际操作中我习惯先抓一次完整的上电训练过程。正常流程应该是Detect→Polling→Configuration或Recovery→Equalization→L0每个Phase的TS1报文会按顺序出现。如果在Phase 1停了很久、一直在重复相同的系数请求基本就能判断是TX均衡无法满足接收端需求如果在Phase 2反复超时重点怀疑接收端的CDR、DFE或者供电噪声。协议分析仪唯一的门槛是价格和操作难度并不是每个团队都有。如果一时没有也可以退而求其次在FPGA里通过调试探针读取PCIe硬核内部寄存器很多IP会暴露LTSSM当前状态的观测信号。比如Xilinx的XDMA IP调试时可以直接看到当前处于哪个LTSSM子状态判断有没有进入Equalization、卡在哪个Phase。3.3 眼图测试与SI验证均衡协商最终解决的是信号完整性问题如果协商成功但实际传输质量差眼图测试能帮你看到真实好坏。Gen5链路测试需要用足够带宽的示波器建议至少33GHz以上否则测出来的眼图会有明显失真。测试时把探头放在接收端用示波器对测到的信号做CTLE仿真处理模拟接收端均衡后的眼图效果。重点看眼高、眼宽、抖动这几个指标。Gen5的眼图模板比Gen4严格很多很多在Gen4下“还行”的信号到Gen5就是不够格。如果眼图结果不理想可以从几个方向下手看发送端均衡参数是否合理。如果波形里的预加重/去加重不明显考虑在BIOS或寄存器里手动调整Preset。看信道损耗预算。计算发送端到接收端整个链路的插入损耗包括PCB走线、过孔、连接器、插卡金手指看是否在Gen5规定的预算内。看接收端均衡配置。有些设备的RX均衡是固定的不会自动完全适配这时需要手动配置CTLE曲线或者DFE tap值。做压力测试的话BERT误码仪可以配合使用打PRBS31码型长时间跑误码率。如果误码率高于1E-12量级实际传输时大概率会触发链路重训。4. 常见问题与排查技巧实录4.1 训练失败时设备去哪了这是最让人头大的问题之一BIOS里看不到设备Linux下lspci也扫不到设备就像不存在一样。出现这种情况先不要急着怀疑均衡协商先把基础问题排除掉。最快的判断方法是在BIOS里把PCIe速率固定到Gen1。如果Gen1能正常枚举说明设备本身没坏问题出在高速训练环节均衡协商是重点怀疑对象。如果Gen1也枚举不到大概率是供电、复位、参考时钟这些基础条件有问题。供电和复位的坑我在Gen5板卡上踩过多次。有些设备对PERST的时序要求严格PWRGD和PERST的先后顺序、保持时间不够就会导致设备无法完成初始化。另外Gen5卡的工作电流比Gen3/Gen4的卡更大插槽供电不足时会出现刚上电正常、一进入高速训练就掉电的情况表现也是设备直接消失。4.2 协商不到Gen5只能降速怎么办“BIOS里设了Auto实际跑在Gen3”——这种情况太常见了。均衡协商失败后主机BIOS通常会自动降速重训沿Gen5→Gen4→Gen3的顺序往下试直到链路能稳定建立。所以看到LnkSta降到了Gen3或Gen4不等于设备不支持更高速度而是说明高速协商没有通过。按以下顺序排查先把PCIe速率固定到Gen4看能否稳定运行。如果Gen4稳定说明基础信号链路没有致命问题只是Gen5的margin不够。检查主板或设备BIOS里的均衡Preset设置手动尝试不同的Preset组合有时能直接改善Gen5协商成功率。确认参考时钟配置。Gen5对SSC展频时钟和参考时钟噪声的容忍度更低如果使用分离参考时钟SRIS两个时钟源的频率偏差必须满足规范否则均衡协商容易失败。尝试改成Common Clock模式往往能解决问题。检查PCB走线和连接器。Gen5链路对走线长度、过孔数量、连接器损耗非常敏感如果走线过长或过孔残桩过多必须考虑加Retimer或Redriver做信号整形。我之前遇到一个案例Gen5 NVMe盘在A主板上跑Gen5没问题换到B主板上只能跑Gen3。最后查到原因是B主板的参考时钟走线过长时钟信号抖动偏大导致Gen5的CDR阶段一直无法锁定。这是典型的时钟问题引发的均衡失败和PCB走线本身没关系。4.3 EQ超时与反复重训的真实案例均衡协商如果迟迟无法完成LTSSM会触发超时机制。超时后的行为取决于平台实现可能是降速重训也可能是直接宣告链路失败。有个印象很深的案例一台服务器Gen5 NVMe盘插入特定插槽后系统间歇性报错设备不断消失又出现伴随着速率跳变。抓日志发现LTSSM在Recovery.Equalization里频繁进出且每次都在Phase 1超时。把同一块盘换到另一个走线更短的插槽后问题彻底消失。这个案例的教训是Phase 1反复超时表面看是发送端无法满足接收端的系数请求实际根因往往是信道损耗超过了接收端均衡能力的补偿上限。这时候不要在均衡参数上死磕回头检查硬件走线、过孔和板材才是正确方向。另一个案例跟DFE收敛有关某Gen4设备在32GT/s下该设备支持Gen5但当前配置Gen4偶尔出现CRC错误速率会降到Gen1再重训回去。升级固件后问题消失原因是新固件调整了Phase 2阶段的DFE训练序列长度让接收端有更充裕的时间收敛。这个案例告诉我们有些设备固件里的均衡策略是可以改的遇到反复问题不妨查查设备厂商有没有更新固件。4.4 工具与流程速查调试PCIe均衡问题时我一般会按下面的工具组合推进排查阶段工具/方法可获取的信息快速定性lspci -vvv、UEFI Shell pci命令当前速率、宽度、错误计数训练过程分析协议分析仪TS1/TS2的EQ字段、Phase流转、超时位置PHY状态观测FPGA调试探针、IP内部寄存器LTSSM子状态、EQ Phase信号质量高带宽示波器33GHz眼图、抖动、幅度、预加重波形误码验证BERT误码仪PRBS误码率、压力测试基础条件万用表、示波器供电电压、复位时序、参考时钟波形这套组合下来大多数均衡协商问题都能定位到具体环节。最怕的就是上来就拿着示波器到处量没有先确认训练卡在哪个Phase——方向错了后面的功夫都白费。我个人在实际操作中最深的体会是解决均衡协商问题先看流程、再看参数、最后才动硬件。先搞清楚卡在Phase几、双方交换了什么请求能省下大量盲猜的时间。另一个实用建议是Gen5板卡在第一版PCB评审时就按规范算好损耗预算给均衡留足margin别等样品焊好了再跟Phase 0到Phase 3斗智斗勇。