
搞嵌入式的谁没被网口调试折腾过几回。尤其是ZYNQ这种ARMFPGA的异构平台PS侧的MAC通过EMIO引到PL再接到外部PHY看起来只是绕了个路实际上一路都是坑。最近我调的一块板子就是这样PS-MAC配RGMII接口经过PL的EMIO引脚送到板上的RTL8211E PHY芯片测试时发现网络根本跑不起来——链路偶尔能link上ping一下通两包就断用UDP测试更是错包满天飞ethtool显示CRC错误帧数量惨不忍睹。折腾了整整一天软件配置翻了个底朝天最后拿示波器量RGMII信号才发现根本不是软件的事RGMII电平给错了。2.5V电平标准的接口被接到了3.3V的IO bank上整个信号电平体系不匹配高速双沿采样怎么可能稳定。这篇文章就把这次ZYNQ网口调试过程完整复盘一遍内容包括为什么要用PS-MACPL-EMIO这种方案、数据异常的现象怎么判断、排查顺序怎么走、以及电平匹配背后的电气原理。不管你是画板子的硬件工程师还是写驱动的嵌入式软件工程师这篇文章应该能帮你少加几个小时的班。1. 为什么非要用 PS-MAC PL-EMIO 引出网口1.1 PS自带网口还不够MIO不够用时的选择ZYNQ-7000的PS侧集成了两个千兆以太网MACGEM0、GEM1默认情况下RGMII信号可以走MIO引脚直接输出。很多入门套件就是这么用的MIO上接一颗PHY比如RTL8211E或者KSZ9031数据手册照着抄基本一次通过。但实际项目里MIO引脚不一定省得下来。比如板子上同时要接SD卡、UART、USB、SPI Flash、GPIO等MIO一共就那么多引脚分给GEM的RGMII一下要占12根左右很容易就被挤占。再比如PHY芯片希望放在PCB的另一侧或者离FPGA内核更近的地方MIO信号的布线绕不过去走PL侧反而更顺。这时候PS-MAC PL-EMIO方案就成了很自然的选择GEM的RGMII信号不通过MIO输出而是从PS侧通过EMIO路径映射到PL内部再经由PL的IO引脚连接到外部PHY。等于把MAC信号的“路由权”从PS交给了PL具体落到哪个物理引脚、走哪一层、要不要在PL里做逻辑处理全都自由了。这种方案在高端通信板和自研核心板上尤其常见。因为PL侧引脚多、排列灵活还能把多个网口的RGMII统一规划到同一组BANK上方便电源和走线设计。很多zynq开发板摄像头输入的方案里数据通路占用了MIO和PL大量引脚网口往往也只能走EMIO这条路。1.2 EMIO引出不仅是换个引脚电气行为全变了第一次用EMIO的人容易有一个错觉MIO和PL普通IO本质上不都是芯片引脚嘛电平差不太多吧这个想法就是后面各种“灵异事件”的源头。MIO引脚的电气特性由PS侧对应的MIO BANK供电电压决定一般可以配置成1.8V、2.5V或者3.3V。而通过EMIO引出来之后RGMII信号变成了普通PL IO BANK信号电平完全由那个BANK的VCCIO电压决定。开发板上PL的IO BANK电压经常通过跳线帽或0欧电阻来选择。注意这不是“差不多能用”的问题。RGMII在千兆模式下是125MHz的双沿采样信号对电平阈值、上升沿时间、噪声裕量的要求都极其敏感。PL BANK的电平和PHY芯片的接口电平如果不一致高速信号根本无法稳定采样。这个坑在设计阶段特别容易埋下原理图里看到PHY芯片用2.5V电源供电但分配给RGMII的那个PL BANK电源却被人顺手设成了3.3V或者反过来PL BANK是2.5VPHY的VDDIO却选了3.3V。然后一边在软件里怀疑驱动、怀疑设备树、怀疑DMA描述符一边还想着是不是PHY芯片焊接虚了。实际上十有八九就是电平的问题。2. 数据异常的典型现象先对号入座2.1 现象一链路起不来PHY仿佛“死了”最扎心的一种情况是PHY连链路都不认。用ethtool看link status一直是down插上网线后指示灯的物理状态都不对。这时候很多人的第一反应是PHY芯片供电没焊好、复位有问题、晶振没起振但万用表量下来全正常。再翻设备树PHY的ID也能读得出来可就是link不上。这种“能读PHY ID但link不上”的组合迷惑性非常强。MDIO能正常读写说明PHY的供电、时钟、复位以及管理接口都是通的芯片起码没死。问题大概率就出在RGMII数据接口上。可能是PHY的接收侧认为TX信号无效也可能是PHY发送侧输出的信号根本达不到对端的高电平阈值两边怎么都握不上手。我这次遇到的就是这个情况的变种静态看寄存器自协商状态一直在变但始终没进入link up。当时还以为是PHY的自动协商配置写错了反复读写AN寄存器折腾了好几个小时。2.2 现象二能link但疯狂丢包更多时候电平不匹配并不是“完全不能用”而是极其不稳定。链路能协商起来link灯也亮但ping对面设备丢包率20%、50%甚至80%都有平均延迟忽高忽低。用ifconfig和ethtool看RX errors、CRC errors快速累加刷两下屏幕就是天文数字。这种状态还有一个更迷惑的行为刚插上网线的头一两秒内可能还能通几个包紧接着就开始大规模丢包或者完全超时。如果碰一下网线或者板子状况还会变得更糟。根本原因是电气容限太差信号稍微受点干扰采样点就掉到了错误阈值区间。115毫秒的延迟、无规律的乱序、连续CRC错误都在这个阶段出现过。很多人这时候会去怀疑PHY的时钟延迟配置比如RTL8211E的0x0017寄存器、KSZ9031的延时钟控制位把delay位翻来覆去地改结果毫无改善。这也很正常因为问题根本不在时域而在电压域。2.3 现象三只有百兆千兆协商不上还有一种更隐蔽的情况RGMII接口明明支持千兆但最终协商结果永远是100Mbps/Full把网线对面那台千兆交换机的速率也一起拉下来。遇到这种问题往往会把矛头指向PHY配置寄存器里的千兆模式或者觉得是板子做工不行。实际上千兆对应的是125MHz时钟下的DDR双沿数据而百兆是25MHz时钟下单沿有效。电平不匹配时125MHz信号的建立保持时间几乎不够用而25MHz的信号时间裕量反而大了很多所以系统被迫退回百兆甚至百兆模式下还能勉强工作。如果你发现千兆打流全是错包百兆却能凑合那大概率就是信号电平或者信号完整性问题。顺着这个思路也能解释为什么很多人搜“zynq的以太网udp测试”“网口调试助手连不上”时现象描述基本都是“速率上不去、通了也不稳定”——本质都是在千兆电气链路这个环节出了问题。现象特征最可能的因素重点排查方向完全link不上PHY电源/复位/晶振、电平不匹配测量PHY供电、复位、RGMII信号幅度link上但疯狂丢包RGMII电平不匹配、时钟相位异常示波器量信号摆幅、核对VDDIO/VCCIO只能百兆、千兆协商不上信号完整性、时序裕量不足检查等长、串阻、PHY内部delay能通但CRC错误持续增加电气阈值/时序边沿问题ethtool -S统计、示波器看边沿3. 排查实录三层过滤锁定根因3.1 软件层把驱动和设备树翻个底朝天遇到网口异常我第一件事还是先查软件毕竟软件改起来最方便。ZYNQ上跑Linux通常用的是Xilinx维护的emacps驱动设备树里要配置MAC节点、PHY的地址、interrupt、mdio总线等。这一遍我把设备树里emacps节点挨个核对phy-handle、interrupt-parent、local-mac-address全部看了一遍又确认PHY驱动是不是加载成了通用的genphy而不是RTL8211E的专用驱动。还手动用mdio-tools去读PHY寄存器确认PHY ID寄存器能读到正确值——RTL8211E的PHYID一般是0x001cc816附近读到就说明MDIO通路本身通畅。接着用ethtool把PHY协商模式、速率、自协商状态全部dump出来也都能正常显示驱动复位PHY不报错。软件这一层几乎挑不出毛病驱动正常加载、MDIO能访问、寄存器能读写、中断也配了。可网络就是不通。当时那种感觉就是明明所有开关都打开了机器却死活不干活。3.2 PHY层能读ID不代表数据通路正常排查过程中最关键的一个认知转变就是要分清两条完全独立的路MDIO管理接口和RGMII数据接口。MDIO只是管理通道负责读写PHY寄存器。它能读到PHY ID只能说明PHY的电源、时钟、复位、管理接口这几样是好的。但RGMII数据线上跑的是125MHz的源同步信号和2.5MHz的MDIO管理时钟完全不是一个量级两者的电气要求和逻辑判据也完全是两回事。不要以为“MDIO能通信”就等于“PHY数据通路正常”。为了验证MAC这一侧的收发逻辑本身可以在PL内部把RGMII的发送和接收信号做回环Loopback也就是把TXD[3:0]和RXD[3:0]、TX_CTL和RX_CTL在逻辑上短接再把TX_CLK和RX_CLK也绕回来。这样绕开PHY直接验证GEM的收发通路。如果回环测试正常说明MAC侧软件和DMA链路都没问题。我做完回环后发现数据收发在MAC内部完全正常问题就被牢牢锁定在了PHY与PL之间的物理链路上。3.3 物理层示波器一量就露馅到了这一步才拿出示波器。单端探头、DC耦合分别去量RGMII的TX_CLK、TXD[0]、TX_CTL这几个关键信号。注意探头要靠近引脚测别隔着长长的测试线否则看到的都是反射和振铃自己吓自己。示波器上电后看到125MHz的TX时钟是高电平约3.3V的方波时心里基本就有数了。板子上这颗PHY的VDDIO明明是2.5VPHY的RGMII输出能力上限就是2.5V结果PL这边送过来的信号却是3.3V。再到PL方向量了一下这个BANK的VCCIO实测确实是3.3V。也就是说PL-EMIO引出的RGMII信号完全被3.3V BANK决定了PHY接收端看到的3.3V信号已经远远超出了按2.5V逻辑设计的高电平范围。真相到这里就完全清楚了不是软件问题不是PHY坏不是时钟不同步就是PL-EMIO所在BANK的电压给错导致RGMII的信号电平体系整体错位。之前花在设备树、PHY寄存器上的时间严格来说不算白费但也确实没抓住主要矛盾。4. RGMII电平背后的电气原理为什么这一步最容易错4.1 RGMII标准与2.5V LVCMOS的关系RGMII是从GMII接口简化来的把8位数据线减成4位通过时钟双沿采样DDR实现同样的带宽。正因为数据在时钟的上升沿和下降沿都有效时序裕量被压缩得很紧对信号电气质量的要求也就格外高。IEEE 802.3z里定义的RGMII电气特性默认参考的是2.5V LVCMOS电平标准。VIH大约要超过1.7VVIL大概要低于0.7V上升沿和下降沿也有明确约束。当然实际PHY芯片为了提高兼容性往往支持更宽的VDDIO范围从1.8V到3.3V都可能但有一个核心逻辑绕不开PHY芯片的RGMII接口输出电压幅度是跟随它的VDDIO电源走的。所以谈RGMII电平匹配不能只说“2.5V是标准”更要看PHY芯片的VDDIO实际接了几伏以及它对端PL/FPGA引脚所在BANK的供电电压是不是一致。这两者一致才是电气匹配的本质。4.2 PHY芯片的VDDIO决定一切的引脚PHY芯片的RGMII接口电压并不是凭空产生的一般由专门的IO电源引脚控制。不同厂商对这个引脚的叫法不一样有的叫VDDIO有的叫DVDDIO还有一些芯片把RGMII的数字接口电源和模拟电源分开供电。原理图设计时这颗引脚接几伏RGMII输出高电平就是几伏。我用的RTL8211E它的VDDIO支持2.5V和3.3V可以通过硬件引脚配置或者寄存器选择。板子上这颗RTL8211E的VDDIO被接到了2.5V。这意味着PHY的RGMII输出最高只能到2.5V输入阈值也按2.5V逻辑计算。可另一侧PL BANK的VCCIO是3.3V发出来的信号高电平是3.3V两边从物理根本上就不匹配。反过来如果PL BANK是2.5V而PHY是3.3VPHY发3.3V出来PL的2.5V BANK虽然勉强能认得出高电平但输入已经超出了2.5V BANK的绝对最大额定值通常是VCCIO0.5V长期跑有可靠性风险内部ESD保护二极管可能导通波形也会被拉变形。所以无论哪个方向能凑合的部分都是侥幸不该当作设计方案来依赖。PHY型号IO电源名称典型电压支持备注RTL8211EVDDIO2.5V / 3.3V通过引脚或寄存器选择KSZ9031VDDO1.8V / 2.5V / 3.3V不同电源分组需分开配置88E1512VDDIO2.5V / 3.3V手册对电源时序要求严格AR8031VDDIO2.5V / 3.3V千兆设计里很常见表格数据只能作为参考具体一定以对应PHY芯片最新数据手册为准。拿到的型号批次不同、版本不同电气参数都可能调整。4.3 PL侧VCCIO与PHY电源不匹配的影响链条不少人会问逻辑高电平认得出来不就行了吗问题在于阈值容限和输入保护这两个细节。以PL输出3.3V、PHY按2.5V接收为例。PHY的高电平输入阈值按大约1.7V算3.3V的信号理论上确实在阈值之上似乎能识别。但要注意2.5V供电的PHY输入引脚通常不允许比VDDIO高太多当3.3V信号强行灌进引脚时内部上拉和ESD保护二极管会开始导通等效于给信号挂了一个到VDDIO的钳位二极管高电平被压在VDDIO0.3V附近上升沿被拖慢波形出现塌陷或振铃。再加上RGMII是125MHz双沿采样几个纳秒级别的边沿变形就足以让采样点在错误的时刻取到错误的数据。结果就是CRC错误帧、乱序数据、链路不稳定一起出现。我之前在PHY寄存器里反复调RX Delay和TX Delay本质上是想通过时域补偿来挽救一个电压域就错误的状态当然怎么调都调不好。反向场景也一样PHY输出2.5V到PL的3.3V BANKPL侧LVCMOS33的高电平阈值是2.0V2.5V只比阈值高了0.5V噪声裕量几乎为零走线稍长、串扰稍大高电平就跌到了阈值以下。同样的2.5V信号低于3.3V标准意义上的“理想高电平”所以PHY输入和PL输出之间每个边沿都在阈值边缘挣扎。4.4 电平异常与时序异常的判别方法电平问题和时序问题是RGMII两大常见故障。外在表现很像数据错乱、丢包、CRC错误但排查路径不同。经验性判断可以这样把网口强制到百兆模式再测如果稳定很多说明大概率跟时序或电平有关因为速率降下来时钟边沿变缓裕量变大。但电平错误对速率的敏感度通常不如时序错误那么强低速时也偶尔错包只是错得少一点。更直接的办法是示波器量幅度量到的高电平电压和设计值差了超过0.5V那根本不用再看时序电气层就没达标。波形特征也能帮助区分。如果PHY输入端看到明显的顶部削波或者底部台阶那基本就是过压保护二极管导通、VDDIO偏低导致的钳位效应。如果幅度正确但边沿乱飞、过冲严重那才应该是时序和信号完整性问题。分析到这里已经可以比较确定地指出本次故障是“电平”问题不是“时序”问题。5. 修复与验证电平改对之后的一整套动作5.1 硬件调整VCCIO跳线、PHY电源配置确认根因之后修复硬件其实不复杂但操作一定要谨慎。首先确认PL这个BANK的VCCIO是怎么供电的。开发板上PL BANK电压经常由跳线帽或者0欧电阻选择常见选项是3.3V、2.5V、1.8V。我需要的修改是把VCCIO从3.3V改成2.5V同时确认这个BANK上其他外设能不能也工作在2.5V。如果其他3.3V专用器件也挂在同一个BANK上那就要考虑把RGMII信号挪到一个独立BANK或者把PHY的VDDIO改成3.3V。折中方案也要心里有数如果PHY支持3.3V VDDIO而且PL确实没有2.5V BANK可用可以把PHY的VDDIO跳到3.3V让两边统一在3.3V。但注意RGMII标准本身以2.5V为参考3.3V高压摆幅下信号上升沿更陡串扰和EMI的影响也更大不是首选方案。我这次板上有现成的2.5V电源可以给PL BANK所以直接改了VCCIO选择把这个BANK拉到2.5VPHY继续维持2.5V两边完全对齐。改完之后再量一遍BANK电压确认没有因为负载变化导致压降异常。然后检查电源芯片的带载能力2.5V电源如果原本只给少数器件供电新增PL BANK这一路负载后纹波会变大必要时适当增加滤波电容。5.2 软件侧配合修改与确认电平问题本质属于硬件设计问题但软件上也要做几件配合确认的事。第一确认设备树里没有强行把PHY配置成特殊模式比如强制千兆而不自协商以免和硬件修正后的状态冲突。第二重新检查PHY的延迟相关寄存器。RTL8211E这类芯片一般都有RX Delay和TX Delay的控制位只要PHY本身有内部时钟延迟模块优先用内部延迟方案而不是依赖PCB走线长度去凑相位。电平修复之后时序裕量增大之前为了对抗错采样而乱调的寄存器值要全部恢复默认或者按标准值重新设置。我重新上电之后先用ethtool确认link speed回到了1000Mbps/Full再用自定义的UDP打流工具测丢包率从之前的惨不忍睹降到了0ethtool -S里的CRC errors也归零。那一刻才真正松了口气。之前软件里查来查去那些“一切正常”确实只是表象真正的瓶颈一直都在电气层。5.3 从链路到数据的完整验证方案修复完成不能只看一眼link up就收工。我建议按下面这个顺序做一遍完整验收物理层示波器再测一遍RGMII各关键信号确认高电平幅度和设计值吻合边沿无明显振铃和过冲。链路层ethtool查看自协商结果、link up状态、速率是千兆还是百兆。统计层ethtool -S看rx_crc_errors、rx_fifo_errors、tx_errors等计数器是否清零。数据层用iperf或者自写UDP工具做双向打流千兆速率下持续跑半个小时观察丢包率。压力测试同时跑DMA、大量中断、双网口收发确认负载下网络依然稳定。UDP测试我习惯分三种模式各跑一遍小包、大包、burst。小包重点看延迟抖动大包重点看吞吐burst模式重点看接收缓冲是不是会溢出。电平问题修复前丢包和乱序都很明显修复后包序号连续延迟稳定在几十微秒级别双向吞吐都能跑到900Mbps以上。把这些结果记录下来才算一次完整的验收。6. 设计阶段就该注意的事6.1 画原理图时先列一张“电平匹配表”踩过一次坑后我现在画任何带PHY的原理图第一步就是列一张电平匹配表。表里至少要有PHY芯片型号、PHY的VDDIO电压、RGMII接口实际工作电平、对端PS MIO BANK或PL BANK的VCCIO电压、MDIO/MDC对应BANK的电压。这几列逐项填完发现任何一组不相等就先改原理图而不是等板子回来再调试。另外提醒一个细节PL BANK电压不只是一个“电压值”问题还要检查这个BANK所有引脚上有没有其他3.3V外设。即使理论上BANK支持2.5V如果同一BANK还挂着3.3V的LED、SPI Flash、ADC之类器件那这个BANK就不能单独改成2.5V。要么把RGMII信号单独安排到一个独立BANK要么在硬件上确认那些3.3V外设本身也兼容2.5V逻辑。很多“改完电平板子直接点不亮”的后续故障都是忽略了同BANK其他器件的电平约束。6.2 高速接口的PCB走线与电平验证清单除了电平RGMII作为高速DDR接口对PCB也有一套额外要求。常见准则TXD[3:0]、TX_CTL、TX_CLK这6根发送信号尽量等长RXD[3:0]、RX_CTL、RX_CLK这6根接收信号尽量等长组间可以不严格一致。走线阻抗控制在50欧左右尽量有完整参考平面串阻按PHY手册选一般22到33欧。但这些属于第二优先。电平没搞对后面信号完整性优化得再好也没用。我给自己的检查清单排了个顺序电压对不对VCCIO与PHY VDDIOIOSTANDARD选没选对XDC里是否与BANK电压匹配走线阻抗和等长端接和串阻PHY内部延迟配置时钟与数据相位关系按这个顺序过一遍绝大多数RGMII异常都能快速定位。热词里那些“千兆网口电路设计”“rtl8211网口phy芯片什么场景会进低功耗模式”的问题很多到最后其实也是输在电压域这个起点上。我自己在这次项目里最大的体会是嵌入式里很多“数据异常”并不等于“逻辑错误”。示波器才是最终判官。尤其像RGMII这种高速接口逻辑电平、时序、信号完整性几条线互相纠缠任何一条的电气参数不达标表现都可能是一模一样的“通断续续、错包一片”。这次之后我每次画ZYNQ网口相关原理图之前都会先把VCCIO和VDDIO之间的匹配关系写进需求表里宁可多花十分钟确认也不愿意再花一整天去测。另外一个实用的小技巧送给正在调RGMII的朋友如果原理图阶段不方便确定BANK电压可以先把RGMII引脚集中放到一个备用BANK并在BANK上预留VCCIO跳线选择。这样后期调试时可以直接跳线切换电压做对比实验快速判断问题是出在电平还是出在时序。实测下来这点设计灵活性远比省几个引脚更有价值。