尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
Bittware VV4 移植 Corundum:开源 100G 网卡 FPGA 实战
1. 为什么要把 Corundum 搬到 Bittware VV4 上第一次拿到 Bittware VV4 这块卡的时候我盯着板子上那颗 VU13P 发了会儿呆。这卡是典型的 PCIe 加速卡形态单槽全高、被动散热板载 4 路 QSFP28 接口理论上一口气能跑 4 个 100G 口。但问题也很直接Bittware 原厂给的参考设计基本围绕他们自家的 Shell 和 IP 生态转想跑一个开源、可改、社区活跃的 100G 网卡逻辑就得自己动手把 Corundum 这套东西塞进去。Corundum 这个项目在开源网卡圈子里算是老熟人了。它的定位很明确——用 FPGA 实现一个高性能、可综合、参数化的 NIC 核心支持多队列、PCIe DMA、精确的收发路径而且整套 RTL 是开源的你能从队列管理一直改到 MAC 层。对于做网络加速、智能网卡、甚至只是想搞明白 100G 线速收发包到底怎么落地的人来说Corundum 是一条绕不开的路。但“开源”和“能跑”之间隔着一条河。Corundum 官方主要维护的是基于 Xilinx 官方开发板比如 Alveo 系列的参考设计板级相关的约束、时钟、PCIe 硬核配置、QSFP 引脚映射这些都得针对具体板卡重新做。Bittware VV4 用的是 VU13PPCIe Gen3 x16QSFP28 光模块接口和 Alveo 的板级资源分布不完全一样。所以这次移植的核心工作就是把 Corundum 的 RTL 和 Bittware VV4 的物理资源对接起来让它在真实硬件上跑通 100G 收发。这篇文章适合谁看如果你手上有 Bittware 的卡或者任何一块 VU13P/VU9P 级别的板子想跑开源 100G NIC那这篇就是给你写的。如果你只是刚入门 FPGA想看看一个真实的 100G 网卡项目长什么样也能从里面摸到不少工程细节。我会把整个移植过程拆成几个阶段从环境准备、板级适配、时钟约束到上板调试和踩坑记录尽量把每一步的“为什么”讲清楚。2. 移植前的整体思路与方案选型2.1 为什么选 Corundum 而不是自己从零写自己从零写一个 100G NIC 不是不行但代价太大。PCIe DMA 引擎、描述符管理、收发队列、流控、MAC 层对接这些东西每一个单独拎出来都够写几个月。Corundum 的价值在于它已经把这些模块做成了参数化、可配置的 RTL而且经过了多轮流片和实际部署验证。它的架构大致分几块PCIe 子系统负责和主机通信DMA 引擎搬数据队列管理模块维护发送和接收队列MAC 层对接以太网 PHY还有一套控制寄存器接口供驱动读写。选 Corundum 的另一个原因是它的可移植性设计。它的 RTL 里把板级相关的部分抽象成了几个接口比如 PCIe 硬核的配置、时钟输入、GT 收发器的位置这些在移植时只需要改对应的 wrapper 和约束文件核心逻辑基本不用动。这比那种把板级资源写死在代码里的设计友好太多。2.2 Bittware VV4 的板级资源盘点Bittware VV4 的核心是 Xilinx Virtex UltraScale VU13P这颗芯片的逻辑资源、DSP、BRAM 都很充裕跑 Corundum 的 100G 配置绰绰有余。板载 4 个 QSFP28 笼子每个支持 100G通过 GTY 收发器连接到 FPGA。PCIe 接口是 Gen3 x16直接连到主机的 PCIe 根复合体。时钟方面板上有专门的时钟芯片产生参考时钟QSFP 和 PCIe 各有自己的时钟域。移植前我先把板子的原理图和引脚约束翻了一遍重点确认三件事QSFP 的 GT 通道映射、PCIe 的参考时钟来源、以及系统复位和配置相关的引脚。这些信息决定了后面约束文件怎么写。Bittware 通常会提供一份板级约束模板里面包含了引脚定义和基本的时序约束这份模板是移植的起点。2.3 移植路线的取舍移植有两条路可以走。一条是直接用 Bittware 的 Shell把 Corundum 的逻辑挂到 Shell 的 PCIe 和网络接口上。另一条是抛开 Shell自己从 Corundum 的参考设计改把板级相关的部分替换成 VV4 的。我选了第二条原因是 Bittware 的 Shell 封装比较重里面有不少他们自己的 IP 和授权限制改起来反而束手束脚。Corundum 的参考设计结构清晰板级适配层薄改起来更可控。当然这条路也有代价PCIe 硬核的配置、时钟约束、GT 的复位序列这些都得自己搞定。但好处是整条链路透明出了问题能一路查到 RTL 层不会被 Shell 的黑盒挡住。3. 环境搭建与工程结构梳理3.1 工具链版本选择Xilinx 的工具链版本对 UltraScale 的支持很关键。我用的 Vivado 2021.2这个版本对 VU13P 的支持成熟而且 Corundum 的官方脚本在这个版本上验证过。太新的版本有时候会引入一些 IP 核的兼容性问题太老的版本又可能缺少某些 UltraScale 的时序模型。2021.2 算是一个比较稳的平衡点。除了 Vivado还需要一台 Linux 主机来跑编译和驱动。Corundum 的驱动是内核模块编译需要对应的内核头文件。我用的 Ubuntu 20.04内核 5.15编译驱动没遇到大问题。主机和板卡之间的 PCIe 通信依赖驱动加载后的字符设备所以驱动编译通过是上板前的必要步骤。3.2 Corundum 源码结构速览Corundum 的仓库结构不算复杂但第一次看容易迷路。核心目录大致分这几块rtl下面是所有 RTL 源码fpga下面是各板卡的参考设计sw是驱动和工具scripts是编译脚本。移植时主要动的是fpga目录下的板级工程以及rtl里少数和板级相关的 wrapper。rtl里的核心模块包括mqnic_core主逻辑、mqnic_pciePCIe 接口、mqnic_eth以太网接口、mqnic_dmaDMA 引擎。这些模块本身是板卡无关的移植时不需要改。真正要改的是顶层 wrapper它负责把核心模块的接口连到具体的 PCIe 硬核和 GT 收发器上。3.3 建立 VV4 专属工程目录我习惯在fpga目录下新建一个bittware_vv4文件夹把参考设计的约束和脚本拷过来改。这样做的目的是保持和上游的隔离后面 Corundum 更新时只需要对比板级目录的差异不会把核心逻辑的改动搞混。工程目录里放三样东西约束文件xdc、编译脚本tcl、以及板级 wrapper 的 RTL。约束文件是移植的重头戏里面要定义时钟、引脚、时序例外。编译脚本负责调用 Vivado 的 IP 核生成、综合、实现、比特流生成。板级 wrapper 则是把 Corundum 的顶层接口和 VV4 的物理引脚对接起来。这三样东西配合好了工程就能跑起来。4. 板级适配的核心细节4.1 PCIe 硬核配置与时钟约束VV4 的 PCIe 是 Gen3 x16用的是 UltraScale 的 PCIe 硬核。Corundum 的参考设计里 PCIe 配置是通过 IP 核生成的移植时要改几个关键参数链路宽度改成 x16链路速度改成 Gen3参考时钟频率改成板子实际提供的 100MHz。这些参数在 IP 核的配置界面里改改完重新生成。时钟约束是容易出问题的地方。PCIe 的参考时钟从板子的时钟芯片来经过 IBUFDSGTE 进入硬核。约束里要定义这个时钟的周期和抖动范围还要定义硬核输出的用户时钟。Corundum 的逻辑跑在用户时钟域如果时钟约束不对综合出来的时序会报一堆违例上板后链路可能根本起不来。提示PCIe 参考时钟的约束一定要和板子实际提供的频率一致。VV4 的 PCIe 参考时钟是 100MHz如果你按 125MHz 约束链路训练阶段就会失败而且报错信息往往很模糊不容易定位。4.2 QSFP28 的 GT 通道映射VV4 有 4 个 QSFP28 笼子每个笼子对应 4 对 GT 收发器。移植时要把 Corundum 的以太网接口连到正确的 GT 通道上。这需要查板子的原理图确认每个 QSFP 的 TX/RX 对连到 FPGA 的哪些 GT bank 和通道。VV4 的 GT 通道分布不是连续的有些 QSFP 的通道跨了 bank约束时要特别小心。我一开始只跑一个 QSFP 口选了 QSFP0对应 GT bank 的 4 个通道。约束里定义了这 4 对收发器的引脚位置和参考时钟。Corundum 的 MAC 层支持多口但第一次移植建议先跑单口把链路跑通再扩展。单口跑通后加第二个口只需要复制约束和例化逻辑工作量不大。4.3 复位与配置引脚的处理VV4 的复位和配置引脚在板级约束里有定义但 Corundum 的参考设计用的是自己的复位逻辑。移植时要把板子的全局复位信号接到 Corundum 的复位输入上确保上电后逻辑能正确初始化。配置引脚主要是 JTAG 和配置模式相关的这些在约束里声明一下就行不影响逻辑功能。复位逻辑里有个细节PCIe 硬核的复位和用户逻辑的复位是分开的。硬核复位由板子的 PERST 信号控制用户逻辑复位由硬核输出的复位信号控制。Corundum 的复位模块要接对这两个信号否则会出现硬核起来了但用户逻辑没复位的情况表现为链路能训练但驱动读不到设备。5. 编译、上板与调试实录5.1 综合与实现的参数调整第一次综合的时候Vivado 报了不少时序违例主要集中在 PCIe 用户时钟域和 GT 的收发路径上。分析下来有两个原因一是时钟约束不够紧二是布局布线时 GT 通道的位置不理想。调整方法是把 PCIe 用户时钟的约束收紧同时在实现策略里选择性能优先的布局布线选项。综合选项里有个-flatten_hierarchy参数我设成了rebuilt这样 Vivado 能跨层次优化逻辑对时序有帮助。实现阶段用了Performance_ExplorePostRoutePhysOpt策略这个策略在布线后会做物理优化对高速路径的时序收敛效果不错。调整后时序违例基本清掉了只有少数路径有很小的负 slack上板后不影响功能。5.2 比特流下载与链路训练比特流生成后用 Vivado 的硬件管理器下载到 VV4。下载完成后先看 PCIe 链路有没有训练成功。在 Vivado 的硬件管理器里能看到 PCIe 硬核的状态寄存器如果链路宽度显示 x16、速度显示 Gen3说明训练成功。如果显示 x1 或 Gen1说明链路有问题通常是参考时钟或复位的问题。链路训练成功后主机端应该能枚举到设备。用lspci命令能看到 Xilinx 的设备 ID。如果看不到先检查驱动有没有加载再检查 PCIe 配置空间有没有被正确映射。我遇到过一次枚举不到设备的情况最后发现是板子的 PERST 信号没接对硬核一直处于复位状态。5.3 驱动加载与回环测试驱动编译通过后用insmod加载。加载成功后dmesg里会打印设备初始化信息包括队列数量、DMA 通道等。然后可以用 Corundum 自带的测试工具做回环测试。回环测试是把一个 QSFP 口的 TX 和 RX 用光纤跳线连起来发一批数据看能不能正确收到。第一次回环测试没通过收发包计数对不上。排查后发现是 GT 的复位序列有问题收发器没完全初始化。Corundum 的 GT 复位逻辑需要根据板子的参考时钟稳定时间来调整VV4 的时钟芯片稳定时间比参考设计里的长所以复位等待时间要加长。改完复位计数器后回环测试通过100G 线速下丢包率为零。5.4 常见问题速查表问题现象可能原因排查方法PCIe 链路宽度只有 x1参考时钟频率不对或复位未释放检查时钟约束和 PERST 信号主机枚举不到设备驱动未加载或配置空间映射失败用 lspci 和 dmesg 查看回环测试丢包GT 复位序列不完整加长复位等待时间时序违例集中在 GT 路径布局布线策略不优换用性能优先的实现策略驱动加载后设备无响应用户逻辑复位未释放检查硬核输出的复位信号6. 移植过程中的经验与避坑6.1 时钟约束宁紧勿松时钟约束是移植里最容易埋雷的地方。我一开始为了省事把 PCIe 用户时钟的约束设得比较宽松综合能过但上板后链路偶尔会掉。后来把约束收紧到实际时钟的 90% 周期时序虽然难收敛但上板后链路稳定了很多。经验是时钟约束宁可紧一点让工具去努力收敛也不要松松了上板出问题更难查。6.2 GT 复位序列要按板子调Corundum 参考设计里的 GT 复位序列是针对 Alveo 板子调的VV4 的时钟芯片和电源时序不一样直接照搬会出问题。我的做法是把复位计数器加长同时增加一个超时保护如果复位在预期时间内没完成就重新触发。这个改动不大但解决了回环测试丢包的问题。6.3 先单口后多口VV4 有 4 个 QSFP 口但第一次移植千万别一上来就搞 4 个口。单口跑通后多口的扩展只是复制约束和例化工作量小而且风险低。我见过有人一上来就配 4 个口结果链路训练和时序问题混在一起排查了半个月。先跑通一个口把时钟、复位、GT 这些都验证过再扩展就顺了。6.4 驱动和 RTL 要版本对齐Corundum 的驱动和 RTL 是配套的寄存器定义和队列格式在两边要一致。移植时如果只更新了 RTL 没更新驱动或者反过来会出现驱动读到的寄存器和 RTL 实际行为对不上的情况。我的做法是把 RTL 和驱动放在同一个 git 分支里管理每次改 RTL 都同步检查驱动有没有对应的改动。6.5 保留调试接口上板调试时Vivado 的 ILA 是救命稻草。我在 PCIe 用户接口和 GT 收发路径上都插了 ILA抓取链路训练和收发包的关键信号。ILA 会占用一些 BRAM 资源但对调试的帮助远大于资源开销。等链路稳定后再把 ILA 去掉重新综合出最终版本。7. 后续可以继续做的方向单口 100G 跑通只是第一步。接下来可以做的包括把 4 个 QSFP 口都配起来跑多口并发优化 DMA 引擎的队列深度提升小包性能对接 DPDK 或者 XDP让主机侧的应用能直接走 Corundum 的收发路径还可以在 Corundum 的逻辑里加自定义的包处理模块做硬件卸载。我个人在实际操作中的体会是移植这件事最花时间的不是写代码而是查板子手册和调时序。Corundum 的 RTL 本身质量很高板级适配层也不厚只要把时钟、复位、GT 这三样搞对剩下的就是耐心调试。VV4 这块卡资源足、接口多跑通之后能做的事情很多值得花时间把它吃透。
RELATED

