ARTICLE DETAIL

资讯详情

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

Xilinx FPGA 10G Ethernet Subsystem调试实战:从Example到上板

Xilinx FPGA 10G Ethernet Subsystem调试实战:从Example到上板 几个月前接了一块带SFP接口的高速采集板在Vivado里搜到Xilinx官方10G Ethernet Subsystem这个IP核时其实蛮兴奋的可当我把example design生成出来、点开工程树的那一瞬间还是有点懵几百个文件支持层、testbench、约束文件堆在一起官方文档PG157几百页完全不知道该从哪看起。为了搞清楚这套Xilinx FPGA 10G Ethernet Subsystem的example到底该怎么用我把整个流程完整走了一遍从IP配置、仿真、上板到最终移植到自己的工程前后踩了不少坑。这篇文章不打算复述官方的每一步操作而是把我认为最影响成功率的几个环节讲透特别是那些文档里一笔带过、实际调试时却会卡很久的地方。不管你是做数据中心网卡、图像传输还是高速数据采集只要打算在FPGA上跑10G以太网这篇内容大概率能帮你省下几个通宵。1. 先搞清楚10G Ethernet Subsystem的“家底”比急着跑example更重要1.1 为什么市面上几乎都用这套官方子系统很多人看到10G以太网第一反应是FPGA里不就有高速收发器嘛直接串并转换不就行了实际上一个完整的10G以太网物理链路远不止收发器这么简单。以太网帧需要做FCS校验、帧间隙控制、前导码处理物理编码子层要做64B/66B编解码、加扰解扰、块同步再往下才轮到GT/GTH/GTY这类高速串行收发器做并串转换和时钟恢复。这几个层次如果全部自己用Verilog写光是对齐和状态机就够写几千行而且极易出现各种边角case。Xilinx的10G Ethernet Subsystem恰恰把MAC、PCS、PMA和可选FEC整合在一个IP核里用户拿到的是一个带AXI4-Stream接口的“黑盒”大量繁琐的底层细节都已经处理好了。更重要的是每个IP都自带example design里面包含了完整的时钟方案、复位逻辑、共享收发器资源和测试模块。对于第一次接触10G的设计者来说example并不只是一个demo它其实就是官方认定的一套“标准接法”。1.2 IP内部帮你把数据包处理了什么我在调试时习惯把这条链路分成几段来理解这样定位问题会快很多用户侧64bit、156.25MHz的AXI4-Stream数据接口配合tvalid、tready、tlast、tuser等信号完成以太网帧的收发。MAC层负责以太网帧的组帧/解帧包括前导码、SFD、长度/类型、数据填充、FCS校验同时管理最小帧长、最大帧长、帧间隙等规则。PCS层把MAC层过来的并行数据编码成64B/66B码块加入同步头和扰码保证接收端能恢复时钟并完成块对齐。PMA层负责和FPGA内部GT收发器对接把并行数据变成差分串行信号送到SFP或者背板走线。可以把它想象成一个快递转运中心MAC是前台接待负责核对包裹信息PCS是中转分拣线负责把不同尺寸的包裹重新打包成统一规格PMA是传送带负责把包裹送上高速轨道。example design把这条“传送带”的前后左右全部接好我们真正要关心的是最外边那两个接口——用户数据接口和差分串行接口。1.3 Example里你真正需要关注的核心信号打开example顶层文件后不需要每个信号都看懂但下面几类信号必须能认出来差分串行接口txp/txn、rxp/rxn分别对应SFP的发送和接收差分对。GT参考时钟通常叫gt_refclk_p/gt_refclk_n10GBASE-R场景下多为156.25MHz差分时钟。用户侧收发接口rx_axis_tvalid、rx_axis_tready、rx_axis_tdata、rx_axis_tkeep、rx_axis_tlast等以及TX方向对应的信号。状态类信号复位完成、rx_link_up、tx_link_up、统计计数向量等。AXI4-Lite管理接口用于读写IP内部寄存器配置回环模式、查询链路状态、读取接收/发送统计。把这些信号在Example文件里找到后再去跑仿真或者上板你会对整条链路的状态一目了然。我第一次调试时就是没分清“PCS没同步”和“MAC接口没数据”是两码事结果在用户逻辑里查了半天纯属浪费时间。2. Vivado生成的Example工程到底长什么样目录和模块逐个说2.1 一条命令把example工程生成出来在Vivado里配置完10G Ethernet Subsystem这个IP后IP会出现在工程的IP Sources面板中。正常情况下右键该IP选择“Open IP Example Design”Vivado会弹出一个路径选择框让你决定example工程生成到哪里。这里有个小建议路径千万别带中文、空格和过长的层级最好放到一个单独的example目录下否则后面综合仿真时各种工具脚本容易报路径错误。生成后Vivado会直接用新工程打开一个独立窗口这个工程和你原本的项目已经没关系了是一个完整的、可以直接综合仿真甚至烧录的example。我第一次用的时候以为它只是生成了几个文件到自己项目里差点把整个example的约束都混进正式工程最后导出网表时出了不少冲突。不同Vivado版本生成的工程结构略有差异但基本都包含这几类内容顶层RTLexample_top之类是整个example的入口。支持文件包括时钟模块、复位模块、GT共享逻辑等。IP核心文件真正的10G Ethernet Subsystem实例化代码以及加密网表。仿真目录包含testbench用于跑行为级仿真。约束文件包含引脚位置、参考时钟约束、时序约束。2.2 Example design的模块层级与文件命名规律以我用的Vivado版本为例example工程里通常能看到一个以IP名称为前缀的顶层文件比如xx_10g_ethernet_example_top.v然后在示例目录下还有xx_10g_ethernet_support.v这类支撑文件。support文件里一般会例化GT参考时钟的IBUFDS_GTE、复位同步逻辑、GT common的QPLL配置等。这些代码不是给用户“看热闹”的而是实际跑通链路必需的初始化逻辑。往下再拆一层会看到IP的wrapper或者核心例化文件里面调用了Xilinx封装的10G Ethernet Subsystem。这一层通常是加密的或者网表形式千万别去改它也基本改不了。我建议拿到example后第一件事是打开顶层文件先用搜索功能把所有带txp、rxn、refclk、axi_lite的管脚列出来再对照原理图或者开发板手册。这样能在心里建立一张“信号地图”后续查问题按图索骥效率会高很多。2.3 哪些文件要改、哪些不要碰example design里除了IP核心之外的文件大体分两类一类是“示例专用逻辑”比如为了演示而增加的ILA、VIO、LED驱动、按键复位处理等另一类是“必要支撑逻辑”比如GT参考时钟buffer和GT common共享逻辑这类是真正需要移植进自己工程的。很多初学者容易犯的错是把example_top当成模板直接在上面加自己的业务逻辑。短期内看着方便但example顶层里往往塞了大量演示代码综合后不仅浪费资源还会引入不必要的约束后期时序收敛非常难受。正确的做法是保留必要支撑逻辑参考example的时钟、复位和接口连接方式重新写一个干净的业务顶层。IP内部的东西一个字符都不要动example_top里的专用测试模块则要坚决剥离掉。3. 把Example设计跑起来配置要点、仿真和第一手波形解读3.1 IP配置里这几个选项决定成败在生成example之前IP配置界面里有一些关键选项必须提前想清楚否则后面改起来很麻烦。首先是协议模板。10G Ethernet Subsystem支持多种模式像10GBASE-R、10GBASE-KR等。普通SFP光模块场景下选10GBASE-R线速率是10.3125Gbps参考时钟用156.25MHz。这里经常有人犯一个低级错误以为“10G以太网”线速率就是10Gbps仿真配置成10G。实际上串行线上因为8B/10B或64B/66B编码开销线速率比有效速率高10GBASE-R用64B/66B编码后为10.3125Gbps。参考时钟必须和这个线速率匹配否则PCS和PMA根本对不上。然后是Shared Logic选项。这个选项决定GT common资源、参考时钟buffer是放在IP核内部还是外部。如果选择“Include shared logic in example design”生成的example会多出很多顶层支撑逻辑方便你单独观察和调试如果选择“Include shared logic in core”IP核会更加独立集成进正式工程更省事。我的建议是第一次调试选前者等链路完全调通、准备产品化时再改成后者或者手动把共享逻辑抽出来统一管理。还有收发端Flow Control。如果只是做点对点裸数据搬运可以把Pause帧处理关掉这样用户逻辑会简单不少。但如果你要对接交换机或者标准以太网设备最好保留流控否则对端有可能因为缓冲满发暂停帧而你的MAC忽略之后导致丢包。3.2 第一次跑仿真的正确姿势example设计自带testbench直接设为顶层后跑行为仿真通常不会报错。但仿真启动后你要有心理准备10G IP的仿真模型初始化时间比较长尤其是GT收发器的模拟模型起来非常慢。前几次我盯着波形以为工程卡死了其实是在等PLL锁定和复位释放。跑仿真前建议先打开testbench看一下它的流程。官方example的testbench一般会做这么几件事等待电源稳定和复位释放配置IP内部寄存器内部或外部回环测试通过用户接口发送以太网帧检查接收统计是否匹配。这些流程不一定按顺序出现版本不同差异也比较大。但核心逻辑都在你可以通过观察仿真日志里的打印信息来判断进行到了哪一步。仿真时间上10G链路跑几十微秒其实就能看到PCS同步完成但MAC收发帧可能需要再等一点时间。为了节省时间不要一上来就跑1毫秒先跑个10~20微秒看看状态信号能否拉起来确认链路没问题再加大时间。如果testbench支持快速同步模式优先开起来能省很多仿真等待时间。3.3 波形判读怎么确认链路真的通了仿真波形里我习惯优先看这几个信号参考时钟和PLL锁定状态GT参考时钟进来后QPLL/QPLL锁存信号应该拉高这是所有后续工作的前提。复位完成信号比如areset_done、gt_reset_done等复位没结束后面一切状态都白看。PCS同步/链路up信号名字里带link_up、align或sync的状态信号一般会在复位释放后一段时间内变高表示接收端已经从串行码流里恢复出正确的66bit码块边界。用户接口的valid和ready链路up后testbench会开始发送数据。观察tx_axis_tvalid和tready握手确认数据真的从用户侧发出去了。如果你看到link_up始终拉不高第一反应不要去看MAC八成是PCS/PMA层的问题先查参考时钟、PLL锁定和PMA回环配置。把链路状态信号按层级分开对待定位速度会快很多。4. 上板实测SFP光模块调试中那些反复出现的坑4.1 回环测试的三级跳仿真通过后上板才是真正的开始。我强烈建议所有10G调试都按“三级回环”来推进而不是一上来就插光模块连交换机。第一级是IP内部的PCS/PMA回环。通过AXI4-Lite寄存器或者example里的VIO按键把发送方向的数据在PCS/PMA内部直接环回到接收方向。这一级能验证用户逻辑发出去的帧“能走通射频前端”也能验证参考时钟、复位、收发数据通路这些基础模块。只要这级回环能收发成功说明IP本身配置和用户逻辑基本没问题。第二级是用GT收发器的近端回环或者用IBERT硬核去测一下眼图。IBERT不是10G Ethernet Subsystem的一部分但它是Xilinx FPGA调试高速串行链路的一把利器。把同一个GT句柄配置成IBERT模式发起PRBS测试能快速判断物理层信号质量、眼图和误码率。等到误码率为0、眼图睁开足够大再回到10G Ethernet Subsystem继续调。第三级才是外部光模块回环或对接交换机。光模块接好后用一根短光纤把TX和RX对接观察link_up和统计计数。如果外部回环通过再尝试接交换机此时要特别注意对端设备的速率自协商能力、SFP兼容性和光纤类型。4.2 Link始终起不来从参考时钟到线速率逐项排查external loop下link up起不来是最常见的问题这里列一个排查顺序基本覆盖90%的原因排查项检查方式常见原因参考时钟用示波器或ila抓refclk频率频率错误、差分时钟没进来、时钟buffer位置不对线速率核对IP配置与对端能力10GBASE-R必须是10.3125Gbps不是10GSFP模块量模块供电、检查TX_DISABLE电平模块没插好、被disable、兼容性差极性通过寄存器或例化参数设置PT_INVPCB上RX±接反需要取反接收同步看rx_link_up、rx_bytealigned等信号光模块光功率过低、光纤衰减、对端没起来共享逻辑检查GT common是否锁定两个IP共用GT bank时资源冲突或复用错误有一次我怎么调都link不起来最后发现问题居然出在SFP的TX_DISABLE被板子上拉到了高电平相当于光模块一直被关着当然不可能有光出来。这种问题光看FPGA内部信号很难发现因为FPGA并不知道外面光模块的状态所以调物理层时一定要结合电路图。4.3 抓到的错误帧在哪个计数器里如果link已经up但数据传输出错就要去读统计向量和状态寄存器。10G Ethernet Subsystem的用户接口会拉出一堆统计信号名字很长比如以tx_good_frames、rx_good_frames、rx_bad_frames、rx_crc_err等命名的信号。不同版本信号名略有差异建议以PG157里的寄存器表和顶层接口定义为准。调试时我的习惯是在example工程里加一个ILA核把这些统计信号和用户接口状态打出来触发条件设成rx_bad_frames从0变成1。这样可以在坏帧出现时把前后几个时钟周期的数据都抓下来直接看是CRC错、FCS错还是FIFO溢出定位方向会非常明确。另外一个常见坑是错误计数突然暴涨但链路状态一切正常很多时候是外部对端在发送pause帧或空闲帧而你这边没让MAC正确识别。如果不需要流控直接在配置里关掉BER和错帧统计立刻干净很多。5. 从Example到真实工程接口裁剪、约束收敛和上板注意5.1 从example移植时哪些模块必须保留当你决定把example里验证通过的链路搬到自己的正式工程时需要保留的模块可以概括为三块IP核心、GT共享逻辑、时钟复位支撑逻辑。IP核心就是你在IP Catalog里配置好的那个10G Ethernet Subsystem实例通常是一个wrapper文件实例名以你IP名称为前缀。GT共享逻辑负责QPLL、参考时钟缓冲等资源这部分的例化代码经常藏在example的support文件中。不要以为IP核只要自己例化就行GT共享逻辑如果缺失综合可能不报错但上板后GT永远锁不上而且这种问题特别难查。我自己吃过一次亏直接把IP核心复制到新产品省掉了example里的GT common相关代码结果兄弟团队用同样代码没问题我这边死活不latch。后来对比发现就是GT reference clock buffer和QPLL共享逻辑没带过去。所以移植时务必逐行比对example里的support模块把每个和gt_common、refclk、reset相关的信号都保留。5.2 用户侧AXI4-Stream接口怎么接业务逻辑10G Ethernet Subsystem的用户侧接口本质上是AXI4-Stream协议带tvalid/tready握手。写业务逻辑时建议先用一个简单的FIFO做速率匹配再进入后续处理模块。因为10G线速下用户侧时钟是156.25MHz数据位宽是64bit也就是每拍最多能传8字节。如果你的业务逻辑偶尔出现一个周期处理不完必须依赖tready反压否则FIFO会溢出。下面是一段非常简化的Verilog片段只是展示接用户RX侧时的基本思路reg [63:0] rx_data_q; reg rx_valid_q; always (posedge rx_axis_aclk or negedge rst_n) begin if (!rst_n) begin rx_valid_q 1b0; end else begin if (rx_axis_tvalid rx_axis_tready) begin rx_data_q rx_axis_tdata; rx_valid_q 1b1; // 这里根据 tkeep/tuser 判断帧边界写入用户FIFO end else begin rx_valid_q 1b0; end end end重点不是这段代码本身而是你要意识到用户接口上的数据不是简单的“一拍一个数据”它带帧的概念。tkeep表示每拍哪些字节有效tlast表示帧结束tuser上通常还带有帧起始和错误标记。接收方向必须按这些信号把完整的以太网帧切片重组再判断CRC和帧长。凡是只看到tdata就直接存起来的设计十有八九会在帧边界和半字节对齐上出问题。5.3 时钟与复位的处理要点10G Ethernet Subsystem内部有很多时钟域但用户最关心的只有两个用户侧接口时钟通常由IP输出例如156.25MHz和AXI4-Lite管理时钟通常由外部提供比如100MHz。在example中这两个时钟的连接方式已经示范得非常清楚你要做的是在正式工程里保持同样的时钟拓扑。特别提醒用户侧156.25MHz时钟不要随便用一个外部晶振代替它应该是从GT参考时钟经过IP内部恢复/分发出来的时钟。原因很简单RX方向数据本身就是从串行码流里恢复出来的它的相位和参考时钟不是严格同源贸然把业务逻辑放到另一个独立时钟域会引入大量跨时钟域问题。复位方面Xilinx这个IP通常要求在上电后给一个持续时间足够的异步复位随后由IP自身完成同步释放。example里的复位模块已经处理好了但如果你在正式工程里偷懒直接用一个全局复位按键建议加一个类似reset_sync的同步释放逻辑避免在高速数据接口上出现亚稳态。5.4 上板之后综合实现阶段的心得把example移植到正式工程后第一步综合实现大概率会遇到两类问题时序收敛不满足和GT管脚位置冲突。10G用户接口跑在156.25MHz对于现代FPGA来说频率不算高但问题是数据总线和控制逻辑往往跨越多个模块很容易出现一个组合逻辑链从FIFO到业务模块再到统计更新最后时序违例。我的经验是业务逻辑里所有状态寄存器一定用时钟沿打拍更新不要用纯组合逻辑去拼接valid信号更不要在同一拍里做过多判断。如果出现了时序违例优先在这个链路里插入流水寄存器而不是盲目调综合策略。GT管脚位置冲突则是一个头痛的问题。10G Ethernet Subsystem的收发器必须放在支持所需线速的GTH/GTY bank上而且参考时钟引脚位置有严格限制。不同bank之间不能随意跨接GTX/GTH/GTY在不同器件上支持的速率也不同。建议你在项目一开始就打开Package Pinout视图确定好RXP/RXN/TXP/TXN和refclk的物理位置再开始写约束。否则布局布线后才发现位置不合法改起来相当伤筋动骨。根据我个人的习惯凡是要新做一个带10G接口的板子我都会先在网上搜一下同一系列FPGA的评估板原理图看看官方或者大厂是怎么分配GT位置、怎么接SFP座子的。照抄成熟设计能避免很多物理层的新坑。最后再分享一个小经验10G Ethernet Subsystem调试时无论如何都要保留一个能方便读取内部状态的寄存器接口或者ILA探针。哪怕你觉得后期资源紧张也尽量多抓几个链路状态信号出来。很多问题不是逻辑错而是状态信号被错误地忽略导致在一个已经出错的链路上反复验证。尤其是第一次接触高速串行收发器的朋友先学会把link_up、gtpowergood、tx_fault这些信号用ILA抓出来再谈业务逻辑这才是真正能帮你省时间的方式。
返回列表