资讯动态

Corundum 100G 网卡核移植到 Intel Stratix 10 VV4 的工程实践

发布时间:2026/9/26 1:45:13 来源:尧图企业网站定制
1. 项目概述为什么非要把Corundum搬上VV4有人问我手里有现成的100G商用网卡为什么还要折腾一块FPGA去跑开源的100G NIC软核我的回答很简单商用网卡是个固定功能的黑盒而 Corundum 是能让你自己改协议、加卸载功能、做网络测量的开源方案。Corundum 是目前 FPGA 网卡方向最完整的开源实现主线支持从 10G 一路做到 100G自带 PCIe DMA、多队列收发、网卡驱动和 PTP 相关逻辑。配合 Bittware VV4 这块基于 Intel Stratix 10 的 PCIe 加速卡等于用开源 RTL 给自己做成了一块可随时改功能的 100G SmartNIC。这篇文章先记录整个移植过程的第一阶段。我不会只贴“结果能用”而是把架构拆解、环境准备、工程骨架搭建这些前置工作讲透。后面再看驱动和性能调优时你就能明白每个参数为什么这么配。适合正在做 FPGA 网络加速、SmartNIC 原型验证、或者单纯想在 Intel 平台上跑通 Corundum 的工程师。如果你是第一次接触 100G 设计文里涉及 SerDes、PCIe 硬核、Ethernet MAC/PCS 这些概念我也会用比较容易理解的方式解释。1.1 Corundum到底牛在哪Corundum 不是一个简单的 MAC 或者 DMA 控制器它是一整套“网卡 RTL 主机驱动”的解决方案。RTL 侧包含 PCIe DMA 引擎、发送调度、接收分发、以太网 MAC/PCS 接口、统计、流表等模块主机侧提供 Linux 内核驱动能把 FPGA 上的队列映射成标准网络接口。也就是说它不是只点亮链路就完事而是能真正收发数据、跑 iperf3、看 ethtool 统计的完整网卡。它还有一个很关键的设计选择核心 RTL 尽量与 FPGA 厂商解耦。Xilinx 和 Intel 平台之间的差异被隔离在少数 wrapper 模块里所以移植一个新板卡时大部分代码不需要动我们要做的核心工作就是“把板级专用的 PCIe 和以太网 IP 接进 Corundum 的通用接口”。1.2 VV4平台到底提供了什么Bittware VV4 是面向高性能计算和网络加速的 PCIe 板卡核心是一颗 Intel Stratix 10 系列 FPGA板上带多个 QSFP28 光口笼子支持 100G 光模块接入同时还带 PCIe 主机接口和板载 DDR。对 100G NIC 来说最关键的硬件条件是三样足够多的 25G SerDes 通道、稳定的 100MHz PCIe 参考时钟、以及 156.25MHz 的 transceiver 参考时钟。Stratix 10 的收发器跑 25.78125Gbps 这个速率很从容逻辑资源对 Corundum 来说也绰绰有余。当然不同批次或者不同配置的 VV4 在光口数量、DDR 容量、PCIe 宽度上可能有差异。我下面写的引脚、IP 参数都属于“常见配置”你动手前一定要以自己手里板卡的手册和原理图为准。移植 FPGA 工程最怕的就是对着网上的旧教程抄引脚最后编译过了但板子不工作。1.3 移植要做的三件事整个移植可以拆成三个层面。第一个是工程层让 Quartus 认识 VV4 的器件型号、引脚分配、时钟约束。第二个是 IP 层生成对应 Stratix 10 的 PCIe 硬核 IP 和 100G Ethernet IP替换掉 Corundum 里默认的厂商 wrapper。第三个是验证层加载 bitstream 后主机能枚举到 PCIe 设备光模块能协商出 100G 链路驱动能把接口拉起来。第一阶段主要解决前两层工程问题链路验证属于“摸到门槛”。如果你能把这三层都跑通Corundum 迁移到其他 Intel FPGA 板卡上的流程也就基本掌握了。2. Corundum架构拆解与移植评估2.1 一条报文从主机到光口要理解移植工作先得知道数据是怎么走的。你从服务器通过 100G 网卡传一个大文件报文路径大致是Linux 协议栈 → 驱动把描述符写进 FPGA 的队列内存 → Corundum 的 DMA 引擎把数据从主机内存搬到 FPGA 的缓冲 → 发送调度器从队列里取包 → 进入以太网 MAC 做 64B/66B 编码 → PCS 层做加扰和对齐 → PMA 层并串转换 → 光模块发出。接收方向完全相反DMA 再把数据写回主机内存同时还能做校验和、RSS 哈希这类卸载。这里面最灵活也最能体现 Corundum 价值的是 DMA 和多队列调度。Intel 或 Xilinx 的 PCIe 硬核通常只负责物理层和事务层真正的 DMA 引擎是 Corundum 自己的 RTL。所以你可以改队列数量、改仲裁策略甚至把某些流直接导到 FPGA 上的自定义处理逻辑这就是商用网卡做不到的。Corundum 内部大量使用 AXI4-Stream 和 AXI4-Lite 接口这也是它能跨厂商迁移的基础。Xilinx 的 CMAC、Intel 的 Low Latency 100G Ethernet IP虽然物理接口不一样但最后都能通过一个 adapter 转成 AXI-Stream 接到 Corundum 的统一数据通路上。2.2 Intel平台上的差异点Xilinx 平台上的 Corundum 移植文章已经很多了但换到 Intel Stratix 10 会遇到几个明显的差异。第一是 PCIe IP。Stratix 10 用的是硬核 PCIe必须通过 Quartus 的 IP 向导生成输出接口可能是 Avalon-MM 或 Avalon-ST 风格而 Corundum 内部是 AXI 风格中间必须有一个 bridge 做转换。第二是以太网 IP。Intel 的 Low Latency 100G Ethernet IP 封装了 MAC、PCS、PMA它的接口时序、复位要求、状态信号命名都和 Xilinx CMAC 差很多。第三是引脚约束方式。Stratix 10 的 transceiver 引脚绑定通常和 IP 绑定得很紧直接写set_location_assignment反而容易出错。我整理了一个简单的对照表方便你评估手头要改哪些东西模块Corundum通用部分VV4板级/厂商定制部分PCIeDMA引擎、队列管理、地址映射Intel FPGA PCIe IP、Avalon/AXI bridge、100MHz参考时钟以太网调度、统计、收发缓存Intel Low Latency 100G Ethernet IP、25G SerDes通道时钟复位PLL锁定后的内部复位同步板载156.25M/100M时钟源、transceiver reset时序QSFP控制I2C控制器、模块状态读取QSFP笼子的ResetL、ModPrsL、LPMode引脚映射看明白这张表你就知道第一阶段最花时间的地方不在 Corundum 的 RTL而在这些板和 IP 的“缝合”工作。2.3 资源与带宽评估动手之前先做粗略的资源评估。100G 以太网在 QSFP28 光模块下通常走 4 条 25G SerDes 通道Stratix 10 的收发器完全够用。PCIe 接口方面如果板卡是 PCIe Gen3 x16单向带宽大约 126Gbps对 100G 网卡来说是够的但富余不多一旦要开启大量流表或 PTP 功能DMA 的效率就会成为瓶颈。这也是为什么 Corundum 的驱动层会关注队列数量和中断策略。逻辑资源上Corundum 本身加 Intel 100G Ethernet IP在 2800 级别 ALM 的 Stratix 10 上可以轻松放下不需要担心规模问题。真正需要花心思的是时序收敛和复位时序这一点后面单独说。3. 开发环境与源码准备3.1 选择Quartus版本Stratix 10 只能用 Quartus Prime Pro 版本不能用标准版。具体版本号我建议选一个自己熟悉且对 Stratix 10 支持成熟的比如 20.4 或 21.3。Intel 的 IP 和 Quartus 版本绑定得很死一个版本的 100G Ethernet IP 生成出来换一个 Quartus 版本经常要重新生成。Corundum 仓库里如果已经带了某个 Intel 目标的旧工程文件直接用新版本 Quartus 打开大概率会提示 IP 版本不匹配不要慌删掉旧 IP 重新生成一次就好。另外Bittware 官方会提供 VV4 的板级文件包括引脚约束、示例工程和编程方式。强烈建议先去下载里面很多 QSF 内容可以直接复用。自己从原理图一个引脚一个引脚抠既费时间又容易出错。3.2 拉取Corundum源码源码直接 clone 就行git clone https://github.com/alexforencich/corundum.git cd corundum目录结构大致是这样corundum/ rtl/ # 与厂商无关的核心RTL fpga/ # 各厂商、各板卡的工程脚本和约束 modules/ # 可选的扩展模块 drivers/ # Linux内核驱动源码fpga目录里能看到很多现成板卡目标比如 Xilinx 的 U250、Intel 的某些开发板。VV4 大概率不在里面所以我们不是“选一个目标然后编译”而是“照着已有目标新增一个 VV4 目标”。3.3 新增工程目标的原则新增目标时最忌讳的是把板级细节硬塞进 Corundum 核心代码。正确做法是新建一个独立的板卡文件夹里面放 QSF、SDC、IP 生成脚本、顶层 wrapper所有厂商相关的代码都在这个文件夹里不动rtl目录下的通用模块。之后如果要换板子只需要再建一个文件夹或者改几行配置。具体到 Corundum 的构建流程它会通过 Makefile 调用 Quartus 的工具链来生成工程。新增目标时主要补两部分一个是板的引脚、时钟和约束文件另一个是 Intel IP 的配置脚本或者现成的 Qsys/Platform Designer 工程。你不需要一次做完先做最简单的最小系统再逐步加功能。4. 移植实操搭建VV4工程骨架4.1 读原理图先把引脚表列全动手配 IP 之前先花半天时间读 VV4 的原理图。重点找四类信号。第一是 PCIe x16 通道的收发和参考时钟注意时钟是独立 100M 还是从 PCIe 插槽取。第二是 QSFP28 的 SerDes 通道和参考时钟。100G 光模块通常一个 QSFP 口对应 4 对收发差分线而且参考时钟必须是 156.25MHz 级别很多板卡在 QSFP 笼子旁边放了专用时钟芯片。第三是 QSFP 管理信号包括 I2C 的 SCL/SDA、模块在位检测 ModPrsL、复位 ResetL、低功耗模式 LPMode。第四是板上 FPGA 配置相关的引脚比如 JTAG、MSEL、状态 LED调试时用得着。把这些信号整理成一个简单的表格列名可以是“功能、原理图网络名、FPGA引脚”。后面写 QSF 约束时对着这个表格抄比来回翻 PDF 高效得多。另外特别注意原理图上有没有标注差分对反相板厂经常在实际布线中交叉 TX/RX这个坑会在链路调试时冒出来。4.2 生成板级专用IP进入 Quartus先新建一个空工程器件选择 VV4 上那颗具体的 Stratix 10 型号。然后打开 Platform Designer添加 Intel FPGA PCIe IP。这里需要关注几点PCIe 宽度选 x16速度选 Gen3模式选 Hard IP。生成 IP 后先不要急着集成 Corundum可以先用 IP 自带的 example design 编译一次确认 PCIe 硬核本身能在你的 Quartus 版本下正常工作。这一步能帮你把“IP 问题”和“Corundum 问题”分开。接着添加 Low Latency 100G Ethernet IP。配置时选择 100G 模式通常对应 4 通道 25.78125Gbps参考时钟选 156.25MHz。FEC 默认可以关掉先让链路起来后面再根据对端设备决定是否开 RS-FEC。每次生成 IP 后立刻打开 example design 编译一次因为 Intel IP 在不同 Quartus 版本下的生成结果差异很大先把 IP 验证通过再往 Corundum 里接。4.3 顶层RTL怎么改Corundum 的 Intel 路径已经准备了一个顶层 wrapper它承担两件事把 Intel PCIe IP 的接口转成 Corundum 需要的 AXI 接口把 Intel 100G Ethernet IP 的接口转成 Corundum 的以太网接口。我们要做的就是把自己生成的 IP 实例化到这个 wrapper 指定的位置并确保 IP 的名称和 wrapper 里例化的名称一致。有一个非常容易漏的地方是复位和时钟域。PCIe IP 的 user clock 频率不是固定的由 IP 的配置决定Ethernet IP 的核心时钟也是自动生成。顶层一定要把这两个时钟分别接到 Corundum 对应模块的时钟输入同时在跨时钟域的地方补好同步逻辑。不要盲目地把所有时钟都接同一个 PLL 输出否则跑起来后数据错乱很难查。QSFP 控制这块Corundum 自带 I2C 控制器可以直接读写 QSFP 的 EEPROM 和诊断寄存器。如果 VV4 的 QSFP 笼子需要先拉高 ResetL、等待一段时间再检测 ModPrsL这个时序要在顶层用简单的状态机实现。很多移植工程做完后光模块灯不亮问题几乎都出在这里。4.4 QSF/SDC约束文件引脚约束和时钟约束是第一阶段最繁琐的部分。QSF 文件大致长这样set_global_assignment -name FAMILY Stratix 10 set_global_assignment -name DEVICE VV4上实际Stratix 10型号 set_global_assignment -name TOP_LEVEL_ENTITY 顶层模块名 set_global_assignment -name SDC_FILE constraints/board.sdc set_location_assignment PIN_AA1 -to pcie_rx_p[0] set_location_assignment PIN_AA2 -to pcie_rx_n[0] ...SDC 里至少要有两个时钟一个是 PCIe 100MHz 参考时钟一个是 QSFP 的 156.25MHz 参考时钟create_clock -name pcie_refclk -period 10.000 [get_ports pcie_refclk_p] create_clock -name qsfp_refclk -period 6.400 [get_ports qsfp_refclk_p]这里有个细节如果参考时钟是直接接到 transceiver 的专用引脚上那么 Quartus 在编译时会把它识别成 IP 内部时钟你写get_ports可能找不到对象。更稳妥的做法是在 IP 生成后用get_clocks查到实际的时钟名再在原约束基础上补充。4.5 编译与首次点亮约束写完后先跑一次 Analysis Synthesis把语法错误和引脚错误清掉再跑 Fitter。第一次布局布线后一定要看时序报告特别是 transceiver 附近的时钟域。如果时序不过优先检查约束是否写全再看 IP 参数是否和 Corundum wrapper 匹配不要一上来就调逻辑。编译通过后生成.sof文件通过 JTAG 加载到 VV4。加载完先看两个信号光模块的 ModPrsL 是否正常识别PCIe 上游是否枚举到新设备。如果lspci里多出一个 Network controller说明 PCIe 硬核已经起来。接下来插上光模块看模块协商状态。第一次点亮不需要追求 100G 满速看链路是否 link 上再看能不能通包就够了。4.6 驱动编译与基本连通性测试硬件链路起来后把 Corundum 的 Linux 驱动编译进当前内核。需要确保机器安装了对应内核版本的 header 包然后进drivers目录执行make。加载驱动后ip link应该能看到一个新的网络接口。先不要着急跑 iperf3先用简单的 ping 验证双向通路。如果 ping 不通但链路是 link 的大概率是 MAC 的收发通路有问题比如前面说的 SerDes 极性反接或者 PCS 的对齐状态没起来。这些坑会在下一节展开。5. 常见问题与排查技巧实录5.1 问题速查表现象排查方向PCIe设备枚举不到查PCIe参考时钟和复位、硬核配置、板卡供电、BIOS里Above 4G Decoding是否开启光模块灯不亮/模块不识别查QSFP的ResetL、ModPrsL、I2C地址和SCL/SDA引脚链路能link但包不通查SerDes收发极性、PCS对齐状态、FEC开关、对端设备和线缆驱动probe失败查BAR空间大小、MSI-X配置、内核header版本、DMA一致性设置100G只能跑到几十G查驱动队列个数、中断合并、CPU核数绑定、PCIe DMA效率这张表是调试时的第一索引但实际过程中经常是多个问题叠加出现需要耐心一层层剥开。5.2 三个最容易被坑的细节第一个是 SerDes 收发极性反接。FPGA 板卡为了走线方便经常把 TX 和 RX 方向接反或者把差分正负对调。这种情况下光模块的激光器和接收机都能工作但 MAC 层一直无法建立同步。不要飞线改硬件直接用 Intel 100G Ethernet IP 里的极性反相配置或者通过 transceiver reconfiguration 接口设置几分钟就能解决。第二个是参考时钟来源搞错。有的板卡每个 QSFP 口有独立的 156.25M 时钟有的是多口共享。如果在 IP 配置里选错了时钟源PLL 永远锁不住表现就是 IP 的状态寄存器里rx_pcs_ready一直拉低。遇到这种情况先回来看时钟树原理图比反复改 IP 参数有效。第三个是复位顺序。Stratix 10 的 transceiver 对复位时序比较敏感正确做法是先等参考时钟稳定再释放 PMA 复位最后释放 PCS 和 MAC 复位。如果你把所有模块的复位都连到一个公共复位信号上大概率会偶尔出现链路起不来的现象。我在顶层加了一个简单的延迟链按照固定间隔逐级释放复位之后再没有出过类似问题。5.3 一个建议移植 FPGA 网卡这种事最好的调试工具不是逻辑分析仪而是你手里那颗 100G 光模块和一根质量靠谱的 DAC/光缆。很多“诡异”问题其实是线缆或者光模块本身造成的。调试早期我建议先用短距离直连铜缆避免光模块的光功率和兼容性问题干扰判断。等逻辑完全稳定后再上光模块做长距离测试。6. 移植第一阶段手记到这里第一阶段该说的基本说完了从拆解 Corundum 架构、评估 VV4 资源到生成工程、点亮链路每一步都踩在“板级缝合”这个主题上。后面还有 Linux 驱动多队列、DMA 性能和流表卸载这些更硬的课题我会在后续文章里继续记录。我个人在移植过程中最大的感受是Corundum 自己的 RTL 相当稳定真正花时间的全是接口缝。比如 Intel IP 的地址对齐、Avalon 和 AXI 之间 bridge 的时序、不同时钟域之间的同步这些不翻手册真的很难一次性猜对。如果你也在做类似的 FPGA 网卡移植不妨先像我一样把环境准备和 IP 验证做扎实再进入驱动和性能阶段。最后分享一个小经验在 VV4 上第一次看到lspci识别出那颗虚拟网卡设备时其实比看到 100G link up 更让我安心。PCIe 枚举通过说明硬核、时钟、复位这条最复杂的链路已经打通了后面即使出现网络不通也都是可以慢慢查的局部问题。移植 100G NIC 就是这样每通一层剩下的路就清楚一分。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