相关推荐

RISC-V微内核Hypervisor Bao在BPI-SM10上的深度移植实践

RISC-V微内核Hypervisor Bao在BPI-SM10上的深度移植实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📅 2026/11/6 4:48:27
ESP32-P4NRW32X工业芯片深度解析:RS485远距通信与双核异构架构

ESP32-P4NRW32X工业芯片深度解析:RS485远距通信与双核异构架构

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📅 2026/11/6 4:48:27
光伏逆变器参数设计:从组串配置到MPPT与LCL滤波的工程实践

光伏逆变器参数设计:从组串配置到MPPT与LCL滤波的工程实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📅 2026/11/6 4:48:27
MORE NEWS

更多资讯

📰

半正定矩阵:概念、判定与应用全解析

1. 半正定矩阵的基本概念半正定矩阵(Positive Semi-Definite Matrix,简称PSD矩阵)是线性代数中一类特殊的对称矩阵。这类矩阵在优化问题、机器学习、信号处理等领域有着广泛的应用。简单来说,一个实对称矩阵A如果满足对于所有非零…

📰

C++将二叉树转为双向链表及判断两个链表是否相交

前言 这篇把两个常被放在一起问的指针操作题放在一篇里讲。第一题是把一棵二叉搜索树(binary search tree, BST)原地转换成一个有序的双向链表,不新建结点,只改写指针;第二题是判断两个单链表是否相交,如果…

