☰
FPGA光纤通信入门:Aurora IP核回环测试手把手实战指南
2026/10/7 22:46:52 网站建设 项目流程

干了这么多年FPGA,从第一次接触高速串行接口开始,光纤通信就是绕不开的坎。早年调GTX简直要命,每次上板都像开盲盒。后来把Xilinx的Aurora IP核吃透了,才算真正"不求人"。这篇就从最实用、最基础的数据回环测试入手,手把手带你把这个链路跑通。

回环测试,英文叫Loopback Test,做过高速接口的人都知道,这是验证一条物理链路能不能用的黄金标准。说白了就是发端送出去的数据,从另一端回到收端,然后把数据比对一下。能比对通过,证明你的时钟、复位、GT收发器、光模块、协议IP、用户逻辑这一整条链路全是通的。这篇文章针对完全没有接触过Aurora IP核、或者接过光纤但一直没跑通的新手,也适合想系统梳理Aurora调试思路的老手当速查手册。

1. Aurora IP核在FPGA光纤通信里的位置

1.1 从GTX/GTH串行收发器说起

要搞懂Aurora,先得知道它的地基是什么。Xilinx 7系列及以后的FPGA,内部都集成了一组高速串行收发器,系列不同叫法不同,Artix-7上叫GTX,Kintex-7上叫GTX或GTH,Virtex-7上有GTZ,UltraScale系列叫GTH/GTY。这些收发器才是真正负责把并行的用户数据变成高速差分串行比特流,再推出去的东西。

GTX收发器内部大致分两半:PMA和PCS。PMA是纯模拟部分,负责高速串行数据的收发,包括时钟恢复CDR、串并转换、差分驱动和接收。PCS是数字部分,负责编码、解码、弹性缓冲、通道绑定、时钟修正这些。我们用户平时写的逻辑不直接跟PMA打交道,都是交给PCS提供的接口去访问。问题在于PCS接口是并行数据,通常64位或32位宽,时钟频率跟线速率挂钩,直接用起来很费劲。

Aurora IP核干的事情,就是在GTX/GTH这类原生收发器之上,包一层统一的协议与用户接口。它把通道初始化、通道绑定、时钟修正、错误监测这些脏活累活全干了,然后向用户暴露一个干净的AXI4-Stream接口。用户逻辑只需要往这个接口写数据、从接口读数据,根本不用关心底层8B/10B编码、弹性缓冲里的时钟修正逻辑。这就是为什么我说Aurora是FPGA光纤通信入门的起点,它把高速链路从"芯片级调试"拉到了"逻辑级调试",心智负担降了一个量级。

1.2 Aurora协议:轻量级链路层的设计哲学

Aurora协议本身是Xilinx定义的开放链路层协议,专门为了FPGA之间或FPGA与ASIC之间的点到点高速通信设计的。它不搞PCIe那套复杂的枚举和配置机制,也不像Ethernet要照顾各种拓扑和碰撞检测,它就是一个纯粹的轻量级点对点协议。你打开Aurora 8B/10B的PG046文档,会看到整个协议的核心就是:把用户数据流组织成帧(Framing模式)或连续流(Streaming模式),加上极少量的控制字符,然后交给GTX处理。

8B/10B编码是这里的关键配角。每个字节在传输前会被编码成10比特,保证串行数据流的直流平衡和足够多的跳变沿,这样接收端才能从数据里恢复时钟。代价是20%的带宽开销,也就是说6.25Gbps的线速率,实际用户可用带宽是5Gbps。Aurora 8B/10B的另一个机制是通道绑定(Channel Bonding),当你用多条lane并行传输时,接收端必须把分散在多个收发器里的数据重新对齐,Aurora IP会用特殊字符序列在初始化阶段完成这个操作,用户感知不到。

这就是Aurora的设计哲学:最快的速度、最小的开销、最低的实现复杂度,代价是牺牲通用性。它不关心你传的是以太网包还是PCIe TLP,它只保证你的字节流从A点无损地到B点。这正好迎合了FPGA开发者的核心诉求——很多场景就是两片FPGA之间要传数据,Aurora是最直接的答案。

1.3 回环测试为什么是首选验证手段

回环测试在地理上分两种:片内回环(Loopback)和片外回环。片内回环是利用GT收发器自带的回环模式,发送端的数据经过PMA和PCS在芯片内部回到接收端;片外回环是把你自己的TX引脚用光纤跳线或同轴线接到自己的RX引脚,数据真正通过物理介质走了一趟。不管是哪种,逻辑上的效果一样:发端写进去的数据,收端能原样读出来。

