尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

ZYNQ7035万兆网测速:瓶颈在DMA与缓存对齐,附调优技巧

ZYNQ7035万兆网测速:瓶颈在DMA与缓存对齐,附调优技巧 简介面向FPGA开发者的ZYNQ7035光纤接口万兆网测速完整工程基于Vivado工具链实现主控芯片为XC7Z035FFG900-2支持向XC7Z035系列其他型号移植可用于高速光纤通信链路调试与性能验证。压缩包共797个文件约160.78MB核心内容涵盖Verilog/VHDL源码、XDC引脚约束、DCP网表、Vivado工程与IP配置XPR/XCI、BIT比特流、LTX调试探针以及DO/VDS仿真脚本、TCL命令和RPT报告等便于直接编译和复现。当前已有476人学习下载。项目代码可顺利编译运行提供从RTL设计到上板测试的一整套万兆网测速方案能帮助开发者快速搭建基于ZYNQ的光纤收发平台理解高速串行收发器配置与回环测速流程显著降低高速接口开发门槛。1. 为什么ZYNQ7035做万兆网测速瓶颈不在MAC而在DMA与缓存对齐把ZYNQ7035的光纤接口跑上万兆说难不难XC7Z035的PL侧有足够的GTX高速收发器和逻辑资源Vivado里也有现成的10G Ethernet IP核可以直接例化。但真去测速就会发现光链路UP、链路层状态正常速率却始终卡在7Gbps甚至更低。做过几块板子之后我的结论是MAC和PCS层的设计Vivado已经替你包好了真正决定吞吐的是PS与PL之间的数据搬运——AXI DMA描述符的管理、缓存行对齐、中断合并的频率这三个点任何一个处理不合适吞吐就打不满。这篇文章按我实际搭建的顺序来讲从SFP光模块接入到Vivado里搭最小Block Design再到Linux下用iperf3测速最后落在几个能把速率从9.0Gbps顶到9.4Gbps的验证和排查技巧。适合手里有ZYNQ7035开发板、正在做网络转发或高速数据采集的FPGA工程师。2. 从光纤到PSZYNQ7035万兆链路的逻辑架构与关键选型2.1 光纤接口≠MACSFP、PCS/PMA与10G Base-R的关系很多人在Vivado里搜“光纤”找到IP核这是个常见误区。光纤接口本身是物理层的SFP cage和光模块对应到Xilinx体系下是GTX高速收发器外接的串行通道而万兆网要跑的是10G Base-R协议逻辑上分为PCS物理编码子层和MAC媒体访问控制层两段。ZYNQ7035的PL侧集成的是GTX收发器线速率最高12.5Gbps承载10.3125Gbps的10G Base-R信号绰绰有余不需要外部PHY芯片SFP光模块直连就可以。从协议分层看动态链接过程是这么串起来的GTX完成串并转换和时钟恢复PCS负责64b/66b编码、加扰以及链路同步状态机的维护MAC层处理以太网帧的封装、FCS校验和流量控制。在Vivado里用Xilinx官方提供的AXI 10G Ethernet IP核实际是把MAC和PCS打包给了你对外暴露两类接口一侧是串行的GTX引脚接SFP另一侧是AXI4-Stream数据接口接到DMA或FIFO。这意味着你不用关心64b/66b编码细节但必须清楚PCS层有一个“链路同步”状态link-up要在这里确认。ZYNQ7035开发板上SFP通常接在Bank 115或Bank 116等有GTX的Bank上参考时钟大多用156.25MHz。需要注意参考时钟的来源是板上晶振还是由PS端可配置时钟输出。这个时钟抖动直接影响PCS层误码率布局布线时它与GTX的引脚分配要优先满足同一Bank约束后面在XDC里会体现。2.2 两条技术路线PSLinux方案与PL纯逻辑方案万兆测速的落地路线工作量差异很大得先选清楚。我一般根据测试目的来分要测“链路能通多快”选PL纯逻辑方案要测“系统能转发多快”选PSLinux方案。PSLinux方案的核心是把AXI 10G Ethernet IP挂在PS的HPHigh Performance口或ACP口上再用AXI DMA做数据搬运。PS上跑Linux和网络协议栈应用层用iperf3测试。这条路线贴近真实服务器网卡的使用模型TCP/IP收包、协议栈处理、socket开销都算进去了测出来的结果和商用网卡对比有参考性。代价是IP核配置项多DMA描述符管理要在驱动层做对排查链路要跨PL和PS两层。PL纯逻辑方案不经过PS在PL内部自己写一个发包模块比如固定构造UDP帧通过AXI4-Stream直接喂给10G MAC收端用计数器或者ILA抓波形统计。这种方式适合验证链路质量或做数据采集板卡因为避开了OS和驱动的不确定性能测出纯MAC层的最高线速。但注意它测的不是“万兆网”的端到端性能光纤对端还得有一台能打满万兆的仪表或服务器。两条路线的关键参数对比如下对比项PSLinux路线PL纯逻辑路线IP核选择AXI 10G Ethernet AXI DMA任意厂商10G MAC 自研数据产生模块数据接口AXI4-Stream / AXI4-Lite配置自定制Stream接口测速工具iperf3、ethtool、ifconfigILA抓包、帧计数器主要瓶颈DMA描述符、中断、CPU调度MAC收发FIFO深度、时序收敛适用场景网络转发、协议栈测试、服务器板卡线速采集、协议卸载、波形抓取2.3 数据通路设计AXI DMA的SG模式为何是默认选择在PSLinux路线里数据通路设计成“PS配置PL搬运”的双通道结构。PS的M_AXI_GP口用来读写IP核的控制寄存器比如通过AXI4-Lite配置MAC地址、速率、流控等数据本身走AXI DMADMA挂在HP口上带宽足够不占用CPU去逐字搬运。AXI DMA有三种模式Direct Register模式适合单次传输且数据量小SG模式适合大块连续传输并支持描述符链表CDMA专门做内存到内存拷贝这里的网络场景通常只用SG模式。SG模式的好处是CPU只需在初始化时把描述符链表放到内存里DMA传输完成后通过中断通知CPU收包和发包可以在描述符上并行推进从而把吞吐打开。描述符每一项里包含地址、长度、控制字和下一项指针驱动要保证这些结构在物理上是连续的或者用IOMMU映射过。一个常见的坑AXI DMA的S2MM通道收方向要求缓冲区地址至少按缓存行对齐但Linux协议栈分配的skb缓冲区起始地址是可变偏移的直接交给DMA写数据可能导致部分缓存行被覆盖而引发一致性问题。正确做法是在设备树里给DMA分配专用的、对齐过的DMA内存池或者驱动里用dma_alloc_coherent申请一致内存。设备树里大致是这样描述的axidma: dma40400000 { compatible xlnx,axi-dma-1.00.a; reg 0x40400000 0x10000; dma-channels 1; dma-channel { interrupts 0 29 4; xlnx,include-sg; }; }; axiethernet: axiethernet40c00000 { compatible xlnx,axi-ethernet-1.00.a; reg 0x40c00000 0x40000; local-mac-address [00 0a 35 00 01 22]; xlnx,has-statistics; };这里的xlnx,include-sg一定要保留它使驱动进入SG模式如果删掉DMA只能做单次传输吞吐会退化到几百Mbps。reg的基地址来自Vivado地址编辑器里PS给IP核分配的地址每个工程不一样不要直接抄要看Address Editor的映射。3. 在Vivado里把万兆链路搭起来最小Block Design与关键参数3.1 Block Design的最小组成PS、AXI 10G Ethernet、DMA、Clocking Wizard在Vivado 2023.2里新建Block Design最小能跑通万兆链路的连接方式我固定用这几组ZYNQ7 PS、AXI 10G Ethernet、AXI DMA、Clocking Wizard、以及Processor System Reset。PS的HP口通过AXI Interconnect接DMA的S2MM和MM2SPS的GP口接10G Ethernet的AXI4-Lite配置口和DMA的AXI4-Lite寄存器口。以太网IP的中断和DMA的中断分别接到PS的PL-PS中断端口上Vivado会自动分配中断ID但建议手动固定两个不同的中断号方便Linux侧确认。Clocking Wizard在这里起两个作用一是给AXI DMA和10G MAC生成核心时钟二是给GTX的参考时钟做缓冲。参考时钟的选择有个细节如果板上SFP模块的参考时钟是独立晶振直接约束为GTX专用时钟引脚如果是由PS MGTREFCLK输出的则需要在Vivado中配置为使用PS侧时钟资源这时PS内还要开启对应的时钟输出。务必先看原理图再配置这一步错了波形能生成但光模块不会亮。连接完成后Validate Design会提示必需的连接比如AXI 10G Ethernet的axi_txd_arstn复位要靠Processor System Reset的输出。这里有个容易漏的10G MAC的复位必须处于“低有效”状态和DMA的复位极性一致否则上板后一侧能起来另一侧永远在复位状态现象就是link up了但收发计数为零。3.2 10G Ethernet IP核参数参考时钟、MAC地址与Flow Control双击AXI 10G Ethernet IP核参数页里需要逐项确认。“Physical Interface”选“GT”表示使用GTX收发器参考时钟频率根据原理图填156.25MHz“Speed”固定10G“MAC”选项勾选“Include AXIlite”用来做寄存器配置“Flow Control”建议先关闭特别是做测速时不希望pause帧影响吞吐结果。RX和TX的复位阈值保持默认的100us即可。有一个参数是“Statistics Counters”建议开启。它会把MAC层的收发帧数、CRC错误、FCS错误统计到一组寄存器里Linux下可以用ethtool把这些计数器拉出来对后面判断丢包到底发生在MAC层还是DMA层非常关键。如果嫌寄存器数量太多也可以只在调试版本的工程里开量产时再关掉以节省面积。AXI DMA的参数设置更需要注意收发两个通道都要选择SG模式地址位宽跟随AXI互联设置为64位缓冲区长度寄存器位宽保持默认的26位最大支持64MB传输但实际驱动里会用32KB左右的描述符缓冲区没必要改大。DMA的微DMA功能在ZYNQ7045上验证过有兼容性问题ZYNQ7035上我干脆关闭省得Linux驱动适配时多一个变量。生成比特流之前跑一次综合资源评估至少要心里有数。我在XC7Z035上实测AXI 10G Ethernet AXI DMA AXI Interconnect的组合大约消耗2.4万个LUT和3.1万个FFBRAM约15块占PL资源20%上下。如果看到LUT占用超过40%多半是AXI Interconnect的数据宽度设置成了256bit导致跨时钟域逻辑膨胀改成与DMA一致的64bit即可。3.3 管脚约束与时钟约束XDC里必写的三行Vivado综合布线后生成比特流失败常见原因不是逻辑错误而是约束缺失。最小系统至少要写三组约束SFP收发引脚、GT参考时钟引脚、以及SFP的MOD_ABS和TX_DISABLE控制脚。GT收发引脚通常由Vivado根据IP核配置自动分配不需要手写但参考时钟的管脚声明必须写在XDC里。参考时钟约束示例set_property PACKAGE_PIN AH12 [get_ports gt_ref_clk_p] set_property PACKAGE_PIN AH11 [get_ports gt_ref_clk_n] set_property IOSTANDARD LVDS [get_ports {gt_ref_clk_p gt_ref_clk_n}] create_clock -name gt_ref_clk -period 6.4 [get_ports gt_ref_clk_p]第一行指定差分时钟P端引脚第二行指定N端第三行设置电平标准为LVDS第四行创建周期为6.4ns的时钟约束对应156.25MHz。注意GT参考时钟的约束不要用get_pins去绑定GT内部节点只约束到顶层端口就够了Xilinx会自动传递给GT的专用时钟网络。如果板上的参考时钟实际是125MHz-period要改成8ns而不是去改IP核里填的156.25MHz否则时序分析会报大范围的hold violation。SFP控制脚的约束里有个容易忽略的TX_DISABLE这个引脚必须初始化为低电平否则光模块发送端被强制关闭。有的开发板这个脚被上拉到高硬件上也没有跳线那么必须在XDC里加set_property STARTUP_WAIT或者在FSBL里初始化GPIO不然链路永远无法建立。4. Linux下用iperf3测速从能ping通到跑到9.4Gbps4.1 设备树匹配与驱动加载先确认irq和dma都映射对上板后先不急着跑iperf先用Linux的启动日志确认三个设备都枚举成功。开机后执行dmesg | grep -i xilinx应该能看到axiethernet、axidma、interrupt-controller三条记录。如果只看到Axi Ethernet但没有DMA多半是设备树里DMA节点的中断号被PS中断控制器占用如果两个设备都有但ifconfig看不到网卡接口重点查AXI地址是否和Vivado的Address Editor一致。接口起来之后用ethtool eth0确认速度和双工模式ethtool eth0 ethtool -S eth0第一条命令会显示Speed: 10000Mb/sDuplex: Full第二条拉出MAC层统计。重点看rx_total_bytes是否随着外部打流在增长如果链路已link-up但字节计数不动问题不在MAC而在DMA收方向要么描述符没准备好要么中断没分配对。此时用cat /proc/interrupts看DMA对应的中断号是否在增长中断号增长而字节数不增长说明收的是空描述符。还有一个我踩过的坑驱动默认会打开RX和TX的coalesce中断合并。中断合并虽然能降低CPU占用但合并时间太长会把小包堆积起来导致iperf单流速率上不去。测速之前用ethtool -C eth0 rx-usecs 8 tx-usecs 8把合并时间降到微秒级吞吐会有明显提升。4.2 iperf3测速单流与多流分别能说明什么问题测速命令按照常规iperf3用法就好。服务端在ZYNQ7035板卡上iperf3 -s -p 5201PC端作为发送方iperf3 -c 192.168.1.10 -p 5201 -t 30 -u -b 8G这里-UDP测的是纯数传能力8Gbps的带宽设置是为了留出余量观察丢包。TCP测速时加-P 8开8个并发流避免单流受TCP窗口和CPU单核限制。记录几个典型数据点单流UDP如果只能到8.5Gbps大概率是DMA或PCIe侧的瓶颈多流TCP如果总和到9.2Gbps以上而单流到不了4Gbps大概率是ZYNQ7035的PS侧两个A9核跑协议栈已经到极限了和PL侧的MAC没有关系。测速过程中同时用top观察CPU占用会发现irq线程占满一个核。这是预期现象10G线速的收包中断频率很高PS只有一个双核A9协议栈吞吐上限大约在6到9Gbps之间主要取决于包大小。MTU从1500改到9000jumbo frame吞吐通常能涨20%到30%因为单位包处理开销摊薄了。板卡和对端服务器都要同时改MTU只改一端会分片效果反而更差。4.3 从9.0到9.4调缓冲区、CPU亲和性、DMA一致性如果UDP测试已经在9Gbps附近想再往上挤一点按顺序做三件事。第一增大DMA接收环形缓冲区的描述符数量。默认驱动里rxringsize是128改成512可以在突发流量下减少丢包但代价是内存占用增加ZYNQ7035的DDR资源足够放心改。第二把处理中断的CPU和iperf进程绑到不同核上。设置echo 2 /proc/irq/irq/smp_affinity后DPDK或协议栈处理线程占用另一个核避免两个核争抢同一个缓存行。第三件事比较隐蔽AXI DMA的S2MM通道在单次传输结束时会写一个状态字节到描述符里如果这个描述符所在的内存被CPU缓存了DMA写入和CPU读取之间需要一次dmac_flush次数多了会直接降速。解决方法是驱动里用dma_alloc_coherent分配描述符内存保证它的一致性属性而不是用kmalloc加手动flush。改完这三点同样是UDP 30秒测试速率能从9.0Gbps波动爬到9.3到9.4Gbps线速上限约9.42Gbps10G扣除编码前导与IFG的物理极限再高就该怀疑光模块或光纤质量了。5. 测速结果验证与异常分析一跑就断、速率上不去的排查技巧5.1 用ethtool计数器定位丢包层测速结果不理想第一步不是改代码而是看计数器。执行ethtool -S eth0只关注四类字段rx_total_bytes和tx_total_bytes看宏观通量rx_crc_errors判断物理层误码rx_fifo_errors判断DMA收FIFO是否溢出rx_errors是MAC层收包错误汇总。如果CRC错误很多说明光模块或光纤链路易出问题GTX方向的信号完整性不达标优先换一根短一点的光纤试试如果CRC很少但rx_fifo_errors持续增长问题就在DMA来不及搬数据检查DMA中断和描述符在设备树里是否绑定正确。5.2 用环回拆解问题把PL层和PS层分开验证ZYNQ7035里有一个更快的拆解手段把AXI 10G Ethernet的TX和RX数据通路内部环回打开。IP核的寄存器里有一项loopback模式设为“MAC local loopback”之后数据从DMA发出就直接回到接收端不经过SFP光口和物理光纤。此时用iperf打到本机ZYNQ7035的IP如果速率也能到9Gbps说明DMA和MAC都是好的排除发问题到最后的光模块和光纤如果环回都跑不满就老老实实回到第4章的调优顺序去检查DMA不要折腾对端光纤链路。5.3 一个容易忽略的细节SFP的link-up时间与FEC阈值最后提一个现象跑速过程中偶发链路断开又立即自动恢复表现为iperf出现几秒的gap或重传但ethtool eth0看到的link一直是up。这通常是PCS层发生误码触发了链路重同步而MAC层中断没有上报。对策是检查SFP模块是否支持10G Base-R自协商ZYNQ7035的AXI 10G Ethernet IP默认关闭自动协商如果对端光模块强制开启自协商两边就会反复切换。建议两端都设置强制10Gfull并在IP核内关闭autoneg再看连续12小时长时间压测的rx_crc_errors确认FEC没有隐性问题。本文还有配套的精品资源点击获取
返回列表