资讯中心

Corundum开源100G FPGA网卡移植到Intel Stratix 10板卡实践

📅 2026/9/26 5:34:57
Corundum开源100G FPGA网卡移植到Intel Stratix 10板卡实践
那块Bittware V4板卡在防静电袋里躺了大半年这次终于有理由让它干点正经事把Corundum这个开源100G NIC设计移植上去。第一眼看到Corundum仓库时大多数人会以为它是拿来即可用的实际上它在Xilinx平台上跑得挺欢换到Intel Stratix 10的板子上就是另一回事。这篇算是整套移植过程的第一篇主要讲清楚为什么选这个组合、需要替换哪些东西以及代码拿到手之后从建工程到编译通过的全过程顺便把踩过的坑都记下来。这篇内容适合两类读者一类是做FPGA网络加速、想快速拥有一个可用的100G网卡原型的工程师另一类是准备把Corundum迁到非Xilinx平台的硬件开发者。读完之后你至少能知道移植一条开源网卡链路需要动哪些地方而不是对着一个大仓库无从下手。1. 为什么选Corundum加Bittware V4这个组合1.1 Corundum到底是什么Corundum是Alex Forencich维护的一套开源FPGA网卡实现和NetFPGA这类教学型项目不同它的设计更接近商用网卡包含了PCIe DMA引擎、多队列收发、TSN时间同步、RoCEv2卸载等完整功能。它支持10G、25G、40G、100G多条线路速率核心思路是在FPGA逻辑里自己实现MAC层和DMA路径物理层的SerDes和PCS/PMA部分由各厂商的IP或者硬核来兜底。这套代码最大的价值在于它把“网卡”从黑盒子变成了一个可以打开看的数据通路。开发者在Vivado里跑通参考设计之后再去改报文格式、队列调度、流表逻辑都比拿商用网卡SDK舒服得多。而且它对PCIe的DMA处理写得很整洁中断合并、描述符环管理这些传统意义上的复杂逻辑全部用RTL实现且注释清楚做体系结构研究的人拿它做起点非常合适。不过所谓“开源”并不等于“开箱即用”。Corundum官方仓库里完整的参考实现是以Xilinx器件为基础写的尤其是PCIe IP的封装、GTY收发器配置、以及10G/25G Ethernet Subsystem的适配层都和Xilinx绑定死了。把一个项目从Xilinx平台迁到Intel平台不是简单改改例化而是要把整个平台支撑层从厂商依赖里剥出来用自己的板级逻辑重新包一遍。1.2 Bittware V4这块板子值得折腾的地方选择Bittware V4的原因很直接它满足一个100G网卡原型平台的全部硬指标。首先是PCIe接口这决定了DMA带宽能不能跑到线速的边缘其次是光口数量V4板载QSFP28接口可以支持100G光模块这也是Corundum发挥作用的基础再次是逻辑规模Stratix 10的资源和DSP算力足够把多队列网卡逻辑放进去还能留出空间做后续的功能扩展。另一个加分项是E-Tile收发器。Intel Stratix 10的E-Tile在高速以太网支持上专门做了优化它的Native PHY IP可以直接配置4x25G的100G以太网物理层并且RS-FEC、自适应均衡这些功能都有成熟IP支撑。做100G移植时最怕的事情是FPGA的高速收发器没有对应的PHY IP可用那才叫欲哭无泪。Bittware V4这块板子把光模块到E-Tile之间的高速线路都连好了省去自己画几十Gbps差分线的麻烦。选择它还有一层现实因素板卡配套的BSP和参考约束相对规范PCIe、QSFP28、时钟芯片都有明确的手册描述。对于移植过程中涉及的引脚分配、时钟拓扑确认有一份高质量硬件手册能省掉大量用万用表猜板子的时间。如果你是第一次碰这块板子别急着开Quartus先把原理图和板卡手册导出来后面每一步都离不开它。1.3 移植工作的本质把厂商依赖从逻辑里剥出来Corundum的RTL逻辑大体上是厂商无关的。mqnic_core内部的队列管理、RAM接口、AXI转发、MAC收发引擎都只用标准逻辑实现理论上放在任何FPGA上都能运行。而真正和厂商深度绑定的是支撑这些RTL的物理层和总线IP具体来说就是PCIe硬核、收发器PHY、以及连接这些硬核到用户逻辑的接口适配。移植的核心工作量因此很明确识别哪些模块可以直接复用哪些模块属于厂商平台层必须替换。我习惯用一张表格来划分这条边界因为接手的移植任务十有八九是死在不清楚这条边界上。模块区域是否复用处理方式mqnic_core、队列管理、MAC收发包引擎完全复用直接加入工程保持RTL原样基于Xilinx的PCIe DMA封装XDMA相关适配不可复用换成Intel P-Tile PCIe Avalon-MM IP并写适配层Xilinx GTY收发器、10G/25G以太网Subsystem不可复用换成E-Tile Native PHY和100G Ethernet IPXilinx全局时钟、复位原语不可复用换成Intel时钟复位结构并重写复位时序顶层例化、引脚约束、时序约束不可复用按Bittware V4板卡手册重新编写把这张表列清楚之后移植就不再是盲目的代码搬运而是有明确施工图的工程改造。Corundum的RTL部分几乎不用改这句话听起来很爽但真正让人头大的反而是那些“不用改”之外的东西。2. 移植前的方案选择与平台拆解2.1 硬件手册是移植的第一参考任何移植都从硬件手册开始。Bittware V4的板卡手册里我最先圈出来的信息有三块QSFP28高速串行信号接到E-Tile的哪个bank、每个通道参考时钟来自板载哪个振荡器、PCIe硬核所在的P-Tile引脚以及PERST复位连接方式。这些信息在Quartus的器件选型和引脚规划阶段能直接减少大量不确定。其次要确认的是板卡上可编程时钟芯片。很多高端FPGA板卡为了兼顾不同协议速率会用Si534x这类时钟芯片动态生成参考时钟。在把Corundum移植到Bittware V4时100G以太网要求收发器参考时钟稳定通常使用156.25MHz或者161.1328125MHz这类频率具体取决于PCS/FEC配置。如果你遇到硅后链路不稳定甚至link完全起不来先回头去查时钟芯片的默认配置输出别急着翻逻辑。2.2 决定IP选型的几个关键链路在Quartus里配置平台子系统时PCIe和Ethernet两个IP的选型几乎决定了整个移植周期。PCIe侧Stratix 10的P-Tile硬核通过Avalon-MM接口和用户逻辑交互对应的是Corundum里的PCIe DMA主机逻辑。这里有个重要的适配点Corundum内部使用的是带AXI风格的请求响应接口而P-Tile IP输出的是Avalon-MM或者Avalon-ST格式需要准备一个总线转换模块把地址、数据、突发计数、读写通道全部映射过去。Ethernet物理层这边用E-Tile Native PHY IP生成4个25G通道再通过100G Ethernet IP把MAC和PHY数据通路衔接起来。这里特别要注意的是RS-FEC的开关。对于100G SR4光模块短距场景开RS-FEC通常是推荐的但Corundum本身的MAC逻辑对RS-FEC的支持要看具体版本移植初期可以先关闭RS-FEC把链路跑通再逐步打开验证。这条路径选对了后续移植会顺畅很多。我个人的经验是不要一上来就在Platform Designer里追求大而全。先把PCIe IP和Ethernet IP单独生成最小可用的子系统跑一下仿真确认接口信号方向和时序符合预期再和Corundum的RTL对接。否则两边IP同时报错时你连问题出在哪一半都分不清。2.3 时钟和复位最容易被低估的重灾区100G以太网对时钟的要求极其苛刻。参考时钟进入E-Tile收发器之后IP内部会生成多个时钟包括高速SerDes时钟、PMA时钟、MAC核心时钟。Corundum的逻辑是在自己的时钟域里跑的和Intel IP内部时钟天然是异步关系因此必须要在MAC和PHY之间设置正确的异步FIFO否则时序收敛了数据也会在随机时刻错位。复位路径同样容易踩坑。Xilinx环境下一个全局复位把它们都摁下去通常也能跑起来。Intel Stratix 10的E-Tile有一个规定的复位序列必须满足上电稳定时间、参考时钟锁定等待、PHY复位释放先后顺序然后才能给PCS/MAC逻辑释放复位。官方IP会提供相应状态信号比如rx_pcs_ready、tx_ready这些信号必须纳入你的复位控制逻辑而不是简单拉一下全局复位就完事。我在移植初期吃过这个亏仿真里看到的复位释放顺序不满足E-Tile要求结果上板之后100G链路链路状态一直起不来TX的ready信号始终为低排查半天才发现是复位状态机写得太随意没有等待参考时钟稳定也没有做分级释放。后来改成按顺序复位链路就老实了。3. 第一阶段移植实操记录3.1 用Quartus搭建平台子系统移植的第一步是在Quartus Prime Pro里新建工程器件选型对应Bittware V4板卡上的具体型号。工程建立之后打开Platform Designer开始搭平台子系统。首先添加P-Tile PCIe Avalon-MM IP配置为主机接口模式数据位宽按256bit跑地址宽度对应BAR空间大小。这里的每一处配置都要和Corundum顶层里的DMA参数对齐。然后是E-Tile的100G Ethernet IP。选择带Native PHY的配置线速率25G通道数4输入参考时钟频率按板卡实际提供的频率填写。IP会生成一个Avalon-ST数据接口位宽通常比较大同时输出PHY层的状态信号和统计计数器。这些信号后续都要映射到Corundum的100G MAC接口上。Platform Designer里生成子系统之后建议先把系统总线连接图导成PDF看一遍确认每个master和slave的地址映射没有冲突。我遇到过把PCIe配置空间和BAR空间地址重叠的失误仿真看不出问题上板后驱动第一次去读配置寄存器就把总线搞挂。这种低级错误在脑子里过一遍不如在地址图上看一遍。3.2 顶层RTL重写把厂商平台包进Corundum外面Corundum原有顶层文件是针对Xilinx参考板写的移植时要新建一个针对Bittware V4的顶层把Corundum的mqnic_core核心例化在里面同时把Quartus生成的Platform Designer子系统也例化进来。两个部分之间的所有接口都要在这里完成时钟域和协议域的转换。以PCIe侧为例P-Tile IP会输出Avalon-MM的读和写通道其中包括读数据返回、写数据输入、突发计数、等待信号等。而Corundum的DMA逻辑期望的是具有AXI风格的读请求、读完成、写请求、写完成握手。两者之间需要一个桥接转换模块我会在顶层里单独写一个pcie_avmm_to_axis_adapter专门负责把Avalon的突发拆分重组为AXI风格的事务。Ethernet侧类似100G Ethernet IP输出的Avalon-ST数据总线位宽和时序与Corundum内部接口之间需要做位宽匹配和tuser信号映射。有一个细节很容易漏两个IP对报文起始tuser的定义可能差一个周期导致MAC解析报文时把包头序号算错报文整体偏移最终表现为CRC永远错。这个问题的排查方法写在后面的章节里。3.3 约束文件与器件布局Quartus工程中的引脚约束和时序约束是移植过程中最琐碎也最容易因为抄错而出错的环节。引脚分配必须以板卡原理图为准。QSFP28的高速差分对、PCIe的收发通道、参考时钟输入、以及各类状态LED和I2C信号每一个都要在qsf文件里手动绑定位置。做完引脚约束之后还要花时间做时钟约束。参考时钟进入FPGA后建议用create_clock约束其频率和精度再让Quartus通过derive_pll_clocks自动推断PLL输出时钟。对于跨时钟域的异步FIFO路径要设置合适的false path或者set_max_delay约束避免Quartus在异步路径上强行做时序收敛白白浪费布线资源。器件布局也是移植后被反复折腾的事情。100G以太网数据通路最好固定在靠近E-Tile收发器的一组逻辑阵列里PCIe DMA逻辑则靠近P-Tile一侧。Quartus的Fitter默认行为有时会为了满足全局时序把你模块打散导致关键路径绕远。我的做法是适当使用LogicLock区域把以太网收发包引擎固定在收发器附近这样不仅时序收敛更容易后续调试时信号定位也更方便。3.4 先用仿真验证再上板千万不要在第一次编译通过后就急着烧FPGA先跑仿真能省下位数众多的时间。Quartus生成的IP自带仿真模型Corundum仓库里也有相对完整的仿真测试平台。把两者结合先做一次纯功能仿真检查PCIe的DMA读写事务能在仿真模型里完成一轮描述符处理再检查以太网MAC能正常处理一个ARP报文。仿真阶段最容易验证出的是接口位宽和握手信号不匹配的问题。ModelSim或Questa里波形的信号名几乎可以对照两个IP的接口定义逐一点查一旦发现valid和ready始终没有同时拉高就说明握手逻辑有问题而这种问题在RTL仿真里几分钟就能定位放到上板后要接逻辑分析仪才能查。我在仿真时还会提前把复位时序的检查项做成断言。比如复位释放之后E-Tile的tx_ready信号必须在规定时间内拉高如果没有断言会立刻报警省去事后翻波形找原因的麻烦。4. 编译、时序收敛与常见问题排查4.1 第一次编译就失败的三大典型原因第一次完整编译的成功率不会太高多数问题集中在下面三类。一类是Platform Designer生成的接口与顶层实例化名称不一致导致综合阶段找不到信号。这类问题还好办把报错信号和IP向导里的端口列表对一下就解决。另一类是引脚约束冲突。Bittware V4的板卡上有些引脚连接到了板载LED或者拨码开关这些普通I/O引脚本身没有问题但如果你不小心把同一个引脚同时分配给两个功能Quartus会在Fitter阶段报错。这类错误很隐蔽因为原理图PDF里的引脚列表很长靠肉眼检查容易漏好在报错信息会明确列出冲突的引脚名。还有一类是E-Tile PHY的硬核资源被重复使用。如果Platform Designer里不小心添加了两个占用同一物理通道的收发器IPQuartus会报资源冲突。遇到这个错误就要回头审视IP配置里的通道分配确保每个通道只被实例化一次。4.2 设备能枚举但DMA不工作的排查顺序如果上板之后在Linux下能够看到PCIe设备lspci能正确列出Vendor ID和Device ID说明PCIe物理链路和配置空间已经正常这通常意味着P-Tile硬核配置没有大问题。接下来DMA不工作时的排查我习惯按照下面的顺序来。第一步检查BAR空间映射。在Linux里用lspci -v看BAR地址是否分配正确然后通过/dev/mem或者开发驱动里直接读寄存器的方式验证能否访问到Corundum的CSR空间。地址能读回来再继续读不到就先查PCIe IP的BAR配置和地址译码逻辑。第二步检查IRQ。Corundum使用MSI/MSI-X中断来通知DMA完成Intel的PCIe IP需要显式使能MSI-X相关配置如果漏掉中断永远不会来DMA虽然完成但驱动收不到通知表现出来就是卡死。排查时可以先关闭MSI改用传统INTx验证一次能缩小问题范围。第三步检查描述符环。DMA引擎本身的工作依赖主机内存里的描述符如果驱动下发的描述符格式和硬件期望不一致硬件会一直停在等待描述符的状态。这里没有捷径只能对照Corundum的寄存器手册逐一确认每个字段的偏移和比特含义。4.3 收发器链路起不来的自查清单移植过程中100G链路无法建立连接是最让人沮丧的场景因为物理层的问题表现得很一致但原因千奇百怪。我整理了一个自己经常翻阅的自查清单按步骤走能覆盖掉大部分原因。现象排查点处理建议TX的PMA/PHY一直不在ready状态参考时钟是否稳定时钟芯片输出频率是否正确用示波器测实际输出核对原理图默认配置RX信号检测不到光模块信号光模块是否被正确初始化I2C通路是否阻塞检查QSFP28的管理I2C地址映射单独用I2C工具读取模块ID链路层显示UP但RX错误计数持续增长RS-FEC使能与对端不一致关闭RS-FEC再测试确认基础链路无误后重新协商报文CRC错误且错误位置固定MAC和PHY之间数据字节序错位检查tuser对齐确认256bit总线上的字节偏移上面的表里每一个问题我都实际遇过其中最隐蔽的是光模块初始化。QSFP28模块的I2C引脚如果被主板锁在复位状态模块不会输出光信号PHY自然收不到信号。Bittware V4板卡上通常有可直接操作的I2C控制器但也可能有与BMC共用的仲裁逻辑必须等BMC释放之后才能访问。4.4 时序收敛的实用建议Stratix 10编译一次动辄几个小时如果时序不收敛反复重编会非常消耗耐心。我能给的最实在建议是先用编译报告里的关键路径列表找瓶颈而不是盲目切换Fitter策略。对于MAC数据通路通常瓶颈在宽位宽数据总线的组合逻辑链路上适当在路径中间插几级寄存器就能改善。打开Quartus的跨时钟域报告确保所有异步FIFO路径都被正确识别没有给错误约束。我发现很多时序违例其实是异步路径没有做约束导致Fitter傻傻地企图收敛一个不可能收敛的路径白白浪费资源。把这个处理好往往编译报告里的时序违规数目会大幅下降。另一个提高效率的技巧是在小规模局部编译模式下先验证RTL改动功能不做全局布线等代码稳定后再启动完整编译。Quartus支持增量编译第一次编译后第二次改动只重新布线改动的模块能把迭代时间缩短到可以接受的范围内。5. 截至目前的平台状态与下一步安排5.1 当前进度和已验证的范围到这一步Quartus工程已能完整编译通过时序收敛到全绿状态。烧录到Bittware V4板卡后PCIe链路枚举正常lspci能够看到分配好的BAR地址Corundum的CSR寄存器可以通过开发驱动正常读写。以太网侧内部回环模式下MAC数据通路功能正常收发统计计数器的报文数量符合预期但还没有接入真实100G光模块进行外部打流测试。这个阶段的状态可以称为“软件可见、链路未验”平台层的PCIe搬移已经打通DMA引擎能够完成主机到FPGA的描述符交互但报文还没有真正走过光模块的物理链路。接下来所有风险集中在PHY配置和光模块链路稳定性上这部分需要借助外接光模块和对端设备完整验证。5.2 后续工作方向下一步要做的就是编译Linux内核驱动把Corundum自带的驱动代码对接上去完成主机的网络接口注册。这个步骤完成之后才能用标准的ping和iperf做端到端测试验证真实光链路上的收发链路和中断驱动性能。然后再逐步打开RS-FEC功能继续往线速方向调优。还有一个方向是多队列和TSN特性的验证。Corundum在功能完备度上超过很多商业网卡多队列调度和PTP时间同步都能在实际系统中产生价值。这些内容展开讲又是一大篇后面我会按主题拆开记录。移植到这一步我最大的感受是Corundum把网卡里最难的部分已经做得很扎实了真正让移植工程变得麻烦的是各厂商IP之间的封闭性和接口差异。以后看到“开源”这两个字别太乐观先把硬件手册和IP用户指南准备好再动手比什么都重要。

看完文章,想为自己的企业也做一次专业网站诊断?

尧图顾问免费为您评估现有网站,并给出建站/改版建议与报价方案。

免费获取方案