回环测试的价值在于它把整条链路的验证工作拆成了一个最干净、最可判定的闭环。没有对端设备、没有时序同步问题、没有应用层协议协商问题,你只需要在发端注入有规律的数据(比如线性递增计数),在收端比对就行。能跑通回环,至少说明你的IP配置、参考时钟、复位策略、用户接口逻辑全部正确。之后再去对接真实的远端设备,定位问题就简单得多。我在实际项目中,不管接到什么新板卡,第一件事永远是做回环测试,把硬件和底层链路验到确定性正确,再往上垒业务逻辑。

2. 搭建回环测试环境:硬件准备与IP参数配置

2.1 硬件选型:开发板、光模块、光纤跳线

先说板卡。做Aurora回环测试,任何带GTX/GTH收发器和SFP+接口的FPGA开发板都行。Xilinx官方的VC707、KC705、AC701常见,国内黑金、正点原子、米联客的A7开发板也几乎都留了SFP+接口。我自己常用的是Artix-7系列的板子,GTX线速率最高支持6.6Gbps,跑Aurora 8B/10B完全够用,而且A7功耗低、开发成本也低,很适合练手。

光模块和光纤非常重要,很多新手在这上面踩坑。SFP+封装的光模块分多模和单模两种,多模模块波长850nm,配OM3/OM4多模光纤跳线,特点是便宜,适合短距离(几百米内);单模模块波长1310nm或1550nm,配单模光纤跳线,适合长距离传输。回环测试直接用一根短跳线,把SFP+模块的TX和RX两个口连起来就行。很多SFP+模块自带两个LC接口,一根双工LC跳线插进去就完成了TX到RX的回环,非常简单。要注意的是,别把光模块的TX Disable引脚拉到高电平,否则激光器不发光,链路起不来。

如果你手上没有光模块,退一步也可以用SMA转接线做电口回环。把GTX的TX差分对和RX差分对通过SMA线直接连起来,绕开光模块,也能验证GT收发器本身。但最终还是要过光模块的,因为光电转换、信号幅度整形这些环节是电口回环覆盖不到的。我推荐有条件就直接上光纤回环,一步到位。

2.2 参考时钟:整个链路的命门

高速串行链路里,参考时钟的质量直接决定链路能不能稳定跑起来。Aurora IP核需要的时钟只有两个,但缺一不可:一个是GT参考时钟(GT RefClk),另一个是初始化时钟(INIT_CLK)。GT参考时钟从FPGA专用引脚进入GT Quad,必须是一个干净的差分时钟源,板子上通常由可编程晶振(比如SI570)或固定晶振提供。Aurora配置界面里会让你填参考时钟频率,这个值必须跟板上实际的晶振频率严格一致,否则GT的PLL锁不住或者输出频率不对。

GT参考时钟频率跟线速率之间是倍数关系,具体算法跟用的是QPLL还是CPLL有关。拿常见的Aurora 8B/10B来说,线速率6.6Gbps,参考时钟150MHz,QPLL倍频44倍,关系一一对应。线速率3.125Gbps,参考时钟312.5MHz或125MHz都可能,取决于倍频设置。所以配置IP之前,先打开你的板卡原理图,看清楚SFP+对应的GT Quad接的是哪个晶振、频率多少,把这个数值填对,这一半的坑就躲过去了。参考时钟的抖动指标也很重要,最好用低抖动振荡器,FPGA的专用参考时钟引脚通常已经做了阻抗匹配和隔离,不要接到普通IO上。

初始化时钟INIT_CLK是另外一个50MHz或100MHz的普通时钟,给IP核内部初始化状态机用的,频率不需要很严格,50MHz最常见。有的板子直接用系统时钟分频得到,也有的独立晶振,问题不大。

2.3 在Vivado中创建Aurora 8B/10B IP核

打开Vivado,创建工程,在IP Catalog里搜索"aurora",会看到几个结果:Aurora 8B/10B、Aurora 64B/66B。我们这里用8B/10B,应用最广泛,拓扑也最简单。双击打开配置界面,关键参数我逐个说。

