ARTICLE DETAIL

资讯详情

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

ZYNQ PL端纯逻辑实现千兆UDP以太网,微秒级延迟

ZYNQ PL端纯逻辑实现千兆UDP以太网,微秒级延迟 做ZYNQ开发这些年以太网这块我大部分时间都是走PS端的GEM控制器Linux里一个socket下去UDP包就出去了。但这次项目不一样数据源是PL端的高速ADC甲方要求从采样到UDP包上线的延迟控制在微秒级而且要能完全自定义包内容。软件协议栈在这种需求下很尴尬——中断调度不确定、包格式不好定制、时序更没法精确控制。我索性把以太网MAC和UDP协议栈全放到PL里实现PHY用RTL8211跑通千兆和百兆自适应。整个过程踩了不少坑尤其是在RGMII时序和自适应切换上。这篇文章把我的完整实现思路、关键代码、实测数据和踩坑记录都整理出来给正在或准备在ZYNQ PL端做以太网开发的朋友做个参考。1. 为什么绕开PS端GEM非要在PL里做UDP1.1 PS端GEM方案的痛点ZYNQ的PS端自带Gigabit Ethernet MAC控制器芯片内部已经集成了DMA、描述符管理、MDIO控制器配合Linux的macb或gem驱动上电就能跑千兆网。很多项目用这套方案稳定且开发速度快。我之前的几个项目也都是这么干的但这次的需求让软件方案走不下去。第一是延迟。Linux协议栈从应用层write到数据真正出现在RGMII引脚上中间要经过系统调用、套接字层、IP协议栈、驱动、DMA描述符最后才到MAC。这个路径的延迟是毫秒级或至少几十微秒级别而且不稳定中断优先级、CPU负载、内核调度都会抖动。ADC数据要求微秒级出包这个路径完全无法接受。第二是包格式。软件协议栈只能按标准的IP/UDP报文格式发如果我想在以太网帧里塞自定义字段、自定义前导或者在包间隔里插入硬件时间戳软件方案基本没戏。硬件方案在这些方面自由得多。第三是PS端资源的消耗。ZYNQ的PS端跑Linux时以太网中断、DMA操作都会消耗CPU资源。如果PS端还要跑控制算法、人机交互、数据记录网络高负载时会挤占CPU时间。把网络处理下沉到PLPS就彻底解放了。1.2 三种方案对比做项目之前我把可选方案列了个对比表方案延迟吞吐能力包格式自由度开发复杂度资源占用PS Linux socket几十微秒到毫秒级不稳定可达千兆线速依赖驱动低只能标准报文低高占用CPUMicroBlaze LwIP毫秒级依赖软核中断百兆量级千兆很吃力中可部分修改中中纯PL逻辑MACUDP微秒级完全确定可满千兆线速高任意自定义高低不占CPU最终选择纯PL方案。PL里实现以太网MAC和UDP协议栈本质是构建一条纯硬件的数据通路应用数据写入FIFOUDP发送引擎从FIFO读出数据封装成帧过CRC32校验再经过RGMII接口送到RTL8211 PHY全部是组合逻辑加状态机的流水线没有软件参与。延迟可以做到几十个时钟周期。1.3 项目对带宽的真实需求这个项目的ADC是16bit、双通道、125MSPS理论数据率是500MB/s也就是4Gbps。显然单路千兆以太网扛不住原始码率所以前端做了压缩和数据抽取最终有效数据流约700Mbps左右。这个带宽值刚好卡在百兆和千兆之间所以PHY必须能跑到千兆同时为了兼容现场只有百兆网络的场景又要能自动降到百兆工作。这也是RTL8211这种千兆PHY最常见的应用场景——自适应能力必须可靠不能出现插上百兆交换机就断链的问题。2. 硬件搭台RTL8211电路要点与MDIO调试2.1 RGMII接口信号连接RTL8211和ZYNQ PL端通过RGMII接口连接信号组如下发送时钟GTX_CLK由MACPL提供千兆125MHz百兆25MHz发送数据TXD[3:0]4bit DDR发送时钟上下沿各送4bit发送控制TXD_CTL包含TX_EN和TX_ER同样是DDR接收时钟RX_CLK由PHY恢复从接收数据中提取的时钟接收数据RXD[3:0]4bit DDR接收接收控制RXD_CTL包含RX_DV和RX_ERMDIO / MDC管理接口PHY寄存器配置用RTL8211的模式配置是通过strap引脚在复位时采样的。我这里把PHY固定在RGMII模式PHYAD地址设成0x01。需要注意PHYAD引脚同时影响MDIO的访问地址如果设成多个值MDIO命令里的PHY地址必须对应。2.2 MDIO读不到PHY ID的问题第一次上电调试MDIO读寄存器2和寄存器3返回的全是0xFFFF。用示波器看MDC和MDIO波形是有的方向也没错但PHY就是不回答。后来查手册才发现问题RTL8211的上电时序里有个要求必须先给复位引脚一个低电平脉冲且低电平时间至少要10ms拉高之后还要等至少50ms内部时钟和寄存器才能稳定。我的板子复位信号是CPU GPIO控制的FPGA加载完驱动GPIO复位但MDIO状态机在FPGA配置完瞬间就开始轮询根本没给PHY留够初始化时间。解决办法是MDIO状态机加一个上电延时计数FPGA一下子配置完成后先等100ms再启动MDIO访问。这个延时用简单的计数器实现就行没必要用定时器。加上延时之后PHY ID能稳定读回来RTL8211E系列常见的ID是0x001CC9xx开头具体型号略有差异以手册为准。2.3 RTL8211关键寄存器配置RTL8211常用寄存器如下寄存器名称关键位作用0x00BMCRbit15 复位bit12 自适应使能bit13/bit6 速率选择基本控制0x01BMSRbit2 链路状态bit5 自适应完成基本状态0x04千兆控制bit8/bit9 千兆半/全双工广播千兆能力广告0x1APHYSR1bit15 链路bit14 双工bit13:12 速率状态监视0x1FRTL8211扩展配置可能影响RX时钟延迟等扩展实际配置流程是写寄存器0 0x1200开启自适应并重启协商写寄存器4 0x0140广
返回列表