尧图精选

Corundum开源100G网卡移植到VV4 FPGA板卡实战记录

🕒 发布时间:2026/9/27 3:55:10 📁 来源:尧图网络
如果你一直在找一套真正意义上的开源100G网卡方案那Corundum这个名字你应该不陌生。它不是那种只放一堆RTL代码的PPT开源项目而是从FPGA固件到Linux内核驱动全部开放、能实打实跑满线速的东西。最近我在做一件折腾事把Corundum从它熟悉的Xilinx官方开发板环境移植到Bittware VV4这块商用FPGA板卡上。这个过程远比想象中琐碎——换板卡意味着PCIe路径、GT收发器引脚、时钟树、QSFP28管理、约束文件全都得重来一遍。这篇文章是移植记录的第一篇先把整体思路、板卡摸底和最容易翻车的地方讲清楚后面几篇再逐个拆解具体模块的改法。先说清楚这篇适合谁看。如果你打算基于Corundum做自定义100G网卡、想把手里的非官方FPGA板卡跑成网卡用或者虽然不搞FPGA但想知道开源网卡到底能不能落地这篇都值得读完。如果你只是想找现成的商业网卡那可以关掉了这里讨论的是“自己动手改RTL”的路线。1. 为什么偏偏是Corundum和VV4这个组合1.1 开源100G网卡方案的现状你其实没多少选择说句实话网卡这个领域开源生态并不繁荣。100G商用网卡以Mellanox、Chelsio、Intel为主驱动是闭源的寄存器手册也是NDA满天飞你想在网卡里加一段自定义逻辑比如精确打时间戳、自定义流表匹配、旁路DMA基本没戏。FPGA网卡是一条出路但市面上能买到的FPGA网卡方案大部分也是绑定厂商私有框架真正把RTL全开放给你的数来数去Corundum是这个圈子里绕不过去的一个。Corundum由Alex Forencich发起最吸引人的地方在于它不是一个“玩具”项目。它提供了一套完整、模块化的100G以太网MAC/PCS、PCIe DMA引擎、队列管理、以及Linux驱动。这意味着你拿到手的不是一个需要再补几万行逻辑的半成品而是能跑通TCP/IP协议栈、能跟标准交换机互通的正经网卡。它的BSD许可以及对RTL完全开放的态度让它成了FPGA网络研究社区里事实上的标配起点。这套设计支持10G/25G/40G/100G多速率而且内部高度参数化。核心的MAC和PCIe部分拆得很干净基础模块是bs Lib那种通用RTL库的风格很多模块连注释都写得跟教程一样。它的Linux驱动直接把标准网络接口暴露给内核上层的socket应用完全感知不到底层是FPGA还是ASIC网卡。就冲这一点它就比那些需要自研整套驱动框架的开源项目省了太多事。1.2 选VV4而不是官方开发板的原因Corundum官方示例支持不少Xilinx板卡比如VCU118、VC709和部分Alveo加速卡。理论上直接用官方板卡最省心但我选Bittware VV4有自己的考量。VV4的核心资源非常能打Virtex UltraScale级别的FPGA集成了PCIe硬核片上逻辑和DSP足够跑100G的完整收发数据通路板载QSFP28接口和DDR4内存。更重要的是VV4是一块通用商用板卡原理图和硬件手册都是完整公开的这意味着它在移植时几乎不存在“黑盒模块”——所有引脚、时钟分配、电源时序都能查到适合做深度的二次开发。相比之下某些商业加速卡把很多底层细节藏起来想在RTL层面做一些定制就不太方便了。另一个原因是VV4的板卡定位非常适合做网络研究。它不是为了某个固定云业务设计的板载资源和对外接口都比较均衡适合挂到自己实验室的服务器上当开发平台。而且在二手市场VV4这类老牌FPGA板卡的价格比官方开发板合理不少对预算有限的团队来说用商业板卡替代官方开发板跑开源网卡是一条性价比很高的验证路径。当然这条路需要付出的代价就是官方示例用不了了所有适配工作都得自己来。2. 动手移植前必须先摸清的板卡底细2.1 VV4的硬件结构两个FPGA的板子谁是主控先别急着拉代码第一步是搞清楚你手里的板卡到底长什么样。VV4这板子的硬件架构比较特别它不是单FPGA设计而是板载了两片Xilinx的Virtex UltraScale系列FPGA。这种双芯片架构在高端网络加速板卡上很常见一片负责跟主机PCIe打交道另一片专职做数据处理。移植Corundum时必须明确一个问题哪片FPGA最终要承载Corundum的整个网卡逻辑如果选错了FPGA后面所有引脚约束和时钟约束全都要推翻重来。从PCIe链路来看跟主机相连的那个FPGA是必须作为主FPGA的因为Corundum的DMA和寄存器访问通道都依赖PCIe。另一片FPGA在Corundum这套方案里大概率用不上最多做旁路数据处理。这里我的建议是先查VV4的手册确认PCIe x16链路到底接到哪片FPGA的哪个Bank再把Corundum的顶层设计落到对应的器件上。别想当然地认为第一片FPGA就是主控有些板卡会把PCIe直接接到编号靠后的FPGA上。顺便提醒一句双FPGA板卡上电和复位时序也比单芯片复杂两片FPGA各自有独立的配置模式、时钟源和复位输入。Corundum的全局复位逻辑通常会假设只有一颗FPGA所以移植时需要把VV4上主FPGA的复位信号和PCIe的PERST信号对好否则可能出现PCIe已经枚举成功但内部状态机一直没被释放的情况。2.2 时钟树移植中最容易翻车的第一站硬件板卡移植最容易翻车的不是逻辑代码而是时钟。Corundum设计里对时钟是“挑食”的官方示例板卡都是按特定时钟拓扑调好的换到VV4上最常遇到的问题就是“看起来时钟频率没错但GT收发器死活不上线”。先罗列一下Corundum在运行100G模式时需要的几路时钟。第一路是系统时钟一般是200MHz用于PCIe AXI-Lite桥、队列管理器和控制逻辑。第二路是MAC用户时钟100G模式下的AXI接口位宽是512bit对应的接口时钟约195.3125MHz这是用100G线速率除以512bit算出来的——100e9/512195.3125e6。第三路是100G光口物理层的那路GT参考时钟标准值通常是156.25MHz。这三路时钟在VV4板卡上的来源各不相同。系统时钟一般来自板载可编程振荡器GT参考时钟则被接到主FPGA特定Bank的MGTREFCLK引脚上MAC用户时钟通常由GT收发器恢复出来的时钟再跨到用户逻辑域。移植时不能只改频率还要确认时钟信号到底接到了哪些物理引脚上否则一个BANK号对不上综合可能能过但上板跑起来就是全乱。2.3 对照Corundum的三大时钟需求我在移植前做了个表格把自己要的时钟和VV4能提供的时钟一项项对齐这个表格强烈建议你也做一份用途Corundum默认要求板卡实际来源移植动作PCIe系统时钟200MHz自由运行时钟板载可编程时钟确认引脚必要时用MMCM分频匹配MAC用户时钟100G下约195.3MHzGT恢复时钟或独立时钟检查是否可跨时钟域GT参考时钟156.25MHzQSFP28附近MGTREFCLK引脚与GT位置约束一起核对用户侧低速时钟通常50~125MHz板载时钟用于I2C、复位等外围逻辑这份表格在动手改RTL之前一定要拿VV4的原理图逐项核对一遍。尤其是GT参考时钟它跟GT收发器位置强绑定你选哪一组QSFP28对应哪一片GT Quad完全由板卡布线决定。Corundum原版的通用顶层不会知道你VV4的QSFP28接在哪个Quad这一步就是移植的核心工作量之一后面第五章节会展开细说。3. 搭好工程与工具链别让环境成为第一个坑3.1 源码获取与固件目录结构说完理论进入实际操作。先把Corundum代码拿到手。它的源码托管在GitHub上直接git clone即可。注意这个仓库用了Git LFS管理部分大型文件克隆完记得执行git lfs pull否则后面在Vivado里生成IP时会报一些莫名其妙的文件缺失错误。这是一个很多人一开始没注意、然后排查了半天才发现的坑。Corundum的FPGA部分目录结构相当规整。核心代码在fpga/mqnic下面这是网卡主逻辑所在包含PCIe对接、队列、MAC配置这些模块。fpga/lib则是一些通用基础库比如AXI、以太网MAC、FIFO这些。每个官方支持的板卡都有一套自己的顶层wrapper和XDC约束文件目录名一般直接用板卡型号命名。移植到VV4本质上就是新增一个board目录把官方板卡的wrapper改造成适配VV4的顶层再把引脚约束全部替换。3.2 Vivado版本、Board Files与IP许可用什么Vivado版本会直接影响移植难度。Corundum官方持续在跟进的版本我用下来Vivado 2021.1比较稳很多社区里的移植案例也都是在这个版本上完成的。新版本Vivado也能打开旧工程但IP核版本升级可能引入额外的兼容问题如果你的工程里恰好用了某个官方示例IP升级的时候IP会被自动刷新刷新完可能需要重新配置。首轮移植我建议保持官方推荐版本等跑通了再考虑升版本。VV4这块板卡不一定有现成的Vivado Board Files。Board Files的主要作用是让你在Vivado图形界面里选封装、选引脚配置更方便但对Corundum这种以脚本和约束文件为主的工程来说Board Files不是必须的——你完全可以手工创建工程、指定器件型号、再手动加入XDC约束。Bittware更新过VV4的支持包网上能搜到但某些旧版本只支持特定Vivado版本如果要装记得匹配好。另外注意Xilinx的IP许可问题。Corundum依赖的以太网MAC/PCS、PCIe硬核这些IP在UltraScale器件上基本都是免费内置的不需要额外购买许可证。但Vivado本身必须是被正常许可的版本WebPack版能不能支持VU190级别的器件我不确定我实际用的是完整版。如果你的团队没有Vivado正版授权这一步提前处理好不然到了综合阶段卡住很浪费时间。3.3 先跑仿真验证理解移植工作开始之前我强烈建议先花一两天时间跑通Corundum自带的仿真环境。不是为了验证功能——官方代码基本没问题——而是为了让自己彻底理解数据通路是怎么串起来的。你可以打开仿真波形观察PCIe TLP是怎么变成AXI事务的队列描述符是如何被搬运到FIFO里的MAC发送侧又是怎么把AXI数据变成以太网包的。这些理解在接下来改顶层时非常值钱因为很多引脚命名在去板级wrapper里是跟物理信号直接相关的如果你不知道它对应逻辑里的哪一环改起来就是瞎蒙。Corundum的仿真环境适配了常见的仿真器Vivado自带的XSim和开源生态的Verilator都能跑。如果你用的是XSim直接按make脚本执行即可。仿真时重点观察几个关键信号复位释放的顺序、PCIe的AXI-Lite寄存器能否正常读写、MAC发送FIFO的AXI握手。这些如果通了基本说明你理解对了整体框架再进入改板级逻辑就有底了。4. 第一步移植实操PCIe与寄存器空间适配4.1 Corundum的PCIe路径硬核还是XDMA移植过程中第一个真正动手的地方是PCIe。Corundum在Xilinx平台上的PCIe实现依赖的是FPGA里集成的PCIe硬核IP。在UltraScale器件上这个硬核集成块能直接产生AXI4和AXI4-Lite接口Corundum就是靠这套接口把网卡寄存器空间和DMA数据通路暴露给主机的。这里有一个很多人绕弯路的点Corundum并没有默认绑定Xilinx的XDMA IP也就是那个带DMA引擎的闭源NIC。Corundum把DMA引擎做在了自己开源的逻辑里PCIe硬核IP只负责TLP层和AXI桥接。这意味着你在Vivado Block Design里做PCIe部分时配置项主要围绕BAR空间、AXI接口宽度、中断引脚来设置而不是去生成一个完整的XDMA Example Design。对VV4来说主FPGA的PCIe硬核位置和引脚在器件上是固定的你只需要在IP配置里选择对应的GT Quad和链路宽度即可。VV4一般支持PCIe Gen3 x16或者x8Corundum的数据通路带宽要够至少配置成x8以上。x4链路跑100G DMA理论上是够呛的因为PCIe Gen3 x4的理论吞吐只有约32Gbps根本喂不满100G网卡的收包速率。4.2 BAR映射与mqnic_core的寄存器改动PCIe BAR空间是网卡与主机软件交互的窗口。Corundum通常把BAR0作为寄存器空间映射到AXI-Lite总线上里面放类似mqnic_core的控制状态寄存器。BAR2作为DMA数据空间映射到AXI4总线上用于描述符和包buffer的访问。这个分割是Corundum驱动正常运行的前提。换板卡时BAR0的基地址由PCIe枚举时自动分配RTL侧不需要写死但BAR空间的大小必须和PCIe硬核的配置一致。如果硬核里把BAR0配成了64KB而mqnic_core里的寄存器译码逻辑实际访问范围只有4KB那也不会出大问题——最多浪费一点地址空间。真正要小心的是BAR2这个DMA空间它的大小直接决定了主机能访问多少DMA缓冲区你至少要配到4GB以上的64位地址空间否则大流量下DMA寻址会撞墙。我第一次移植时就在这里犯过错参考官方配置把BAR2配成了32位地址空间驱动加载正常接口也能起来但一跑大包iperf就出现卡顿和丢包查了半天发现是DMA高32位地址没被正确解析。后来把BAR2改成64位地址空间问题立刻消失。这个细节在官方示例里可能不会踩到因为官方板卡的驱动和硬件配置是配套的但你一旦改板卡PCIe硬核配置里的地址位宽必须跟着板卡DMA能力走。4.3 用ILA和仿真确认传输通道PCIe这条链路怎么验证是否真的通了不要盲目上板打流那样问题太发散。我的经验是先在Vivado例化一个ILA探针挂在PCIe硬核的AXI4-Lite接口上观察主机驱动加载时产生的寄存器读写事务。驱动中对mqnic_core的访问是第一步如果ILA里能看到写0x0这种reset寄存器的TLP落下来说明PCIe枚举和BAR映射已经正确寄存器通路是通的。接下来验证DMA通道。这时候可以用一个小技巧在ILA里同时抓取AXI4数据通道和中断输出然后从主机侧用一个简单的PCIe读写工具对BAR2地址发起读写。如果数据能完整经过AXI4通道到达板卡侧的FIFO并且中断能正常拉高那么DMA数据通路的静态检查就过了。这里不需要真的跑网络流量纯内存读写验证已经把大部分PCIe适配问题暴露出来了。5. 硬骨头GT收发器与QSFP28的物理映射5.1 100G物理层拆解PCIe通了只是让板卡“能被主机访问”真正让Corundum变成网卡的是光口物理层。这部分也是整个移植里最跟板卡硬件绑定、最不能靠猜的部分。100G以太网的物理层不是一根线跑100G而是四条独立收发器通道每通道25.78125Gbps合成100G带宽。FPGA里这些高速收发器就是GT在UltraScale里是GTY每个GT Quad包含四路收发器刚好对应一组QSFP28的四条通道。QSFP28端口的物理连接是固定的它插到FPGA的哪一组GT Quad、每组GT Quad用哪个参考时钟输入这些信息只能从VV4的原理图里找。Corundum官方示例板卡上这些映射关系已经写好在XDC里了你不需要关心。但到了VV4上整个GT映射表就是你的核心工作。你需要打开VV4的原理图找到QSFP28笼子到FPGA Bank的连线表记录每一路TX/RX对应FPGA封装的哪个引脚同时还要确认MGTREFCLK引脚在哪。把这些整理成一张引脚映射表再换成XDC里的get_ports定位这一步千万别省略我见过直接把官方XDC里的引脚名字改成VV4的名字就上板的人结果是GT位置全错综合能过但bit文件下载后链路永远无法建立。5.2 改GT位置约束的正确姿势GT的位置约束有两种改法。一种是在XDC里用PACKAGE_PIN和LOC直接把收发器引脚定到具体的封装引脚上另一种是在User Constraint里指定get_cells -hierarchical定位到GT primitive。Corundum这种用IP核分层的设计最省事的方法是在XDC里约束顶层引脚名然后让Vivado自动做引脚到GT Quad的路由。实际操作时我推荐一个顺序先把QSFP28的TX/RX、参考时钟这些引脚放到XDC中跑一次综合看Vivado报出的GT位置分配结果。然后对照原理图检查这些GT Quad是否跟QSFP28的物理连接一致。如果一致说明布线方向选对了如果不一致多半是你某个引脚名写错了或者原理图看错了。这种“先综合后核对”的方式比纯手工改LOC绑定要稳得多因为Vivado的布局器可能会优化掉一些冗余约束。这里还想强调一个细节GT Quad的摆位不是任意的一个Quad里四路收发器必须来自同一个时钟域不能把其中两路参考时钟按156.25MHz另外两路按另一个频率。QSFP28的四条通道必须共享同一个参考时钟资源否则收发器之间bandwidth不匹配链路根本建不起来。移植时一定要确认所有四路TX/RX都在同一GT Quad或者由同一个参考钟驱动的一组Quad内。5.3 QSFP28管理I2C、复位、中断与ModPrsL很多人移植时只关注高速数据线忽略了QSFP28的管理信号结果光模块插上去完全没反应。QSFP28模块本身的低速管理接口是一组I2C总线用于读取模块的EEPROM比如厂商信息、光功率、温度这些。此外还有几个重要的低速控制信号ModPrsL表示模块在位低电平有效Reset和LPMode分别控制模块复位和低功耗模式IntL则是模块中断输出。Corundum内部自带I2C控制器用来扫描光模块。到了VV4上你要把这组I2C信号和QSFP28的物理引脚对接上。这里面有个容易忽略的问题QSFP28的I2C地址可能因为硬件拉高/拉低而不同默认一般是0x50但某些板卡会把A0/A1地址引脚接成别的值。Corundum在扫描时会按固定地址去查询如果你的板卡地址不同模块的EEPROM读不到驱动就会报PHY模块不存在。另外注意复位逻辑的极性。QSFP28的Reset是低电平复位但很多FPGA板卡上的GPIO输出极性经过反相器实际拉高才是复位。这种电平极性问题很难从原理图中一眼看出来需要配合信号实测。我的建议是先在ILA里抓一下几个控制信号的状态再决定要不要在RTL里加反相逻辑。5.4 参考时钟来源的选择GT参考时钟看起来简单其实是很多移植翻车的地方。100G的GT参考时钟一般是156.25MHz但不同板卡对这个时钟的处理方式不一样。有些板卡用一颗可编程时钟芯片给GT提供参考时钟开机后默认输出可能是125MHz要做I2C配置之后才能切到156.25MHz。如果你忽略了这一步GT收发器的参考时钟对不上综合时查不出任何错误上板后光是时钟恢复就会失败。VV4的板载时钟方案具体怎么配需要查手册。有些是可编程时钟芯片在上电后自动加载EEPROM配置到正确频率有些则需要主机通过I2C去写。我建议在移植初期先用示波器实测一下GT参考时钟引脚上是否有波形、频率是否对。没有示波器的话也可以在Vivado的Hardware Manager里看GT的时钟状态寄存器那里能直接读出来参考时钟锁定状态。这一步验证成本很低但能省下后面两天瞎折腾的时间。6. 移植的验收标准与后续路线6.1 怎么算移植成功移植这件事不能靠“感觉差不多”来判断要有一份明确的验收清单。我给自己定的验收标准大致如下你可以根据自己的需求调整验收项通过标准主要排查手段PCIe枚举主机能看到设备驱动能加载lspci、dmesg寄存器访问驱动对BAR0读写无错误dmesg、ILA波形DMA通路主机与FPGA互传数据正确自定义PCIe读写工具光模块识别模块EEPROM能被读取ethtool -m链路建立对端能看到端口upethtool、ip link收发包正确对打无CRC错包、无丢包ethtool统计、iperf3线速带宽100G口跑出接近线速iperf3 -u或TCP多流在这份清单里前四项属于“板卡适配完成”的范畴后三项才是真正“跑通网卡”的范畴。第一次移植不建议一上来就追求线速能把链路建立起来、驱动能识别端口、小流量包不出错就已经赢了大部分问题。线速优化是后面的事而且100G线速通常需要调整MSI-X中断、DMA描述符数量、CPU绑核这些参数这些跟Corundum本身的适配关系不大更多是主机侧调优。6.2 我的推进清单如果你也想复现这次移植按照下面的顺序推进能省掉不少弯路。第一步拉源码跑通官方仿真理解数据通路。第二步建VV4的顶层工程先用Vivado跑综合确保器件型号、引脚约束、时钟约束无误这步只求综合通过不求上板跑通。第三步把PCIe硬核配置好上板验证PCIe枚举这一步建议用Vivado自带的Hardware Manager直接看PCIe配置空间不要急着加载Corundum驱动。第四步把GT和QSFP28的物理约束搞定上板验证光模块识别和链路建链。第五步加载驱动用环回方式验证收发包无误。最后才是对打流量和性能测试。每个步骤之间留出足够的验证时间。PCIe和GT是整个系统里最复杂的两部分分别单独调试能大幅降低排错复杂度。如果一上来就把全部模块合在一起任何一个信号没对你都不知道是该查PCIe还是该查GT那种调试体验相当痛苦。6.3 后续文章要覆盖的内容这一篇算是一个开头重点放在了“移植前该想清楚什么”和“硬件层面怎么摸底”上。后面几篇我打算按模块继续拆PCIe硬核的具体配置流程、mqnic_core里面针对VV4的寄存器适配、GT收发器IP的重建方式、QSFP28 I2C扫描逻辑的具体修改点以及驱动加载后遇到的各种链路异常。有些坑我自己也在踩比如双FPGA板卡上PCIe复位和GT复位的时序配合这类问题光看代码很难想明白等有了更完整的调试结论再拿出来分享。按我的经验这种移植项目最忌讳的就是把所有内容压缩在一篇文章里写到后面自己都分不清是步骤还是踩坑记录。分篇写虽然看起来慢但每一篇都能给后来者一个可以照做的完整切片。这篇的“切片”就是硬件架构与时钟、PCIe和GT的整体规划下一期直接从PCIe生成工程的实际配置开始聊。
上一篇/下一篇内容由系统自动关联 返回资讯列表 →