拓十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Corundum开源100G NIC移植到Bittware VV4:时钟复位改造实战

Corundum开源100G NIC移植到Bittware VV4:时钟复位改造实战 手里有一块Bittware VV4手头正好有个需要100G网卡的项目买成品卡太贵商业IP又动辄几十万授权费于是我想到了Corundum——这个GitHub上star数可观的开源NIC项目。Corundum支持10G/25G/100G代码全开源RTL层和Linux驱动都有硬件上原生适配VCU118、VCU1525、Alveo U250这些Xilinx开发板。但VV4不在官方支持列表里这就意味着必须自己动手做移植。这篇文章是移植系列的第一篇主要讲移植前的架构梳理、工具链准备、时钟复位方案改造以及第一轮综合布线如何跑通。适合手里有类似Xilinx UltraScale板卡、想把Corundum跑起来、又不想被官方板卡捆绑的FPGA工程师和网络研发同学。我会尽量把每一步都写明白包括我踩过的坑和当时脑子里的决策逻辑。1. 为什么一定要碰Corundum这块硬骨头1.1 开源100G NIC可选方案没那么多先给不熟悉这块的朋友补个背景。网上能搜到的开源NIC方案真正能跑到线速100G的屈指可数。NetFPGA系列更多是教学和科研用途跑到100G需要SUME板卡和一系列商业IP配合移植成本不低。而Corundum是少有的、从MAC到DMA再到Linux驱动全链路开源的实现。它不只是个玩具作者Alex Forencich把很多生产级细节都做了多队列DMA、MSI-X中断、流式哈希、时间戳、PTP甚至MAC合并TSN相关都有完整RTL实现。更关键的是Corundum的驱动是内核模块不是那种只在bare-metal下跑的玩具代码。这意味着只要硬件移植成功Linux下直接insmod就能当一块正经网卡用支持ethtool、支持中断、支持多队列收发。这一点在评估移植可行性时非常重要——如果只能跑个回环测试那这块板子的价值就大打折扣了。1.2 VV4到底给了我们什么底子Bittware VV4这板子核心是Virtex UltraScale系列的旗舰器件具体型号不同批次有差异但基本都是VU37P这个级别。板上资源对100G NIC来说非常充裕大量GTY收发器、充足Block RAM和UltraRAM、可编程时钟芯片、双路QSFP28光口、PCIe x16 Gen3接口还配了DDR4存储。对比Corundum原生支持的VCU118VV4的核心优势有两个。第一是PCIe接口是x16的带宽余量比VCU118的x16还宽裕第二是板上时钟方案有可编程时钟芯片理论上可以生成Corundum期望的各种参考时钟频率不用额外飞线改板。但劣势也很明显Corundum官方没有为VV4提供任何参考工程所有引脚映射、时钟约束、复位逻辑都得自己从头来。1.3 移植到底在移什么很多朋友一听移植就觉得是要改大段RTL代码其实不是。Corundum的核心逻辑DMA引擎、MAC、调度器、寄存器空间是板卡无关的它们通过标准AXI接口互联不关心具体跑在哪块板子上。真正需要动刀的地方就三类引脚约束PCIe lane、QSFP28的TX/RX、I2C、中断、LED这些信号要映射到VV4的实际封装引脚上。时钟方案原版参考板用的板载时钟频率、GTY参考时钟来源和VV4可能完全不同需要重新设计时钟树。复位与板级初始化光模块的上电时序、复位信号极性、可编程时钟芯片的初始化配置这些和板卡硬件强相关。把这三件事想清楚移植工作其实就完成了一半。剩下的事情就是逐项落实、编译、上板验证。所以我在做这次移植时第一件事不是碰代码而是花了一个晚上把Corundum的仓库结构和VV4的原理图资料过了一遍。2. 动手前先把Corundum的架构掰开揉碎2.1 一条数据从网线走到CPU的完整路径理解Corundum的数据通路是移植的基础否则你连报错信息都看不懂。我画一条最简路径外部光纤 → QSFP28模块 → GTY收发器 → 100G MACCMAC硬核→ MAC接收流水线删除前导码、FCS校验、解析头部→ DMA描述符引擎 → AXI4接口 → XDMAPCIe IP→ 主机内存反过来发送方向就是逆过程。这里有个非常关键的点Corundum的PCIe子系统和DMA引擎用的是Xilinx XDMA IP而不是自己造一套PCIe控制器。XDMA的作用是打通PCIe物理层并向上提供AXI接口Corundum的DMA引擎则在AXI层面处理描述符、队列、中断。这样做的好处是PCIe链路相关的时序和物理层问题全部交给Xilinx IP解决坏处是移植时必须保证XDMA的配置lane数、Gen速度、AXI位宽和VV4的实际PCIe拓扑一致。2.2 Corundum工程里真正要改的文件Corundum的仓库组织非常清晰fpga/目录下按板卡分工程比如mz_pcieAlveo U250、vcu118这些。每个工程目录里大致有顶层Verilog文件例化了Corundum所有子模块并完成引脚连接。XDC约束文件定义引脚位置、IO标准、时钟约束、时序例外。IP配置目录XDMA、CMAC、时钟管理IP的XCI文件。构建脚本Vivado Tcl脚本或Makefile用来一键生成工程。移植到VV4的操作思路就是以官方某个结构最接近的工程为模板我们用的是VCU118的100G配置替换顶层文件里的板级信号、重写XDC、重新生成IP配置核心的rtl/目录下的内容一行都不需要动。这在实践里非常符合预期——Corundum的RTL分层做得干净板级相关的内容被刻意隔离在了顶层。2.3 为什么说XDMA是移植的接口锚点这个点我要单独拎出来说。玩FPGA的都知道PCIe IP是重灾区配置稍有差池板子上电后主机根本枚举不到设备。XDMA IP在Corundum里的角色非常特殊它把PCIe链路、AXI接口、中断信号全部绑定在一起了。移植时你需要确认以下几项是否和VV4匹配PCIe lane数VV4是x16物理接口XDMA配置也要选x16。PCIe速度Gen3对应8GT/sXDMA要选Gen3。AXI接口位宽Corundum的DMA引擎通常需要512位的AXI数据通路才能跑满100GXDMA的AXI从接口位宽也要一致。中断方式Corundum用的是MSI-XXDMA要确保使能并把中断引脚连到顶层。我见过不少人移植时忽略AXI位宽的一致性结果编译能过但吞吐卡在50G上不去。这个东西属于跑起来很容易跑得快很难的那类坑等你在iPerf上看到性能不对劲再去回头查时间成本就很高了。所以建议一开始就锚定XDMA的接口配置把它当成整棵树的根。3. 工程准备Vivado版本、许可证与板卡资料清单3.1 工具链版本对齐是玄学别乱升级Corundum的README里写得很清楚推荐用Vivado 2019.x或2020.x系列。很多人不把这当回事拿着Vivado 2023.1就开整了。我强烈建议先不要升级大版本因为Corundum的IP配置文件和旧的XDMA IP接口定义在新版本的Vivado里经常会报IP revision mismatch之类的错误而且不好修。我这次用的是Vivado 2020.3和官方验证版本比较接近遇到的一个问题是有个IP的License缺失后面细说。如果你跟我一样是干这行的老油子机器上可能同时装着好几个版本的Vivado记得在启动时用vivado -version确认当前环境别被2019年的旧工程脚本带到错误版本去。3.2 Bittware板卡资料开局先收集这四样VV4不像VCU118那样在Xilinx官网有全套官方资料资料得从Bittware的支持站点扒。移植前建议一次性把下面这四类文件找齐原理图PDF最好有关键部分的截图PCIe、QSFP28、时钟芯片、配置Flash这几页是最常用的。引脚约束文件XDC或CSV有些板卡厂商会提供完整的引脚清单直接节省大量对照原理图的时间。Board Definition FilesBDF如果厂商提供了Vivado BDF可以直接用Board Part创建工程PCIe和DDR的部分IP会自动配好。参考设计哪怕是个LED闪烁的demo也能帮你确认工程引脚命名习惯和时钟管理方案。我的建议是全部下载放本地建个vv4_ref目录后面写XDC时反复要翻。千万别高估自己的记忆力一个QSFP28的TX差分引脚在原理图第32页你以为记住了三个小时后编译报错时再回头翻时间就全浪费了。3.3 第一步先建一个能点亮板卡的空工程在动Corundum之前我建议先做一个冒烟测试一个最简单的Vivado工程不加任何IP只用几条语句点亮板上的LED或者读取板卡ID寄存器。这一步的目的不是验证什么功能而是确认三件事工具链对VV4这个具体器件型号支持是否正常。JTAG/PCIe链路是否稳定能不能正常下载bitstream。板上时钟能不能通过IBUFG进入FPGA全局时钟网络。这一步太容易跳过了但跳过它后面出了错你会分不清是Corundum代码的问题还是环境的问题。我实际做的时候直接在VV4板上跑了一个10分钟的呼吸灯程序顺便验证了下载器连接稳定性。确认没问题之后才开始正式移植Corundum工程树。4. 时钟与复位改造其他都是体力活这里是技术活4.1 时钟树差异是移植翻车第一高发区很多移植项目死在引脚约束之前先死在时钟上。Corundum原生参考板VCU118的时钟方案大概是这样的板上有个可编程时钟发生器分别提供PCIe参考时钟、GTY参考时钟、以及给FPGA逻辑用的用户时钟通常频率是100MHz、125MHz、156.25MHz这几个档位。VV4的时钟芯片型号不同默认配置和输出频率也不一样甚至不一定开机就能输出Corundum期望的频率。所以移植的第一步不是写XDC而是把VV4原理图里的时钟拓扑画出来问自己三个问题哪些时钟是固定频率、哪些是可编程的GTY参考时钟从哪个bank进来、用的哪个引脚可编程时钟芯片的默认配置有没有在开机时自动加载我拿到的VV4板子上有多个时钟源一个PCIe参考时钟100MHz、一个给GTY bank的参考时钟通过可编程芯片生成、还有一个板载用户时钟通常也是100MHz或125MHz。Corundum工程里用了Xilinx的Clocking Wizard来生成内部各模块需要的时钟这个IP可以从板载用户时钟分频/倍频得到所需频率。但如果GTY的参考时钟频率和Corundum的CMAC IP配置不一致编译不出错上板就是link不起来。4.2 给GTY收发器配好参考时钟这里要展开说一下GTY参考时钟的坑。100G以太网的PMD层用的是4条25Gbps的SerDes通道GTY收发器的参考时钟频率取决于你需要的线速率和PLL配置。25G NRZ场景下参考时钟通常是125MHz或156.25MHz。Corundum的100G参考设计里CMAC IP会要求GTY参考时钟引脚绑定到特定bank而且这个bank的位置在VCU118和VV4上可能完全不同。我的做法是先读Corundum的VCU118工程XDC找到GTY参考时钟的引脚约束和频率约束再看VV4原理图里哪个bank有可用的参考时钟输入引脚然后修改XDC中对应的PACKAGE_PIN和PLL_REF属性。如果VV4上该bank没有外部参考时钟接入就必须换一个bank并且相关的GTY channel位置也要重新映射。这里有个变量容易被忽略CMAC IP在生成时已经把GTY位置的约束写死在IP核里了。如果你只改了顶层XDC里的引脚映射但CMAC IP内部生成的GTY位置还是VCU118的旧bank综合时会直接报错或者绕回到错误的引脚。正确的顺序是先根据VV4的bank分布决定使用哪些GTY channel然后重新生成CMAC IP或者修改XCI里的参数再写顶层引脚约束。4.3 复位域设计别让PCIe PERST背锅复位信号看起来简单实际上是另一个翻车高发区。Corundum的顶层设计里有几个复位来源PCIe的PERST#信号、系统上电复位、以及各个时钟域自己的复位由Clocking Wizard的locked信号驱动。不同板卡的复位信号极性可能不同。VCU118上PERST#是低有效而VV4的PCIe接口信号命名可能有差异甚至复位信号到达FPGA之前还经过了一级缓冲或反相器。如果你的XDC里把IO标准或引脚接错了上板后主机可能识别不到PCIe设备如果复位一直处于有效状态系统就会卡在设备枚举到但寄存器读出来全是垃圾值的诡异状态。我建议在顶层模块里用逻辑分析仪核ILA或者简单地把复位释放状态连到LED上做可视指示。先把PCIe复位释放、时钟锁定、MAC复位完成这三个状态都点亮再考虑其他功能。这一步能帮你省下大半天的排查时间。5. 引脚映射与XDC重写把抽象变成约束5.1 对照原理图逐信号过一遍时钟和复位方案定了之后剩下的引脚映射就是实实在在的体力活了。Corundum顶层里会暴露一组板级信号包括PCIe相关PCIe TX/RX差分对、PERST#、参考时钟。QSFP28相关TX/RX差分对、模块存在检测MODSELL、复位RESETL、低速I2CSCL/SDA、中断INTL、TX_DISABLE。板上辅助LED、启动模式引脚、UART等。做法很简单打开VV4原理图的对应页面把每个信号在FPGA封装上的引脚号找出来整理成一张映射表然后写进XDC。要注意差分信号的命名方式比如qsfp0_tx_p和qsfp0_tx_n。Vivado的XDC里差分对只需要约束P端引脚N端会自动推断但IO标准要写对一般是LVDS或者DIFF_SSTL12具体看原理图上接的端接电压。5.2 XDC里哪些约束要重写我这次写的XDC里除了PACKAGE_PIN和IO_STANDARD之外还有几个关键约束必须处理set_property PACKAGE_PIN AY3 [get_ports pcie_rx_p[0]] set_property IOSTANDARD LVCMOS18 [get_ports pcie_perst_n] set_property IOSTANDARD LVDS [get_ports qsfp0_tx_p[0]]普通数字信号的IO标准VV4可能用LVCMOS18或LVCMOS25一定要和原理图一致否则上板电压域出错严重时可能损伤引脚。PCIe的差分引脚上除了位置约束还要加上set_property PCIE_1P0 TRUE之类的属性吗其实XDMA IP内部会处理这些顶层XDC反而不需要额外写太多PCIe物理层约束这是Xilinx IP的设计哲学——把复杂性收进IP核里。对于QSFP28的I2C引脚因为它是开漏结构XDC里还需要加上PULLUP属性设为TRUE否则I2C总线可能拉不高导致读不到光模块的EEPROM。5.3 第一轮综合布线的预期结果写完全部的XDC之后就可以跑综合和布局布线了。第一次跑综合大概率不会一次通过常见的报错有这几种PACKAGE_PIN指定的引脚不存在或bank不对。这个好解决回头翻原理图就行。时钟约束缺失或矛盾。Corundum参考工程自带一套时序约束但时钟引脚名字和频率和你的新XDC不一致时创建时钟的命令会报错。IP核的接口引脚和顶层连接不一致。可能是你修改了CMAC IP的通道配置后顶层里的信号连接没跟着改。第一次综合通过后先别急着上板用report_timing_summary捞一眼时序。只需要看WNS和TNS是不是正值如果为负就说明约束没写对或者布局布线太挤先排查约束问题不要盲目加流水线。我第一次跑到这一步时WNS是负的0.6ns排查了半天发现是Clocking Wizard的输入时钟约束写错了——我写的200MHz实际板上给的是125MHz。修正后WNS就转正了。这就是为什么前面的时钟梳理这么重要。6. 移植第一阶段的收尾工程跑通后的复盘6.1 资源与时序的初步体检第一轮布局布线跑通后我想推荐大家花十分钟认真看一眼利用率报告。Corundum的100G配置在VU37P上的资源占用大概是LUT利用率20%出头FF、Block RAM都在30%以内GTY收发器用了8个左右两路QSFP每路4个UltraRAM用了不多。如果发现某个资源突然爆高比如Block RAM超过60%多半是DMA描述符缓存配置或者队列数量被IP参数放大了可以回头去调XDMA或DMA模块的参数。时序上WNS为正且余量大于0.05ns就可以考虑上板测试了。如果余量很逼近0建议先别急优化时钟约束或者调整布局策略符合Congestion选项别带病上板不然后面跑100G压力测试时系统会隔几分钟就卡死你根本分不清是驱动问题还是时序问题。6.2 这个阶段最容易踩的坑汇总把这一阶段我踩过和见过的坑汇总一下给后来人排雷第一个坑是XDMA IP的License。Corundum默认配置里XDMA IP会被加密或者标注为需要付费License但实际上Xilinx对XDMA的评估版License足够跑Corundum这种场景。如果你在生成IP时报License错误去Vivado License Manager里看看是不是缺少xilinx_pcie_dma这个Feature。有时候重装一遍IP或换个Vivado版本就解决了。第二个坑是QSFP28的模块复位时序。很多QSFP28模块要求复位信号拉低至少一段时间然后释放再等待模块内部初始化完成之后才允许I2C访问。如果直接开机就去读模块信息I2C会返回NACK让人误以为硬件坏了。Corundum顶层会有模块初始化逻辑但要确认它们被正确连接到QSFP28的低速引脚上。第三个坑是PCIe枚举时的BAR空间问题。Corundum的XDMA IP默认BAR空间大小和数量可能与VV4的PCIe桥的prefetchable窗口不匹配导致驱动加载时ioremap失败。这类问题在XDC阶段几乎无法发现要在上板测试阶段用lspci -vv确认。虽然本篇还在编译阶段但建议提前把XDMA的BAR配置截图留档方便后续排查。第四个坑是启动模式。VV4可能默认从SPI Flash启动而你下载bitstream时用JTAG两者引脚配置不同。如果用JTAG下载后一切正常但重启掉电就没配置了不用慌这并不代表移植失败只需要把配置模式改成JTAG优先或写一份mcs烧进Flash即可。我在没确认这一点之前还以为是复位信号接反了白白查了半天。6.3 下一篇上板实测前的最后一块拼图到这里工程已经能在VV4上完整编译出bitstream时序收敛资源余量充足。但这只是整个移植工作的第一步——bitstream能生成不代表网卡能用。下一篇我会接着写通过PCIe把设备枚举起来、加载Corundum内核驱动、用光模块回环和100G流量测试验证收发通路以及调通之后怎么用ethtool查看队列和中断情况。说到最后的个人体会做这种板级移植心态一半是工程能力一半是资料检索能力。Corundum的开源生态和Xilinx的文档已经帮你扫平了大部分障碍剩下那些真正考手艺的地方——时钟树怎么梳理、复位域怎么划分、资源瓶颈怎么定位——恰恰就是FPGA工程师的看家本事也是这种项目最有意思的地方。如果你手上也有一块冷门板卡在犹豫要不要碰Corundum我的建议是先花一个晚上确认硬件资源底线只要GTY数量够、PCIe lane够、有可编程时钟就值得一试。
返回列表