
最近调一块FPGA板卡卡在PHY芯片的SGMII链路上整整一个周末。现象很典型PHY的link灯亮着但FPGA侧的状态机就是死活进不了对齐状态偶尔能跑起来一加压就狂报错。最后发现不是线没接对也不是代码写错而是我对SGMII这条链路的“协同设计”理解不够——FPGA和PHY芯片之间不是简单的“把总线接上”它是一个包含编码、自协商、时钟恢复、复位时序、PCB信号完整性在内的一整套系统。这篇文章把我从协议、硬件设计到调试链路踩过的坑串起来聊一遍也适合正在做千兆网口、FPGA高速接口设计的同行参考。1. 为什么SGMII能成为FPGA与PHY协同设计的“默认接口”三类接口的取舍逻辑1.1 GMII/RGMII/SGMII的直观对比FPGA和PHY芯片之间的数据通路历史上经历过GMII、RGMII、SGMII三种主流形态。它们的核心区别可以浓缩成一张表接口信号线数量数据位宽时钟速率对齐难度适用场景GMII22根以上8bit125MHz/25MHz/2.5MHz中。并行总线等长要求高老一代设计引脚消耗严重RGMII12根4bit DDR125MHz/25MHz/2.5MHz高。DDR上下沿采样skew控制苛刻主流低成本方案SGMII4根收发各一对差分串行1.25Gbps低。从数据流中恢复时钟中高端FPGA板卡、高速背板RGMII看起来引脚少但实际工程里非常不省心。数据在时钟的双沿采样PCB上要求数据线和时钟线做严格的等长处理普通FR4板材、走线不换层时还好一旦经过连接器、过孔、背板时序窗口会被严重压缩。很多做ARM/MCU的硬件工程师在RGMII上吃过亏PL端FPGA和PHY芯片隔得远一点信号跑起来就是各种偶发错误。SGMII把并行总线变成了两对差分串行线数据通过8B/10B编码内嵌时钟接收端用CDR恢复时钟。它对PCB的等长要求大幅降低也不需要像RGMII那样处理DDR采样的建立保持时间。FPGA和PHY之间哪怕距离稍远只要差分阻抗控制好走线稍微绕一下都没问题。1.2 “少引脚、多麻烦”的交换什么情况下值得用SGMIISGMII不是没有代价。它把原先RGMII在PCB上的时序压力搬到了SerDes、编码、自协商这些IP和行为模型上。没有高速收发器的FPGA很难直接支持SGMII就算FPGA有GTX/GTH也需要正确配置PCS/PMA处理自协商状态机。所以什么情况下值得上SGMII我自己的判断标准有三条板上有多个千兆PHY引脚资源紧张BGA扇出困难。设计对PCB面积、层数敏感希望减少并行信号线。FPGA与PHY的物理距离较远或者中间要经过背板、连接器。反过来如果只是做一个功能验证板PHY就近放在FPGA旁边引脚又充裕RGMII反而更直接调试也简单。很多PHY芯片本身同时支持RGMII和SGMII可以在一个板卡上把两种接口都留出来方便兼容不同方案。我做过的项目中FPGA侧同时接RGMII和SGMII两种PHY的前端板也不少见逻辑上通过MDIO配置PHY的工作模式即可。2. 链路“握手”的底层逻辑8B/10B、PCS/PMA与自协商机制2.1 SGMII链路是怎么“握”起来的“握手”这个词听起来抽象实际就是收发两端完成同步、协商速率、进入数据状态的过程。SGMII链路建立大致是这么一条路径FPGA和PHY上电各自时钟稳定。FPGA侧PCS完成复位GT收发器锁定参考时钟CDR开始工作。PHY上电后在SGMII侧持续发送配置有序集Configuration ordered sets里面包含自己支持的速率能力。FPGA侧PCS识别到对方的配置码流回复自己的配置码流双方完成自协商。自协商完成后链路进入Data mode正常收发以太网帧。SGMII的自协商是基于8B/10B编码中的K码实现的。8B/10B把8bit数据映射成10bit多出来的码元一部分用于控制字符也就是K码。链路对齐靠/C/配置, /I/idle, /K/comma这些码流来完成。FPGA内部的PCS本质上就是一个状态机先通过comma对齐字节边界再检测配置码流然后交换速率信息最后进入数据收发。2.2 自协商的两个层面PHY对PHY与PHY对MAC很多人在调试SGMII时糊涂是因为没分清楚两个自协商PHY芯片对外MDI侧比如RJ45网口和交换机/PC之间的自协商属于介质侧。PHY芯片对内SGMII侧和FPGA MAC之间的自协商属于MAC接口侧。这两个层面互相独立但状态又互相影响。PHY的SGMII侧如果配置成强制1000MFPGA侧的PCS也必须匹配成强制模式不能一边强制一边自协商否则状态机会一直跳。另外SGMII自协商需要传输速率能力信息它和1000BASE-X的自协商格式有区别PHY的寄存器/strap没设对把SGMII误配成1000BASE-XFPGA侧就会收到一堆无法识别的configuration码流链路自然起不来。2.3 时钟恢复为什么参考时钟精度和抖动都很重要SGMII的串行速率是1.25Gbps千兆有效数据8B/10B编码开销。接收端的CDR要从数据边沿中恢复位时钟参考时钟在这里只提供一个粗略的频率基准CDR再通过PLL锁定到数据流上。参考时钟的ppm精度要求不需要像并行总线那么苛刻工程上一般是±50ppm以内的晶体就可以但抖动要尽量小。我一个真实教训是FPGA的GTREFCLK用了板上某颗共享时钟上面还挂了别的器件结果抖动偏大SGMII链路频繁出现误码用IBERT看眼图明显发虚后来换到独立低抖动时钟输出才稳定。3. FPGA侧硬件设计的关键点SerDes选型、参考时钟与复位时序3.1 用GTX/GTH还是普通LVDS IOFPGA侧实现SGMII最可靠的方式是使用高速收发器也就是Xilinx的GTX/GTH/GTYP、Intel的Transceiver、高云/安路的SerDes。使用厂商提供的SGMII IP内部会把8B/10B、自协商状态机、时钟恢复都吃完用户侧得到的是一个类似GMII/AXI-Stream的接口省掉大量编码工作。不建议用普通LVDS IO去拼SGMII。虽然1.25Gbps的比特率在高端FPGA的LVDS IO上可能勉强够跑但CDR模块通常不在普通IO里需要在逻辑里自己实现数据恢复时钟同步和抖动容限都很难保证。即便用SelectIO里的ISERDES/OSERDES硬核做出来的链路稳定性也远不如真正的GT通道。用GT通道时的关注点主要是三个GT所在的Quad与PHY芯片的物理布局尽量让差分走线短、直避免换层。GT参考时钟必须接在专用时钟引脚上不能随便接普通BANK。GT的复位顺序和复位完成信号要和PHY芯片的复位输出/状态引脚做握手。3.2 参考时钟设计同源低抖动是稳定性的宝藏SGMII的参考时钟在FPGA侧是GTREFCLK在PHY侧是PHY的125MHz/25MHz时钟。我推荐把两边的参考时钟做成同源让FPGA和PHY的PLL基准来自同一颗时钟芯片的不同输出。同源有什么好处CDR本质上是在比较两个PLL之间的小频率差如果两边参考时钟来自不同晶体频率都标称25MHz但实际一个25.001MHz一个24.999MHz虽然都在误差范围内但链路长期运行会出现周期性相位漂移表现为偶发误码。同源时钟把这个问题直接消灭在源头。时钟芯片选择上我用过硅谷的Si5338、TI的LMK系列普通项目也可以用一颗时钟Buffer从同一个晶振分出两路。关键是保证分配到FPGA GTREFCLK和PHY的时钟抖动在要求范围内。3.3 复位时序不是拉一下低就完事SGMII调试里“复位”这个看似简单的动作反而是重灾区。GT收发器的复位包括电源稳定后的上电复位。DRP配置完成后的初始化复位。TX/RX各自独立的复位。状态机级联复位比如MAC重置后GT也要跟着重置。Xilinx官方推荐GT复位要用类似gth_rst_gen的流程复位信号需要持续一定时间而且要等TX/RX的resetdone拉起来再释放用户逻辑。很多人只做一个全局复位导致GT初始化没完成就去跑SGMII自协商状态机卡死。PHY侧的复位同样要注意。PHY的复位引脚低有效复位释放后上电初始化需要时间短则几毫秒长则几十毫秒。稳妥做法是用FPGA的一个GPIO控制PHY复位FPGA上电后延时几百毫秒再释放PHY复位然后通过MDIO轮询PHY的ID寄存器读到正确ID后才认为PHY就绪再启动SGMII链路。3.4 IP配置与用户逻辑的边界Xilinx的“1G/2.5G Ethernet PCS/PMA or SGMII IP”是使用最广泛的方案。配置IP时有几个容易忽略的地方接口类型选择SGMII而不是1000BASE-X。数据路径宽度16bit和8bit对应的内部时钟不同要和前端FIFO匹配。MDIO接口要不要使能如果PHY侧SGMII自协商由IP的PCS内部完成MDIO可以留着做管理用。选择“外部PHY”还是“内部PMA”如果只用GT原始收发再自己实现PCS不要勾选内部PMA配置逻辑完全不同。用户逻辑侧的常见做法是把SGMII IP封装成一个MAC接口再接上TX/RX FIFO和DMA模块。调试时先通过IP的状态寄存器观察链路是否对齐再跑数据。4. PHY芯片与PCB协同设计模式配置、AC耦合电容与高速差分走线4.1 PHY的模式配置strap引脚和MDIO寄存器各管什么PHY芯片不像FPGA它没有复杂的软件初始化上电瞬间通过硬件引脚的电平状态决定工作模式这些引脚叫strap/config引脚。常见配置包括工作接口模式SGMII还是RGMII。自协商开关AN enable/disable。速率1000M/100M/10M。Master/Slave时钟关系。MDIO地址。strap引脚在上电或者复位释放时被锁存所以PHY的复位信号最好由FPGA控制这样可以通过控制释放时间来配合整个板卡的初始化流程。如果PHY复位不干净或者strap引脚上拉了错误电平PHY进入预期之外的模式SGMII链路起不来很难排查。MDIO寄存器用来确认PHY状态。调试时第一步永远是读PHY ID寄存器确认管理通道通第二步读AN状态寄存器和Link状态寄存器确认PHY本身是否认为链路OK。如果MDIO都读不对先查MDIO引脚的上拉电阻、时序、时钟频率。4.2 AC耦合电容位置、容量和雷区SGMII是串行交流耦合链路要在差分信号路径上串接AC耦合电容。常见的做法是0.1uF也有用0.01uF的。电容位置没有严格要求要么靠近发送端、要么靠近接收端但只能放一端两边都放会让链路电容值翻倍影响低频分量。我的习惯是放在接收端附近也就是PHY的RX差分输入侧放一对0.1uFFPGA的RX差分输入侧放一对0.1uF。这样发射端过来的直流偏置不会影响接收端也能统一不同PHY板卡的接法。注意AC耦合电容的封装选择0603在大多数情况下够用但如果走线过密0402也可以关键是寄生电容和耐压满足要求。还有一点AC耦合电容下面尽量不要铺连续的电源平面要挖掉一些地减少焊盘寄生引起的阻抗突变。4.3 高速差分走线的工程要求SGMII两对差分线的PCB布线要求比RGMII宽松很多但也不是随便走都行。基本要求差分阻抗控制在100Ω±10%。对内等长控制在5mil以内有这个余量就够了。TX和RX两组对之间尽量拉开距离避免串扰。走线远离高速时钟线、电源开关节点、以及其他SerDes通道。换层时差分对旁要有回流地孔避免参考平面断裂。如果FPGA和PHY放在同一块板上走线长度一般不会超过2-3英寸这对SGMII来说非常轻松。但如果SGMII要经过背板连接器就必须更严谨地模拟链路比如连接器厂商提供的IBIS模型做仿真。4.4 电源和去耦容易被忽略的隐性故障源PHY芯片供电一般有1.0V内核电压、1.8V/2.5V/3.3V IO电压这些电源管脚如果去耦电容不足会在突发数据时产生电压跌落导致误码。我的经验是PHY的每个电源管脚都放一个0.1uF高频去耦电容然后每个电压域再放几个1uF和10uF的大电容布局时尽量靠近PHY电源引脚。FPGA侧GT的电源同样要关注QOR、VMGTAVCC这些专用电源如果纹波偏大GT通道的抖动特性就会恶化间接导致SGMII误码。用频谱仪或示波器测一下电源噪声如果有尖峰优先处理开关电源的反馈环路和LC滤波参数。5. 握手失败的现场排障从link灯不亮到偶发误码的完整排查链路5.1 链路起不来的排查顺序SGMII起不来故障现象分两类完全拉不起链路或者能link但不稳定。完全拉不起来的排查顺序我建议按这个流程来第一步读PHY ID。用ILA抓MDIO时序或者写一个小状态机通过MDIO读PHY的寄存器2和3。如果读到ID说明PHY管理通道正常。如果读不到查MDIO引脚、上拉、PHY复位。第二步读PHY的AN状态寄存器。确认PHY的SGMII侧是处于自协商中还是协商完成。如果PHY侧一直显示协商失败查strap配置是否正确尤其是SGMII模式和速率配置。第三步看FPGA侧PCS状态。Xilinx SGMII IP输出中有status信号包含链路同步sync_status、对齐状态等。如果FPGA侧一直没有sync用IBERT测试GT通道是否健康。第四步检查AC耦合电容。用示波器量差分引脚看波形幅度是否正常。SGMII差分红蓝幅度一般在几百mV到1.2V之间如果幅度异常检查电容有没有焊反、是否贴错容值、接收端端接电阻是否匹配。第五步检查TX/RX是否接反。SGMII一对是TX差分对、一对是RX差分对如果FPGA的TX接到了PHY的TX交叉到对端设备还说得通但FPGA和PHY直接对接时必须是TX接RX、RX接TX。很多人第一次画板会在这翻车。5.2 通了但频繁报错时钟、双工与EEE是三大元凶链路能link但数据报错优先级最高的怀疑对象是参考时钟。用示波器看FPGA GTREFCLK和PHY侧时钟的实际波形确认频率和抖动。如果手头没有高带宽示波器用IBERT看误码率也是一个办法。第二个高频问题点是双工模式不匹配。FPGA侧IP强制全双工PHY侧如果因为strap或寄存器被设成半双工链路虽然能建立但数据交互会撞包表现为CRC错误急剧增多。检查PHY的AN能力寄存器把双工设置对齐。第三个点容易忽略EEE节能以太网。现在很多PHY默认支持EEE如果FPGA侧MAC不支持EEE收到LPI信号会误判为链路故障导致周期性断链。在PHY寄存器里关掉EEE或者保证FPGA侧也开启EEE支持。5.3 一个能复现的实战案例复盘我遇到的典型案例是FPGA和88E1512之间的SGMII链路上电后大约30秒内工作正常之后CRC错误飙升再往后直接断链。一开始怀疑PHY芯片过热后来用IBERT测GT通道短时间内无错误排除了FPGA侧问题。再用MDIO反复读PHY的SGMII状态寄存器发现SGMII的自协商状态会周期性重新启动而且PHY的EEE状态寄存器被触发。最后定位是PHY芯片的EEE功能默认开启在空闲时进入低功耗状态而FPGA侧的PCS/MAC没有正确回应LPI导致PHY认为对端不兼容而重新协商。解决办法是在PHY寄存器中关闭EEE或者把FPGA侧的MAC换成支持EEE的版本。这个问题和PCB无关纯粹是PHY配置和MAC能力不对齐导致的。5.4 调试工具清单与实用技巧我调试SGMII的常用工具集ILA集成逻辑分析仪抓FPGA内部的状态信号、MDIO读写时序、PCS status寄存器是最常用的手段。IBERTXilinx自带的比特误码率测试工具在Vivado里可以快速搭建GT环路测试验证通道的信号完整性和时钟质量。示波器至少500MHz带宽能看SGMII差分对波形和时钟。没有真差分探头时用两个普通探头做数学减法也能粗略看差分眼图。热风枪/酒精棉签遇到温度相关的偶发故障先局部加热再用棉签蘸酒精快速降温缩小故障范围。调试时一个实用小技巧先使用PHY的Loopback功能把PHY侧接收到的数据环回看FPGA侧是否正常收到再用GT近端PMA Loopback测试逐段隔离问题。这个思路适用于任意高速接口调试SGMII也不例外。在几十个项目里攒下的经验是SGMII链路的稳定性七成取决于硬件设计阶段对参考时钟、AC耦合电容和差分走线的把控三成取决于FPGA侧对复位时序和自协商状态机的敬畏。不要以为厂商IP现成就可以随便接一定要把GT复位和PHY复位的时序衔接想清楚很多偶发问题都是复位时序不满足导致的。我自己现在画SGMII相关板卡时有个固定习惯FPGA和PHY的时钟必须同源PHY复位必须由FPGA控制MDIO上拉电阻留在板子上方便调试SGMII差分对预留0欧姆电阻位以应对不同PHY的极性要求。这几点看起来不起眼实际排障时能省下好几天时间。