如果你在Vivado的IP Catalog里直接输入“Ethernet”搜索,搜索结果里几乎总会躺着这么一条:1G/2.5G Ethernet PCS/PMA or SGMII。名字又长又绕,不少兄弟第一次看到就直接划过去了,但只要做FPGA以太网,你早晚要回来面对它。这个IP解决的是从MAC层到物理介质之间的那段链路,业界叫PCS/PMA,而SGMII是它最常用的一种串行接口形态。简单说,你的数据先由MAC整理成帧,接着PCS负责编码和链路管理,PMA负责把并行数据变成高速串行电信号送出去。这篇文章不打算帮你逐页翻译数据手册,而是把我调这个IP时踩过的坑和理清楚的逻辑一次说透。不管你是要把FPGA接到外部PHY芯片再出网口,还是两个FPGA用SGMII直接互联,又或者挂1000BASE-X光模块,这套IP基本都能覆盖。适合刚接触以太网的FPGA工程师,也适合被link_status折磨到怀疑人生的老伙计。
1. 先理解它到底搞定哪一段:从MAC到网口的最后一公里
1.1 以太网链路的“接力棒”到底怎么传
在写代码之前,我建议先花十分钟把链路模型理清楚。以太网发送数据可以简化成一条流水线:CPU或逻辑产生数据,交给MAC层组帧,MAC再把帧送到PCS子层做编码,最后交给PMA子层完成并串转换,信号才真正上到PCB走线。这条链路里每一层只认自己的接口,也只在完成自己那部分工作后把接力棒往下传。
具体到本文这个IP核,它覆盖的是PCS加PMA部分。MAC负责组帧、填充、FCS校验,IP核不关心这些;PCS负责8B/10B编解码、自协商状态机、时钟补偿和链路状态管理;PMA负责高速收发器的串并转换、时钟数据恢复CDR。很多人以为PHY芯片就是全部物理层,其实PHY芯片内部同样包含PCS和PMA,只不过被封装在芯片里了。FPGA里这个IP核只是把PCS/PMA用逻辑和高速收发器实现了,让你可以直接对接外部PHY,或者直接对接光模块。
举一个生活例子:MAC是负责打包发货的仓库,PCS是给箱子捆绳贴标签的工人,PMA是那条把货物送出去的传送带。仓库只管箱子内容是否正确,工人只负责标签和封装,传送带只关心箱子跑得快不快。分层明确意味着你可以单独排查任何一段,也意味着任何一段出了问题,表现完全不同。
1.2 为什么千兆时代大家更爱SGMII,而不是RGMII/GMII
如果你做过以太网,一定见过GMII、RGMII、SGMII这些接口名词。它们本质都是MAC和PHY之间的数据通道,差别在于位宽、时钟方案和引脚数量。
| 接口类型 | 数据位宽 | 时钟方案 | 典型引脚数 | 最大速率 | 主要痛点 |
|---|---|---|---|---|---|
| GMII | 8bit | 125MHz SDR | 24个以上 | 1Gbps | 引脚多,PCB布线拥挤 |
| RGMII | 4bit | 125MHz DDR | 12个左右 | 1Gbps | 需要处理DDR时序和IO延时校准 |
| SGMII | 1bit串行 | 1.25Gbps差分对 | 2对差分 | 1Gbps,可扩展2.5G | 需要高速收发器支持 |
GMII是老牌接口,8位并行数据加控制信号,一次就得拉十几二十根线,在现在动不动就多层高密度PCB上很不友好。RGMII把数据线砍到4根,用双沿采样换带宽,缺点是时序约束麻烦,源同步接口在FPGA里还得做IDELAY校准,稍不注意就出现偶发错包。SGMII则干脆把数据变成一对高速差分信号,引脚少、PCB好走线、EMI也更干净。
SGMII的“快”不是靠并行堆出来的,它靠的是线速率1.25Gbps承载1Gbps的数据,多余的0.25G是8B/10B编码开销。2.5G SGMII在此基础上把线速率拉到3.125Gbps,数据有效带宽到2.5Gbps。这样超千兆场景下,你不需要引入XGMII那样庞大的并行总线,一对差分线就能解决。所以我说SGMII是“最后一公里”的优雅解法。
2. 动手配置前,先想清楚三件事:模式、速率和角色
2.1 1G还是2.5G?看你的PHY芯片和收发器余量
配置这个IP核的第一道选择题,就是速率。1G SGMII是最成熟的玩法,市面上绝大多数千兆PHY都支持,PCB设计、变压器选型、连接器要求都非常成熟。如果你只是做常规千兆网口、工业通信板卡、或者和电脑直连调试,直接选1G就好,没必要给自己找额外麻烦。
2.5G SGMII适合那些带宽需求超过千兆但还不到万兆的场景,比如高速数据采集、视频传输、NAS加速卡。要注意的是,2.5G SGMII不是所有PHY芯片都支持,你得选像RTL8221、YT8531这类明确支持2.5G SGMII的PHY,并且PHY芯片在硬件上也要有能力完成2.5G电口或光口转换。另一个硬约束是FPGA里的高速收发器线速率必须覆盖3.125Gbps,这个一定在选型阶段就确认好,别等画完板子再发现GT跑不到。
我曾遇到一个项目,为了省成本选了老款FPGA,GT收发器最高线速率勉强卡在3.125Gbps附近,结果温度一上来误码率就开始飘。后来我们不得不把速率降到2.5G甚至退回1G用,整个架构全部推倒重来。现在我的习惯是选型时给线速率留20%以上余量,尤其是在2.5G SGMII这种刚好卡在GT中档速率的情况下。
另外要有个心理准备:2.5G模式下IP核的用户侧接口不再是标准8bit GMII,并行数据位宽和逻辑时钟都会变化。以Xilinx这套IP为例,2.5G模式下example design里会给出对应的用户侧接口,千万不要把1G模式的GMII引脚时序直接套进去。
2.2 MAC模式还是PHY模式?和外部PHY连接时这是生死线
这个点如果搞错,链路永远起不来,而且你排查三天都未必想到。SGMII协议本身是一个“MAC到PHY”的接口协议,自协商的机制是MAC侧主动发出包含速率和双工字段的配置字,PHY侧收到后回送确认。也就是说,SGMII两端必须有明确角色:一端当MAC,一端当PHY。
当你的FPGA IP核要连接外部PHY芯片时,FPGA侧必须处于MAC模式。PHY芯片通过strap引脚被配置成PHY模式,两者配合才能完成自协商。如果你去翻网络搜索热词,会发现有个高频问题叫“sgmii ip核与phy芯片一起使用时,应配置成mac模式”,说的就是这件事。反过来,如果你的FPGA要和一颗交换芯片连接,交换芯片内部通常是MAC侧,那FPGA里这个IP核就要配置成PHY模式。
我更想强调一个容易被忽略的场景:两个FPGA用SGMII直接互联。这时候没有外部PHY,两个FPGA之间依然是SGMII协议,那么必须一端配置成MAC模式,另一端配置成PHY模式,否则两边都等着对方先发言,自协商永远卡死。不少同学第一次做FPGA到FPGA的SGMII互联,两边都用默认的MAC模式,结果链路一直link不上,查了半天时钟和PCB,最后发现是角色没配对。
配置界面上通常有一个类似“SGMII PHY Mode”的选项,默认关闭。和外部PHY芯片连接时保持关闭,只有当你确定对端是MAC设备时才需要打开。这个开关的代价很大,但也很好验证:用MDIO去读PHY芯片的link状态,如果PHY侧一直在“等待AN”,而FPGA侧也一直在“等待AN”,十有八九是两边角色撞了。
2.3 SGMII和1000BASE-X,名字像但别混用
单看引脚和物理层,SGMII和1000BASE-X几乎一模一样,都是一对差分发送、一对差分接收,线速率都是1.25Gbps。但它们的协议语义不同。SGMII是MAC与PHY之间的接口,数据速率可以协商,并且带完整的MAC侧AN配置字;1000BASE-X是物理层PCS之间的连接协议,速率固定1G,自协商的内容主要是流控、远端错误等能力字段,和SGMII的AN机制完全不同。
实际工程里最常见的错误,是用SGMII模式去接一个1000BASE-X光模块,或者反过来用1000BASE-X模式去接一个SGMII接口的PHY芯片。结果往往是物理层信号看起来有了,但自协商永远过不了,或者链路偶发建立又马上掉线。接入FPGA之前,先确认对端设备到底是什么:交换芯片的SerDes口通常是SGMII或1000BASE-X可选,光模块几乎肯定是1000BASE-X,普通RJ45网口PHY芯片一般是SGMII接口。
3. 工程实现:从新建IP到链路打通的完整过程
3.1 Vivado里创建IP核的配置要点
在Vivado的IP Catalog里搜索“1G/2.5G Ethernet PCS/PMA or SGMII”,双击进入配置界面,马上会看到一堆选项。我这里不是让你照着点,而是告诉你每个关键选项背后影响什么。
第一,Interface Mode选择SGMII还是1000BASE-X,直接决定PCS内部的自协商状态机行为。如果你不确定,先想清楚对端设备,前面已经说过,这个选错是灾难性的。第二,Line Rate/Speed选择1G还是2.5G,这一步影响GT的线速率配置和用户侧接口位宽。第三,Transceiver选择要指定GT的位置和参考时钟源,参考时钟建议接到专用MGTREFCLK引脚,而不是普通IO或者内部逻辑分频时钟,这直接影响抖动性能。第四,Shared Logic选项建议在项目早期选择把共享逻辑放在core内部,减少外部接线;等你需要把多个IP核共用一组GT时钟时,再考虑放到example design里统一管理。第五,MDIO接口务必启用,后面调试外部PHY全靠它。
配置完成后,先打开IP核生成的example design,这是一个可以综合的完整参考工程。不要急着删掉它,里面包含GT位置约束、时钟约束、复位时序和上电顺序,这些是你自己写约束时最容易漏掉的东西。我通常的做法是在example design基础上做减法,保留时钟和复位部分,替换掉用户逻辑。
3.2 时钟、复位和MDIO:三个最容易翻车的细节
时钟方面,SGMII强制需要125MHz参考时钟,2.5G模式下参考时钟通常还是125MHz,因为GT内部的PLL可以把频率倍频到3.125Gbps。参考时钟的质量直接决定误码率,最好来自板载晶振或时钟芯片,再通过IBUFDS_GTE这类专用原语接入GT。不要在普通逻辑里做分频再送进去,哪怕频率对,抖动也大概率不合格。
复位方面,IP核会给出类似tx_reset_done和rx_reset_done的信号。上电后必须等待这两个信号都拉高,再开始向IP核发送数据。我看到太多人忽略这个时序,结果表现为第一帧必丢,或者链路偶尔通偶尔不通。复位释放过早,GT的PMA还没完成初始化和校准,数据进去就是乱的。
MDIO方面,和外部PHY芯片通信的调试手段就靠它。上电后先通过MDIO读PHY的寄存器0x0,触发软复位,再读0x1查看link状态,读PHY的模式寄存器和AN结果寄存器,确认PHY是否已经处于SGMII模式且AN完成。如果MDIO读不到数据,先查MDIO地址对不对、MDC时钟有没有、上拉电阻是否满足PHY芯片要求,不要一上来就怀疑IP核配置。
注意:MDIO地址不是“自动发现”的,它通常由PHY芯片的引脚硬拉决定。有的PHY默认地址和手册表格不一致,因为上电时锁存了错误电平。调试前用万用表量一下地址引脚最稳妥。
3.3 回环测试与链路验证:按层逐级打怪
我调试这个IP核的习惯是严格按照“PMA近端回环 -> 外部PHY回环 -> 真实设备互连”这个顺序进行,每一级都先证明自己这层没问题,再往下走。
第一步,配置IP核的PMA近端回环,让发送数据从GT内部直接返回到接收路径,不经过外部PHY。此时如果用户侧能看到自己发出的数据原样收回来,说明FPGA内部的GT、PCS、时钟链路基本正常。这个测试也验证了用户侧接口时序对不对。
第二步,关闭PMA回环,让信号经过外部PHY芯片。先在PHY芯片里配置回环,常见的有digital loopback或analog loopback,万兆以下的PHY基本都有,看寄存器手册就能找到。这时数据路径是FPGA发 -> PHY芯片 -> PHY芯片内部返回 -> FPGA收,能通就说明FPGA和PHY之间的SGMII接线、电平、耦合电容都没问题。
第三步,用真实网线连接电脑或交换机,做ARP或者ICMP测试。如果通了,恭喜;如果不通,抓包看前导码和FCS是否正常,同时检查MAC侧的发送时序。
回环测试通过并不代表自协商没有问题。自协商是另一套完全独立的状态机,回环绕过了AN,所以你可能碰到“回环全通,但真实链路link不起来”的情况,这时候回到第2章看角色配置和PHY的strap设置。
4. 常见问题与排查技巧实录
4.1 link_status一直为0,链路死活不建立怎么办
这个问题我调试时遇到最多,通常按以下优先级排查。
首先看接口模式:SGMII和1000BASE-X选错没有。这个前面反复强调,不再展开。然后看MAC/PHY角色:FPGA连接外部PHY时必须配成MAC模式。很多PHY芯片上电后默认不是SGMII模式,而是靠strap引脚决定,比如某些RTL8211系列要配成SGMII模式才能和FPGA的SGMII接口对接,否则FPGA发出的AN配置字它根本不响应。
接下来看MDIO能不能读到PHY寄存器。读不到就顺着MDIO的连线、地址、上下拉查下去。能读到但link_status始终为0,检查PHY的模式寄存器和AN使能位。最后检查参考时钟是否稳定,用示波器看125MHz的频率偏差和抖动,如果你用的是普通时钟芯片而不是低抖动晶振,很可能源头就埋了雷。
还有一个经常被忽略的:SGMII是点对点差分接口,FPGA的tx要接到PHY的rx,FPGA的rx要接到PHY的tx。不是像网线那样收发交叉的概念,但确实有人会把两个tx对接。这种错误原理图阶段不注意,DEBUG阶段要花很久。
4.2 自协商成功了,但数据发不出去或丢包
自协商成功只代表物理链路建立,不代表数据通路完整。这时候优先检查用户侧MAC接口时序。1G SGMII模式下,用户侧是类GMII接口,有tx_en,tx_er,txd[7:0]等信号,这些信号必须和IP核提供的时钟严格对齐。自研MAC最容易出的问题是前导码处理不对,或者发送过程中tx_er被无故拉高,导致对端网卡把包丢掉。
我建议先用最简单的ARP请求来测试,因为ARP包短、结构简单、不需要IP协议栈。先发固定长度的包,从64字节开始,再逐步加长,观察是否有长包特有的问题。如果你用到巨型帧,还要确认PHY芯片和PC网卡都支持。
另一个注意点:这个IP核不负责FCS生成和校验,那是MAC层的事。如果你的MAC没有自动计算FCS,发出的包在语义上就不完整,对端网卡会直接丢弃,表现就是ping不通但链路是好的。
4.3 2.5G模式下上不了速率或误码高
2.5G SGMII的线速率是3.125Gbps,相比1.25Gbps,对信号质量和时钟抖动的要求高了一个量级。如果你遇到“协商到2.5G但跑流就误码”的情况,先别急着换IP配置,按顺序检查这几项。
第一,参考时钟的抖动指标。用频谱仪看125MHz参考时钟的相噪,如果抖动大,优先替换低抖动晶振。第二,GT的发送预加重和接收均衡参数。不同的PCB走线长度、过孔数量、连接器质量,对均衡的要求完全不同,可以借助误码仪来扫参数。第三,PCB上的AC耦合电容、端接电阻、过孔stub长度。SGMII差分对上的焊盘和过孔都会引入反射,3.125Gbps时这些反射对眼图的影响会明显放大。
如果你用的是比较旧的FPGA架构,还要确认GT的线速率范围是否真的支持3.125Gbps,很多老器件标称最大速率是3.2Gbps,但留的余量非常小,温度一变化就出问题。我的经验是选型时直接跳过这种临界器件,省下的成本最后都会变成调试成本。
4.4 PC端网卡与驱动层面的干扰排查
调试FPGA和电脑直连时,一个经常被忽视的因素是PC侧的虚拟化软件。Hyper-V、VMware这些虚拟化平台会创建虚拟以太网设备,例如Hyper-V virtual ethernet adapter,并且可能把虚拟交换机绑定到物理网卡上。这种情况下你用Wireshark抓包,抓到的是虚拟交换机内部的流量,FPGA发过来的报文可能根本没到抓包接口,或者被虚拟交换机截胡了。如果PC端死活抓不到FPGA发来的包,先禁用虚拟交换机对物理网卡的绑定再试。
另外某些Intel网卡默认开启硬件卸载功能,TCP checksum offload、Large Send Offload这些,会导致Wireshark看到的报文校验和错误,或者看到超大帧。调试时建议临时关闭TX/RX卸载功能,并确认网卡驱动版本。驱动本身不是FPGA侧的问题,但排查时如果不排除,很容易把怀疑对象引错方向。
5. 容易被忽略的细节:MDIO、选型与PCB端接
5.1 MDIO地址冲突与PHY器件管理
一个MDIO总线上可以挂多个PHY,但每个PHY必须有不同的地址。实际项目里,板卡级联或者多网口设计时,MDIO地址冲突非常常见。PHY的地址由引脚在复位时的电平决定,有的PHY芯片还需要外部电阻上下拉,而不是芯片自动分配。
调试前先把PHY芯片的地址引脚电平量一遍,再通过MDIO扫描的方式读PHY ID寄存器,看看总线上到底有几个设备、地址分别是什么。如果你的板卡上有一排PHY,每个地址都核对一遍再写驱动,能省很多时间。MDIO时序也有一些坑,比如MDC的最小时钟周期、数据建立保持时间,很多PHY芯片要求MDC达到一定频率才能正确响应,如果总线过长还要考虑是否加缓冲。
5.2 器件选型时就要确认线速率余量
不要以为“支持千兆”就等于能跑2.5G,这个坑我前面已经讲过。再补充一点,即使选型表上写着线速率覆盖3.125Gbps,也要看参考时钟支持的频率范围、GT的锁相环配置是否方便。有些FPGA内部PCIe和以太网共用GT资源,你还要算好通道数,别等布局布线阶段才发现GT通道不够。
我的习惯是列一个选型表格,把线速率、参考时钟、GT数量、PHY接口类型、功耗都放一起,逐项打勾。特别是“FPGA线速率余量”这一项,至少要留20%以上余量。2.5G SGMII对很多中低端FPGA来说已经是高压区,慎重再慎重。
5.3 SGMII差分对的端接与耦合
SGMII在MAC和PHY之间通常采用AC耦合方式,也就是在差分线上串接电容。如果两块板互联,每块板上至少各放一个耦合电容,常见值在0.1uF到0.22uF之间,具体看PHY芯片手册要求。PHY芯片的SGMII输入侧往往内置端接电阻,但输出侧是否需要外加端接,一定要对照数据手册确认。
PCB布局上,SGMII差分对内等长、对外保持间距、参考地平面完整,这些基本功在1.25Gbps时可能还能凑合,到3.125Gbps就避无可避。另外注意不要在差分对上打太多过孔,尤其不要出现长stub。如果信号要从板边连接器走,预留好连接器的信号完整性参数,必要时在连接器附近留出均衡电阻的调试位。
调试到这个阶段,我最常做的一件事就是把PHY芯片的寄存器从头到尾dump一遍,特别是mode寄存器、link状态、AN完成位、速率协商结果。与其反复猜,不如一次看全。这套IP核本身不复杂,复杂的是它和外部PHY之间那些“看起来不重要但实际决定生死”的细节。项目做多了你会发现,SGMII链路建不起来,多半不是IP核的问题,而是你在模式选择、时钟、PHY配置和PCB端接这些地方埋下的雷。