开源100G FPGA UDP移植与上板测试全流程详解
2026/9/8 18:46:15 网站建设 项目流程

最近项目里需要把一套高速数据采集板卡的通信通路从开发板环境迁移到自研板卡上,主控是UltraScale+系列的FPGA,光口走QSFP28模块,上位机通过光纤直连或者交换机收发UDP包。整个方案的底层不是从零写的,GitHub上能找到不少开源的100G UDP工程,但别人的板卡上跑得顺的工程,搬到自家板卡完全就是另一回事。这篇博文把整套“开源100G FPGA UDP移植+上板测试”的过程从头梳理一遍,内容包括工程结构分析、器件替换、约束适配、物理层验证、协议层调试,以及最后打流测试中踩过的一些坑,希望能给正在做类似移植的朋友一些参考。

这个主题适合有一定FPGA基础、至少碰过10G或者40G以太网、现在想把100G UDP通路跑起来的开发者阅读。如果你只是想了解100G以太网在FPGA上怎么实现,这篇文章也能帮你建立一个整体认知:100G链路不只是一根光纤插上就能通,里面涉及GT高速收发器、PCS/FEC、MAC、UDP逻辑、主机接口等多层内容。下面直接进正题。

1. 项目概述与移植目标

1.1 这个项目在做什么

所谓“开源100G FPGA UDP”,本质上就是用FPGA的GT高速串行收发器连接光模块,在物理层之上完成以太网帧的接收和发送,再把UDP报文载荷交给用户逻辑处理。FPGA端的典型架构是:QSFP28光模块 → GTY/GTM收发器 → 100G MAC/PCS(通常是厂商IP Cores)→ UDP协议栈逻辑 → DMA/FIFO接口 → DDR或PCIe。

这套方案解决的核心问题是“高速数据怎么从光纤进到FPGA逻辑里,再以UDP包的形式发出去”。应用场景很典型:高速数据采集卡(示波器、频谱仪、软件无线电设备)、网络测试仪、存储网关、数据中心里的可编程网卡等。项目里要处理的往往是几百Gbps级别的数据流,通用CPU直接处理这个量级的网络包不太现实,FPGA加UDP offload就成了一个性价比很高的选择。

1.2 为什么选开源方案而不是自己从零写

刚开始接触这个项目时,团队内部也讨论过要不要完全自研,后来评估之后果断放弃了。原因很直接:100G以太网的底层复杂度远超10G/40G。光是在PCS层,64B/66B编码、多通道绑定、对齐标记、RS-FEC编解码(如果开FEC的话)这些模块,自己写RTL并验证到可以商用级别,工作量非常大,而且出问题的概率极高。

商用IP(比如Xilinx的100G Ethernet Subsystem)虽然功能完整,但授权费用不低,而且对于很多学习型项目和早期原型验证来说,用开源工程把上层的UDP通路跑通,再用厂商IP替换底层,是更平滑的路径。开源社区里像verilog-ethernet、Corundum这类项目,已经把MAC层到UDP层的逻辑写得比较成熟,特别是Corundum支持100G,自带DMA引擎和UDP offload,非常适合作移植基础。

这里要给第一次做这类移植的读者提醒一个关键认知:开源工程不等于完全开源。绝大多数100G UDP开源工程依赖Xilinx或Intel的GT收发器和CMAC IP,所谓“开源”的部分其实是UDP协议栈和用户逻辑。真正从物理层到MAC层全部用纯RTL写并开放出来的项目很少,就算有,也几乎没有直接用在高速板卡上的成熟案例。所以,拿到一个开源工程后,先看它依赖了哪些厂商IP,再决定移植策略,这比上来就改代码重要得多。

要理解移植工作到底要做什么,得先把100G UDP通路拆开看。很多朋友第一次接触100G,会以为它跟千兆网卡一样,只要把PHY芯片接上就能跑,实际上完全不是这个思路。

2. 移植前必须理解:100G UDP链路的组成

2.1 100G不是一条道,而是四条道并行

100G以太网在物理层并不是单路100Gbps,而是4条25.78125Gbps的通道并行组成,这个接口形态叫CAUI-4。FPGA侧的四路GT lane分别连接到QSFP28光模块的四路电气接口上,光模块再把电信号转换成四路光信号通过光纤传输。QSFP28模块之所以叫“28”,就是因为单路速率是28Gbps级别,正好覆盖25.78125Gbps的100G BASE-R线速率。

