ARTICLE DETAIL

资讯详情

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

FPGA实现千兆UDP通信:TSE IP核配置与协议栈设计详解

FPGA实现千兆UDP通信:TSE IP核配置与协议栈设计详解 1. 项目概述为什么要在FPGA里折腾UDP通信做FPGA通信的同学肯定都有过这种经历调通了串口觉得太慢想上以太网查了一堆资料发现全是在讲PC端的Socket编程真正讲FPGA侧怎么把Triple-Speed Ethernet IP核跑起来的文章少得可怜。我去年接手一个数据采集项目前端ADC采出来的数据要通过千兆网实时上传到上位机带宽需求大概在700Mbps左右。串口肯定不行USB方案又要挂处理器最后定了纯FPGA实现UDP卸载引擎这条路——也就是标题里说的用ALTERA现在叫Intel的Triple-Speed Ethernet IP核配合自研UDP协议栈做高速数据传输。这个方案非常适合以下场景数据采集卡、软件无线电前端、图像采集与传输、工业现场实时控制。它解决的核心问题是在不依赖CPU和操作系统的情况下让FPGA直接以线速收发以太网报文把UDP的打包、校验、拆分全部用硬件逻辑完成延迟可以压到微秒级甚至亚微秒级。1.1 先搞清楚TSE IP核到底是干啥的Triple-Speed Ethernet简称TSEIP核是Intel FPGA官方提供的以太网MAC软核支持10/100/1000Mbps三档速率。它内部实现了完整的MAC层功能包括帧的封装与解析、CRC32校验、流控pause帧、VLAN标签处理等。它的对外接口分两路一路是数据通路采用Avalon-ST接口另一路是寄存器配置通道采用Avalon-MM接口。很多新手会混淆的一个点是TSE IP核只到MAC层不包含PHY芯片也不包含TCP/IP协议栈。它管的是OSI七层模型里的第二层也就是数据链路层。三层以上的事情——IP地址、端口号、UDP校验——全部要你自己在FPGA逻辑里写出来。这既是这个IP核的痛点也是它的灵活之处不需要的协议层完全可以砍掉只保留必要的硬件逻辑资源占用和延迟都能做到最优。1.2 方案选型TSE IP核 vs 现成协议栈芯片市面上实现FPGA以太网通信其实有三条路第一条是直接用TSE IP核自己写UDP协议栈也就是本文要讲的方案第二条是挂一个WIZnet W5500这类硬件协议栈芯片通过SPI接口访问芯片帮你把TCP/UDP都处理好了第三条是用带ARM硬核的SoC FPGA比如Cyclone V SoC在Linux里跑标准Socket。三条路线对比下来W5500方案开发最快但带宽上限只有100Mbps左右而且多一颗芯片成本摆在那SoC方案功能最全但实时性受操作系统调度影响不适合硬实时场景TSE IP核方案前期开发量大但跑满千兆线速没问题延迟完全可控而且IP核本身是免费的部分器件要License不过Cyclone系列一般直接能用。我当时选TSE IP核还有一个重要原因项目后续要扩展多通道以太网一片FPGA上可能要跑4路千兆MAC。TSE IP核例化多个实例很方便资源占用也清晰可预估这在纯硬件方案里是天然的优势。2. TSE IP核配置实战逐项拆解Quartus里的选项打开Quartus我现在用的是Quartus Prime Standard 20.1在IP Catalog里搜“Triple-Speed Ethernet”会看到“Triple-Speed Ethernet Intel FPGA IP”。双击之后进入配置界面这里面的选项密密麻麻但真正影响后续开发的核心配置其实就那么几项我一个个说。2.1 速率与接口模式GMII、RGMII还是SGMII第一个要选的是MAC与PHY之间的接口类型。常见的选项有GMII并行接口发送和接收各8根数据线加时钟和控制线总共大概24根信号。1000Mbps时时钟125MHz100Mbps时时钟25MHz10Mbps时2.5MHz。优点是时序简单调试方便缺点是引脚太多布线压力大。RGMII源同步DDR接口数据线减到4根时钟125MHz上升沿和下降沿各采4位。引脚省了一半但对PCB布线等长要求更高而且FPGA侧要处理DDR采样逻辑上稍微麻烦一点。SGMII串行接口用FPGA的高速收发器transceiver和PHY通信速率1.25Gbps含8B/10B编码开销物理层上相当于一根差分对。引脚极少EMI特性好也是目前工业千兆PHY的主流接口。我这次用的是SGMII接口原因是板子上选的PHY芯片是TI的DP83867IR只支持SGMII。这里有个容易踩的坑SGMII有两种配置方向——TSE IP核既可以把SGMII PCS做在IP内部也可以只提供MAC逻辑把SGMII/PCS功能留给外部。在TSE IP核里如果选择了“SGMII”作为与PHY的接口实际上IP核内部已经包含了PCS层你需要外接的只是物理层PHY芯片。值得注意的是热搜里提到“SGMII IP核与PHY芯片一起使用时应配置成MAC模式”这说的就是TSE IP核充当MAC角色PHY芯片工作在PHY模式。两者通过SGMII接口对接中间不需要其他逻辑。如果反了——比如把TSE也配成PHY模式——两边都是PHY谁发时钟、谁做自协商就全乱了链路根本不可能协商起来。2.2 Avalon-ST数据通路配置数据通路是整个TSE IP核的命脉。配置界面里会让你选数据接口宽度有8位和32位两种对应发送侧还有64位选项不过一般用32位足够。这里建议直接选32位因为32位接口在千兆速率下时钟125MHz逻辑时序压力小很多。如果选8位千兆时数据时钟会跑到125MHz的4倍即500MHz这在普通FPGA逻辑里非常难收敛时序。还有个关键选项是“Enable Magic Packet”和“Enable Wake-on-LAN”这两个是做远程唤醒用的普通项目直接关掉。流控Flow Control选项里如果做UDP传输且不跑TCP建议把流控也关掉——UDP本身不保证可靠传输流控只会增加额外逻辑而且某些交换机配置不对的时候PAUSE帧反而会把链路搞死。2.3 MDIO管理接口配置MDIOManagement Data Input/Output是MAC管理PHY的串行接口用来读写PHY的寄存器配置速率、自协商、环回测试等。TSE IP核里有一个MDIO控制器通过Avalon-MM接口访问。配置界面里会让你填MDIO时钟分频这个要根PHY芯片的规格来。DP83867的MDIO最高时钟是2.5MHz而MDC时钟由系统时钟分频得到我当时系统时钟是125MHz分频系数填了50125/502.5MHz。MDIO这一块很多人会忽略一个细节TSE IP核有一个功能叫做“MDIO与内部寄存器共用Avalon-MM地址空间”默认情况下MDIO的命令寄存器、数据寄存器会映射到IP核的寄存器空间里你直接通过Avalon-MM总线读写这些地址就行。但要注意不同版本的TSE IP核MDIO寄存器偏移地址不一样。我用的IP核版本里MDIO命令寄存器偏移0x90数据写寄存器偏移0x94数据读寄存器偏移0x98PHY地址通过命令寄存器高位指定。如果发现读PHY寄存器读不出正确值先查一下IP版本对应的寄存器手册别上来就怀疑硬件。2.4 时钟与复位最容易翻车的地方TSE IP核的时钟体系看起来简单实则细节很多。它主要有以下几组时钟Avalon-ST收发时钟也就是数据通路时钟千兆模式下125MHz100M模式25MHz10M模式2.5MHz。这个时钟是TSE MAC根据配置自动从GMII/SGMII时钟域转换后输出的你不用自己切换但要注意它在你配置速率变化时会跟着变。寄存器配置时钟一般接100MHz或125MHz用于Avalon-MM寄存器读写。PHY接口时钟SGMII模式下PHY接口时钟来自FPGA的高速收发器参考时钟通常125MHz。复位方面TSE IP核有独立复位和整体复位的区别。IP核会输出一个clk_ref_status信号如果参考时钟没锁住这个信号会拉低这时候即便你复位了IP核也不工作。排查时钟问题时第一步永远是看clk_ref_status第二步才是看复位。我见过好几个同事调了一天TSE最后发现是收发器参考时钟没给对clk_ref_status一直是0。3. UDP协议栈的FPGA实现从帧格式到状态机IP核配置好只完成了一半工作真正的大头是UDP协议栈的硬件实现。别被“协议栈”这三个字吓到UDP是一个极其精简的无连接协议相比TCP那堆状态机、重传机制、窗口管理UDP在FPGA里实现起来要轻松得多。3.1 先搞清楚报文长什么样要做UDP协议栈脑子里必须时刻记住三种帧格式以太网帧、IP报文、UDP报文。它们是一层套一层的关系。以太网帧由14字节头部加数据加4字节FCS组成。头部依次是6字节目的MAC、6字节源MAC、2字节以太网类型。咱们发的是IPv4 UDP报文所以以太网类型填0x0800。这里特别强调一下这14字节的数据在TSE IP核发送时是要你自己拼好给它的IP核不会帮你加以太网头——它默认你给的数据就是完整的MAC帧从目的MAC到负载。IP报文头标准是20字节关键字段有这么几个版本号和头部长度一个字节IPv4固定为0x45总长度2字节IP报文总长包含IP头本身协议号1字节UDP填170x11源IP、目的IP各4字节首部校验和2字节只校验IP头注意不是全包校验和还有标识、标志、片偏移这几个字段我们做单包传输不分片所以标识可以随便填个自增数标志字段填0x4000禁止分片或者直接填0UDP头8字节2字节源端口、2字节目的端口、2字节UDP长度UDP头加负载的长度、2字节校验和。UDP校验和是可以不做的——IPv4协议里UDP校验和是可选的全0表示未计算。接收端如果校验和字段为0直接跳过校验。在UDP卸载引擎里特别是发送方向为了省逻辑资源完全可以把校验和填0。但接收方向呢我强烈建议还是做一下UDP校验和解析里的校验判断——因为上位机发下来的包如果被网卡硬件计算了校验和你没有校验逻辑容易把错误数据当正常数据处理调试排查的时候会非常恼火。3.2 发送通路打包流水线发送侧的核心思路是应用层数据进FIFOTSE MAC从FIFO读出数据时我们在前面拼接以太网头、IP头、UDP头同时在数据末尾追加FCS由MAC硬件自动计算添加。我用的是Altera官方推荐的发送时序Avalon-ST发送接口有一个sof开始帧信号和eof结束帧信号配合valid/ready握手。发送流程如下第一步在sof拉高的第一个周期里往sopstart of packet标志里写入帧控制字。这里的“帧控制字”是TSE特有的一种前置控制信息32位数据里高16位是帧长度从以太网目的MAC开始算不包含CRC低16位是各种控制位。这里有个巨坑TSE IP核对帧最大长度的默认限制是1518字节也就是标准以太网帧长14头1500负载4CRC。如果你发的UDP包负载超过1472字节1500-20IP头-8UDP头MAC会把超长的帧直接丢掉。解决办法是在Avalon-MM寄存器区里把MAX_FRAME_LENGTH寄存器改大比如改成2048或者更大否则用户数据稍微多一点就发送失败。第二步紧接着帧控制字之后发出以太网目的MAC、源MAC、类型字段0x0800。这些数据用连续几个时钟周期依次送出。第三步发IP头。IP头20字节可以预先在逻辑里生成好除了总长度、源IP、目的IP和校验和以外其他字段都是固定值。IP校验和使用的是累加和法——把所有16位字相加进位回卷最后取反。这个计算可以用组合逻辑在几个周期内流水完成也可以查表法但为了通用性建议直接用加法树。第四步发UDP头。UDP长度等于IP总长度减20也就是8加负载长度。端口号是配置寄存器里的值可以随时改。第五步负载数据从FIFO读出一路直通到Avalon-ST数据线上。此时要把IP总长度和UDP长度这两个值在FIFO读指针走到末尾时计算出来回填到包头里。这里有个工程技巧我们是在负载通过的时候用计数器统计实际字节数统计完后再重发一个包的时候填到包头里。所以你看到的实现里有一个“长度寄存器更新逻辑”和“首包丢弃/重试逻辑”处理不好就会出现第一包长度错的、后面包长度对的情况。我推荐一个更稳的办法应用层在写FIFO的时候往一个单独的sideband FIFO里写入本次数据包的字节数协议栈从sideband FIFO提前读到长度这样就不存在回填滞后的问题了。第六步MAC内部自动计算并追加CRC32发送结束。3.3 接收通路从线速里把UDP头挑出来接收方向比发送麻烦因为你面对的是满速到达的数据流没办法“先缓冲再处理”必须在线in-line完成解析。TSE IP核的Avalon-ST接收接口输出的是完整以太网帧不包含CRCCRC已经被MAC验证并丢弃只通过一个status字告诉你好坏。接收数据流里sof标志对应目的MAC的第一个字节eof对应帧最后一个数据字节。接收方向要做这样几件事第一验证MAC帧状态。TSE IP核在每个帧结束时会送出一个16位的status字包含CRC错误、帧过长、截断错误等标志。收到任何错误标志直接把这一帧丢弃数据不进应用FIFO。第二以太网类型判断。从目的MAC开始数14个字节之后是2字节类型字段。如果这个值不是0x0800IPv4整帧丢弃。第三IP头校验和验证。如果源IP是PC发来的PC网卡硬件生成的IP校验和肯定是对的但保险起见还是验一下。校验和验算就是整个IP头按16位累加结果应该等于0xFFFF因为校验和字段本身是取反存入的加一起刚好全F。我见过某些驱动写的IP校验和是错的尤其是一些老网卡所以接收侧做一次校验还是值得的。第四UDP端口匹配。只有目的端口等于配置值的包才接收。注意UDP端口是2字节大端序FPGA侧要注意字节序转换。第五负载写入FIFO并附带长度信息给应用层。这里要留心一帧内的总字节数如果大于我们内部FIFO的容量会出现截断需要设置一个“帧长超限”标志直接把帧丢掉避免给上层一个半截数据包。接收侧还有个大坑是“帧间空隙”和背压。TSE IP核的Avalon-ST接收接口如果下游ready拉低MAC会暂停接收但PHY/SGMII链路还在源源不断进数据这会导致MAC内部FIFO溢出溢出时MAC会丢弃当前帧并置一个溢出标志。所以你的接收侧处理逻辑必须保证足够的吞吐——说白了就是读FIFO的速度必须大于等于写FIFO的速度。千兆线速下纯接收是125MB/s而一个简单的解析状态机加FIFO读写在FPGA里做到这个速度毫无压力但前提是不要让锁存逻辑、长组合链路拖后腿。3.4 ARP协议处理第一次联调前必须解决的绊脚石很多第一次调试UDP的人会卡在一个诡异的问题上FPGA发的UDP包用Wireshark能看到但上位机网络调试助手就是收不到。原因十有八九是ARP没处理。PC的TCP/IP协议栈有个脾气它要发任何IP包给一个目标前会先查ARP缓存表。如果缓存里没有目标的IP到MAC映射它会先发一个ARP请求对方回了ARP应答把映射关系记录到缓存里然后才肯发那个真正的UDP包。问题来了——如果你的FPGA不处理ARPPC发ARP请求来问“谁是192.168.1.10”你没有任何响应PC的缓存表里永远不会有你的MAC地址于是PC发给你的UDP包就一直卡在ARP阶段。解决办法是在FPGA里加一个极简的ARP处理器收到一个请求帧如果目的IP是我们自己的IP就发一个ARP应答把自己的MAC地址填进去。ARP应答帧长42字节14以太网头28 ARP数据字段都是现成的把ARP请求帧里的发送方MAC和IP和目的方MAC和IP对调操作码从1请求改成2应答源MAC改成我们自己的MAC其他照抄即可。我见过有人图省事在PC上手动加静态ARP表项命令是arp -s 192.168.1.10 00-11-22-33-44-55。这种方法调试时可以但换台电脑、重启一次就丢了不可能作为量产方案。老老实实写个ARP处理模块大概30行状态机的活别偷懒。4. 上板调试与网络联调从灯不亮到跑满带宽所有代码写完、综合通过只是万里长征第一步。真正的噩梦从烧录开始。4.1 调试环境搭建Quartus、USB-Blaster和常见驱动事故开发工具方面ALTERA FPGA现在统一用Quartus Prime。Cyclone IV/V/10系列用Quartus Prime Standard或者LiteLite只支持部分中低端器件Arria/Stratix系列要用Pro版本。我项目里用的是Cyclone V GTQuartus Prime Standard 20.1就够了。调试器是USB-Blaster这里就绕不开热搜里的那个词“altera usb-blaster代码39”。代码39是Windows设备管理器里的一种错误状态表示设备驱动加载失败。我遇到了不止一次绝大多数情况是驱动签名问题——Windows 10/11强制驱动签名而Altera的老版驱动特别是Quartus 13.0及之前自带的没签名系统直接拒绝加载。解决办法有几个第一个是右键驱动文件inf选择“安装”如果还不行就要在高级启动选项里禁用驱动程序签名强制第二个是换新版本Quartus自带的USB-Blaster驱动新版驱动是签名过的还有个常见坑是用了山寨USB-Blaster这种克隆版驱动和官方不一样需要装卖家提供的替代驱动装的时候注意选“WinUSB”模式而不要选“JTAG”模式。另外用USB 3.0口连接的时候偶尔出现识别不了的情况换到USB 2.0口或者换个Hub口往往就好了——别问我为什么硬件兼容性的玄学问题实测有效。4.2 网络调试助手联调实录必须抓包的双端口思维FPGA侧写好了UDP发送逻辑接下来就是和PC联调。我的做法是PC上装两个工具一个是Wireshark一个是网络调试助手我用的是NetAssist国人写的挺好用当然其他类似工具也行。第一轮测试先把板子和PC直连不用交换机。以太网直连是交叉线还是直通线现在大部分网卡都支持自动翻转所以市面上买的成品网线基本都能直连。FPGA板上自带的是RJ45座加网络变压器连着PHY DP83867。直连后Wireshark选择一个关键选择抓包时选对网卡。很多人电脑有多个网卡虚拟机虚拟网卡、无线网卡、蓝牙网卡一堆选错网卡什么都抓不到。抓包看到FPGA发的UDP包后先看三个点以太网类型是不是0x0800IP头长度和校验和是否正确UDP校验和字段是否填了0但被Wireshark标红。有些网卡有硬件UDP校验和卸载功能可能把FPGA发来的、校验和为0的UDP包直接丢弃。这种情况在Windows上比较少见Linux上遇到过解决方法是把PC网卡属性里的“接收校验和卸载”关闭。4.3 常见问题速查表联调时我遇到过的坑调试过程我整理了这份速查表基本覆盖了90%的新手问题现象可能原因排查方法网线插上PHY链路灯不亮PHY芯片供电/复位/时钟异常量PHY的1.0V/2.5V供电检查复位引脚时序检查25MHz晶振链路灯亮但PC显示网络未识别PC和FPGA之间ARP不通抓包看有没有ARP请求发出FPGA侧看是否有收到帧能收到ARP请求但不回ARP应答ARP处理模块状态机问题SignalTap抓接收通路的数据看ARP帧是否被正确解析收到UDP包但负载数据全错字节序颠倒检查Avalon-ST数据的字节序SGMII接口有10/100M与1000M的字节序差异偶尔丢包频率随机接收FIFO溢出或者UDP长度超限看TSE的status字里溢出标志加大FIFO或者检查帧长寄存器配置发送速度上不去只有几Mbps握手效率低或者FIFO深度不够检查Avalon-ST的ready信号拉低占空比优化流水线减少气泡周期5. 性能调优与项目经验复盘UDP通信调通只是第一步真正体现功力的地方在于传输效率和稳定性。这一部分我总结几条实实在在的经验。5.1 吞吐率优化深挖Avalon-ST握手的每一个气泡千兆线速即125MB/s的裸数据速率看似很快但如果你在Avalon-ST接口上处理不好实际吞吐可能只有几十MB/s。带来吞吐损失的几个关键因素帧间隔时间以太网标准要求帧与帧之间至少要留96比特时间的间隔即12字节的IFG。千兆下这个间隙是96ns这是协议层面的硬性要求IP核已经处理了。但如果你在发送侧手动插入额外的等待周期吞吐就会下降。我见过有人写发送状态机时多加了一个空闲时钟周期千兆直接掉了近1%的吞吐可别小看这一点——当你要跑满带宽时每个周期都得省。FIFO几乎满/空阈值如果发送FIFO的几乎满信号配置得太保守比如水位线设到90%就停止写入那么实际可用FIFO容量只有90%当应用层突发数据稍大FIFO满后握手反压吞吐就会降。建议把almost_full阈值调到95%以上并对上层做适当的突发块大小控制。跨时钟域低延迟设计如果FPGA内部是200MHz逻辑时钟而TSE数据通路是125MHz中间用异步FIFO桥接是自然的做法。我建议异步FIFO的读侧和写侧都采用“show-ahead”模式即first-word fall-through可以有效降低一拍的读延迟。用这些优化后我实测的单路UDP发送吞吐可以到999Mbps占线速的99.9%接收方向也能跑到980Mbps以上主要损耗还是来自协议帧头本身的开销。5.2 资源占用与关键路径优化一个32位Avalon-ST接口的TSE MAC核在Cyclone V上大概占用2000-3000个ALM自适应逻辑模块加上你自己的UDP协议栈不含FIFO大概1500-2500个ALM。整体下来单路千兆UDP方案在Cyclone V上占用的逻辑不到10%资源非常充裕。时序方面最容易出问题的路径是状态机里的帧长度计数器——它是从帧开始一直计数到帧结束的组合加法链。如果FIFO读出的数据位宽是32位而你要统计的是字节数这个字节计数器累加逻辑的位数会很长16位以上而且是每个时钟周期都要更新。优化方法是把加法拆成流水级或者用两个计数器分摊一个算32位字个数另一个算尾字节余数最后在帧尾处组合算出总字节数这样关键路径能短不少。5.3 稳定性验证别只测一包数据调通UDP之后稳定性验证是决定项目能不能交付的关键。我建议做三类测试第一类是长时间满负荷灌包测试用上位机以最大速率连续发UDP包超过24小时统计丢包率。FPGA侧要设计一个包序号字段——每次发送把序号加1上位机端检查序号连续性就能精确统计丢包。这个测试能暴露FIFO边界问题和异步FIFO空满标志的亚稳态bug。第二类是速率阶梯测试从1Mbps开始逐级加到1000Mbps每档跑5分钟记录丢包率。这个能找到系统在某个中间速率下的特殊问题——比如时钟切换瞬间的状态机跑飞。第三类是热插拔测试反复拔插网线验证PHY从掉线到重新建链的长链路恢复逻辑。这里有个工程细节PHY掉线时TSE IP核内部的收发时钟可能会停振或者产生毛刺你得通过PHY的link状态寄存器轮询来检测链路状态一旦发现链路断开主动复位TSE IP内部所有状态机并丢弃所有未发完的帧。否则链路恢复后状态机可能停留在上一帧的中间状态导致后续所有帧都错位。我测试中还遇到过一个问题长时间运行后偶发一帧“坏状态”status字里出现CRC错误。排查后发现是PHY芯片的SGMII接口偶发误码导致MAC接收侧CRC校验失败。解决办法有两条一是看PHY有没有内置的FEC或者重传机制很多PHY没有二是应用层做重传——UDP协议本身不允许重传但应用层可以加确认包机制发现丢包就请求重发。这就是为什么很多工业以太网协议虽然跑在UDP上但上层都会再加一层自己的可靠传输算法。5.4 字节序问题调试时最隐蔽的敌人整个TCP/IP协议栈的网络字节序是大端Big-Endian也就是高位字节在前。而FPGA里常用的Nios II软核、内部FIFO、SRAM等默认是小端存储。很多第一次做以太网的工程师会对着一堆看起来像是“错位”了的数据发呆。举个例子发送一个UDP端口号0x1388十进制5000在以太网帧里的字节序应该先是0x13再是0x88。如果你在设计逻辑时把Avalon-ST接口的32位数据直接按小端方式拼接那发出去就会变成0x88 0x13。要知道数据在传输线上并没有“大小端”之分大小端只存在于处理器的内存视图里所以你必须在发数据进入TSE之前把字节顺序调整成“以大端顺序在线上依次出现”。TSE IP核本身不负责这个转换它的数据线上你给什么它就按什么顺序发送出去。解决办法一般是在协议栈输出的32位数据上做字节重排比如把d[31:24]和d[7:0]交换。这个逻辑写起来容易调试起来难最好的办法是从头就在代码里明确注释好每一字节的位置别等到板上调试才来猜。6. 写在最后的几句实在话TSE IP核的UDP通信方案我前前后后做了快两个月才完全跑稳。回头看去真正花时间的不是IP核配置而是那些文档里永远不会写明白的细节——字节序、ARP处理、帧长限制、PHY链路状态恢复。这些东西网上资料零散官方手册写得像是给熟手看的摘要每个坑都得自己踩一遍。如果你正准备做类似的项目我建议路径是这样的先用最简单的GMII接口配合一个便宜的RTL8211 PHY调通UDP通路把协议栈逻辑验证熟了再切换到SGMII接口或者换更高端的FPGA。上来直接搞SGMII一旦出问题你根本分不清是协议栈的bug还是串行收发器没配置对排错难度直接翻倍。另外Quartus自带的SignalTap逻辑分析仪一定要用熟练。我调试TSE IP核内部信号时几乎全靠SignalTap看Avalon-ST接口上的sof/eof/valid/ready时序以及MDIO总线上读写PHY寄存器的波形。没有SignalTap的话靠肉眼在板子上量引脚等于是蒙着眼睛走路。后续如果你想把方案升级可以考虑的方向包括加入TCP协议栈代价是逻辑资源和开发时间翻好几倍、做多通道MAC聚合、实现DMA对接PCIe接口、用TSE IP核的VLAN功能做数据流分类。路还长但第一步——把UDP跑起来——走通了后面都是水到渠成的事。
返回列表