ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

Xilinx Aurora IP核详解:FPGA高速串行通信的配置、选型与调试实战

Xilinx Aurora IP核详解:FPGA高速串行通信的配置、选型与调试实战 简介面向FPGA开发者与高速串行通信工程师的Xilinx Aurora IP核使用指南代码包重点解决IP核生成步骤、参数配置、接口定义与仿真验证中的常见问题。压缩包共3个文件以HTML说明文档为主附带inscode工程入口与gitignore配置整体仅7KB轻量便于快速部署、按需查阅和二次开发。已有163人学习下载适合需要上手Aurora 8B/10B或64B/66B编码方式的开发者。内容系统梳理了用户侧数据接口、状态控制端口与时钟接口的功能完整讲解Framing和Streaming两种传输模式下的时序差异并给出PG046、PG074官方文档索引。工程仿真实例涵盖数据生成与检查逻辑以及LocalLink到AXI4-Stream总线转换的实现细节可辅助读者从接口信号理解到仿真验证快速落地并迁移到实际项目中。 做高速板间通信的FPGA工程师早晚会碰到Xilinx Aurora IP核。我第一次调它是在一块带SFP光口和GTX收发器的板子上对方丢给我一个只有几句注释的example design让我把传感器数据从光口送到对面的FPGA。本想着按IP配置向导点几下就能跑通结果第一天全耗在channel_up不拉高、数据发出去收不回来这类问题上。后来把Aurora 8B/10B和64B/66B的区别、GT参考时钟、用户接口握手逻辑彻底啃了一遍才算真正会用。这篇文章就把我使用Xilinx Aurora IP核的过程中总结出来的选型思路、配置要点、能直接抄的代码和调试经验一起整理出来给第一次接触Aurora、或者已经卡在链路调不通的工程师做一个完整参考。1. Aurora在高速串行链路里的定位与选型逻辑1.1 Aurora到底帮你省掉了哪些事Xilinx FPGA里的GTP/GTX/GTH/GTY这些高速收发器能力的下限和上限都很高能跑到几百Gbps但直接操作原语并不友好。你要自己处理上电复位顺序、参考时钟管理、通道的comma对齐、弹性缓冲、通道绑定、错误检测和恢复哪一个环节出问题整条链路就是黑的。而Aurora IP核把这一整套物理层和链路层逻辑封装成了黑盒对外提供一个干净的AXI4-Stream接口用户只需要关心数据怎么组帧、怎么握手不用去跟SerDes原语较劲。Aurora本质上是一个轻量级点对点串行协议没有PCIe那套复杂链路训练也没有以太网MAC层的调度和协商延迟可以做得非常低。它最适合的场景就是FPGA对FPGA通信、板卡之间通过背板或光纤互联、ADC/DAC数据流搬运这一类点对点高带宽传输。它的定位简单粗暴两个设备之间建一条高速管道管道怎么建、怎么维护Aurora帮你搞定你只需要往管道两头塞数据。1.2 什么时候该选Aurora什么时候该换别的不少朋友会把Aurora和JESD204B、PCIe、甚至自己写的SerDes控制逻辑混在一起比。我自己的选型习惯是这样的方案编码开销典型场景上手复杂度Aurora 8B/10B20%FPGA间中低速互联、光纤传输、简单数据流低有完整例程Aurora 64B/66B约3%高带宽点对点多通道绑定中高JESD204B8b/10b变换等多层ADC/DAC采集链路多设备同步高配置项多自定义SerDes控制按需对延迟和协议有特殊要求很高不推荐新手如果你的项目是ADC/DAC到FPGA之间高速采样数据而且有确定性的多链路同步需求JESD204B更合适如果要做主机与设备之间的标准生态互联PCIe更合适。但如果只是两片FPGA、或者FPGA和某块有SFP接口的板卡做高速收发Aurora是最快出活的选择。自己写SerDes控制逻辑不是不行但是要处理的事情太多除非你有非常特殊的协议需求或者极端的延迟要求否则没必要。1.3 8B/10B和64B/66B怎么选Aurora在Xilinx IP核里分成两个Aurora 8B/10B和Aurora 64B/66B。8B/10B加20%开销每一个8bit数据编码成10bit保证线路信号有足够的跳变沿供接收端恢复时钟。它的好处是对齐机制成熟comma检测和通道绑定都是现成的调试起来问题少。64B/66B只用约3%开销带宽利用率高很多适合需要跑几十G甚至上百G的场景但是初始化、加扰、错误处理的逻辑比8B/10B复杂不少。我的建议很直接如果线速率在10Gbps以下项目周期又紧直接用Aurora 8B/10B。等把8B/10B的链路跑通理解了channel_up、GT参考时钟、AXI4-Stream握手这些基本概念再上64B/66B会顺利得多。一上来就挑战64B/66B容易在底层问题上浪费大量时间。2. 创建IP核时的几个决策点线速率、参考时钟、GT位置、共享逻辑2.1 线速率、参考时钟和user_clk的关系在Vivado里配置Aurora IP核时最核心的三个参数是Line Rate、GT RefClk和用户接口数据宽度。它们之间的关系在8B/10B下是这样算的user_clk Line Rate × 0.8 / (数据宽度 × 8)举个例子线速率设置成5Gbps数据宽度选择4字节32bit那么用户时钟就是5G × 0.8 / 32 125MHz如果是64B/66B系数从0.8换成64/66也就是大约0.9697。这个user_clk是Aurora IP核输出的用户工作时钟用户的发送和接收逻辑最好都用它用别的主时钟容易出跨时钟域问题。这里有一个常见坑参考时钟不是随便填的GT收发器内部的PLL对参考时钟频率和线速率之间的倍频关系有限制。同一个GTX参考时钟用156.25MHz能覆盖很多速率档换成100MHz可能某些线速率根本不支持。填完参数后如果IP配置界面提示invalid组合不要硬来要么改参考时钟频率要么换线速率。2.2 用户数据宽度怎么选数据宽度直接影响user_clk频率和逻辑时序。选4字节是大多数应用的平衡点user_clk不会太高逻辑时序好满足接口位宽也适中。选2字节时user_clk会翻倍对时钟频率要求更高选8字节则接口位宽变大对逻辑布局布线有一定压力。Aurora 8B/10B一般支持2字节或4字节用户数据宽度64B/66B可做到4字节或8字节。如果后续要接DDR、DMA或者PCIe的数据通路建议先确定数据位宽和系统时钟规划再回过来定Aurora的参数。2.3 GT位置和参考时钟引脚到底怎么对应这是最容易在硬件上翻车的点。FPGA里每个高速收发器都有固定的物理位置叫做GT channel若干个channel组成一个Quad每个Quad有专用的参考时钟引脚比如MGTREFCLK0P/N和MGTREFCLK1P/N。Aurora配置界面里会让你选择GT起始位置和你用的参考时钟这个必须跟板卡原理图对应起来。我之前有一块板子SFP光口在某个GTY Quad上但IP生成时默认选了另一个Quad的GT。结果综合布线虽然能过但PCB上根本没有走线连到那个位置的引脚上板自然没有信号。正确做法是先看原理图确认光口/连接器对应哪个MGT引脚、哪个Quad、参考时钟从哪个引脚进来再在IP配置里选对位置。如果选错了后面所有调试都是在浪费时间。2.4 Shared Logic的选择策略Aurora IP核在配置时有一项Shared Logic常见选项是“Include Shared Logic in core”和“Include Shared Logic in example design”。新手建议选后者这样生成的example design里会包含完整的GT Common、复位逻辑和时钟管理模块可以直接仿真也能上板。如果选了前者IP核内部会把这些都打包好上层更干净但一旦要调试内部逻辑倒腾起来反而麻烦。多路Aurora共用一个参考时钟时Shared Logic的处理更要谨慎。GT Common资源只能被一个IP核实例化其他核需要共享它。如果两个Aurora核各自选了“Include Shared Logic in core”就可能出现同一个GT Common被例化两次的冲突。工程里有多路Aurora时我习惯的做法是让第一个核拥有Shared Logic其他核在配置里选择共享模式然后在顶层把GT Common单独拉出来统一管理。3. 例程结构与用户接口时序拆解3.1 生成example design后看哪些文件Vivado里右键Aurora IP核选择“Open IP Example Design”会自动生成一个完整可综合的例工程。这个例工程结构一般包含顶层example design、support模块、GT wrapper和一个简单的用户数据模块。第一次看可能觉得文件多但别慌重点看两类一类是GT和时钟相关的support模块一类是用户接口的example design顶层。建议拿到例程后先跑一遍行为仿真不要急着上板。仿真里能看到gt_pll_lock、channel_up这些关键信号的时序关系搞清楚它们大概在多少周期之后拉高。我自己每次新建Aurora工程都会先跑仿真因为上板后如果链路起不来至少能知道是仿真阶段就过不了还是板级问题。3.2 用户接口信号速查Aurora 8B/10B对外接口信号虽然多但真正要关注的也就下面这些信号方向功能user_clk输出用户时钟IP根据配置自动生成user_reset输入用户逻辑复位高有效channel_up输出通道已对齐所有lane都ready时拉高lane_up输出每个lane的对齐状态多位信号gt_pll_lock输出GT PLL锁定状态s_axi_tx_tdata/tvalid/tready/tlast/tkeep输入/输出发送AXI4-Stream接口m_axi_rx_tdata/tvalid/tready/tlast/tkeep输入/输出接收AXI4-Stream接口注意user_reset是高有效还是低有效不同版本IP可能不同一定以实际生成的接口文档为准。还有一点channel_up只表示通道对齐已经完成它不等于“链路稳定运行”的永久保证。链路中途如果出现严重错误channel_up是可能掉下来的所以用户逻辑最好监测channel_up的变化掉链后能回到复位等待状态。3.3 AXI4-Stream握手到底怎么理解Aurora的用户数据接口是AXI4-Stream核心握手规则只有一句话tvalid和tready同时为高才算一拍有效数据传输。用快递来类比tvalid是“我有货要发”tready是“我有地方收”两边都为高货物才真正搬走。发送方向上IP通过tready告诉用户“你可以发了”用户要保证tvalid拉高时tdata是有效数据。如果tvalid为高但tready为低说明IP暂时没准备好数据不能丢用户逻辑必须保持当前状态等到tready拉高。接收方向上方向反一下。IP通过tvalid告诉你“数据来了”你的逻辑通过tready告诉IP“我能收”。如果tready一直为低IP内部的反压机制会生效但反压持续太长时间可能导致FIFO溢出所以接收侧要及时拉高tready。4. 一个适合上板自检的收发代码示例4.1 自检模块的思路与其给一段复杂的FIFO读写代码不如先放一个最简单好查的链路自检模块发送端发出递增的32bit数据接收端收到后检查是否严格递增一旦发现不对就把error_count加1。这个模块非常适合刚上板时确认链路是否打通、数据是否稳定也能确认tlast帧边界是否正确。如果你已经在例程里跑通过可以把这个模块接在Aurora的用户接口上替换原来的测试数据源。4.2 发送端代码递增数据源module aurora_tx_gen #( parameter DATA_WIDTH 32, parameter FRAME_WORDS 64 )( input wire user_clk, input wire user_rst, input wire channel_up, output reg [DATA_WIDTH-1:0] s_axi_tx_tdata, output reg s_axi_tx_tvalid, input wire s_axi_tx_tready, output reg s_axi_tx_tlast ); reg [7:0] word_cnt; reg [31:0] data_cnt; assign s_axi_tx_tvalid ~user_rst channel_up; always (posedge user_clk) begin if (user_rst || ~channel_up) begin word_cnt 8d0; data_cnt 32d0; s_axi_tx_tdata 32d0; s_axi_tx_tlast 1b0; end else if (s_axi_tx_tvalid s_axi_tx_tready) begin s_axi_tx_tdata data_cnt; data_cnt data_cnt 32d1; if (word_cnt FRAME_WORDS - 8d1) begin s_axi_tx_tlast 1b1; word_cnt 8d0; end else begin s_axi_tx_tlast 1b0; word_cnt word_cnt 8d1; end end end endmodule这个模块每64拍组成一帧在最后一拍拉高tlast。数据从0开始递增回卷也没关系接收端只需要检查“上一个值加1是否等于当前值”。通道没对齐时tvalid为0不会往外发数据所以不会在channel_up拉高前污染链路。4.3 接收端代码数据校验与帧计数module aurora_rx_check #( parameter DATA_WIDTH 32 )( input wire user_clk, input wire user_rst, input wire [DATA_WIDTH-1:0] m_axi_rx_tdata, input wire m_axi_rx_tvalid, output reg m_axi_rx_tready, input wire m_axi_rx_tlast, output reg [31:0] recv_count, output reg [31:0] error_count, output reg [31:0] exp_data ); always (posedge user_clk) begin if (user_rst) begin recv_count 32d0; error_count 32d0; exp_data 32d0; end else begin m_axi_rx_tready 1b1; if (m_axi_rx_tvalid m_axi_rx_tready) begin if (m_axi_rx_tdata ! exp_data) error_count error_count 32d1; exp_data exp_data 32d1; recv_count recv_count 32d1; if (m_axi_rx_tlast) recv_count 32d0; end end end endmodule接收端把tready始终拉高只要能收就一直收。收到一帧中最后一个数据时会看到tlast拉高此时把recv_count复位。调试时用ILA抓error_count如果一直是0说明链路数据是干净的。4.4 改成真实业务数据要动哪里真实工程里发的不可能是递增数多半是ADC采样、图像数据或者传感器打包数据。改法很简单发送侧把数据源换成FIFOFIFO有数据且Aurora的tready为高时把FIFO读出的数据放到tdata上同时拉高tvalid接收侧把收到数据写入FIFO或者DDR。要注意的是如果业务时钟和user_clk不是同一个中间一定要加异步FIFO跨时钟域直接把主时钟数据怼到Aurora接口上采样铁定出问题。还有一个容易踩的细节收端不要一看到tvalid就当作帧头开始处理。很多协议是连续数据流tvalid可能一直为高真正的一帧边界要靠tlast来界定。接收侧最好维护一个简单的帧状态机等tlast结束后的第一个有效数据当作帧头再做后续业务处理。5. 链路调不通时的排查链路与经验清单5.1 从现象反推问题的排查顺序Aurora调不通绝大多数情况集中在这几个现象上。我用表格总结了排查思路现象优先检查项可能原因gt_pll_lock不拉高参考时钟频率、复位时序、电源时钟源没起振、参考时钟选错、PLL配置不合法channel_up不拉高线速率、编码方式、对端配置、物理连线两端速率不匹配、光纤/背板链路不通、GT位置选错数据校验错误字节序、tlast位置、数据屏蔽P/N极性接反、接收端帧不同步、环路方向不对运行中偶发断链电源纹波、参考时钟抖动、连接器接触SI问题、温度漂移、时钟芯片锁定不稳定一开始先别急着看数据对不对先抓channel_up。如果channel_up没拉高数据正确性无从谈起。我踩过最典型的坑是板子上可编程时钟芯片还没锁定Aurora就释放了复位GT PLL一直锁不上。后来加了时钟芯片locked信号等它拉高再释放Aurora复位问题立刻消失。5.2 一个完整的排查案例有次在客户板卡上调试现象是PCS回环能过但是外接光模块后channel_up死活不拉高。我按顺序做了下面几步第一步确认本地IP回环正常。把Aurora的loopback配置成PCS内部回环channel_up拉高说明FPGA内部逻辑、参考时钟、GT初始化这些都没问题。第二步检查光模块。换一个已知良好的光模块和光纤故障依旧排除光模块本身。第三步查对端配置。把两个板卡的Aurora配置打出来对比发现线速率一端是3.125Gbps另一端是2.5Gbps。这个差异靠肉眼在逻辑里抓是抓不出来的因为两端各自PLL都锁定但放在一起就是对不上。改成统一速率后channel_up几毫秒内拉高。这个案例想说明的是Aurora调试不能只盯着自己这一端。它是点对点协议两端配置必须完全一致包括线速率、编码方式、参考时钟频率。很多“链路起不来”的问题根本原因是配对双方参数不一致。5.3 数据校验错误的两个心理准备建立好“数据校验模块”后如果发现error_count一直在涨先别急着怀疑Aurora核有问题。第一个要查的是接收端的数据屏蔽时机。channel_up刚拉高的头几个周期IP可能还会输出一些内部对齐阶段产生的内容如果接收校验模块从channel_up上升沿就开始比对前面几个错误可能是“假错误”。正确做法是等channel_up稳定后再开始比对或者干脆利用tlast对齐帧边界在完整帧之后开始统计。第二个要查的是字节序。Aurora的接口位宽是32bit或更大而用户在业务层可能定义了不同的字节排列。有时候发送端发送的0x11223344接收端看到的是0x44332211。这不一定是链路错了而是数据宽度和字节序在两端映射方式不同。处理方式是在发送或接收侧做一次字节重排而不是去改GT极性。5.4 善用IBERT和硬件管理器做物理层诊断如果Aurora这边已经做到PCS回环通过但外部链路误码率很高而且看起来不像配置问题建议不要继续在Aurora逻辑里耗时间直接用Xilinx IBERT IP核去做物理层诊断。IBERT可以测同一组GT通道的眼图、误码率以及接收端均衡参数。它能告诉你信号裕量到底够不够连接器有没有虚焊PCB走线有没有问题。我见过有人在Aurora上连续调了两周最后用IBERT一测才发现某条lane的接收端眼图基本是闭的硬件上问题很大。物理层有问题协议层再对也没用。所以链路不稳定、偶发断链这类问题早用IBERT去定位比在Aurora层面反复猜测高效得多。最后给一个我自己一直用的习惯每当新板子回来先用两个Aurora核搭一个回环测试工程一个做PCS本地回环一个从SFP发出去再绕回来。这样能在最短时间内把“FPGA内部逻辑问题”和“外部链路问题”分开。Aurora这个IP核看着复杂但只要把线速率、参考时钟、GT位置、channel_up这几个关键点吃透后面其实就是普通接口调用的事。真到了某根线始终对齐不上、数据总是间隔性错误的时候优先回头查物理层和参考时钟比反复改逻辑要有效得多。本文还有配套的精品资源点击获取
返回列表