移植时最直观的问题就出在这里:不同板卡的QSFP28模块接在FPGA的不同GT Bank上。以Xilinx UltraScale+器件为例,同一个器件的不同封装引脚分布差别很大,有的板卡把QSFP28放在MGTY Bank 128,有的放在Bank 130,GT Lane的编号也不一样。开源工程里的引脚约束文件(XDC)针对的是原作者那块开发板,到了自己的板卡上,如果不改GT位置和参考时钟引脚,上电后光口是绝对不可能link up的。

还有一个容易忽略的点是参考时钟。100G BASE-R的GT参考时钟一般是156.25MHz,但有些板卡为了兼容其他协议,会用可编程时钟芯片(如Si5344)输出不同频率,例如161.1328125MHz给某些FEC模式或者50G/100G组合模式用。如果移植时没核对参考时钟频率,即使GT Lane位置改对了,link也起不来,或者起来后误码率非常高。所以拿到一块新板卡,第一件事是查原理图,把QSFP28对应的GT Bank、GT Lane、GTREFCLK引脚和时钟频率全部列出来,再和开源工程的约束文件对比,做一张映射表,后面所有工作都基于这张表展开。

2.2 厂商CMAC IP和开源UDP逻辑的分工

前面提到,100G UDP链路是分层实现的。最底下是GT收发器,负责把并行数据变成高速串行信号,以及接收端的时钟恢复;GT上面是PCS层,做64B/66B编解码、lane对齐、FEC等;再往上是MAC层,负责以太网帧的定界、FCS校验、帧过滤;MAC层之上才是UDP协议栈。

在实际工程中,PCS和MAC层基本都是直接用厂商IP完成的。以Xilinx平台为例,就是100G Ethernet MAC(以下简称CMAC)IP,它把GT控制、PCS、FEC、MAC全部封装在一个核里,用户不需要关心底层的对齐和编解码细节。开源工程里给你的是什么?是MAC层以上的UDP协议处理逻辑,包括:ARP请求和应答、ICMP echo应答、UDP端口匹配、校验和计算、收发通道的AXI-Stream接口控制。这一部分用Verilog实现起来相对可控,开源社区也维护得比较成熟,这也就是“开源100G UDP”这个名称的由来。

从自研、开源、厂商IP这几个选择来看,可以做一个简单的对比:

方案底层物理层移植难度可靠性适用场景
完全自研手写GT+PCS+MAC极高中低学习研究、特殊定制
开源工程+厂商CMAC厂商IP中等中高项目原型、学习实践
商用IP+定制逻辑厂商IP商用产品、量产设备

这个表格的意思是:移植工作真正要动的其实是“开源UDP逻辑”和“厂商CMAC”之间的那层接口,以及整个工程的时序、引脚、时钟约束。理解了这一点,就不会被工程里庞大的源码吓到,也不会在错误的方向上浪费大量时间。

3. 移植实操:从开源工程到目标板卡的完整步骤

移植过程听起来抽象,实际操作起来可以分为四个阶段:重建工程、适配约束、适配接口逻辑、上板验证。下面按顺序展开。

3.1 第一步:拿开源工程换到你的板卡,先重建工程

很多新手拿到一个Vivado工程,第一反应是直接打开、修改器件型号然后点Generate Bitstream,这个做法在100G项目里基本不会成功。原因在于原工程的IP核配置、引脚约束、时序约束全部跟原板卡绑定,直接换器件型号会让IP核和约束文件全部报错,即使勉强综合过,上板也跑不起来。

我的建议是:在Vivado里新建工程,选择自己板卡的FPGA型号,然后把开源工程的RTL源码文件加入工程,重新创建和配置所有IP核。以Corundum为例,它的工程里有一个mcap/FPGA的IP core描述文件,但实际用的时候,CMAC、DDR控制器、PCIe控制器(如果板卡支持PCIe)都要根据自己的器件重新配置。这个阶段别嫌麻烦,也不要想着把原工程里的IP核“迁移”过来,在Vivado里旧版本的IP核换个器件重生成,生命周期管理会非常乱。

3.2 第二步:重写XDC约束文件,GT位置是重灾区

XDC约束是上板前最关键的步骤。我把一份最小可用的100G UDP工程约束拆成几类:引脚位置约束(LOC)、时钟约束(create_clock)、差分对约束、电平和端接约束。其中最容易出问题的就是GT位置和参考时钟。

