FPGA实战:SGMII接口从底层机制到双平台调试全攻略

发布时间:2026/10/6 11:44:57
FPGA实战:SGMII接口从底层机制到双平台调试全攻略 做千兆以太网板卡的时候我第一次在FPGA上碰SGMII接口一开始的想法特别天真SGMII嘛无非就是把GMII那种十几根的并行线换成两对差分线数据串行化过去就行。结果板子回来后link一直起不来调了整整两天最后翻到PHY手册里的自协商时序和SGMII的控制字格式才恍然大悟——这个接口的复杂程度比“串行化”三个字要深得多。后面结合Xilinx和Intel两个平台分别做了几版方案踩过不少坑也总结出一套可以照搬的配置流程。这篇文章就把SGMII接口的底层机制、两个主流FPGA平台的IP配置、硬件设计要点和调试排查链路完整梳理一遍适合正在接千兆PHY、准备做以太网接口或者想从RGMII/1000BASE-X切到SGMII的开发者参考。1. 为什么千兆以太网场景绕不开SGMII1.1 从GMII到SGMII减少引脚但不牺牲三速能力早年的FPGA接千兆PHY最直接的方式是GMII接口。GMII在千兆模式下需要24根信号线数据位宽8bit发送和接收各8根再加上TX_CLK、RX_CLK、TX_EN、TX_ER、RX_DV、RX_ER等控制信号布线上非常占地方。等到了百兆和十兆模式时钟还要跟着速率切换MAC侧逻辑要处理三套时钟频率跨时钟域的地方也多稍不注意就出亚稳态问题。SGMII把MAC和PHY之间的数据通路压缩成了两对差分线一对发送、一对接收外加MDC/MDIO管理总线。引脚从二十几根降到个位数PCB走线和FPGA引脚压力都小了很多。更关键的是SGMII可以在不改变PHY链路速率的情况下完成10M/100M/1000M三速自适应。1.2 SGMII的信号定义与物理连接SGMII虽然是串行接口但它不是传统的UART那种异步串口而是带时钟恢复的源同步串行接口。标准SGMII信号定义如下信号方向说明TX_P / TX_NMAC到PHY发送差分对CML/LVDS电平AC耦合RX_P / RX_NPHY到MAC接收差分对CML/LVDS电平AC耦合MDC / MDIO双向/时钟管理接口用于读写PHY寄存器REF_CLKPHY到MAC125MHz参考时钟可选取决于PHY和FPGA方案在多数项目里FPGA内部的SGMII IP用GT高速收发器实现物理层收发外部PHY比如常见的千兆PHY芯片则把SGMII串行信号转换成双绞线上的百兆/千兆信号。FPGA和PHY之间就是两对差分线板上一般串0.1uF的AC耦合电容。1.3 与1000BASE-X、RGMII的本质区别很多人会把SGMII和1000BASE-X搞混。这两种接口在物理层非常相似都是1.25Gbps线速率的8B/10B编码差分信号但它们的协议目的完全不同对比项SGMII1000BASE-XRGMII应用位置MAC与PHY之间PHY与PHY之间光模块/网线MAC与PHY之间数据编码8B/10B8B/10B无编码4bit DDR线速率1.25Gbps固定1.25Gbps固定125MHz DDR引脚数4根差分MDIO4根差分12根单端自协商内容传输速率/双工到MAC远端PHY能力无RGMII是一根时钟DDR传输4bit的双沿接口省引脚但是它的时钟是125MHz/25MHz/2.5MHz动态切换的FPGA时序约束要跟着速率变。SGMII的好处是物理线速率始终保持1.25Gbps速率切换只在协议层做FPGA侧的时钟相对稳定这对后端实现友好得多。实际项目中我一般这样选型如果PHY芯片只提供RGMII口且板子引脚紧张那就用RGMII如果PHY和FPGA之间距离比较远或者需要走背板SGMII的抗干扰能力和引脚优势就非常明显。现在多数主流千兆PHY同时提供RGMII和SGMII两种MAC侧接口给FPGA开发者留了选择空间。2. SGMII的底层机制8B/10B、自协商与链路建立的完整逻辑2.1 8B/10B编码与线速率换算SGMII的数据通路核心是8B/10B编码。8B/10B把8bit数据扩展成10bit码字以保证直流平衡同时提供足够的跳变边沿给接收端的CDR时钟恢复使用。换算关系很简单千兆以太网有效数据速率是1Gbps对应125MB/s1Gbps除以8bit。经过8B/10B编码后每个字节变成10bit速率就变成125MB/s × 10bit 1.25Gbps所以SGMII的物理线速率固定是1.25Gbps。这里有个容易误解的点SGMII在百兆和十兆模式下线速率依然是1.25Gbps不是像并行GMII那样把时钟降到25MHz或2.5MHz。百兆时MAC把每个字节重复发10次十兆时重复100次。接收端解码后自己判断速率。这个设计的巧妙之处在于PHY和FPGA双方的物理层收发器不用动态改变速率只需要在做数据重复/抽样时切换逻辑大大降低了时钟切换带来的复杂度。2.2 SGMII自协商如何传递10/100/1000速率SGMII的自协商机制和1000BASE-X类似都是传送16bit配置字但内容含义不同。SGMII的自协商主要发生在MAC侧IP和PHY之间用来把PHY从远端链路协商到的速度/双工状态传递给MAC侧同时让MAC和PHY双方确认物理链路已经就绪。SGMII配置字的关键位包括速度位、全双工位、ACK位以及链路状态位。当PHY通过MDIO读到远端协商结果后在SGMII链路上周期性地发送配置字FPGA侧PCS解析出速度和双工信息然后把MAC侧的接口切到对应模式。我调试时发现一个常见坑有些FPGA的SGMII IP默认不启用自协商或者要求外部通过MDIO寄存器触发自协商。如果IP配置成强制千兆全双工FPGA侧不看配置字但PHY侧还在等自协商两边永远对不上。所以无论用Xilinx还是Intel的IP先明确SGMII模式是自动协商还是强制模式再决定PHY侧寄存器的配置这是link up的第一步。2.3 时钟恢复与链路建立的正常时序SGMII接收端从串行数据流中恢复出时钟。FPGA内部GT收发器的工作原理是本地PLL产生参考时钟CDR电路基于参考时钟跟踪输入数据边沿从而恢复出接收时钟和数据。链路建立的顺序一般是GT上电初始化 - 参考时钟稳定 - 复位释放 - CDR锁定 - 8B/10B解码器找到K码对齐 - PCS状态机进入同步状态 - 自协商完成 - link up。实际调试时我会按顺序观察几个信号而不是一上来就看link statusGT的TX/RX reset done是否拉高GT的rx byte is aligned是否有效PCS的sync status是否拉高自协商状态机的complete标志是否置位。如果reset done正常但rx byte is aligned始终不拉高基本可以断定是参考时钟异常、线速率配置错误或者物理链路不通如果对齐正常但自协商不完成多半是配置字或者PHY侧的寄存器问题。3. Xilinx平台从IP选型到GMII用户侧打通3.1 选IP与配置参数Xilinx实现SGMII时7系列及之后器件一般用Vivado里的“1G/2.5G Ethernet PCS/PMA or SGMII”这个IP核。它内部集成了GT收发器适配、8B/10B编解码、自协商状态机、GMII/MII接口转换等功能算是一条龙方案。IP配置界面有几个关键参数直接影响后续使用配置项推荐值说明Physical InterfaceSGMII选择SGMII模式而不是1000BASE-XLine Rate1.25G对应千兆以太网Reference Clock125MHzGT参考时钟频率SGMII必须用125MHz10/100Mbps Support勾选需要三速自适应时打开MDIO Interface开启用于读取PHY状态和配置Shared Logic根据工程选择多路SGMII可以共享GT common这里有个细节IP的“Shared Logic”选项决定了参考时钟和GT common是放在IP内部还是外部多路SGMII共用一个GT参考时钟时一般把GT common提到外部否则每路IP都例化一个参考时钟输入会占用太多引脚。3.2 时钟、复位与GT参考时钟设计SGMII对参考时钟的质量要求比较高抖动过大直接导致CDR无法锁定。参考时钟的来源有三种本地125MHz有源晶振、PHY芯片输出的125MHz时钟、FPGA内部PLL基于其他频率分频出的125MHz。我建议优先用前两种。FPGA内部PLL分频虽然方便但是GT参考时钟从PL侧导入要经过全局时钟网络路径上的抖动比专用时钟引脚差。7系列器件的GTREFCLK引脚是专用输入直接引到GT参考时钟缓冲区效果最好。XDC约束参考时钟示例create_clock -name sgmii_refclk -period 8.000 [get_ports SGMII_REFCLK_p] set_property PACKAGE_PIN AH12 [get_ports SGMII_REFCLK_p] set_property PACKAGE_PIN AH11 [get_ports SGMII_REFCLK_n] set_property IOSTANDARD LVDS [get_ports SGMII_REFCLK_p] set_property IOSTANDARD LVDS [get_ports SGMII_REFCLK_n]复位方面SGMII IP通常有独立的复位输入。GT收发器初始化需要比较长的复位序列复位抖动或者释放太早会直接导致CDR锁定失败。我的做法是把异步复位信号先经过一级同步器处理再进入IP的复位输入避免复位释放沿和时钟沿竞争产生亚稳态。3.3 用户侧GMII接口和数据通路示例IP配置完成后用户侧看到的是GMII接口。在千兆模式下发送时钟GB_TX_CLK是125MHz发送数据在时钟上升沿采样百兆模式下时钟会切到25MHz不同版本IP实现有差异务必以你用的IP手册为准。下面是IP例化的关键连接片段example_1g2_5g_eth_pcs_pma u_sgmii ( .gt_rxp_in0 (SGMII_RX_P), .gt_rxn_in0 (SGMII_RX_N), .gt_txp_out0 (SGMII_TX_P), .gt_txn_out0 (SGMII_TX_N), .refclk0 (SGMII_REFCLK), .gmii_txd (gmii_txd), .gmii_tx_en (gmii_tx_en), .gmii_tx_er (gmii_tx_er), .gmii_tx_clk (gmii_tx_clk), .gmii_rxd (gmii_rxd), .gmii_rx_dv (gmii_rx_dv), .gmii_rx_er (gmii_rx_er), .gmii_rx_clk (gmii_rx_clk), .mdio (mdio), .mdc (mdc), .reset (reset), .gt_reset (gt_reset), .status_vector (status_vector), .reset_done (reset_done) );用户逻辑要特别注意mac侧gmii_tx_clk和gmii_rx_clk的方向和频率由IP决定。如果你的MAC逻辑用了异步FIFO跨时钟域要保证FIFO两侧的时钟域声明正确避免出现CDC路径未约束导致后仿真或上板偶发错包。3.4 Xilinx平台自协商配置Xilinx这个IP在SGMII模式下可以通过配置参数选择内部是否启用SGMII自协商。在实际工程里我一般开启自协商同时把MDIO接口引出来由FPGA作为MDIO master去读PHY的寄存器0控制寄存器和寄存器1状态寄存器确认PHY侧的link状态。如果PHY已经通过硬件上下拉强制成千兆全双工FPGA侧也可以在IP配置里把SGMII自协商关掉直接按1000M全双工收发。两种方式都能用但要注意匹配PHY是强制FPGA就必须强制PHY是自协商FPGA就必须自协商。不能一边等协商一边强制发数据否则状态机永远收敛不了。4. Intel平台TSE SGMII的配置路径与时钟方案4.1 Intel平台SGMII相关IPIntel FPGA原Altera实现SGMII的方式比Xilinx要多样一些看具体器件型号和项目需求。老一点的Cyclone IV/V、Arria II时代常用的是“Triple Speed Ethernet MegaCore Function”TSE新一代支持硬核SGMII的器件上也可以用“Low Latency Ethernet 1G MAC”配合SGMII PCS来实现。TSE这个IP集成了10M/100M/1000M三速MAC并且可以选择内部集成SGMII PCS这样MAC和SGMII物理编码层就打包在一起用户侧直接面对Avalon-ST接口比较省事。如果你的项目还需要支持2.5G那要换用Low Latency Ethernet系列IP配置思路会有差异。4.2 Quartus配置流程和关键参数在Quartus里新建工程后从IP Catalog搜索“Triple Speed Ethernet”打开配置界面。需要关注的几个页面项配置项推荐值说明PHY interfaceSGMII PCS让TSE内置SGMII物理编解码Data rate10/100/1000 Mbps开启三速自适应SGMII auto-negotiation开启与PHY协商速度MAC interfaceAvalon-ST用户侧建议用Avalon-ST时序约束简单Enable MDIO开启负责配置外部PHYTSE的SGMII PCS模式对时钟要求比较明确需要为PCS提供125MHz参考时钟同时需要为MAC提供与速率对应的时钟。在Intel的IP中10/100/1000三速模式下用户侧时钟可能不再像传统MII那样分频而是保持125MHz同时用tx_clock_en/rx_clock_en信号来同步数据采样。这一点和Xilinx的IP实现不是完全一致的移植代码时不能想当然。4.3 时钟树与SDC约束设计Intel平台SGMII时钟设计的一般结构外部对应PLL向FPGA输入125MHz参考时钟通过PLL分频/倍频给GT通道和MAC逻辑或者直接使用PHY输出的125MHz时钟作为GT参考。Quartus工程中SDC约束示例create_clock -name ref_125m -period 8.000 [get_ports ref_clk_p] set_input_delay -clock [get_clocks ref_125m] -max 1.5 [get_ports sgmii_rx_p] set_input_delay -clock [get_clocks ref_125m] -min 0.5 [get_ports sgmii_rx_p]TSE IP内部已经把PCS和MAC之间的路径约束好了用户侧主要约束Avalon-ST接口的时钟。如果使用了异步FIFO跨时钟域还要设置set_false_path或者set_max_delay避免时序分析器把CDC路径当作普通同步路径来报。Intel平台对复位要求也很严格。Quartus的TSE IP会把复位时序要求写在user guide里一般要求复位至少保持多个时钟周期且释放要同步到对应时钟域。我习惯在顶层用专门的复位管理模块把上电复位、PLL锁定、以及GT reset done信号组合起来统一生成MAC和PCS的复位时序。4.4 MAC侧接口和寄存器访问差异TSE在Avalon-ST接口下发送通路是avalon_st_tx_data、avalon_st_tx_valid、avalon_st_tx_ready这种valid-ready握手协议接收通路类似。相比Xilinx的GMII接口Avalon-ST天然带有反压机制用户侧逻辑处理流量控制会方便很多。寄存器访问方面TSE通过Avalon-MM从接口配置寄存器和Xilinx的MDIO为用户侧接口的机制不同。调试时我一般会先读TSE的statistics寄存器看TX/RX帧计数是否增长再决定往链路层还是PHY层查。如果寄存器都不增长多半是Avalon-ST握手没打通也就是ready一直没有拉高。5. 板卡与信号完整性SGMII的硬件设计底线5.1 PHY选型与SGMII引脚连接FPGA的SGMII最终要接到PHY芯片上PHY的MAC侧接口如果支持SGMII硬件设计就相对简单。需要注意PHY厂商的SGMII电平定义有的PHY要求FPGA侧的GT配置为CML电平有的接受LVDS。多数情况下SGMII差分对可以通过AC耦合直连但在PHY手册上要确认内部偏置电阻和外部端接电阻的要求。以常见千兆PHY为例典型连接是PHY_SDIN/P接FPGA的TXPPHY_SDOUT/P接FPGA的RXP差分对之间串0.1uF电容电容靠近接收端放置。PHY旁边一般还需要一颗25MHz晶振作为基准时钟PHY内部PLL再生成125MHz的SGMII时钟也可以选择把PHY输出的125MHz时钟引给FPGA作为GT参考时钟。5.2 PCB布线、阻抗与AC耦合SGMII虽然是1.25Gbps相比10G SerDes要友好很多但也不能随便走线。差分阻抗要控制100欧姆差分对内等长控制在5mil以内两对SGMII差分线之间保持至少3倍线宽距离。AC耦合电容选择0402封装走线时要注意电容焊盘对阻抗的影响可以在电容两边做阻抗补偿。另外要注意回流路径。SGMII差分线下方要保持完整的参考地平面不能跨越分割槽。有几次板子link不稳最后发现是参考平面在BGA下方被过孔打碎导致差分阻抗突变信号质量变差。5.3 电源与去耦SGMII依赖FPGA的高速收发器Xilinx 7系列Artix-7的GTP收发器候电源一般需要VMGTAVCC和VMGTAVTT两路通常都是1.0V/1.2V级别Intel Cyclone V上对应的收发器电源是VCCHIPR、VCCPT等。具体以对应器件手册为准但功率和纹波要求都要比普通IO电源严格。我做过一个Artix-7的板子SGMII一直偶发错包后来用示波器测GT电源纹波发现VMGTAVTT的纹波达到了50mV以上。加了LC滤波和加大去耦电容之后问题消失。所以高速收发器电源一定要按照推荐电路来不能图省事和其他1.2V网络共用一颗LDO就算完事。5.4 硬件检查清单检查项要求AC耦合电容0.1uF靠近接收端差分阻抗100欧姆一致性优先对内等长≤ 5mil参考平面完整避免跨分割参考时钟125MHz抖动满足GT要求电源纹波依据器件手册一般在20mV以内复位时序上电后至少稳定若干ms这块检查清单看起来很基础但实际项目里最耗时的往往就是这些小问题。建议硬件评审阶段就拿这张表逐项过能省掉后面三倍的调试时间。6. 调试实战与踩坑排查从回环到link up的完整链路6.1 分级回环先PMA后PCS再外部SGMII调试我首推“分级回环”的思路从物理层到协议层层层确认而不是一上来就测整条链路。第一步PMA回环。在GT内部把发送端数据直接返回接收端不经过外部PHY。这个回环可以验证GT收发器本身、参考时钟和复位是否正常。Xilinx IP可以通过动态配置或者在GT例化时打开near-end PMA loopbackIntel平台的SGMII PCS也有类似配置位。PMA回环通了说明GT物理层没问题。第二步做PCS回环把8B/10B编解码之后的数据返回验证PCS状态机和对齐逻辑。第三步才是外部回环用一根SMA线或者连接器把FPGA的TXP/TXN直接短接到RXP/RXN看外部链路的数据完整性。严重警告PMA回环前一定要确保TX、RX的电平配置正确不要让收发器在未配置状态下长期输出否则部分PHY或FPGA GT可能进入异常保护。6.2 link up失败排查步骤提到link一直起不来很多人第一件事是换PHY寄存器配置其实大部分问题出在更基础的环节。我的排查顺序现象先查什么再查什么reset_done不拉高GT参考时钟是否稳定GT电源是否正常CDR lock不上差分线连接PCS回环确认GT正常同步状态一直跳线速率是否匹配参考时钟频率是否精确自协商不完成配置字格式PHY寄存器模式能link但跑流量错包电源纹波差分信号质量有一个印象很深的例子某次SGMII link一直down寄存器读出来PHY已经link up但FPGA侧自协商就是不完成。后来查了MDIO时序发现MDC时钟频率太高接近手册极限偶发读写错误导致FPGA读到PHY的状态不对。把MDC分频降到2.5MHz左右问题立刻消失。6.3 数据跑通后的稳定性验证link up只是开始SGMII调试里真正耗时间的是稳定性验证。数据链路跑通后建议用以下手段做长时间测试连续发送固定长度的以太网帧比如1518字节统计CRC错误使用硬件计数器统计RX错误帧、短帧、长帧跑PRBS伪随机序列配合收发器自带的误码率统计长时间运行至少24小时观察偶发错误。跑这类测试时我会同时抓取FPGA内部gt_rxbytealigned信号和rxdisperr/rxnotintable信号。如果这两个错误标志偶尔出现说明信号质量或者时钟裕量不足得回头检查电源纹波、参考时钟抖动、PCB差分线质量。6.4 跨平台迁移的注意事项从Xilinx移植到Intel平台或者反过来不能只改IP例化。SGMII协议语义虽然一致但两家的IP实现有几个明显差异用户侧接口不同Xilinx常用GMIIIntel TSE常用Avalon-ST时钟使能方式不同Intel三速模式常用固定高频时钟加时钟使能Xilinx的GMII模式是速率切换时钟复位时序定义不同两者的reset done和复位释放要求各有差异自协商控制方式不同Xilinx在IP内配置Intel很多TSE配置需要用户在寄存器层面控制。我见过最亏的迁移方式是照着Xilinx的GMII时序直接往Intel的Avalon-ST上套结果把valid当成使能来用漏掉ready反压最后丢帧丢得不可收拾。迁移前先把你用的两个IP的数据手册拿出来把接口时序和复位时序逐行对比一遍这个时间花得绝对值。最后说一个我自己的习惯每次调SGMII先把MDIO回读PHY寄存器0和寄存器1做成一个简单的debug脚本再在FPGA里拉出status_vector和错误标志到调试工具。有了这两把“扳手”大部分SGMII问题都能在半小时内定位到具体层。SGMII这个接口说难也难说简单也简单关键是把物理层、编码层、协商层分开看逐层验证大多数疑难杂症都会变成一目了然的配置问题。希望这篇实战记录能让你少熬几个通宵。