
1. 为什么我劝你别再死磕官方手册搞FPGA高速接口的兄弟应该都有同感Aurora 64B/66B这个IP核的官方文档读起来是真的费劲。PG074这份文档我前前后后翻了不下十遍每次遇到问题去查都得在几百页里来回跳转。不是说文档写得不好而是它把IP核配置、时钟架构、复位逻辑、协议细节全揉在一起新手看完第一遍基本是懵的。我这次拿Vivado 2023.1重新走了一遍Aurora 64B/66B的完整配置流程从IP核定制到复位时序调试踩了不少坑也总结了一些文档里不会明说的经验。这篇文章就是把我实际操作的完整过程拆开来讲包括IP核参数怎么选、时钟怎么规划、复位时序到底怎么配合、仿真和上板分别要注意什么。Aurora 64B/66B是Xilinx现在叫AMD了但大家还是习惯叫Xilinx提供的一个轻量级链路层协议IP核主要用于点对点的高速串行通信。它跟Aurora 8B/10B最大的区别在于编码效率——64B/66B编码的开销只有3%左右而8B/10B是20%所以在同样线速率下64B/66B能跑出更高的有效带宽。这也是为什么现在做高速板间互联、芯片间互联大家更倾向于选64B/66B。这篇文章适合谁看如果你已经用过Aurora 8B/10B想升级到64B/66B那这篇能帮你快速过渡如果你是完全没接触过Aurora的新手建议先把8B/10B的流程跑通一遍再来因为64B/66B在时钟和复位上要复杂一些。另外文章里涉及到的复位时序图是我根据实际调试经验整理的跟手册上的示意图角度不太一样更贴近实际波形。注意本文基于Vivado 2023.1版本不同版本IP核界面可能有细微差异但核心配置逻辑是一致的。2. Aurora 64B/66B IP核的核心架构与选型考量2.1 这个IP核到底解决了什么问题在板间或芯片间做高速数据传输如果自己从Serdes开始搭链路层工作量巨大——要做对齐、要做CRC、要做流控、还要处理时钟校正。Aurora协议就是把这些脏活累活打包好了你只需要配置几个参数就能拿到一个可用的高速数据通道。Aurora 64B/66B的核心优势有三个第一编码效率高64B/66B编码每66位只消耗2位开销有效带宽利用率能到97%左右第二延迟低协议本身很轻量没有复杂的握手和重传机制第三资源占用少相比PCIe或以太网MACAurora的LUT和BRAM消耗要小得多。但它的局限性也很明显只支持点对点不支持交换没有重传机制链路误码只能靠上层处理流控是简单的Ready/Valid握手没有拥塞控制。所以Aurora适合的场景是两块板子之间、或者两个芯片之间的确定性高速数据传输比如ADC/DAC数据回传、图像传输、板间互联等。2.2 关键参数选型线速率、位宽、接口类型打开IP核定制界面第一页就是核心参数配置。这里有几个关键选项需要仔细考虑线速率Line Rate的选择取决于你的GT收发器能力和PCB走线质量。Aurora 64B/66B支持从0.5Gbps到16.375Gbps的线速率范围具体上限取决于器件和速度等级。我一般会先确认GT的参考时钟频率然后反推线速率。比如参考时钟是156.25MHzGT的PLL倍频后能支持到10.3125Gbps那线速率就设10.3125Gbps。数据位宽Data Width决定了用户接口的吞吐能力。Aurora 64B/66B支持2字节和4字节两种位宽对应单条Lane。位宽越大用户逻辑的时钟频率可以越低。比如线速率10.3125Gbps64B/66B编码后有效数据率约10Gbps如果用4字节位宽用户时钟需要跑250MHz左右如果用2字节位宽用户时钟要跑500MHz。显然4字节位宽对时序收敛更友好。接口类型Interface有Framing和Streaming两种。Framing模式带CRC校验和流控适合可靠传输Streaming模式没有CRC延迟更低适合对延迟敏感但能容忍偶发误码的场景。我一般默认选Framing因为CRC校验能帮你快速定位链路问题。GT参考时钟选择也要注意Aurora IP核支持从GT的参考时钟或者从Init时钟分频得到。如果板子上有独立的GT参考时钟优先用独立的抖动性能更好。2.3 时钟架构别被init_clk和user_clk搞晕Aurora 64B/66B的时钟架构是新手最容易迷糊的地方。简单来说它有两个主要时钟域Init Clockinit_clk这是IP核内部逻辑的初始化时钟频率要求不高一般给50MHz到100MHz都行。它必须是自由运行的不能停。我一般直接用板子上的系统时钟比如100MHz差分晶振。User Clockuser_clk这是用户接口的同步时钟由GT的恢复时钟或参考时钟分频得到。所有用户侧的数据收发都跟这个时钟同步。user_clk的频率取决于线速率和位宽IP核会自动计算并显示出来。还有一个GT参考时钟gt_refclk这是给GT收发器用的频率和抖动要求都很严格。一般用专用的差分晶振比如156.25MHz或125MHz。这三个时钟的关系是gt_refclk驱动GT的PLL产生高速串行时钟init_clk驱动IP核的复位和初始化逻辑user_clk是从GT恢复出来的并行时钟驱动用户接口。实际连线时init_clk和gt_refclk通常来自不同的时钟源user_clk由IP核输出给用户逻辑。实操心得init_clk的频率不需要很精确但一定要稳定。我遇到过用了一个不稳定的分频时钟做init_clk结果IP核初始化偶尔失败查了好久才发现是时钟抖动太大。3. 手把手配置Aurora 64B/66B IP核3.1 新建IP核与基础参数设置在Vivado 2023.1里打开IP Catalog搜索“Aurora 64B/66B”双击打开定制界面。第一页是“Core Options”Lane Width选4字节如果GT支持的话Line Rate填你的目标线速率比如10.3125GT Refclk选你的参考时钟频率比如156.25MHzInit Clk选你的init时钟频率比如100MHzInterface选FramingFlow Control选None如果不需要流控或Native如果需要这里有个细节Line Rate和GT Refclk的比值决定了GT内部PLL的倍频系数。Vivado会自动计算并显示可用的线速率列表。如果填了一个不支持的线速率界面会变红提示。我一般会先点“Calculate”按钮让工具列出所有支持的线速率然后从中选一个最接近目标值的。3.2 GT Selection与引脚约束第二页是“GT Selection”这里要选具体的GT通道。如果你的板子有多个GT Bank要确认Aurora用的是哪个Bank的哪个Channel。选完之后Vivado会自动生成GT的引脚约束但这些约束需要你根据实际PCB走线修改。关键约束包括GT Refclk的引脚位置必须跟原理图一致GT TX/RX的差分对引脚必须跟原理图一致参考时钟的IBUFDS位置要跟Bank的时钟输入引脚对应我一般会先把原理图打开把GT Bank的参考时钟引脚和收发差分对引脚都标出来然后在XDC里逐个核对。这一步千万别偷懒引脚约束错了上板后链路根本起不来。3.3 共享逻辑与时钟配置第三页是“Shared Logic”这里要选IP核的共享逻辑放在哪里。如果是单个Aurora IP核选“Include Shared Logic in core”就行工具会把所有逻辑都放在IP核内部。如果多个IP核共享GT资源可以选“Include Shared Logic in example design”把共享逻辑放到外面。时钟配置方面IP核会自动生成时钟模块包括init_clk的缓冲、gt_refclk的IBUFDS、以及user_clk的输出。你需要在顶层把这些时钟正确连接。3.4 生成IP核与检查时钟频率配置完成后点“OK”生成IP核。生成过程中Vivado会计算所有时钟频率生成完成后可以在IP核的“Clocking”标签页看到详细的时钟报告。重点检查user_clk的频率是否符合预期init_clk的频率是否在允许范围内gt_refclk的频率是否跟你的晶振一致如果user_clk频率不对说明线速率或位宽设置有问题需要回去重新调整。4. 复位时序Aurora 64B/66B最容易被坑的地方4.1 复位信号的层次关系Aurora 64B/66B的复位逻辑比8B/10B复杂因为它涉及到GT的复位、IP核内部逻辑的复位、以及用户接口的复位。这几个复位信号有严格的时序要求顺序错了链路就起不来。主要复位信号有gt_resetGT收发器的复位高有效。这个信号必须保持足够长的时间让GT的PLL锁定。resetIP核内部逻辑的复位高有效。这个信号要在gt_reset释放后、GT的PLL锁定之后再释放。power_downGT的掉电控制一般不用接0就行。pma_initGT的PMA初始化一般跟gt_reset一起控制。4.2 完整复位时序图与阶段划分根据我的实际调试经验Aurora 64B/66B的复位过程可以分成四个阶段阶段一上电稳定期。板子上电后时钟芯片需要时间锁定GT参考时钟需要稳定。这个阶段一般持续几毫秒到几十毫秒取决于时钟芯片的锁定时间。在这个阶段gt_reset和reset都应该保持高电平。阶段二GT复位期。gt_reset拉高至少持续一段时间具体时间看GT手册一般是几百纳秒到几微秒然后拉低。拉低后GT开始锁定PLL这个过程需要时间一般几十微秒。在这个阶段reset继续保持高电平。阶段三IP核复位释放期。等GT的PLL锁定信号gt_pll_lock变高后再等一段时间一般几百个user_clk周期然后把reset拉低。reset拉低后IP核开始初始化包括通道绑定、对齐等。阶段四链路建立期。reset释放后IP核开始发送和接收对齐序列。等channel_up信号变高说明链路建立成功可以开始收发数据了。注意gt_pll_lock信号是GT输出的表示PLL已经锁定。这个信号必须等它稳定变高之后才能释放reset。我见过有人不等gt_pll_lock就直接释放reset结果链路时好时坏查了好久才发现是复位时序问题。4.3 复位时序的代码实现下面是我常用的复位状态机代码框架Verilog// 复位状态机 localparam IDLE 3d0; localparam GT_RESET 3d1; localparam WAIT_LOCK 3d2; localparam IP_RESET 3d3; localparam WAIT_UP 3d4; localparam READY 3d5; reg [2:0] state IDLE; reg [15:0] counter 0; always (posedge init_clk) begin case(state) IDLE: begin gt_reset 1b1; reset 1b1; if (counter 16hFFFF) begin counter 0; state GT_RESET; end else begin counter counter 1; end end GT_RESET: begin gt_reset 1b0; if (counter 16hFFFF) begin counter 0; state WAIT_LOCK; end else begin counter counter 1; end end WAIT_LOCK: begin if (gt_pll_lock) begin if (counter 16hFFFF) begin counter 0; state IP_RESET; end else begin counter counter 1; end end end IP_RESET: begin reset 1b0; state WAIT_UP; end WAIT_UP: begin if (channel_up) begin state READY; end end READY: begin // 正常收发数据 end endcase end这段代码的核心逻辑是先等上电稳定然后释放gt_reset等gt_pll_lock变高后再等一段时间然后释放reset最后等channel_up变高。每个阶段的等待时间可以根据实际情况调整。4.4 复位时序的仿真验证在仿真里验证复位时序我一般会写一个简单的testbench模拟gt_pll_lock和channel_up信号然后观察复位状态机的跳转。重点看几个点gt_reset释放后reset是否保持了足够长的时间gt_pll_lock变高后是否等了足够多的周期才释放resetchannel_up变高后状态机是否正确进入READY状态仿真通过后再上板实测。上板时可以用ILA抓复位状态机的状态和几个关键信号确认跟仿真一致。5. 常见问题与排查技巧实录5.1 链路起不来先查这几个地方Aurora 64B/66B链路起不来是最常见的问题排查思路可以按以下顺序第一步查时钟。用示波器或ILA确认gt_refclk、init_clk、user_clk都有信号频率正确。特别是gt_refclk抖动要小幅度要够。第二步查复位时序。用ILA抓gt_reset、reset、gt_pll_lock、channel_up的波形确认时序符合上面说的四个阶段。如果gt_pll_lock一直不变高说明GT的PLL没锁定可能是参考时钟有问题或GT配置不对。第三步查引脚约束。确认GT的收发差分对引脚跟原理图一致参考时钟引脚也一致。如果引脚错了GT根本收不到信号。第四步查线速率匹配。两端的线速率必须一致参考时钟频率也必须一致。如果一端是10.3125Gbps另一端是10Gbps链路肯定起不来。第五步查PCB走线。如果以上都没问题可能是PCB走线质量不行比如差分对阻抗不匹配、走线太长、过孔太多。这种情况需要硬件同事配合检查。5.2 常见问题速查表问题现象可能原因排查方法channel_up一直为低复位时序不对用ILA抓复位信号波形gt_pll_lock一直为低参考时钟有问题检查晶振和IBUFDS链路时好时坏复位释放时机不对确认等gt_pll_lock稳定后再释放reset误码率高PCB走线质量差检查差分阻抗和走线长度user_clk频率不对线速率或位宽设置错误重新计算线速率和位宽IP核初始化失败init_clk不稳定换一个稳定的时钟源5.3 独家避坑技巧技巧一init_clk不要用分频时钟。我试过用系统时钟分频得到init_clk结果IP核初始化偶尔失败。后来换成独立的100MHz晶振问题就没了。init_clk虽然频率要求不高但稳定性很重要。技巧二复位状态机的等待时间要留裕量。我一般会把每个阶段的等待时间设成理论值的2到3倍确保各种情况下都能稳定工作。比如GT PLL锁定理论需要50微秒我就等150微秒。技巧三上板前先用example design跑一遍。Aurora IP核自带example design里面包含了完整的复位逻辑和收发测试。我一般会先把example design跑通确认硬件没问题然后再替换成自己的逻辑。技巧四ILA抓波形时注意采样深度。复位过程可能持续几十微秒ILA的采样深度要够否则抓不到完整的复位过程。我一般会把采样深度设成至少8192采样时钟用init_clk。技巧五两端同时复位。如果两端是同一块板子上的两个FPGA最好让它们同时复位避免一端已经发数据另一端还没准备好。如果两端是不同板子可以通过外部信号同步复位。6. 仿真验证与上板调试的衔接6.1 仿真环境搭建要点Aurora 64B/66B的仿真需要GT模型Vivado自带的仿真库里有GT的behavioral模型。仿真时需要注意几点仿真时间要够长GT的PLL锁定在仿真里也需要时间一般要跑几百微秒才能看到channel_up变高。参考时钟要正确驱动仿真里gt_refclk要用差分时钟驱动频率跟实际一致。复位时序要跟实际一致仿真里的复位状态机应该跟实际上板用的完全一样这样才能保证仿真结果有参考价值。我一般会先跑IP核自带的example design仿真确认仿真环境没问题然后再替换成自己的逻辑。6.2 上板调试的ILA配置上板调试时ILA是必不可少的工具。我一般会抓以下几组信号复位相关gt_reset、reset、gt_pll_lock、channel_up时钟相关init_clk、user_clk可以用ILA的时钟域数据相关tx_data、rx_data、tx_valid、rx_validILA的采样时钟用init_clk因为复位过程主要在这个时钟域里。采样深度设成8192或更深确保能抓到完整的复位过程。6.3 从仿真到上板的差异处理仿真和上板最大的差异在于时钟和复位的实际行为。仿真里时钟是理想的上板后时钟有抖动、有偏斜仿真里复位是干净的上板后复位信号可能有毛刺。所以上板后如果链路起不来不要怀疑逻辑先查时钟和复位的实际波形。我一般会先用ILA确认时钟和复位都正常然后再看数据通路。如果时钟和复位都正常链路还是起不来那可能是GT配置或PCB走线的问题。7. 一些实际项目中的经验体会Aurora 64B/66B这个IP核说难也不难说简单也不简单。核心难点就两个时钟架构和复位时序。把这两个搞清楚了剩下的就是按部就班配置。我在实际项目里遇到过最坑的一个问题是两块板子单独测试都正常连在一起就起不来。查了好久才发现是两端的参考时钟频率虽然标称一样但实际有微小偏差导致GT的PLL锁定不稳定。后来换了更高精度的晶振问题就解决了。所以如果你的链路时好时坏不妨查查参考时钟的精度。还有一个经验是不要迷信手册上的复位时序图。手册上的图是理想情况实际调试时你需要根据ILA抓到的波形来调整。我一般会把复位状态机的每个阶段都加上可配置的计数器方便根据实际情况调整等待时间。最后分享一个小技巧如果你用的是Vivado 2023.1可以在IP核的“Clocking”标签页里直接看到所有时钟的频率和相位关系这个比手册上的时钟图直观多了。配置的时候多看看这个页面能帮你快速发现时钟配置的问题。