在UltraScale+器件上,GTY lane的名字格式是“MGTY_X0Y4”,不同封装下同一个bank的GT坐标是固定的,QSFP28模块接在哪个bank,就得用对应的坐标。这个信息只能从自己板卡的原理图和Xilinx封装文件(ug578等)中确认。实际操作时,我会在XDC里写清楚每个GT lane的约束,例如:

set_property PACKAGE_PIN AY10 [get_ports gt_rxp_in[0]] set_property PACKAGE_PIN AY9 [get_ports gt_rxn_in[0]] set_property PACKAGE_PIN BA10 [get_ports gt_rxp_in[1]] # 其余lane依此类推

参考时钟约束则要确认时钟源是板载晶振还是可编程时钟芯片,频率是多少。如果板卡上用了一个可以输出多种频率的时钟芯片,上电默认频率可能不是100G需要的156.25MHz,而是别的值。这种情况需要在FPGA逻辑里通过I2C或SPI接口先把时钟芯片配好,再释放GT的复位。很多板卡设计里,这个配置时序非常关键,配置慢了或者配置错了,GT就一直起不来。

3.3 第三步:UDP逻辑和CMAC之间的接口时序适配

约束文件做完之后,接下来要处理的是逻辑层面的适配。开源UDP逻辑和CMAC之间通常是AXI-Stream接口,位宽一般是512bit,时钟频率约322.265625MHz(100G线速率、64B/66B编码后的实际有效数据速率)。时序上要求tvalid、tready、tlast、tkeep这几个信号之间的握手关系必须正确。很多工程在别的板卡上能跑,移植之后出现丢第一个包或者最后一个包的问题,十有八九是AXI-Stream接口在跨时钟域处理上有BUG。

我在移植的时候,习惯先把CMAC用户侧接口的关键信号用Vivado的ILA抓出来看。注意,ILA本身也会占用逻辑资源,而且在100G数据率下,如果触发条件设置不当,很容易采样丢失。一个更稳妥的做法是:先在UDP逻辑和CMAC之间插入一个简单的数据计数器模块,统计发送帧数和接收帧数,用板卡上的LED或者UART打印出来。上板后先不发业务数据,只发一个内部生成的固定包,看计数是否正常,确认接口握手无误后再接真实业务数据。

这里顺便提一个容易踩的坑:CMAC IP复位之后,需要等待它内部的PCS和MAC完成初始化,这个时间通常有几百微秒到几毫秒,不同配置下不一样。开源工程里一般有一个wait_for_cmac_ready的流程,如果复位时序处理得不对,会出现CMAC永远无法进入ready状态。移植时不要精简这一步,务必在用户逻辑里检测CMAC的user_rx_reset和user_tx_reset信号释放之后再开始发送数据。

3.4 第四步:和用户业务接口的对接,别把字节序搞错

UDP逻辑适配完之后,还要考虑它怎么和你的业务数据对接。如果板卡上有DDR,通常需要一个DMA或者FIFO把DDR里的数据搬到UDP发送通道;如果有PCIe,则要涉及PCIe DMA的描述符逻辑。这部分是移植中最容易出隐蔽问题的地方,因为不同工程的接口格式千差万别。

以字节序为例。CMAC和UDP逻辑之间传输的是以太网帧,以太网帧头是“目的MAC、源MAC、类型/长度、IP头、UDP头、载荷、FCS”,每一段都是大端序。开源工程内部已经把这个处理好了,但当你把自己的数据接入UDP payload时,你的数据是大端还是小端,就完全取决于你的业务逻辑。如果处理不当,上位机收到的payload是反着或者错位的字节序,这不会引起任何错误告警,但解析出来的数据完全是乱的。我的经验是:在业务接口处先发一组特定的字节序列(比如0x00、0x01、0x02...0xFF),在上位机收包后检查字节顺序,确认无误后再接真实数据。

4. 上板测试:从物理层到协议层的四级验证

这一部分是整个移植工作的重头戏。很多朋友上板之后填bit,然后直接把网线插上,芯片烧录完就急着ping、打流,结果发现不通,又不知道问题出在哪一层。正确做法是分层验证,每一层确认无误后再往上走。

4.1 物理层验证:用IBERT测GT的误码率

