拓冰建站拓冰建站
首页 / 资讯中心 / 正文

FPGA网络通信设计:从RGMII到UDP收发通路全解析

从串口调通开始接触网络通信很多人会误以为只是换了个传输媒介结果一上手就被MAC地址、IP校验、帧间隙、时序收敛这些概念按在地上反复摩擦。说实话串口和网口之间的思维差距比UART和AXI之间的差距还要大串口是字节流你只需要关心波特率网口是数据帧你要同时处理位同步、字节对齐、CRC、跨时钟域、背压控制、还有上层协议语义。我当初从近似0基础开始学FPGA前几个部分都在做按键、流水灯、串口回环到了part.7想做网络通信才发现前面那些经验只能让我看懂波形不能让我直接写出一套能跑的MAC层。这篇文章就是给正在走同一条路的人准备的。我会从硬件平台、协议分层、UDP收发通路搭建、调试方法一直聊到后续向TCP/光口/PCIE扩展的思路。内容偏工程实操涉及Xilinx 7系列平台但架构思路同样适用于其他厂商的FPGA。无论你是刚学完时序约束还是已经开始看Tri-Mode Ethernet MAC的文档这篇都会有一点参考价值。1. 从串口调通到网口调通为什么很多人的第二步比第一步痛苦1.1 串口思维与网络协议的维度差异我见过很多同学把串口那套思路搬到网络上写个状态机把数据一位一位发出去然后看上位机有没有收到。串口确实是这样时钟来了就移位数据从TX脚出去对端按波特率采样没有帧的概念没有地址没有校验之外的任何协议负担。但网络通信不是这样。以太网帧有明确的结构前导码、帧起始定界符、目的MAC、源MAC、EtherType、负载、FCS。这些字段不是你想省就能省的。很多人第一次写MAC层发送逻辑觉得“我只是要把几个字节发出去为什么要凑够46字节最小帧长”于是写出来的帧在交换机上直接被丢弃或者在抓包里看到一串奇怪的短帧。这就是没有理解协议是分层约定的不是你自己的传输规则。到了IP层更麻烦。你要处理IP头校验和、分片、TTL还要搞清楚本机IP和对端IP存放在哪里。很多初学设计直接把这些地址硬编码在RTL里改一次IP就要重新综合一次工程虽然能跑通但离“设计”还有距离。UDP层相对简单源端口、目的端口、长度、校验和字段少是初学者切入网络通信的最佳切入点。1.2 我用RGMII初次调试失败的经历我第一次调试RGMII接口用的是Xilinx Artix-7加一颗国产PHY芯片。RGMII这个名字看起来只是“Reduced Gigabit Media Independent Interface”但真正调起来才发现它把时钟和数据的关系压缩到了极限DDR双沿采样、TXD和TXCTL要和对齐到时钟中心、发送时钟由FPGA输出、接收时钟由PHY恢复。这些细节直接决定你能不能跑起来。我当时犯的第一个错误是把RGMII的TX_CLK当普通时钟来约束没有做Output Delay约束结果链路偶尔通偶尔不通。更典型的问题是PHY芯片在复位后需要一段时间才能完成自协商很多人复位释放完立刻开始发数据PHY还在IDLE状态自然一个包都发不出去。后来我养成一个习惯复位之后至少等个几十毫秒或者干脆用状态机轮询PHY的状态寄存器确认Link Up以后再启动收发逻辑。这问题虽然最后查出来只是时序约束和复位时序但排查过程花了我整整一个周末。回头想想这不只是技术问题更是思考方式的问题串口调不通大概率是代码逻辑问题网口调不通可能是PCB布线、PHY配置、时序约束、时钟相位、FCS格式任何一个环节的问题。把这种多维排错思维建立起来才算真正进入网络通信设计的门槛。1.3 对“近似0基础”的建议路径如果你问我从零开始最省力的路径是什么我的建议是不要一上来就自己写完整MAC先拿厂商IP核或开源MAC核跑通一条收发回路把RGMII的时序和PHY的行为弄清楚再考虑把内部逻辑换成自己的UDP/IP实现。部分参考设计会让你误以为“调通了”就是“理解了”所以跑通之后一定要做两件事一件是把抓包波形对着协议文档逐字段分析另一件是把PHY寄存器的配置逐项查手册搞懂。这两件事做完你就有能力自己动手改造数据通路了。2. 硬件平台与PHY选型RGMII/SGMII背后的信号完整性问题2.1 PHY芯片与FPGA的物理连接网络通信设计的底层是物理层FPGA这边通常只做MAC层以上的逻辑PHY负责把数字信号变成差分模拟信号送到网线上。这个分工决定了你的硬件设计里必须有一颗PHY芯片常见的有RTL8211、KSZ9031、YT8521之类的千兆PHY接口模式有MII、RMII、RGMII、SGMII可选。对FPGA入门设计者来说RGMII是平衡复杂度与性能的选项。它用4根数据线加1根时钟线加2根控制线就能跑千兆。但这4根数据线在1Gbps速率下等效频率是125MHzDDR模式下每个时钟沿要传两个bit一个周期传4字节时序预算非常紧张。相比之下MII只有100Mbps时钟25MHz时序宽松得多所以也有人建议新手先从MII起步至少能把“能不能通信”和“信号质量好不好”分开考虑。我个人的观点是如果你手头开发板已经是RGMII了没必要退回去换MII。RGMII的困难主要在约束和调试但调试方法一旦掌握后面再做SGMII、光口会顺畅很多。千万不要在RGMII上跑不通就怪PHY芯片大部分问题都出在FPGA侧的输出时序和PHY配置上。2.2 7系列FPGA的Bank电压、时钟和复位设计选PHY还要考虑接口电平是否匹配。7系列FPGA的HP Bank支持1.5V、1.8V等HR Bank支持1.8V到3.3V而很多千兆PHY的RGMII接口是2.5V或3.3V电平。开发板上一般已经做好电平转换但自己画板子就得特别小心Bank电压没选对IO时序根本没法收敛甚至可能烧IO。时钟设计方面RGMII有两种模式。一种是PHY提供125MHz参考时钟FPGA通过MMCM/PLL生成125MHz发送时钟这种方案对时钟源质量要求高。另一种由FPGA提供25MHz或125MHz时钟给PHYPHY内部PLL生成125MHz这种对FPGA这边更主动但要注意PHY的时钟输入范围。无论哪种方式时钟引脚最好连接到FPGA的MRCC或SRCC引脚才能保证时钟树质量。还有一个容易忽略的细节是PHY的复位信号。很多PHY要求复位脉冲宽度大于10ms复位释放后还要等待时钟稳定和自协商完成。如果FPGA逻辑里只是简单拉高复位脚不给足够时间PHY会处于未就绪状态。我习惯把PHY复位放在FPGA复位管理模块里用计数器产生一个100ms的低脉冲然后等PHY的中断或状态寄存器报告Link Up。2.3 信号完整性走线、电平、上拉硬件层面RGMII的4根数据线加TX_CLK、TX_CTL长度尽量等长误差控制在50mil以内。对于入门设计做不到严格等长也不用过度焦虑因为125MHz信号大概对应60英寸的波长日常的走线偏差不会直接让通信失败但最好还是遵循这个原则能给调试省很多麻烦。PHY芯片的LED引脚、复位引脚、时钟引脚通常有内部上拉下拉配置。上电前建议核对数据手册里的strap pin默认状态因为很多PHY是靠这些引脚在复位后决定工作模式的。我一个朋友调试时发现PHY始终工作在100Mbps查了很久才注意到一个mode strap引脚被外部电阻拉错了电平导致芯片自动降低了工作速率。这个坑在RGMII调试里非常典型遇到速率不对、接口不通第一反应应该就是去看PHY寄存器或者strap配置。另外网络变压器的中心抽头接法、RJ45的屏蔽接地、差分对的100欧姆终端匹配这些直接影响物理层能不能稳定建链。这些偏硬件的知识往往不在FPGA教程里出现但它是“网络通信设计”无法绕开的一环。如果你用的是现成开发板这部分不用管你自己画板子一定把这几个点检查清楚再上电。3. 协议处理路径硬件逻辑实现UDP/TCP的分层设计3.1 为什么不在FPGA里直接跑协议栈聊到协议路径选择有人会问为什么不直接在FPGA里放一个软核或硬核CPU然后跑LwIP或者Linux协议栈这个方法确实存在而且对于功能复杂、业务灵活的产品是合理选择。它本质上是“用CPU的灵活性换取开发效率”在FPGA里跑软核处理ARP、ICMP、UDP遇到协议版本升级改软件就行。但这里有个概念必须分清楚如果是Zynq这种带ARM硬核的平台跑Linux当然可以但如果是纯FPGA如Artix-7、Cyclone V所谓“跑LwIP”通常意味着例化一个MicroBlaze或Nios II软核。软核跑协议栈会占用大量BRAM和逻辑资源数据吞吐也受限于CPU频率和总线带宽。做工业控制、数据采集这种低吞吐场景没问题但做视频传输、高速数据采集场景硬件逻辑实现协议路径才是主流。硬件实现协议栈的缺点是开发周期长调试困难知识点杂。优点是确定性极强不依赖操作系统调度每个时钟周期做什么逻辑都是固定的。用硬件逻辑做UDP并不是说你必须从零开始写CRC、写校验和而是你要理解这些功能块怎么组合在一起最终形成一条从用户数据到网线的完整通路。3.2 MAC、IP、UDP三个模块的职责划分我用硬件逻辑实现UDP收发会把它分成三个清晰层次MAC层负责以太网帧的组装与解析包括前导码、FCS校验、帧间隙、冲突检测半双工模式下、流控帧处理。IP层负责IP报文的封装与解封装处理源IP/目的IP、协议字段、IP首部校验和。UDP层负责端口路由和数据包长度计算UDP校验和可选但建议实现避免数据被静默丢弃。设计时可以采用流水线结构发送方向是“用户接口 - UDP封装 - IP封装 - MAC封装 - RGMII”接收方向相反。每一层只关注自己的头部字段不关心上层内容。关键一点是各层必须能独立被测试。在搭建完整通路之前我会先单独测MAC层直接构造一个以太网帧丢进发送方向用抓包工具或ILA看波形确认前导码和FCS没问题再往上加IP层。逐层搭建出了问题定位起来会快很多。3.3 跨时钟域处理与FIFO设计网络通信设计里很难绕开跨时钟域。PHY恢复的RX_CLK和FPGA内部用户逻辑时钟往往不是同源时钟发送方向也有TX_CLK和用户时钟的跨越。处理不好会出现偶发的数据错位或丢包。我常用的做法是异步FIFO。发送方向用户逻辑把UDP负载写到FIFOMAC发送状态机从FIFO读出数据并封装成帧接收方向相反MAC解析完帧后把负载写入FIFO用户逻辑异步读走。每个FIFO的读写侧分别用自己的时钟配合空满标志进行背压控制。背压控制是很多初学容易忽略的点。网络接口不能像串口那样“我发完就完事”因为PHY和交换机的处理速度是固定的如果你读FIFO的速度跟不上数据就会溢出。设计里必须考虑当FIFO满时发送状态机是暂停发送还是丢弃包接收方向是继续接收还是反压给上游。最简单的处理是FIFO快满时拉高暂停信号但这样可能会引入额外的延迟具体取舍要看你应用对时延的敏感度。4. 一步一步搭出UDP收发通路可复现的工程过程4.1 核选型Xilinx Tri-Mode Ethernet MAC 还是手写RTL搭建完整UDP通路第一步不是写代码而是选型。Xilinx 7系列提供Tri-Mode Ethernet MACTEMACIP核支持10/100/1000Mbps内部包含GMII/RGMII接口转换、FIFO、MDIO管理接口。用它最大的好处是省去大量MAC层兼容性细节缺点是IP核的接口和时序理解起来需要时间。我的建议是如果你是第一次做网络通信用TEMAC作为MAC层是个稳妥选择把精力集中在UDP和IP逻辑上。但不要完全当黑盒至少要把IP核的配置界面打开看看你选的接口模式、FIFO深度、是否使能FCS发送/接收校验这些直接影响后面逻辑怎么写。如果你手头没有这个IP核授权部分厂商需要购买也可以选择开源MAC核比如OpenCores上的ethmac或者自己写一个简化版MAC。自己写MAC初学做起来比较吃力但在调试过程中反而能把MAC帧格式理解得很透彻。我身边不少朋友是先用TEMAC跑通再回头手写简化MAC两条路都值得走一遍。4.2 收发数据通路的状态机设计我用一个简化例子说明发送数据通路的状态机设计假设要发送一个UDP包发送状态机状态可以定义为IDLE等待用户写入请求收到发送脉冲后跳转到PRE。PRE发送8字节前导码和SFD。MAC_HDR发送目的MAC、源MAC、EtherType0x0800。IP_HDR发送IP头20字节包含版本、首部长度、TTL、协议、源/目的IP、IP首部校验和。UDP_HDR发送UDP头8字节源端口、目的端口、长度、校验和。PAYLOAD从FIFO中逐字节读出用户数据。PAD如果负载不足46字节需要填充到46字节。FCS发送4字节CRC32。每一步的字节数、字段值、发送顺序都要对着以太网帧格式核对。实际写状态机时我习惯用一个字节计数器统一控制每来一个TX_CLK就计数一次这样状态切换的逻辑很清晰也不会出现某个状态提前退出或漏发字节的问题。接收方向是发送的逆过程先检测前导码然后解析MAC头判断EtherType是否为IP再解析IP头判断是否为UDP最后把负载写入FIFO。接收链路里最重要的是一定要做CRC校验FCS不对的帧必须丢弃。很多人第一次做接收时发现上位机收到的数据莫名多出几个字节就是因为MAC层没有正确识别帧结束位置或者把CRC也当用户数据交给了上层。4.3 时序约束从时序违例到收敛RGMII设计的成败很大程度取决于时序约束。我们通常需要约束三类路径发送时钟到RGMII输出引脚的路径使用set_output_delay保证数据相对时钟的建立保持时间符合PHY要求。接收时钟到内部寄存器的路径使用set_input_delay。内部跨时钟域FIFO的异步路径使用set_false_path或set_clock_groups处理。我建议调试时先用Vivado的时序报告确认约束是否生效。一个简单方法布局布线后看Post-Implementation Timing Summary里有没有RGMII接口相关的时序违例。如果提示RGMII信号上的延时不满足优先调整输出延迟约束而不是盲目去改逻辑。时序违例还有一个隐蔽来源RGMII的TXD、TX_CTL、TX_CLK三者的对齐关系。吉比特模式下TX_CLK是125MHz并且DDR沿采样很多设计者直接把TX_CLK接到ODDR原语输出一个时钟但数据路径可能没有经过同样的输出寄存器设置导致相移不一致。我一开始也是在这上面栽过跟头后来直接在TEMAC示例设计里看它对ODDR和约束的处理方法仿照那种写法才收敛。4.4 板级回环与上位机验证硬件调试验证是我认为整个环节里最考验耐心的一步。推荐顺序如下先用FPGA逻辑把发送和接收直接回环不经过PHY确认内部通路正确。再通过PHY回环模式很多PHY支持digital loopback确认RGMII接口时序没问题。最后接外部网线用PC抓包工具验证FPGA发出的UDP包是否被正确接收。从PC发送UDP包FPGA接收再通过串口或ILA观察数据是否正确。上位机工具选择很多Wireshark抓包能看到帧的每个字段适合检查协议格式自己写个Python脚本发包收包则适合反复压力测试。用一个Python脚本往FPGA发10000个UDP包FPGA接收后把收到的包数量返回给PC对比有没有丢包这是我最常用的验证方式。无论是哪个环节出问题都建议先打开Wireshark看帧内容而不是猜。还要提醒一点Windows防火墙可能默认拦截UDP广播包或者网卡驱动会过滤非本机MAC的帧。遇到包发不出去不用急着怀疑FPGA逻辑先检查PC网卡和防火墙设置。这类“非FPGA侧”问题是网络通信调试中的常见噪音。5. 从UDP到TCP再到万兆光口和PCIE进阶路线的取舍5.1 TCP状态机为什么比UDP难一个量级UDP跑通以后大概率会想实现TCP因为很多上位机通信都是TCP。但TCP比UDP难在状态管理远不止加几个头字段那么简单。TCP有三个核心问题可靠传输、流量控制、拥塞控制。这意味着你要在硬件里实现序列号管理、确认应答、超时重传、滑动窗口、慢启动、拥塞避免。这些东西在CPU上写协议栈只是调函数但在FPGA里要变成有限状态机。一个最简单的TCP发送状态机要处理SYN、SYN-ACK、ACK、FIN这些标志位的交互还要处理对端乱序包、重复ACK、超时重传状态数往往几十个。我见过不少项目直接用软核CPU做TCP控制面用硬件做数据面加速这种混合架构是比较务实的方案。对于入门者我不建议一上来就全硬件实现TCP。可以先做ARP、ICMPPing和UDP把基础打牢TCP可以先用软核跑LwIP等对协议有了整体把握再考虑把数据面改成硬件。这条路虽然绕了一点但最终做出来的系统更可靠。5.2 光口通信与SGMII的差异如果项目要求更高带宽或远距离传输会用到光口或SGMII。SGMII本质是串行接口速率1.25Gbps通过SerDes引脚连接PHY或光模块。它和RGMII最大的区别是并行转串行信号不再一堆线并行而是走高速差分对时序约束也变成Gigabit Transceiver的约束方式。这部分内容对新手跨度较大但对做过RGMII的人来说是自然的进阶。做光口通信时需要考虑的不只是协议还有物理层的光模块管理SFP的I2C接口、LOS信号、TX_FAULT信号、模块是否在位。FPGA侧通常不用自己处理PCS层直接用Silicon Image或Xilinx的1G/2.5G Ethernet PCS/PMA或SGMII IP核即可。如果直接跳到万兆光口比如10G Ethernet那逻辑设计会再上一个台阶数据宽度从8位变成64位时钟从125MHz变成156.25MHzMAC层要支持64B/66B编码处理逻辑的流水线复杂度显著增加。没有千兆的基础直接上10G会很痛苦。5.3 与PCIE、DDR等技术的结合网络通信设计最终通常不是孤立的往往要和PCIE、DDR、图像处理等模块协同。比如做数据采集卡数据从ADC进来通过网络发到上位机可能需要DDR做大缓冲PCIE做控制通道FPGA网络部分只负责数据搬运。这种场景下网络模块只是整个数据通路里的一环带宽匹配变得很关键。一个常见问题是DDR带宽是够的但UDP模块的处理带宽不够导致数据在缓存里堆积。这时候你可能需要把MAC和DDR之间的FIFO深度加大或者采用多队列调度策略把不同优先级的数据分开处理。调试这种系统时单纯用Wireshark看网络包还不够还要统计FPGA内部的丢包计数、FIFO水位形成一套从源头到目的端的完整监控链路。PCIE和网络结合还有一个很有意思的方向RDMA。虽然FPGA上的RDMA实现复杂但它解决的问题是CPU拷贝开销和高延迟在存储和高性能计算里很有价值。这块技术栈偏深建议先把PCIE基本读写跑通再研究ROCE协议。最后说几个我在网络通信设计里攒下来的经验第一点调网络通信不要一口气把代码写完再上板。先把发送链路做到“固定包长、固定内容、循环发送”抓包确认全对以后再改可变包长再改成FIFO加载数据。每前进一步都做一次回归验证能帮你精准锁定问题出现的位置。第二点学会看PHY的寄存器。很多不稳定现象比如偶发丢包、链路自动降速、CRC错误都是PHY芯片工作异常导致的光看FPGA内部逻辑根本定位不到。MDIO接口其实很简单花半天时间写一个寄存器读写模块调试时会救命。第三点不要把MAC层FCS校验和IP首部校验和搞混。MAC层FCS是CRC32覆盖整个以太网帧IP首部校验和是16位求和校验只覆盖IP首部。这两个字段在调试时经常被同时怀疑搞混了会浪费很多时间。FPGA网络通信这条路难度在于它是一个交叉领域要有FPGA时序设计能力要懂硬件信号完整性还要理解网络协议栈。单一知识背景都不够但它们之间有清晰的学习路径。从串口到MAC从MAC到UDP从UDP到TCP每一层解决一个具体问题脚踏实地上台阶最后回头看你会发现这个part.7真正教会你的不是网络协议本身而是一套从物理世界到数字世界的完整思考框架。
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门