ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

FPGA以太网SGMII接口调试实战:从PHY配置到链路稳定

FPGA以太网SGMII接口调试实战:从PHY配置到链路稳定 做FPGA以太网通信不少人一开始就在MAC和PHY之间的接口选择上犯了难。GMII、RGMII、SGMII名字看着像用起来完全是两码事。尤其是SGMII看着就两条差分线似乎很简单但真正调起来PHY配置、时钟恢复、链路协商、8B/10B编解码任何一个环节卡住网口就是不亮。我最早从GMII切到SGMII的时候以为只是换换引脚约束结果被链路自协商折腾了一整周。这篇就以SGMII接口和PHY配置为主线把我在实际项目中踩过的坑、验证过的方法以及这套链路从复位到数据收发的完整流程一次讲清楚。1. 为什么用SGMII三种常用MAC-PHY接口的取舍先别急着看代码和寄存器选型这件事放在最前面讲。很多初学者喜欢直接抄参考设计觉得哪个接口火就用哪个结果到了布线、时序收敛、跨板调试的时候才发现根本不是那么回事。SGMII并不是在所有场景下都是最优解它只是千兆以太网场景里一个均衡度很高的方案。1.1 GMII的并行困境GMIIGigabit Media Independent Interface是IEEE 802.3标准里定义的并行接口数据位宽8bit125MHz时钟下双向同时传输加上TX_EN、TX_ER、RX_DV、RX_ER、GTX_CLK、RX_CLK等控制信号整体下来要十几根信号线。在单纯的PCB板上拉线倒也没什么但如果你的FPGA是BGA封装引脚资源紧张一片板子上有多个网口那GMII的布线代价就会逼你重新做选择。更让人头疼的问题是时钟域的约束。GMII不是源同步接口但数据与时钟的skew要求很苛刻PCB上每根走线都要尽量等长。125MHz的8位并行总线在Layout时还勉强能控制但一旦跑上DDR3或者做多通道并行处理MAC侧的时序约束很容易出现负slack。我见过不止一次板子回来后因为GMII的一组线等长差了几十mil千兆模式怎么都练不上去最后只能跑百兆。这类问题在调试阶段极其隐晦既不是逻辑错误也不是寄存器配错纯粹是物理层的时序裕量被蚕食干净了。1.2 RGMII的时序压缩RGMIIReduced Gigabit Media Independent Interface就是为了解决GMII信号线太多而出现的。它的思路很简单——把8位数据线改成4位然后在时钟的上升沿和下降沿各采一次用DDR的方式补齐带宽。这样一来信号线数量大幅缩小时钟仍然是125MHz但数据率翻倍成了250Mbps/引脚。RGMII的最大争议在于它的时序模型FPGA侧送给PHY的TX时钟通常需要做90度相移以保证PHY在采数据时落在眼图中央。这部分在代码里的实现方式通常是ODDR原语加相位约束不算难但需要你对时序要求有明确理解。RGMII对PCB布线依然有一定要求尤其是时钟和数据的等长违反了之后轻则链路不稳定重则完全不通。相比SGMIIRGMII省了引脚但没有省掉时序压力只是把压力从并行总线的多根线转移到更窄的时序窗口上。1.3 SGMII的串行方案SGMIISerial Gigabit Media Independent Interface彻底抛弃了并行数据线改用一对发送差分线和一对接收差分线线速率为1.25Gbps内部通过8B/10B编码将8bit数据扩展成10bit并串行发送。与GMII/RGMII相比SGMII的最大优势是引脚少、PCB布线简单而且它不要求高频并行时钟线与数据线严格等长因为数据时钟内嵌在串行码流中接收端可以通过CDR恢复。SGMII的联合了百兆和十兆速率这很关键——尽管物理线路始终跑在1.25Gbps但当链路协商速率为100M或10M时MAC与PHY之间的有效数据率会相应降速SGMII层通过插入空闲码来填满带宽。这意味着同一套串行线路可以适配不同速率切换时不需要重新布板。对比一下GMII适合做调试和教学直观但对引脚和布线不友好RGMII在低成本、低引脚数PCB上很常见但时序要求高SGMII则是高速、多网口、高可靠性场景下的首选代价是你必须在FPGA内部实现或者例化一套PCS逻辑。很多人一听到要自己做8B/10B和时钟恢复就打退堂鼓其实Xilinx、Intel以及主流国产FPGA都提供了现成的SGMII IP核或硬核真正要自己写核心逻辑的情况非常少。我们真正要注意的是如何把这些IP与PHY芯片协同工作起来。2. SGMII链路机制不只是两根线的事SGMII看起来信号就四根TX_P/N、RX_P/N但它内部的工作机制比RGMII复杂得多。很多人调试SGMII遇到问题就是因为它根本搞不清这条串行链路上到底在传什么东西。下面把协议层面的几个关键机制拆开聊。2.1 物理通道与链路速率SGMII物理层的串行数据速率固定在1.25Gbps每一对差分线承载这个速率。发送和接收方向完全对称全双工工作。这1.25Gbps的由来是1Gbps有效数据加上8B/10B编码带来的25%开销1000Mbps × 10/8 1250Mbps。FPGA内部的结构通常是——MAC层产生8bit并行数据经过PCS层的8B/10B编码后变成10bit码字再通过并串转换器SerDes按1.25Gbps的速度逐bit发出。接收方向反过来CDR从差分线上恢复出串行数据和时钟串转并还原成10bit码字经过8B/10B解码后得到8bit数据和控制信号送给MAC层。还有一个容易搞混的概念10M/100M低速模式下SGMII物理层怎么工作。答案是物理线路速率永远不变依然1.25Gbps但有效数据在MAC与PCS之间不是每个周期都有效。比如100M模式下有效数据占比约1/10其余位置填充空闲符号。这点理解之后对于后面看PHY的link状态和调试带宽问题非常有帮助。2.2 8B/10B编码与码流同步8B/10B编码是SGMII的底层核心。为什么要用8B/10B两个理由——直流平衡和时钟恢复。原始数据流的0/1分布是不确定的如果长串连续相同电平接收端的CDR很难恢复出正确的时钟沿。8B/10B编码将每个8bit字节映射成10bit码字且通过计算运行不一致性Running Disparity保证整个码流中0和1的数量尽可能均衡也就保证了电平翻转密度。在SGMII链路上除了数据码字还有控制码字最关键的是K码Comma码。K28.5编码为0011111010或1100000101被用作码流对齐标记。接收端在bit流中不断搜索这个特定的Comma图案一旦找到就据此确定码字边界完成字对齐。这个过程在FPGA里通常由SerDes的接收对齐状态机自动完成但配置SGMII IP时对齐方式Alignment一定要选对比如基于K28.5或者基于可编程对齐模板。另外SGMII每接收一个码字就要判断它是数据码还是控制码。K码有多种用途IDLEK28.5、Start of PacketK27.7、End of PacketK29.7等。以太网MAC层在发送数据帧时帧头帧尾都要打上对应的控制码接收时如果没有能正确识别这些控制码上层就会丢弃该帧。2.3 链路自协商PHY和MAC如何握手SGMII的自协商Auto-Negotiation可能是整个链路中最容易被误解的环节。注意SGMII自协商和PHY与对端设备之间的自协商是两回事但要协同工作。SGMII链路建立初期MAC侧PCS和PHY之间需要协商出工作速率10M/100M/1000M。这个过程在SGMII规范里是通过在空闲码IDLE中嵌入配置信息完成的。PHY和MAC各自发送带有速率能力字段的IDLE码流双方读到对方的能力后选择共同支持的最高速率并锁定然后把link状态拉高。这里有一个FPGA调试中很常见的坑如果FPGA侧的SGMII IP没有正确启动自协商状态机或者PHY配置为强制1000M而不是自协商模式双方速率不匹配PHY侧link灯可能是灭的或者FPGA侧rx_byte_aligned状态一直拉不起来。我调试的时候习惯先把SGMII IP的自协商打开等链路稳定后再看MAC层的收发状态减少变量数。3. PHY配置实战寄存器级操作与MDIO时序SGMII链路建不起来问题经常出在PHY芯片的配置上。PHY芯片上电后的默认状态不一定满足你的系统要求尤其是时钟来源、速率模式、接口模式这些关键项必须通过MDIO总线写寄存器来控制。3.1 MDIO总线时序MDIOManagement Data Input/Output是一种两线管理接口一条MDC时钟线一条MDIO数据线用来访问PHY内部的寄存器。它由MAC侧发起操作读或写16bit长度的寄存器数据。MDC最高频率在IEEE规范里建议不超过2.5MHz不过大多数PHY芯片能承受更高FPGA做主控时一般生成1MHz左右最稳。MDIO的帧格式分几个阶段前导码Preamble32个连续的1用于同步。起始码Start of Frame01。操作码Op Code读为10写为01。PHY地址PHY ADDR5bit用来选中总线上哪个PHY。PHY的地址通常由硬件引脚决定常见配置是0x01或0x00。寄存器地址REG ADDR5bit。写操作时后面直接跟16bit写数据在MDC上升沿采样读操作时先插入2bit的转向时间Turnaround再输出16bit数据。我在FPGA里写过MDIO驱动代码逻辑非常简单一个状态机一个计数器按bit把帧拼出来就行。真正需要注意的是MDIO是双向引脚读的时候还必须切换方向如果不小心让FPGA一直驱动MDIO输出读出来的数永远是全0xFF或者全0x00这是新手特别容易踩的坑。3.2 核心寄存器解读PHY芯片的寄存器空间前16个是IEEE 802.3定义的通用寄存器后面的厂商自定义。要做SGMII的PHY配置最常用的寄存器是这几位寄存器0Control最常用的是第15位Soft Reset、第14位Loopback、第13位Speed Select LSB和第6位Speed Select MSB。这两个速度位组合0010M01100M101000M11Reserved。如果你要强制千兆模式就把第6位置1第13位置0。寄存器1Status第15位是100BASE-T4支持第14位是100M全双工支持第13位是100M半双工支持第12位是10M全双工第11位是10M半双工第10位是100BASE-TX全双工第9位是100BASE-TX半双工第8位是10BASE-TX全双工第7位是10BASE-TX半双工第6位是MF preamble suppress第5位是Auto-Negotiation Complete第2位是Link Status。调试时最常看的就是第2位Link Status为1表示链路通。另外第5位自协商完成如果一直是0说明自协商还没跑完。寄存器4Auto-Negotiation Advertisement用来向对端广播自己的能力比如是否支持10M、100M、1000M以及全双工/半双工。要让PHY和交换机之间协商上千兆全双工这一位的配置要正确。寄存器5Auto-Negotiation Link Partner Ability Register读它可以看到对端广播了什么能力。如果两端能力不符合预期比如交换机只支持百兆你强制配了千兆导致link失败。这时应回退到自协商模式让双方自己商量。3.3 一个完整配置流程假设我用的是一个常见千兆PHY芯片比如RTL8211系列FPGA通过MDIO总线对PHY做初始化我一般按下面这个顺序操作先做PHY的硬件复位等待复位完成。然后通过MDIO写寄存器0把软复位位置1。软复位之后不要立刻写其他寄存器必须等待bit15自动变回0说明复位完成。接着配置寄存器4广播自己支持的能力。比如写0x01E1这个值表示支持10M半双工/全双工、100M半双工/全双工、1000M半双工/全双工。再写寄存器0让bit12Auto-Negotiation Enable和bit9Restart Auto-Negotiation置1同时把bit13和bit6清零让PHY进入自协商状态。然后进入等待状态读取寄存器1看bit5Auto-Negotiation Complete是否为1。自协商完成后读取寄存器1的bit2确认Link Status为1。这里有一个很隐蔽的坑寄存器的Link Status是“latching low”的只要发生过断链它就会一直为0直到你把寄存器1整读一遍之后它才重新反映真实状态。所以在读这个bit之前必须先读一次寄存器1。如果发现Link断也要考虑是不是位锁存导致的误判。配置完PHY之后不要急着发数据先确认SGMII侧的状态。对PHY来说SGMII的接口模式可能也有寄存器要配。在某些PHY芯片上如果你不配置接口模式选择位PHY可能默认工作在RGMII模式导致FPGA这边SGMII怎么都对不齐。所以上电后第一件事是读芯片的ID寄存器寄存器2和3确认MDIO能通、驱动芯片型号和原理图一致再继续配置其他字段。4. 从零到通SGMII环回测试与FPGA侧PCS设计要点先用最低成本的方式把链路打通再谈后续的数据收发。环回测试是调试SGMII链路最有效的手段。我推荐按“PHY环回、SGMII近端环回、远端环回、最终端到端”这个顺序逐步推进。4.1 最省事的验证路径PHY内部环回把PHY的寄存器0第14位置1数据从FPGA的SGMII_TX信号进入PHY从PHY的SGMII_RX信号返回FPGA。此时数据没有经过物理网线和对端设备纯粹验证FPGA到PHY之间的SGMII路径。如果这个环回都不通说明问题在FPGA与PHY之间的串行链路、SGMII IP配置或者MDIO配置上。一旦这个环回通了就证明FPGA的PCS发送接收链路和PHY的SGMII接口基本没问题。如果PHY内部环回通常是过不了。重点排查SGMII IP有没有复位、TX差分线有没有接反、参考时钟是否正常。如果千兆模MAC向PHY发送的以太网帧经PHY环回后MAC能正确收到自己的帧说明整条链路已经通了。4.2 FPGA内部PCS的关键模块与速率适配在FPGA内部如果用的是Xilinx的1G/2.5G Ethernet PCS/PMA IP至少要知道它内部包含哪些模块。一般由PMAPhysical Media Attachment和PCSPhysical Coding Sublayer组成。PMA处理并串转换和时钟恢复PCS负责8B/10B编解码、自协商、链路状态管理。按标准的话说FPGA内部信号通路的时钟关系大致是在千兆模式下用户侧数据接口为8bit 125MHz。再往里面走经过8B/10B编码后变成10bit数据然后被SerDes以1.25Gbps发出。100M模式时用户侧是8bit 12.5MHz后面编码还是10bit线速率仍是1.25Gbps但中间会填大量空闲码。这个速率适配往往被忽视。很多人在千兆模式下能够正常收发一跑到百兆模式就发现带宽不对、丢包严重就是因为没有正确理解MAC接口数据率已经降到12.5MHz。时钟恢复是另一个关键点。SGMII接收端从串行码流中恢复时钟这个时钟频率不一定完全等于标称的1.25GHz会有ppm级的偏差。因此接收侧的FIFO要做跨时钟域处理或者在IP内部用异步FIFO把恢复时钟域的数据搬到用户时钟域。在设计MAC时发送和接收方向一定预留FIFO不要直接让MAC逻辑咬着SerDes的时钟跑。4.3 时序约束与上板调试前检查SGMII的时序约束比GMII/RGMII简单因为内部同步逻辑都在SerDes和IP核里。但你仍然需要做几件事第一SGMII的差分时钟引脚要在XDC或QSF文件里定义引脚和电平标准常用的是LVDS或LVPECL不同PHY的参考设计不一样务必查规格书。第二SGMII IP的复位信号不要随便接。上电后要先等待PHY初始化完成最好由外部控制器在PHY配置结束后再释放SGMII IP的复位。如果PHY还在配置过程中FPGA侧已经开始发码流可能出现SGMII链路在早期一直不能对齐的情况。第三所有跨时钟域的异步信号都要打两拍同步尤其是外部PHY的中断、Link状态信号。SGMII的link状态如果直接接到FPGA内部状态机做复位控制亚稳态问题会放大。这种高速链路加外部慢速信号复位释放一个没处理好就可能起不来。5. 高速线路上最容易翻车的几个环节SGMII虽然信号线少但1.25Gbps的线路速率对信号完整性还是提出了要求。板子跑了千兆就不稳定偶尔link down联调的时候总是时好时坏大多是以下几类原因。5.1 信号完整性与PCB检查清单SGMII的差分对走线要按100欧姆差分阻抗控制AC耦合电容要靠近接收端放置。电容容值一般是0.1uF如果放反或者漏放信号会直接被隔断。SGMII不像以太网PHY到RJ45那一段有变压器FPGA和PHY之间的SGMII是交流耦合的没有电容信号就过不来。差分对两条线等长尽量控制在5mil以内对内等长比线对之间等长更重要。不同SGMII lane之间如果你有多个网口不要平行走长距离这会引入串扰。过孔的stub也会在1.25GHz下引发阻抗不连续建议高速线尽量不走换层非换不可时要加回流地孔。调试时如果发现链路偶尔断开优先检查SGMII差分信号的眼图。没有示波器的话可以观察PHY芯片的寄存器Link状态配合FPGA侧的错误计数器定位。我在调试时发现很多看似程序bug的问题实际上就是SGMII走线上串扰把接收端的信噪比拉低导致偶尔出现误码。5.2 时钟与复位高速链路的两大命门SGMII的参考时钟一般要求125MHz或与之对应且抖动指标有硬性要求。如果从普通的时钟芯片直接拉一路过来未做cleanup容易导致CDR性能下降。有条件的板子一定要优先选择PHY的专用时钟或使用晶体振荡器提供低抖动时钟。复位这里需要特别注意。PHY芯片的硬件复位引脚时序有最小复位脉冲宽度要求上电后要满足PHY的电源稳定时间再复位。FPGA内SGMII IP的复位也要满足时序要求不能与PHY的配置流程混乱。其实一次不够的话就把复位时间拉长一些等PHY侧寄存器完全可访问后再拉高SGMII IP的复位宁可慢一点也不要抢时序。5.3 状态机与链路down调的坑SGMII的链路建立是一个状态机过程从复位、配置、自协商、同步对齐、到最终进入数据收发中间任何一步卡住都可能表现为link丢或数据不通。如果FPGA里自己实现了SGMII状态机建议把状态机状态暴露出来做调试信号。比如同步完成信号、自协商完成信号、错误计数等通过ILA或逻辑分析仪观察。不要只在最终结果那里等一个link up信号那样出了错根本不知道卡在哪一步。如果用的是自带SGMII硬核的FPGA链路状态信号通常从IP核引出。调试时先看reset_done、aisg_lock等信号再看PHY侧的link状态两边都对了才轮到MAC层的事情。我遇到过一种很典型的情况PHY配置没问题SGMII也显示对齐了但收发数据始终不对。最后发现是FPGA侧MAC的接口速率配置错了SGMII协商到100M但MAC还按1000M模式收发帧间隙完全不对。所以前面强调的速率适配在状态机设计里真的要落实到位。6. 一些体会和调试思路上的建议SGMII这套链路如果按从简到繁的步骤排查通常会节省大量时间。第一步确保MDIO能读到PHY ID第二步做PHY的环回测试第三步切换到SGMII IP环回验证FPGA内部PMA/PCS第四步才去接外部对端。很多工程师一上来就直接连交换机调试出了问题满屏抓瞎毫无头绪。特别是SGMII这种高速串行链路它的故障现象往往不直接指向原因。比如对端可以ping通但有大量丢包有可能是PHY速率协商到了100M但系统逻辑跑的是千兆时序再比如链路灯亮但带宽远低于预期可能是SGMII内自适应速率与MAC速率不一致。调试工具方面除了常见的ILA抓内部信号我建议把PHY的所有寄存器空间中实现起来。很多情况下错误是PHY上报的比如接收错误计数器、CRC错误计数器这些寄存器能帮你非常直观地判断链路质量。在实际项目中我逐渐形成了一个习惯任何高速链路调试先从能力出发做排除法。MDIO访问不到先从PHY芯片供电和地址引脚查起。能访问但寄存器值异常查复位和PDN引脚。环回不通查SGMII接口模式、AC耦合电容和差分引脚约束。一层一层往下测思路就会非常清晰。最后分享一个我自己调整过的温度细节SGMII链路对温度比较敏感。刚开始长时间跑没问题高负载跑一小时后开始偶尔出现CRC错误。查了半天发现是PHY芯片散热不良温度升高后内部PLL抖动变大SGMII接收端误码骤增。后来在PHY底下加了大面积的地和散热焊盘问题彻底消失。高速链路的问题不是只有逻辑和协议物理层面的事不要忘。
返回列表