上板测试第一步,不是跑UDP工程,而是先跑IBERT(Integrated Bit Error Ratio Tester)。IBERT是Xilinx FPGA内部的一个自检IP,它通过在GT收发器上生成PRBS码型并回环校验,直接检测物理链路的误码率。这一步的目的就是把“GT到光模块再到对端”这一段物理通道单独验证干净。

创建一个IBERT IP,选择对应的GTY quad,线速率设置为25.78125Gbps,然后综合、实现、上板。之后在Vivado的IBERT GUI或者通过JTAG调试窗口里,观察每条lane的误码统计。正常情况下,四条lane应该全部link up并且误码率为0,或者至少在长时间测试中没有新增误码。如果某条lane误码高,先检查光模块是否插好、光纤端面是否干净、QSFP28的参考时钟是否正常,再用示波器看GT的TX差分信号质量,比如眼图、抖动。

这里有一个实用技巧:不要只在实验室常温下测几分钟就完事。100G链路的误码分布有时是偶发的,建议至少跑一个小时的PRBS31(伪随机二进制序列)测试,同时观察FPGA的温度变化。有些板卡散热不好,温度升高后GT的误码率会明显上升,这种情况在IBERT阶段就能发现,比在协议测试阶段排查容易得多。

IBERT是通过JTAG访问的,不占用你设计的逻辑资源,但要注意它和你的业务工程是两套bit流。也就是说,IBERT验证是“物理层专项测试”的一种方式,测完再下业务bit流。因此,每次插拔光纤或者更换光模块之后,建议重新跑一遍IBERT,确保物理层没有退化。

4.2 MAC层验证:CMAC内部回环测试

IBERT跑通之后,物理通道已经没有大问题了。接下来验证CMAC的PCS/MAC层,最直接的方法是打开CMAC IP的自带回环功能。

Xilinx CMAC IP内部有两种回环模式:Near-end PMA loopback和Far-end PMA loopback。Near-end是把GT的TX数据直接环回到RX路径,不经过光模块和光纤,主要验证FPGA内部的GT和PCS逻辑;Far-end则需要外部环回,通常是通过一个回环光模块或者对端设备把TX信号发回RX端,验证包括光模块在内的整个链路。建议先测Near-end,确认FPGA内部逻辑没问题,再测Far-end。

在回环测试时,不需要把整个UDP逻辑跑起来,可以写一个很简单的测试逻辑:发送端产生固定pattern数据(比如0xBCBCBCBC),通过CMAC TX接口发出,RX接口收到数据后做一个比对,不一致就计数并置位错误标志。这样能非常清晰地验证CMAC的配置是否正常:FEC是否使能、PCS是否对齐、MAC是否正常识别帧边界。

特别注意,如果CMAC配置里开了RS-FEC,回环测试时两端必须都配置成同样的FEC模式。有些工程默认关FEC,有些默认开,移植的时候一定要检查IP配置。我在调试过程中就遇到过一次,板卡A的工程开了FEC,板卡B上重新生成的CMAC默认配置关了FEC,结果两端link up了但误码率一直在报错,排查了很久才发现是FEC配置不一致。

4.3 UDP协议层验证:从ARP到第一个UDP包

物理层和MAC层都通了,接下来进入UDP协议层的验证。这一步最直观的做法就是用PC直连FPGA的光口,先ping一下,通了之后再发UDP包。

先说ping。要ping通FPGA,FPGA端必须能正确响应ARP请求和ICMP echo请求。ARM处理逻辑是否完善,很大程度上取决于开源工程做了什么程度的实现。常见的简化型工程只实现了“固定ARP表项”,也就是FPGA只应答预先写死的某几个IP地址;完整一点的工程才会在每次收到ARP请求时动态应答。

如果发现ping不通,优先排查ARP。在上位机打开命令行,用arp -a看看有没有学习到FPGA的MAC地址。如果没有,说明FPGA没有响应ARP请求,这时候可以用Wireshark或者tcpdump抓包确认。抓包时会发现一个有意思的现象:如果你的主机网卡开启了Offload功能,Wireshark里的ARP包可能是由主机驱动程序合成的,看起来发出去了但实际上没有到物理链路。遇到这种情况,可以先关掉网卡的offload(比如在Linux下用ethtool -K eth0 tx off rx off),再重新抓包。