第一个配置页面是Core Options,选择线路速率(Line Rate)、参考时钟(GT Refclk)、通道数(Lanes)、数据流模式(Dataflow Mode)。通道数选1就够回环测试用,多通道绑定对新手来说复杂且没有必要。数据流模式选Duplex(双向),这样既能发也能收。接下来是用户接口配置,接口模式选Framing或Streaming都行,回环测试建议用Streaming,流模式不需要关心帧边界,省去很多麻烦。如果有Flow Control选项,先关掉,回环测试用不上。

穿行到后续配置页,留意GT Type(是GTX还是GTH),这个由FPGA型号自动决定,一般不用动。另一个重要的选项是GT Loopback,如果勾选了,在IP运行时可以通过动态寄存器把GTX配置成内部回环模式,后续做对比调试非常方便。还有一个Filtered Violation和Mirror Violation端口,是用来上报接收错误的,保持默认即可。配置完成后点Generate,等待IP生成。

这一步我额外啰嗦一句:如果配置完成后还有"Add IP to Block Design"之类的提示,别急着拖到Block Design里,Aurora IP核最好在HDL顶层里直接例化,调试信号看得清楚。生成之后右键IP核,选择Open IP Example Design,这一步后面在仿真章节里会详细展开。

3. 手把手实现数据回环测试:从仿真到上板

3.1 先跑example design仿真,别急着写自己的代码

很多新手拿到IP核第一件事就是自己写顶层逻辑,结果一片乱麻。正确做法是先看example design。右键Aurora IP核,选Open IP Example Design,Vivado会自动创建一个新工程,里面包含了该IP的完整例化、GT初始化逻辑、时钟生成模块、以及一个自带自检功能的testbench。

这个example design的仿真非常值得仔细跑一遍。在Vivado的Flow Navigator里点Run Simulation,选Behavioral,程序会自动跑一会儿。仿真是自动的,example design里的frame_gen模块会往Aurora发送递增数据,frame_check模块会比对接收端数据。如果一切正常,仿真消息框里会有"Data check completed successfully"之类的提示。这个过程能帮你确认两件事:一是IP配置本身没问题,二是Aurora协议在内部自检回环下能完整工作。

仿真是调试高速接口最省时间的手段。上板之前,所有逻辑错误都在仿真里修复,去现场就只是验证时钟和硬件了。我在多个项目里的习惯是:example design仿真通过之后,再基于它的顶层结构去改自己的用户逻辑,而不是自己从零搭。原因很简单,example design里包含了GT参考时钟的IBUFDS_GTE2原语、初始化状态机、复位同步器、时钟修正等一堆底层细节,你自己重写很容易漏东西,而且出的错还特别难查。

3.2 改造顶层逻辑:AXI4-Stream接口的发与收

example design的顶层模块通常叫aurora_8b10b_exdes或类似的名字,里面例化了支持模块(support)和IP核。它已经有了一个完整的用户逻辑demo,我们要做的是替换掉它自带的frame_gen/frame_check,换成自己的、更可控的数据生成和比对逻辑。

Aurora IP核暴露给用户的接口就是AXI4-Stream,收发各一组。发送端信号是s_axi_tx_tdata、s_axi_tx_tvalid、s_axi_tx_tready、s_axi_tx_tlast、s_axi_tx_tkeep,接收端对应m_axi_rx_tdata、m_axi_rx_tvalid一类的。使用逻辑上,发送侧要等tvalid和tready同时拉高才说明一拍数据真正被送出去了;接收侧看到tvalid拉高,就表示这拍tdata上的数据有效,直接采样就行。

最经典的回环用户逻辑是这样:一个计数器从0开始,每个user_clk周期自增;当channel_up拉高且发送FIFO不忙时,把计数值放到s_axi_tx_tdata上,同时拉高tvalid;接收侧,每当m_axi_rx_tvalid拉高,就读取tdata,跟预期的下一个计数值比对,不一致就错误计数加1。这里有个容易忽略的细节:接收端的时钟跟发送端虽然是同一个user_clk,但数据从发送到接收经过了FPGA内部回环或者外部光纤,延迟是不确定的,所以比对的时候不要死板地期待"当前拍的接收数据等于当前拍的发送数据",而是用一个独立的期望计数器,每收到一个有效数据就加1,跟收到的数据比对。这样才能正确应对链路延迟。