📰

SSD硬盘测速工具AS SSD Benchmark:四项指标解读与跑分避坑

简介:AS SSD Benchmark 是一款面向 SSD 用户的轻量级硬盘性能测试工具,版本 v1.8.5611.39791,适合希望了解固态硬盘真实读写表现、排查性能瓶颈或进行硬件选型对比的普通用户与装机爱好者。压缩包共 4 个文件,约 285KB&#xff0c…

📰

C#高性能Socket通信库设计与高并发优化实践

1. 项目概述:高并发Socket通信的核心价值在网络通信领域,Socket编程一直是构建分布式系统的基石。这个C#实现的高性能Socket通信库,完整覆盖了TCP/UDP的客户端与服务端实现,特别针对高并发场景进行了深度优化。我曾在一个物联网平…

📰

010 Editor二进制解析:模板与脚本定位配置块

简介:这是一套面向开发人员、系统管理员及逆向与数据分析学习者的010 Editor十六进制编辑工具包,重点解决二进制文件查看修改、大文本检索替换和复杂文件结构解析等需求。压缩包共35个文件,约19.64MB,以dll运行库、exe主程序、qhc…

📰

KITTI点云可视化工具:纯Python轻量级交互式驾驶场景探查器

简介:本资源是一个面向自动驾驶感知算法学习者的KITTI数据集可视化工具集,专为点云处理与BEV(鸟瞰图)分析初学者及研究人员设计,解决原始.bin点云数据难以直观理解、多视角对比困难等实际问题。压缩包共42个文件&#…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