ping通了之后,再用UDP测试工具收发几个包。这里有个小陷阱:很多开源UDP工程出于简化处理,UDP校验和(checksum)没有正确计算,或者直接填0。上位机软件如果开启了UDP checksum校验,就可能把这些包丢弃或者上报错误。在实际测试时,可以先用Python脚本在FPGA端发一个已知载荷的UDP包,PC端接收并解析,确认载荷正确;然后再让PC发UDP包给FPGA,看FPGA内部计数是否增加。

这里给一段最简单的UDP收发Python脚本,方便临时验证:

# 上位机接收FPGA发来的UDP包 import socket s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) s.bind(("0.0.0.0", 5000)) data, addr = s.recvfrom(2048) print(data.hex())

4.4 100G吞吐打流测试:别急着用iperf3单线程

UDP包收发都正常后,接着就是大家最关心的性能测试,也就是用工具打流。很多朋友直接打开iperf3,一条命令就开始打流,结果发现怎么都打不满100G,于是开始怀疑FPGA逻辑有问题。实际上,100G打流这个事,瓶颈往往不在FPGA,而在测试工具和上位机的协议栈。

iperf3本身是多线程设计,但UDP模式下,单线程在100G链路上很难跑满。原因是CPU要处理系统调用、协议栈、中断,100Gbps相当于每秒约1.48亿个最小以太网帧(按64字节算),这个中断和拷贝开销单核CPU根本扛不住。如果只是想验证“FPGA能不能发出100G的数据”,更好的办法是FPGA内部自发自收:FPGA启动一个计数器,把计数器的值作为UDP载荷持续发给外部回环光模块,再从光模块收到的数据里解析并比对内容。这种方式完全绕开了PC的协议栈,能够直接验证FPGA内部逻辑在满速情况下的稳定性。

如果需要用服务器做真实打流测试,建议这样操作:

  • 在服务器上用DPDK(数据平面开发套件)写一个简单的收包程序,绕开内核协议栈,而不是用通用socket。
  • 如果暂时不想碰DPDK,那就用多线程iperf3,例如 iperf3 -c <FPGA_IP> -u -b 0 -P 8,多线程分散负载。
  • 观察吞吐时,不要只看iperf3打印的带宽数值,也要关注丢包率。iperf3 UDP模式的带宽计算基于发送端发送速率,接收端接收速率可能因为系统缓存溢出而变化。检查接收端是否丢包,可以用 netstat -su 查看UDP层丢包统计。

关于上位机的UDP统计,Linux下可以直接看/proc/net/snmp文件中的UDP段,有UdpInDatagramsUdpNoPortsUdpRcvbufErrors几个字段。UdpRcvbufErrors如果一直在增长,说明接收缓冲区不够,需要调大socket缓冲:

sysctl -w net.core.rmem_max=134217728 sysctl -w net.core.rmem_default=16777216

Windows下也需要在注册表里修改UDP动态端口范围和缓冲区大小,方法类似但路径不同。调试网络工具的问题时,如果看到“packets received 本机一共收到多少个udp数据包”这类统计,可以结合这些字段做判断。

5. 常见问题与排查技巧

移植过程中我整理了一些高频问题的排查顺序,希望对读者有帮助。

5.1 问题一:光口link up了,但误码率时不时的增加

这个问题的排查思路很简单:先从IBERT测起。如果IBERT跑PRBS31有误码,说明物理层就没干净,协议层怎么调都没用。重点检查参考时钟质量、GT供电电源纹波、光模块端面清洁度、光纤弯曲半径。另外值得注意的是,QSFP28模块对静电非常敏感,拿取模块时要做好防静电措施,否则模块内部可能已经损坏,表面看是link up的,但误码率高到无法使用。

如果IBERT干净,但业务数据时有误码,那就不是物理层问题,而是逻辑问题。比较常见的是跨时钟域处理不严谨,导致偶发数据采样错误。可以用Vivado的CDC(Clock Domain Crossing)分析工具检查设计中的跨时钟域路径。

5.2 问题二:ping不通,但抓包发现FPGA有发出ARP响应

这种情况通常是主机网卡没有正确更新ARP表。可以先手动添加静态ARP表项试试:

arp -s 192.168.100.10 00:11:22:33:44:55

如果加入静态ARP后ping通了,说明FPGA的ARP响应包格式正确,只是主机接收后没有处理。这往往和网卡的Offload设置有关,关闭网卡Offload后重新测试,看问题是否消失。

