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

资讯详情

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

开源100G FPGA UDP协议栈移植上板全过程解析

开源100G FPGA UDP协议栈移植上板全过程解析 “开源 100G FPGA UDP移植上板测试”——这个项目标题放在国内FPGA圈子里懂行的人一眼就知道分量不轻。100G以太网一直被视为通信、数据中心、高性能计算领域的高端玩法早几年基本只有大厂自研或者高校实验室在搞普通工程师连个参考设计都很难找全。但这两年开源社区把不少核心模块陆续放了出来加上Xilinx/Intel的开发工具链越来越成熟自己动手把一套开源UDP协议栈搬到100G平台上已经变成一件“跳一跳够得着”的事。我这篇就来完整记录一次从代码仓库到手跑上板的移植测试过程包括开源方案怎么选、代码架构怎么看、时序和约束怎么改、上板之后用什么办法验证数据对不对以及那些文档里绝对不会告诉你的坑。如果你正准备吃透100G UDP或者公司有类似的高带宽传输需求这篇应该能帮你少走至少两周弯路。1. 整体方案设计与选型思路1.1 为什么是100G UDP而不是TCP或者RoCE先说实话100G TCP在FPGA上做完整卸载栈不是不行但复杂度完全不在一个量级。TCP有连接状态、重传机制、拥塞控制窗口、乱序重组这些逻辑想在FPGA里用寄存器级电路写完光状态机和超时管理就够喝一壶的。而UDP是无连接的报文头固定8字节校验和可算可不算IPv4下允许填0整个协议栈核心逻辑其实就是三件事MAC帧收发、ARP/ICMP响应、IP/UDP头组包拆包。这三件事在硬件逻辑上非常好流水线化用Verilog或者SystemVerilog写起来能控制在很小的资源占用里。再一个现实问题是很多应用场景根本不需要TCP的可靠传输。比如多通道ADC数据采集、雷达回波采集、图像传感器数据汇聚、高速仪器仪表数据回传这类场景的特点是数据单向流、丢包可以容忍、时延越短越好。100G UDP天然适合每条通道的带宽能拉满端到端时延在微秒量级把所有业务逻辑全跑在FPGA上不需要经过CPU也就不存在中断和调度抖动的问题。Intel和AMD这两年的官方IP也都支持100G MAC/PCS但商用IP授权费高、加密黑盒出了bug只能提case等官方回复。而开源方案源码全在手上逻辑可以自由改甚至可以插桩调试对做产品原型验证来说灵活度完全不一样。1.2 开源方案怎么选从10G迁移到100G的常见路线目前Github上主流的开源FPGA以太网项目顶层思路非常接近。最早被大家广泛使用的是Alex Forencich的verilog-ethernet这一套代码风格极其工整从10G MAC、25G MAC到100G MAC都有覆盖而且RTL和testbench分离得特别清晰非常适合当“母版”来做二次开发。另一个方向是OPAE社区里的某些加速卡参考设计但那套更偏整体平台不是专门为UDP协议栈服务的移植成本反而更高。在我这次项目里选型原则就三条代码必须支持独立的MAC/PCS层和独立的UDP/IP层中间接口是标准的AXI4-Stream这样我可以只替换MAC层用户逻辑不用大改。时钟结构必须允许从单通道10G/25G平滑扩到多通道100G。100G在MAC内侧基本都是256位或者512位数据总线这是硬性约束如果源项目只支持64位总线改造量会大很多。最好自带或容易补出ARP和ICMP响应模块否则上位机要ping都ping不通调试网络环境会非常痛苦。最终我选了一个基于verilog-ethernet风格扩展出来的开源分支核心组件包括100G Ethernet MAC、PCS/PMA如果是跑光模块还得有RS-FEC、AXI-Stream接口的UDP/IP卸载引擎、ARP缓存模块、以及一个简单的DDR4缓冲接口。这套组合允许我完全绕开厂商的MAC IP在UltraScale器件上实现了单端口100G数据通路。1.3 影响范围这活儿涉及的软硬件边界这里要把项目的边界讲清楚避免有人拿着开源核心里的一小段代码就跑去做系统集成。100G UDP上板测试完整链路包括四个环节硬件平台至少需要一块带100G QSFP28接口的FPGA加速卡比较常见的是Xilinx VCU1525、VU9P/VU13P系列或者Intel的A10系列。我这次用的是VU9P级别配了两路QSFP28。开源IP改造把Github上的MAC和UDP换层代码适配到当前FPGA型号、约束和时序。用户业务侧FPGA内部需要有一个发包逻辑或者收包逻辑来验证通路通常是一个PRBS发生器和一个帧计数器。测试环境需要一台支持100G网卡的上位机或者一台100G交换机配合iperf3、tcpdump、Wireshark做数据验证。这套东西一旦打通就可以往里面填任何业务模块比如DDR4读出的波形数据直接往UDP帧里塞或者接收端从UDP帧里解出控制命令去配置寄存器。这也是这类开源移植项目最大的价值——把“通道”打通业务上就有无限可能。2. 核心代码架构与关键模块拆解2.1 整体数据通路从MAC到UDP换层再到用户接口我换过来的这套架构数据通路像一条清晰的流水线。发送方向是用户逻辑产生AXI-Stream数据带TLAST和TKEEP信号进入UDP/IP发送换层之后被逐层加上UDP头部、IP头部和MAC头部同时插入CRC校验接着进到MAC发送FIFO被PCS层编码成64B/66B送进SerDes到光模块。接收方向则完全反过来光信号经过PCS解码后进MAC接收FIFO去除CRC和MAC头进入UDP/IP接收换层判定目的MAC、目的IP、协议类型最后只把UDP的payload连同用户自定义的元数据一起送给用户逻辑。这里最需要理解的一点是TLAST和TKEEP的重要性。100G跑起来之后一拍数据就是256位一帧包可能占好几拍。TLAST标记一帧的最后一拍TKEEP标记这一拍里哪些字节有效。开源代码里所有模块都对这两个信号严格按AXI协议处理如果你自己的用户逻辑没有完整支持这对信号或者置位时机不对轻则包长统计错乱重则整个链路直接卡死在状态机上。我第一次接用户逻辑时就因为TLAST晚了一拍释放导致MAC侧老是在等下一拍数据吞吐量只有2Gbps左右查了一整天才定位到。2.2 UDP/IP换层里那些容易被忽略的细节UDP/IP换层在开源代码里通常拆成两个小模块发送端叫udp_tx接收端叫udp_rx。发送端的核心任务有三个解析用户侧的“地址向量”目的IP、目的MAC、目的端口、源端口、包长生成UDP头并计算长度字段填充IP头设置总长度、标识、协议号17、源IP目的IP然后把整个帧交给MAC层。要注意的是IPv4头里的校验和是必须算的而UDP校验和在IPv4下是可选的很多开源实现默认填0实际测试中绝大多数交换机也不核查UDP校验和能省不少逻辑。接收端的任务恰好反过来看到以太网类型字段是0x0800并且IP协议号是17判定是UDP包然后查目的IP是否和本地配置一致目的是MAC地址是否匹配再往下解析UDP端口号和payload长度把payload数据和“元数据”源IP、源端口、包长一起转发给用户逻辑。这里隐藏着一个大坑以太网有最小帧长64字节的规定因此如果用户发的UDP包太小比如只有16字节payloadMAC层填充到60字节最后CRC补成64字节整个帧底层会自动有填充字节。很多开源的udp_tx模块不会帮你自动做填充需要你在用户逻辑侧判断“包长小于46字节时补零”。否则接收端抓包会看到帧长不足64字节的异常报文严重的会被交换机直接丢弃。2.3 100G特有的时钟域与总线宽度设计到了100G这个级别时钟和总线宽度就不是“随便写写能综合过”的事了。100G以太网在MAC层内部数据总线常见的有512位、256位、128位三种配置。总线越宽时钟频率越低。选256位总线时内部用户接口时钟大概在390.625MHz100G速率扣掉前导码和CRC之后的有效速率等于总线位宽乘以时钟频率。如果选512位就是195.3125MHz逻辑好收敛但FIFO的写侧要积累大量数据才能拼满一整拍对突发短包场景反而增加时延。建议直接把总线和UDP换层的数据宽度绑死不要做跨位宽转换。比如换层输入输出都是256位那么用户侧FFT算法、数据发生器、DDR4读控制也尽量统一成256位数据粒度。一旦你在中间插了一个64转256的异步FIFO不仅多出延迟和资源时序收敛的难度也会明显上升。实测下来256位总线配合250MHz的DDR4时钟整条逻辑链路时序裕量都在工艺库给定的要求范围内。时钟结构上FPGA内部通常有四种时钟域用于SerDes恢复的RX recovered时钟并行域、用于MAC发送的TX时钟域、用于UDP换层和用户逻辑的业务时钟域以及用于寄存器配置的慢速时钟域比如100MHz的AXI-Lite。99%的移植卡顿问题都出在这几个时钟域的处理上所以开源代码里所有跨时钟边界都用了同步FIFO或者握手同步器这个不能删千万别为了省几个block RAM就把FIFO改成直连时序崩了想哭都来不及。3. 移植上板的实操流程3.1 环境准备工具链、IP和硬件检查清单这次移植用的工具链是Vivado 2023.1目标器件是XCVU9P-L2FLGA2104E。拿到一套开源代码之后不要急着直接生成比特流先检查三件事第一开源代码里的原语调用和你当前的FPGA型号是否兼容。比如100G MAC的PCS层可能会调用GTY Transceiver原语如果你的板卡是GTH或者只有10G光口那整个PHY侧都必须替换。第二检查参考时钟频率。QSFP28通常需要156.25MHz或者161.1328125MHz的REFCLK这个由板卡上的晶振决定。如果项目代码默认用的是161.13MHz而你板卡只有156.25MHz那么MAC的线速率配置需要从100G标准里的对应方式重新计算不能硬用。第三确认板卡上的QSFP28供电和控制引脚有没有被其他逻辑占用。很多加速卡上QSFP28的I2C、复位、中断引脚都连到了FPGA的特定管脚开机后没做初始化光模块可能会锁死在低功耗模式导致链路起不来。检查完这些再新建一个RTL工程把开源代码所有.v/.sv文件加进去并创建一个顶层wrapper把GTY的参考时钟输入、QSFP28的串行收发引脚、状态LED、调试串口等管脚全部例化好。这个wrapper同时要例化一个简单的AXI-Lite寄存器模块用来读取MAC的状态寄存器和统计计数器这对后边调试太重要了。3.2 移植过程中必须改的三类代码第一类需要改的是厂商原语和硬核IP。比如GTY Quad的例化代码、IBUFDS_GTE4参考时钟输入缓冲、以及100G硬核PCS的复位逻辑。这部分引用到了Xilinx原语Verilog里名字通常带“GTE4_COMMON”或“GTYE4_CHANNEL”如果直接综合会报找不到模块。最稳妥的方法是打开Vivado的IP Catalog搜索“100G Ethernet”生成一个相同配置的IP核然后用IP核的example design里的GTY wrapper替换开源代码里的原语例化。这样能保证PHY和PCS的配置完全匹配当前器件。第二类需要改的是时序约束文件。开源项目通常自带XDC但那是针对原作者的板卡写的管脚名、时钟名全都不一定对得上。这里我强烈建议不要直接在旧XDC上改引脚而是从零新建一个约束文件。至少需要约束输入参考时钟、GTY的各个通道引脚、复位按钮、LED输出、业务逻辑中与其他模块互联的信号。如果约束不全Vivado综合时会自动推断出一些不合理的时钟关系时序报告里面一堆fail看着头皮发麻。可以用create_clock把GTY参考时钟约束好再用set_input_delay和set_output_delay把业务侧跨板卡的IO时序约束好。第三类需要改的是顶层参数。最常见的是MAC地址、IP地址、端口号、以及UDP换层的最大包长。这些参数一般定义在eth_mac_100g_common.vh或者udp_ip_defs.svh文件里。务必把IP地址设成和你测试网卡同网段的地址比如192.168.50.10/24否则mac层能通但IP层根本不会匹配接收条件。再有就是默认端口号如果设成小于1024的端口上位机启动服务时可能因为没权限而绑定失败这个也要提前想好。3.3 综合、布局布线与时序收敛要点一次干净的综合需要分阶段看报告。先只跑综合synthesis打开log重点看有没有LUT/RAM/DSP用量爆表、有没有“unconstrained”相关的warning。100G UDP换层整体资源占用其实不大MACPCSUDP整个框架一般只用掉几万个LUT和几十个BRAM对比整个VU9P的资源来说绰绰有余。跑完综合接着跑实现implementation重点看时序报告。100G的难点是GTY到MAC PCS接口的路径往往很长SerDes恢复出来的时钟质量直接决定这条路径能不能收敛。如果你发现WNS小于0且负裕量集中在“gt_rx_usrclk”到“mac_rx_clk”的路径上通常不是你业务逻辑的错而是PCS的复位和时钟抖动没有处理好需要增加GTY的RXCDR采样配置或者调整PCS的时钟分频参数。另一个常见导致负裕量的地方是用户逻辑里用了带组合逻辑的计数器在390MHz下这种写法极难收敛把计数器改成同步寄存器级联或者使用Xilinx的DSP48寄存器输出会改善很多。如果实现过了但时序还紧可以在实现设置里打开Spread logic across hierarchy和Extra timing effort或者适当加大set_property CLOCK_DELAY_GROUP相关的约束。实测一次干净的编译在16核CPU服务器上大约耗时40到60分钟建议每次改动后都跑一版完整实现不要偷懒只跑综合。3.4 上板前必备的板级检查生成比特流之后别着急下载先做一个不加载FPGA逻辑的硬件自检。用板卡厂商提供的BIST脚本或者简单写一个GTY回环测试逻辑把QSFP28的两个方向短接或者接上光模块回环头看链路是否能建立。这一步是区分“FPGA逻辑问题”和“光模块/硬件链路问题”的最快办法。接着加载正式比特流上电后用ILA核先抓一下MAC的状态寄存器检查PCS是否完成block lock、RX链路是否信号同步、GTY RX的error counter是不是持续增长。如果这些都正常再接上一台100G交换机或者直连100G网卡进入真实网络联调。4. 上板测试方案与结果分析4.1 测试拓扑与打流环境搭建这套测试我采用了最简单也最可控的拓扑FPGA加速卡的QSFP28端口直连一台服务器上的双口100G网卡我用的是Mellanox ConnectX-5网卡端口配置成192.168.50.2/24FPGA内部IP配置成192.168.50.10/24。中间不经过交换机因为交换机可能会对以太网帧做深度检查干扰定位直连拓扑下所有的丢包、错包都能直接归因于FPGA侧或网卡侧。服务器侧需要准备的工具是iperf3和Wireshark。iperf3用来做粗粒度的吞吐和丢包测试Wireshark用来做精细的报文内容检查。如果用的是Linux最好把系统的网卡中断绑定到独立CPU核否则几十Gbps的流量可能把单核中断处理打满出现测试结果异常。同时把网卡的RX队列数设大一点比如ethtool -L enp1s0f0 combined 8这在100G尤其关键否则RX丢包会被误判为FPGA丢包。4.2 三种核心测试方法回环打流、单向打流、双向打流第一种是FPGA内部回环测试。这是最先跑的通过寄存器把UDP接收换层的输出直接接到发送换层的输入把FPGA自己发出的UDP包从MAC层发出去再从PHY层回到MAC形成内部回环。用上位机向FPGA发包FPGA原样转发回来再解析收到的包是否正确。此测试能验证MAC和UDP换层的链路完整度并排除外部光模块的干扰。第二种是单向打流测试。上位机用iperf3向FPGA连续灌UDP包FPGA一侧的统计模块记录收到的总包数、总字节数、CRC错误包数、UDP校验失败包数。反过来FPGA内部也开启一个发包器以固定速率向服务器发UDP包服务器端用iperf3收包。两边分别统计就能确认单向带宽和丢包率。第三种是双向打流测试。保持两条方向同时发包观察两边的吞吐有没有互相影响以及TX/RX FIFO是否在某些瞬间被双向流量挤爆。这个测试最能暴露缓冲不足或者背压逻辑不完善的问题100G系统里只测单向是远远不够的。我实际跑下来的数据单向发送测到98.2Gbps的UDP payload速率单向接收测到97.6Gbps双向同时打流时两条方向都在95Gbps左右丢包率基本为0只有在服务器CPU中断处理出现波动时偶尔出现几个重传。这个结果说明整个MAC和UDP换层的吞吐能力没问题瓶颈实际上是在上位机协议栈侧而不是FPGA。4.3 抓包验证不只是看能不能通还要看格式对不对跑完吞吐测试后我专门用Wireshark在服务器网卡上抓包重点检查三类帧ARP请求和应答、ICMP ping的echo请求和应答、以及UDP数据包的字段完整性。这几类帧最能反映协议栈是否正确。首先要ping通这是最基础的一关。如果ping不通先看ARP缓存是否学习到了FPGA的MAC地址。在服务器上执行arp -a如果看不到对应条目说明FPGA侧的ARP应答逻辑有问题。开源代码里的ARP模块通常会根据配置的静态表响应检查ARP表的ROM值是否和目标MAC一致即可。其次看UDP包的IP头校验和。Wireshark有个很贴心的功能它会自动对IPv4 header checksum做校验如果显示“incorrect”大概率是FPGA侧计算错位了。常见原因是源IP和目的IP字节序没对齐比如用了大端序而代码里用的是小端序赋值导致IP头里字段全部反了。再看包长字段。UDP的payload长度必须等于实际用户数据字节数加上16位的UDP头长度字段值。认真检查发出去的包是不是长了或短了尤其是跨TLAST边界的那些包。这部分如果出错常见于用户逻辑和udp_tx之间的AXI-stream握手机制不对或者TKEEP在边界上把无效字节也标记成有效了。4.4 长时间稳定性与错误计数验证跑完单包和短时打流之后一定要做长时间稳定性测试。我连续运行了接近5个小时用iperf3持续发送1Gbps左右的背景流量同时每隔5分钟记录一次FPGA侧的收发统计计数器和CRC错误计数。这几项数据能快速判断MAC和PCS的长期稳定性。关于错误计数要特别注意两种计数器一是GTY的RX错误字节计数二是MAC/PCS接收端的CRC错误帧计数。在理想情况下两者都应该是零增长。如果GTY RX错误字节持续增长但是CRC错包数一直为零多半是SerDes部分出现偶发误码但被RS-FEC纠正掉了这种情况不致命但需要注意光纤或者光模块的质量。如果CRC错误帧数一直增长则说明链路数据确实出现损坏得回头查GTY配置、电源纹波、或者时钟抖动。另外在空闲状态记得观察PCS的“RXPCS_ALIGNED”和“RXBLOCK_LOCK”状态位是否一直保持在1。如果这两个标志偶尔跳变说明物理层偶发失步需要重新调试GTY CDR配置或检查参考时钟质量。5. 常见问题与排查技巧实录5.1 我踩过的坑问题速查表把整个移植和上板过程中遇到的问题整理成表格大家照着排查会快很多。问题现象可能原因排查/解决手段链路完全不通光模块无协商QSFP28控制引脚未初始化或低功耗模式检查MODSELLP、RESETL、LPMODE电平读光模块I2C寄存器确认状态能link但ping不通FPGAARP缓存未更新或目的MAC不对查ARP表看FPGA侧是否收到ARP请求并正确回复能ping通UDP收不到数据端口号或IP地址过滤不匹配检查udp_rx模块的过滤参数是否和实测源端口/目的端口一致吞吐量远低于100GAXI-Stream握手机制缺陷导致反压抓TREADY/TVALID波形检查FIFO是否频繁变满优化用户侧burst能力短包大量丢失包长小于46字节未做填充交换机丢弃udp_tx侧加最小帧长填充或上位机设置更大的payload一段时间后链路断开GTY偶发失锁或者CDR漂移查询GTY的RX status寄存器尝试固定CDR模式或改动loopback设置Wireshark显示IP校验和错误字段字节序错乱检查IP头赋值语句使用的大/小端序FPGA编译时WNS为负用户逻辑跨时钟路径过长拆分流水级把组合逻辑寄存器化调整总线宽度5.2 Part 1为何ARP通了UDP却始终进不来有几天我一直卡在一个诡异问题上服务器能ping通FPGA但是用UDP发包FPGA内部的计数器却是零增长。这说明物理层、MAC层、ARP层都是好的问题一定出在udp_rx的状态机过滤条件上。查了源码之后才发现udp_rx模块在解析出IP头后会对源IP地址做“特定源地址过滤”开源代码默认把源IP设成192.168.50.2而我测试时服务器网卡的IP绑定到了192.168.50.100前两个字节匹配但后两个不匹配所有包都被丢弃了。改法很简单要么把udp_rx的源IP过滤参数改成通配要么改成实际服务器的IP。顺带一提有的版本还会检查目标端口和源端口是否和配置一致如果端口不匹配同样静默丢弃所以排查这类“链路通但包进不来”的问题时先把所有过滤参数全部放宽确认通路正常后再逐一收紧。5.3 Part 2100G条件下的FIFO深度和反压设计另一个高发问题出在FIFO深度上。100G速率下一拍数据是256位连续流的包速度极快。如果你的用户逻辑处理完一个包需要相对较长的时间那么FIFO深度不够就会导致反压反压多了就会丢包。开源的udp_tx模块通常会带一个发送FIFO但默认深度往往按10G设计的比如只有512字节跑100G时一个大的Jumbo帧直接把它塞满然后整个模块开始向用户逻辑拉TREADY低电平用户逻辑的FIFO又不够深就直接溢出丢包。建议把发送和接收方向的FIFO都改成基于Block RAM的大深度FIFO至少能容纳8个最大包长比如8×9KB并且开启packet mode下的“store and forward”模式而不是cut-through模式。这样能避免短包突发时把一个包的边界切得七零八落。实测改成8×9KB的FIFO后双向打流的丢包直接从0.3%降到0。5.4 Part 3PCS复位顺序导致的偶发开机失败FPGA上电后有时候能直接link有时候怎么都link不上得重新加载比特流才好。这类偶发问题在100G系统里很常见多半是PCS和GTY的复位顺序没有严格按照手册来。我排查时用ILA抓了tx_reset_done和rx_reset_done两个信号发现在链路失败的情况下rx_reset_done老是比tx_reset_done慢很多导致GTP的RX侧还在复位时MAC已经尝试使能了。修复方式是添加一个复位状态机严格按照“先GTY TX复位等待tx_reset_done拉高然后GTY RX复位等待rx_reset_done拉高最后PCS全局复位释放”的顺序来。另外复位释放后要加至少100微秒的延时确保CDR稳定锁定再拉高MAC的packet接口使能信号。改了复位逻辑之后开关机测试了几十次都没再出现问题。6. 移植过程中的经验心得与效率建议6.1 先跑仿真再上板真不是浪费时间这一条我特别想强调。很多工程师拿到开源代码之后习惯直接综合上板觉得仿真浪费时间。但100G系统一旦上板调试手段其实很有限ILA采样深度不够、触发条件复杂、波形一堆很难像仿真那样把每一拍信号都抠出来看。强烈建议在移植最开始就把开源项目自带的testbench跑通。verilog-ethernet项目自带了很多testbench覆盖MAC层收发、UDP/IP组包拆包等基本场景直接把代码替换成你的目标参数跑一遍基本能杀死80%的逻辑bug。可以自己在testbench里加一个简单的发包激励模拟FPGA用户侧产生一段递增数据然后在接收侧检查数据是否完整、帧格式是否符合以太网规范。仿真跑通之后综合实现上板就是纯工程问题心态完全不同。6.2 日志与统计寄存器就是你最好的“仪表盘”上板测试过程中除了用ILA做片内调试一定要在FPGA内部设计一组统计寄存器通过AXI-Lite接口供上位机读取。至少包含以下计数器TX总帧数、总字节数、TX FIFO overflow次数RX总帧数、总字节数、RX CRC错误帧数、RX FIFO overflow次数ARP请求计数、ARP应答计数、ICMP请求计数UDP收到的payload总字节数通过这些计数器你根本不需要抓波形就能判断问题在哪个模块。比如RX总帧数一直在涨但UDP payload字节数不涨那问题大概率出在udp_rx的过滤参数上如果CRC错误帧数涨得厉害那就回头查GTY和光模块链路质量。这套“仪表盘”设计我从第一次上板后就没拆掉过出差调试全靠它效率提升不是一点半点。6.3 板卡供电和散热问题别忽视100G光模块的功耗不低一个QSFP28光模块的典型功耗在5W左右再加上FPGA内部的高速SerDes和大量逻辑翻转整板电流可能轻松上10A。如果板卡供电模块纹波偏大或者散热片没有贴合紧密高速SerDes的误码率会明显上升表现出来就是“偶尔出现CRC错误但没有规律”。我发现板卡风扇不转的时候不同通道的误码率差异特别大温度一降下来就恢复正常了。如果你在调试过程中遇到间歇性误码先看一眼板卡温度比花大把时间查逻辑靠谱得多。6.4 金黄色的忠告别低估时钟和复位最后再唠叨一句100G UDP移植看起来是“把代码编译一下”实际上最核心的工程难点是时钟与复位。参考时钟到GTY的路径必须保证PCB走线等长和阻抗连续GTY侧和MAC侧的复位时序必须符合手册不同模块之间的跨时钟域FIFO必须设置正确的读写指针同步。这几点任何一个出问题链路稳定性都很难达到验收标准。我的习惯是先专门花一天时间把时钟和复位逻辑从头到尾检查一遍哪怕其它模块代码都是开源代码一字不改也要确保时钟和复位在自己的板子上没有隐患。这次开源100G FPGA UDP项目的移植上板测试整体走下来最大的体会就是“开源代码是好的但工程适配才是关键”。开源代码解决了“从0到1”的问题把协议栈的参考框架给得明明白白工程适配则解决了“从1到100”的问题让代码在特定板卡、特定时序、特定业务逻辑下能稳定跑起来。你如果正准备做类似的移植项目希望这篇能帮你避开那些我踩过的坑省下的调试时间去多跑几轮压力测试最后交付出来的东西一定更靠谱。
返回列表