我在实际项目中喜欢在用户逻辑里加两个LED输出:一个link_ok,channel_up和gt_pll_lock同时为高时点亮;一个data_error,比对出错就点亮并保持。上板时瞄一眼LED状态,链路好坏一目了然,甚至不用开ILA。这个习惯帮我省了大量跟硬件工程师扯皮的时间。

3.3 约束文件与综合上板流程

仿真通过后,综合上板。example design自带一个约束文件,在工程的constrs目录里有xdc文件,它会定义GT参考时钟引脚、初始化时钟引脚、复位按键、LED等。这些引脚约束是厂商demo板的,跟你的实际板卡不一定一样,必须打开原理图,逐个改成实际引脚。

时钟约束是重点。在xdc里找到参考时钟的create_clock语句,确认周期对应晶振实际频率。比如150MHz时钟,约束写成create_clock -name ref_clk -period 6.667 [get_ports GT_REFCLK_P]。初始化时钟类似,50MHz就是period 20.0。引脚约束用set_property -dict {PACKAGE_PIN xx IOSTANDARD LVDS} [get_ports GT_REFCLK_P]这样的格式,把原理图上的网络名和引脚一一对应。GT差分输入和输出引脚也要约束。光模块的SFP+接口通常还有modsel、los、tx_disable这些控制脚,这些不是GT高速信号,是普通IO,也要适当约束。

上板前还有一步容易被忽略:确认SFP+模块的电源和初始化。有些SFP+模块上电后需要一定时间建立激光器和CDR,如果你的复位逻辑一上电就立刻去拉链路,可能初始化冲突。Aurora example design里有复位延时逻辑,但依然建议在用户逻辑里保证:给光模块的tx_disable引脚一个上电后的低电平延迟,等电源稳定了再使能。这部分可以用一个简单的计数器延时实现,比如延时10ms。

综合、实现、生成比特流,烧录进去。如果一切顺利,你会看到LED显示link_ok亮起,然后data_error保持熄灭,data_valid计数不断递增。到了这一步,恭喜,Aurora光纤回环正式跑通了。

3.4 三类回环方式的实测体验对比

回环测试不是只能用一种方式做。我在同一个板子上把三种方式都试过,它们的差异很有参考价值。

第一种是GT内部回环。在example design或者你自己的逻辑里,把Aurora IP核的GT Loopback端口拉高,数据在GT的PMA层就打转了,不经过任何引脚。这种回环验证的是Aurora协议逻辑,即使板卡上没有插光模块也能跑。好处是调试完全隔离了硬件,快速验证FPGA工程没毛病;坏处是它掩盖了引脚、PCB、光模块上的问题。

第二种是外部电口回环。把GTX的TX差分对和RX差分对用SMA短线连起来,走一遍PCB和芯片封装,但不经过光模块。这种回环验证了PCB走线和GT收发器本身的信号完整性,连接器、SMA线缆、匹配电阻都测到了。

第三种是外界光纤回环,也是最终形态。光模块插到SFP+,光纤跳线把TX和RX连起来,整个光电链路都参与进来。这种回环能发现光模块速率不匹配、光纤插反、光功率不足等问题。

我的测试策略是:先跑Aurora内部回环确认IP配置正常,然后跑外部光纤回环验证完整链路。如果光纤回环失败,再退到电口回环去二分定位是光模块的问题还是GT收发器的问题。这个顺序能最大程度减少变量,避免来回烧板子。

4. 常见问题排查实录与经验总结

4.1 常见故障速查表

做Aurora回环测试,遇到的绝大多数问题都可以归到三个层面:时钟复位问题、GT链路问题、用户逻辑问题。我把自己踩过的坑汇总成下面这张速查表,基本覆盖了新手能遇到的大部分情况:

现象常见原因排查手段
gt_pll_lock一直为低GT参考时钟没进来或频率不对示波器测参考时钟引脚,核对频率与IP配置是否一致
channel_up一直为低,但pll_lock正常复位没释放、光纤没接好、光模块不发光检查光模块tx_disable电平,检查TX/RX是否接线
光纤回环失败,但内部回环通过光模块速率超出范围或光纤类型不匹配换速率匹配的模块和正确的光纤跳线
数据比对错误但LED没灭你的user逻辑期望计数器不同步改用收到的数据本身做自校验,或者重置期望计数器
上板后user_clk频率不对user_clk是从GT时钟分频得到,跟线速率相关查看IP里的时钟输出频率,确保用户逻辑时序满足
仿真正常但上板完全不通引脚约束缺失或不匹配打开xdc核对每个引脚约束,检查时序约束是否完整