另外一个容易忽略的点是:FPGA和PC必须在同一个子网内。有的FPGA工程默认IP是192.168.1.10,而PC的网卡IP可能是192.168.100.10,不在同一个网段,ARP请求根本不会发出来。建议把PC网卡IP改成和FPGA同一子网,并且用直连线连接,避免交换机配置问题干扰。

5.3 问题三:长时间跑流之后吞吐掉到零,FPGA侧统计还在发

这通常是上位机侧的接收瓶颈导致的反压问题。FPGA作为一个UDP发送端,是没有拥塞控制机制的。如果上位机来不及接收,系统socket缓冲区满了之后,数据包会被丢弃,但FPGA并不知道,它还在继续发送。这样就会出现“FPGA发得快,PC收得少”的现象,如果PC长期无法接收,外部设备可能会通过某种流控机制影响整条链路。

解决思路有几个层面:首先,如果是用通用socket收包,考虑用内存映射的方式(比如PF_RING、AF_XDP)提高收包效率,或者用DPDK。其次,增大socket缓冲区也能缓解,治标不治本。最后,如果业务允许,在FPGA端做一个简单的流控:上位机周期性反馈接收计数,FPGA如果发现计数停止增长,主动暂停发送,等对方恢复后再继续。很多商用网卡都有这种流量控制机制,纯FPGA方案就需要自己实现一个类似的小逻辑。

5.4 问题四:Wireshark抓包过滤器填了udp,却抓到ICMP

这个问题在网络调试里经常遇到。Wireshark有两套过滤机制:Capture Filter(捕获过滤器)和Display Filter(显示过滤器)。如果你在显示过滤器栏填了“udp”,它只是把已经抓到的包里非UDP的隐藏了,但文件里仍然有ICMP等非UDP包。如果真正想要在抓包时直接丢弃非UDP包,需要在Capture Filter栏填过滤表达式。很多人只改显示过滤器,就会产生“我加了udp过滤但还能看到icmp”的错觉。

在FPGA调试场景下,还有一个特殊原因:有些FPGA发出的非UDP包(比如ARP、ICMP)占流量比例很小,Wireshark的显示过滤器“udp”通常已经把它们隐藏了,但如果你看到的是和UDP无关的协议报文,比如TCP或者其他奇怪协议的包,大概率是你PC上的其他进程在发包,而不是FPGA发的。

5.5 常见问题速查表

现象优先排查次要排查
光口link up但误码高参考时钟频率、光模块端面GT供电、光纤弯曲半径
link up后CMAC一直报reset检查CMAC复位时序和参考时钟配置检查FEC配置是否一致
ping不通但UDP直连可用ARP响应逻辑是否完整网卡Offload、静态ARP表
小包正常但大包丢包严重MTU、IP分片处理UDP载荷长度配置
上位机收包统计增长但业务解析乱字节序、UDP payload偏移数据包头字段拼接
iperf3带宽上不去换多线程、关闭CPU节能检查socket缓冲区大小
抓包看到非UDP协议显示过滤器和捕获过滤器混淆PC本机其他进程发包

6. 移植完成后的最后一个小技巧

这套100G UDP移植和上板测试做下来,我最大的体会是:分层验证真的不能跳步。以前为了赶进度,IBERT测了几分钟就急着上UDP逻辑,结果光口偶发误码的问题拖到协议测试阶段才发现,排查起来非常痛苦,既要怀疑逻辑问题又要怀疑物理层问题。后来老老实实把IBERT跑足一个小时,再往后反而顺利很多。

另外一个非常容易忽略的点就是光模块和光纤的日常维护。100G光模块的端面非常小,灰尘、指纹都能明显影响信号质量。上板测试过程中,凡是遇到莫名其妙的误码和丢包,先把光纤拔下来,用光纤清洁笔或者专用的清洁棒擦一下端面,再重新插上。很多时候问题就解决了。这个习惯能帮你省掉一半的排查时间。

最后再说一点关于后续扩展的建议:如果现在的FPGA板卡还带PCIe接口,可以考虑在开源工程的基础上把DMA引擎加上,做成一个完整的100G智能网卡方案。这样不仅能用网络收发数据,还能让CPU通过PCIe直接访问FPGA的DDR,整个系统的灵活性会提升一个台阶。不过这一步涉及PCIe的枚举、DMA描述符管理、中断处理等复杂逻辑,建议先在这个UDP通路稳定运行一段时间后,再逐步扩展。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询