这张表的顺序是按排查优先级排的,自上而下检查一遍,大部分问题都能定位。

4.2 复位时序:channel_up拉不高的头号元凶

很多人的Aurora起不来,问题不在IP配置,而在复位时序。Aurora IP核有一个异步复位的输入端,通常命名为reset_n或RESET_N,低电平有效。example design里会在support模块中做一个复位同步和释放逻辑,但如果你自己例化IP,要格外小心这个复位。我见过有人在顶层逻辑里用了一个几十毫秒的低电平脉冲去复位,结果刚好把Aurora初始化状态机打断,链路永远起不来。

正确的复位时序应该是:上电后,INIT_CLK稳定后,复位至少保持几个时钟周期,然后释放,之后不要再动它。Aurora内部有自己的上电初始化流程,一整套走完(包括GT PLL锁定、通道绑定、初始化)才把channel_up拉高。如果用户复位的时机恰好落在GT初始化中途,IP核会一直等复位释放,甚至可能反复触发错误状态,导致channel_up永远为低。处理方式是给复位信号增加上电延迟逻辑,一般用INIT_CLK驱动的计数器延时50ms再释放复位。

GT初始化还有个容易被忽略的点:如果光模块没有插好或者模块的速率不匹配,GT的CDR可能无法锁定到有效数据流,channel_up同样拉不高。这种情况别急着改代码,先检查光模块是否正常发光,可以拿光功率计测一下,或者用手机摄像头看SFP+接口里有没有红光(注意激光安全,不要直视),一般多模模块工作时能明显看到暗红色光。

4.3 调试三板斧:ILA、示波器和日志输出

调试Aurora链路,我用得最多的就是ILA(Integrated Logic Analyzer)这个集成逻辑分析仪。在Vivado里把channel_up、gt_pll_lock、user_clk、s_axi_tx_tvalid、s_axi_tx_tready、m_axi_rx_tvalid、错误计数这些信号Mark Debug,综合实现后打开硬件管理器,就能实时观察链路状态。特别是回环测试中,如果tready一直拉不高,说明发送通道没准备好,再回溯去看状态寄存器,往往能找到原因。

示波器主要用于验证参考时钟。如果你是第一次在一块板子上调GT,上电后先别急着烧比特流,用示波器探头测一下GT参考时钟引脚的差分信号,确认有干净的正弦波、频率与设计一致。如果这里就是乱的,后面所有问题都白查。有条件的实验室可以看眼图(Eye Diagram),没有条件也一样能调通,别被高级仪器唬住。

最后一个我个人的土办法:在用户逻辑里放一个错误统计计数器,通过UART或者虚拟IO(VIO)把错误数实时读出来。数据比对错误并不总是致命的,有时候链路抖动导致偶发误码,计数器能看出来是0还是蹭蹭往上跳。偶尔的误码可能是信号完整性问题,持续大量的错误基本就是链路没通。这个思路也顺带给你做了长期监测,比只看一个LED直观多了。

5. 几点经验之谈

回环测试跑通之后,整个Aurora链路就算拿下了。但作为过来人,我再分享几条掏心窝的经验。

第一,永远不要在没跑仿真的时候就直接上板。Aurora IP核的example design自带自检仿真,不花你一分钱,就是几秒钟的等待时间。仿真过了再上板,能帮你砍掉一半的排查成本。第二,光模块和光纤是整个链路里最容易被忽略的硬件变量,有问题先换模块试,一对便宜的模块才是最好的排查工具。第三,一旦板卡上的SFP+速率支持不了你配置的线速率,IP核会一直处于复位状态,所以选板子之前一定要确认SFP+接口能跑多快,光模块的速率等级要和线速率匹配。最后,回环测试通过只是起点,后面接真实设备时还要处理对端的链路协商、协议对齐、背压等问题,但有了回环测试打底,你已经可以把问题范围缩小到对方设备了。

我最初调Aurora的时候,光是在复位和时钟上就卡了整整两天,当时的体会是"这东西真难伺候"。但当你真正理解它的结构,按照先仿真、再内部回环、再外部回环的顺序步步为营,你会发现Aurora其实是FPGA高速接口里最温柔的一款。希望这篇能帮你少走些弯路,让光纤通信这件事真正"不求人"。

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

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

立即咨询