先把话说在前面:Aurora 8B/10B这IP核,说简单也简单,说复杂也真能把人绕晕。简单在于它本身是个轻量级串行协议,不牵扯PCIe那套复杂的事务层,也不用像以太网那样处理各种协商机制;复杂在于它毕竟跑在GTX/GTH高速收发器上,一旦涉及复位时序、时钟修正、通道绑定、用户接口握手,任何一个环节没伺候好,板子上就是死活link不上。我见过太多人卡在channel_up起不来这一步,也见过不少人仿真全过、上板就白屏,最后查出来是复位释放顺序有问题。这篇东西我尽量按自己的实际项目经历来写,从IP配置讲到仿真验证,把容易踩的坑都摊开来说。
1. 先搞懂Aurora 8B/10B到底解决什么问题
Aurora 8B/10B是Xilinx提供的一个轻量级高速串行通信协议,跑在FPGA内部的GTX/GTH/GTY等高速收发器上。它不规定上层业务格式,只负责把你要传的数据可靠地从A点搬到B点,有点类似于搬家公司的角色——你只管把东西打包好交给它,它负责运过去,中间走高速还是走小路你不用操心。
这句话听起来简单,但背后隐藏了几个关键设计点,值得展开聊一下。
1.1 为什么选8B/10B编码而不是别的
8B/10B编码的核心思想是把8比特数据映射成10比特码字,多出来的2比特用于保证DC平衡和提供足够的跳变沿。DC平衡的意思是码字里0和1的数量尽量相等,避免信号长时间保持同一电平,这对交流耦合的高速链路是必须的。足够的跳变沿则方便接收端从数据流里恢复出时钟。
类比一下:你坐高铁,8B/10B编码相当于每隔一段距离就设一个里程标,列车员能随时知道自己跑到哪了。接收端不需要单独的时钟线,直接从数据里“提取”时钟,省掉了一根线,换来的是更高的设计复杂度。这套机制在10Gbps以下的速率里非常成熟稳定,所以Aurora 8B/10B至今仍在大量项目里服役,尤其是那些不需要跑到10Gbps以上、但又不想碰复杂协议的场景。
1.2 Aurora协议层的三个核心机制
编码解决的是物理层的事,而Aurora协议本身还定义了几个数据链路层的机制,这部分才是设计者真正需要关心的。
第一个是时钟修正。两个FPGA之间通信,即使标称速率相同,实际晶振频偏也不可能完全一致。时间一长,接收端的FIFO就会溢出或读空。Aurora的处理方式是周期性发送时钟修正序列,接收端检测到之后调整FIFO的读写指针,把频偏带来的误差消化掉。这个机制不需要用户干预,但如果你在仿真里刻意制造频偏,就能观察到Clock Correction事件的发生,这在上板调试时非常有用。
第二个是通道绑定。如果你用多条lane并行传输,由于每条lane的物理延迟不同,数据到达接收端的时刻会有差异。Aurora通过通道绑定序列来对齐所有lane,绑定完成后数据才能在用户接口上以正确的顺序呈现。这个机制在多lane场景下是必须的,但也会引入一个副作用:只要有一条lane的通道绑定失败,整条链路就起不来,channel_up信号会一直保持低电平。
第三个是关键码字管理。Aurora在数据流中插入特定K字符来标志帧边界、空闲状态、时钟修正序列等。K字符不参与业务数据传输,接收端靠识别这些K字符来维持链路状态机。这个机制解释了为什么Aurora用户接口的tlast、tvalid在某些时序下必须严格遵守规范——因为IP核内部是靠K字符位置来判断帧边界的。
1.3 Aurora 8B/10B和Aurora 64B/66B的区别
新手经常混淆这两个IP。简单说,8B/10B版本跑得慢但逻辑简单、延迟低,适合板间中短距离传输;64B/66B版本效率更高、支持更高速率,但IP核配置更复杂,对参考时钟和PCB的要求也更苛刻。8B/10B支持的线速率上限受限于GTX本身,7系列大概在6.6Gbps左右,UltraScale+上配GTH可以到更高。如果只是板内或短距离板间传输几Gbps的数据,Aurora 8B/10B是性价比很高的选择——它不像PCIe那样需要枚举和驱动,也不像以太网那样需要MAC和地址解析,本质上就是一根“高速管道”。
2. IP核配置:每个参数都不是白设的
很多人拿到Aurora IP核,看着图形化界面里的选项一头雾水,随便选几个参数就Generate,结果仿真或上板一堆问题。这里我把关键配置项逐个拆开讲,并结合实际项目经验给出推荐值。
2.1 线速率、参考时钟与GT位置
这三个参数是联动的,必须一起看。
线速率是你要跑的链路速率,比如3.125Gbps、5Gbps、6.6Gbps等。参考时钟频率则取决于GTX/GTH的PLL配置。以7系列GTX为例,参考时钟通常选择100MHz、125MHz或156.25MHz,IP核会根据线速率自动计算PLL的倍频系数。这里有个基本原则:参考时钟的质量直接决定了抖动性能,最好使用板载专用时钟芯片输出的差分时钟,不要从普通IO引脚拉个单端时钟凑合。
GT位置的选择容易被忽略。Aurora IP核会要求你指定使用哪个Quad(GTX Bank),不同的Bank对应的参考时钟引脚不同。如果同一Bank已有其他高速IP占用,或者参考时钟引脚被复用,就会产生冲突。我遇到过的情况是:工程里同时用了Aurora和PCIe,两者都想要同一Quad的参考时钟,结果Aurora一直锁不住PLL,最后把Aurora挪到另一个Quad才解决。
这里给一个经验值:如果线速率≤5Gbps,优先选100MHz参考时钟;如果线速率在5~6.6Gbps之间,125MHz或156.25MHz更容易满足时序收敛。具体数值以IP核生成后的Report为准,它会明确告诉你推荐的参考时钟频率。
2.2 流模式还是帧模式
Aurora 8B/10B的Native接口提供两种模式:流模式(Streaming)和帧模式(Framing)。
流模式下,数据像水管里的水一样连续流动,没有帧边界的概念,收发双方靠tvalid/tready握手持续传输。这种模式适合传输连续的数据流,比如ADC采样数据、视频流等。缺点是如果链路中断,重新同步后数据边界就丢了,需要上层协议自己处理。
帧模式下,每个传输单位是帧,接口上有s_axi_tx_tlast信号来标志帧结束。IP核会自动在帧间插入空闲周期,接收端则通过检测帧起始和结束来恢复数据边界。帧模式适合传输离散的数据包,比如以太网帧、自定义命令包等。它的好处是链路重同步后帧边界依然能恢复,代价是多了一点带宽开销。
实际项目中我90%的情况都选帧模式,哪怕传连续数据也会人为切帧。原因很简单:调试方便。帧模式下你能清楚地看到tlast的位置,用ILA抓波形时能快速定位数据边界在哪;流模式下如果出了错,你都不知道从哪个比特开始重新对齐。
注意:帧模式下s_axi_tx_tlast必须在一个周期内拉高并同时s_axi_tx_tvalid有效,否则IP核内部状态机会错乱。这个细节在仿真里不容易暴露,但上板后会导致帧错位,后面调试会发现数据全对但边界总是偏的。
2.3 用户接口数据宽度
Aurora 8B/10B的用户接口宽度与线速率和用户时钟频率相关。公式很简单:用户数据宽度 = 线速率 / 用户时钟频率 × 8 / 1000。举例:线速率5Gbps,用户时钟100MHz,则用户数据宽度为5 × 1000 × 8 / 100 / 1000 = 40比特?不对,这里容易算错,我重新说。
正确的计算方式是:用户时钟频率 = 线速率 × 用户接口宽度系数 / 8。Aurora 8B/10B IP核的固定关系是用户时钟频率 = 线速率 / (用户数据宽度 × 10 / 8) ——换句话说,线速率是10比特编码后的速率,有效数据速率是8/10,用户数据宽度乘以用户时钟频率等于有效数据速率。
举一个实际例子。我要跑5Gbps,GTX的线速率是5Gbps(注意这是编码后的速率),有效数据速率是5 × 8 / 10 = 4Gbps = 4000Mbps。如果用户数据宽度选32比特,则用户时钟频率 = 4000 / 32 = 125MHz。如果选64比特,则用户时钟 = 62.5MHz。
这个参数没有绝对的好坏之分。窄接口配高时钟,逻辑时序压力大但资源占用少;宽接口配低时钟,时序容易收敛但内部布线压力大。我的建议是:先用默认值,也就是IP核根据线速率自动推荐的宽度,我实际项目里5Gbps的Aurora通常配32位@125MHz,时序很容易收敛,逻辑端也不至于太多信号,调试的时候一眼能看清数据。
2.4 复位与时钟模块相关配置
Aurora IP核内部的复位逻辑非常关键。IP核会输出gt_reset(复位GT)、reset(复位用户逻辑)和power_down信号。这几个信号在Example Design里是连在一起的,但实际项目中必须仔细设计它们的时序关系。
核心原则有两条:一是GT的复位必须在参考时钟稳定之后释放;二是用户逻辑的复位必须在Channel Up之后释放。如果违反这两条,可能出现GT PLL锁上了但通道起不来、或者用户逻辑已经开始发数据但链路还没同步的情况。
我在Example Design里见过一个常见做法:用MMCM锁定信号和GT TX/RX复位完成信号做级联,形成复位链。这个做法是对的,但很多新手抄过来之后没理解为什么要用两级同步器处理异步复位,结果在仿真里直接拉高复位释放,造成亚稳态隐患。板上不一定出问题,但出了就是偶发、难复现的问题,非常棘手。
2.5 其他重要配置项
- AXI4-Stream接口:现代Vivado版本里,Aurora原生接口推荐使用AXI4-Stream封装,方便和FIFO、DMA等IP对接。建议直接选AXI4-Stream,省去自己转换的麻烦。
- 流量控制:如果你需要接收端反压发送端,可以启用用户流量控制。但这个机制会引入额外的握手延迟,纯数据传输场景下建议关掉,用自己设计的FIFO反压机制更可控。
- 线路速率自动协商:Aurora 8B/10B不支持自动协商,两端必须固定在同一速率。注意别跟Aurora 64B/66B的自动协商混淆。
- scrambler/descrambler:8B/10B版本不需要握手扰码器,64B/66B版本才有这个选项,别选错。
3. 层次化设计:从GT到用户接口的信号全景
Aurora 8B/10B的IP核内部结构可以理解为三层:GT层、Aurora协议层、用户接口层。理解这三层分别负责什么,对上板调试大有帮助。
3.1 GT层:物理收发通道
GT层就是Xilinx的高速收发器硬核,包括PMA和PCS子层。PMA负责模拟前端,比如差分信号的收发、时钟恢复;PCS负责数字处理,比如8B/10B编解码、弹性缓冲、时钟修正等。Aurora IP核例化了一组GT,并自动完成了这些配置。
GT层有几个信号对用户是暴露的,分别是gt_rxp_in/gt_rxn_in(接收差分对)、gt_txp_out/gt_txn_out(发送差分对)、gt_refclk_p/n(参考时钟)。这些信号在顶层连接时要注意:如果Aurora IP核不是直接放在顶层,差分引脚穿过中间层时需要使用缓冲或直连逻辑,不能随便打一拍——高速信号不进寄存器,这是铁律。
3.2 Aurora协议层:链路管理与通道对齐
这一层由IP核内部状态机实现,对用户是透明的,但它的运行状态会体现在几个关键信号上,典型的就是channel_up和lane_up。
lane_up表示单条lane的物理层已经同步,channel_up表示所有lane都已完成绑定和对齐,是整条Aurora链路可用的标志。上板调试时,这两个信号就是你的“生命线”:如果lane_up没起来,说明物理层有问题;如果lane_up起来了但channel_up没起来,说明通道绑定失败,大概率是两条lane的延迟差异过大或时钟修正行为异常。
3.3 用户接口层:跟你的业务逻辑打交道
在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、m_axi_rx_tlast、m_axi_rx_tkeep等。理解tready和tvalid的握手时序是使用这套接口的基础。
AXI4-Stream的握手规则是:只有当tvalid和tready同时为高时,这一拍的数据才被真正传输。发送端不能依赖tready为高时才开始驱动tdata,必须保证在tvalid拉高期间tdata保持稳定。接收端看到tvalid拉高时可以拉高tready表示接受,也可以暂时不拉高实现反压。
很多第一次接触AXI4-Stream的人会踩一个坑:在tready没拉高时就把tvalid置高了,数据也放在了总线上,但下一拍tready拉高时数据已经变了,导致传输的数据错误。正确做法是把数据锁存到寄存器,等到tready有效的那一拍再把寄存器的值输出到总线上,或者干脆让数据源一直保持有效直到握手完成。
注意:Aurora IP核的tready在通道未建立时是拉低的,所以用户逻辑必须等待channel_up后再开始发送数据,否则数据会一直堆积在FIFO里,倒不会丢,但会引入较大的延迟。
4. 实战仿真:搭建Aurora回环测试平台
仿真这一步我是强烈建议新手不要跳过的。虽然Aurora的Example Design自带仿真环境,但那只是验证IP核本身的功能,你自己的用户逻辑是否正确、数据通路是否通畅、跨时钟域处理是否可靠,这些都需要自己在仿真里验证。我自己的做法是:拿到新板子的第一步,永远是先把Example Design的仿真跑通,然后改成回环模式,最后再接入自己的逻辑。
4.1 用Example Design快速起步
在Vivado里生成Aurora 8B/10B IP核后,可以在IP核配置界面直接点击Open IP Example Design,Vivado会自动生成一个完整的测试工程,包含顶层模块、GT例化、复位逻辑、ILA调试核和仿真测试平台。这个Example Design是官方验证过的,理论上直接综合、上板就能link,跑板级回环没问题。它的价值在于给你一个“已知能跑”的参考,后续出了问题可以对比查找。
仿真这个Example Design需要注意的是:GTX的仿真模型非常消耗仿真时间,尤其是7系列GTX,simulation速度极慢。我一般用Vivado自带的xsim,配合Example Design自带的仿真脚本,在综合之前的behavioral simulation阶段跑,速度还能接受。如果需要跑大量数据的长时间仿真,建议把GT模型替换成简化的线缆模型,或者直接缩短时钟修正周期,这需要修改IP核内部的参数,操作起来比较繁琐,不如老老实实跑behavioral sim。
4.2 搭建自己的回环测试bench
我的标准做法是例化两个Aurora IP核,一个作为Master,一个作为Slave,中间用线缆模型连接,让Master发送的数据经过Slave回环后由Master接收。这样做的原因是真正上板时经常是两个FPGA或一块FPGA的两个Bank互相通信,按这种方式仿真最接近真实场景。
Testbench的激励逻辑分三步走:
第一步,产生复位:上电后拉高复位信号,等待至少几个微秒后释放。复位释放时机必须在参考时钟稳定之后,可以借助MMCM locked信号来同步。
第二步,等待channel_up:持续监测两个IP核的channel_up信号,直到它们都拉高后开始发送数据。仿真里这个等待时间取决于GT模型的锁定时间,通常几微秒到几十微秒不等,需要耐心等。
第三步,发送测试数据:可以是一个简单的计数器、一组递增数据、或者伪随机序列。用计数器最直观,看到接收端按顺序收到0、1、2、3就能判断链路通了;伪随机序列则能检查是否有比特翻转。
4.3 仿真波形里看什么
跑完仿真后,重点观察以下几处波形。
第一处是复位释放后gt_reset_done信号是否拉高。如果这个信号一直为低,说明GT复位没完成,检查复位时序或参考时钟。
第二处是lane_up和channel_up的上升沿。正常情况下两者会在复位释放后几百纳秒内依次拉高。如果lane_up拉高后channel_up迟迟不来,那就是通道绑定失败,检查多lane时两端的GT位置是否对称、时钟修正序列是否正确插入。
第三处是发送端和接收端的数据是否一致。可以在Master发送前在数据里嵌入一个特征值,比如在帧的第一个beat放0x5A5A5A5A,接收端检测到这个值就拉高一个标志信号,波形上一目了然。
4.4 仿真中容易踩的坑
第一个常见坑是:仿真时tdata宽度和实际配置不一致。如果你把用户接口改成64比特,但testbench里还按32比特构造数据,波形上看当然全错。建议始终从IP核生成的例化模板里复制接口定义,不要手敲。
第二个坑是:试图在channel_up拉高之前就给Aurora IP核发送数据。有些新手的testbench在复位释放后立刻拉高tvalid,由于AXI4-Stream的缓冲特性,数据不会丢失,但接收端在链路建立前收到的数据全是无效的,会导致第一个帧的边界错误,然后整个仿真数据对不上。正确做法是等channel_up后再开始发数据。
第三个坑是:没有考虑时钟修正和通道绑定的周期性行为,在仿真波形里看到链路偶尔出现“空闲插入”就以为出错了。其实那是IP核正常的时钟修正操作——接收端的tvalid会在这些周期拉低,属于预期行为,不应当作错误处理。
5. 上板调试:那些仿真永远发现不了的问题
仿真跑通了,综合、布局布线、生成bitstream,信心满满地把程序下载到板子上,结果发现channel_up死活不亮。这时候才是真正考验功底的时候。下面整理几个我实际遇到过的案例和排查思路。
5.1 channel_up不亮的排查顺序
第一步,用ILA抓gt_reset_done。如果这个信号一直为低,说明GT根本没有完成复位,排查参考时钟是否稳定、复位释放时序是否正确、MMCM是否锁定。这一步可以用Vivado的Hardware Manager直接读寄存器状态,也可以通过约束文件里的mark_debug把信号引出来。
第二步,确认gt_refclk的频率和波形质量。用示波器量板上的差分时钟引脚,确认频率和幅度正确。GTX对参考时钟的幅度和抖动非常敏感,如果时钟是普通晶振出来的而不是专用时钟芯片,锁不住很正常。
第三步,检查Q0/Q1的电源和接地。GTX的供电对纹波极其敏感,如果电源纹波太大,会导致PLL锁定失败或误码率飙升。用示波器看GTX供电电压,纹波应控制在几十毫伏以内。
第四步,检查差分信号的串接电容和端接电阻。Aurora是交流耦合的,发送端和接收端的差分对之间需要放置串接电容,接收端还需要100欧姆差分端接电阻。如果漏了端接电阻,高速信号反射会非常严重,导致接收端无法恢复时钟。
提示:很多开发板的原理图里,FPGA GTX引脚会直接连到SFP连接器或FMC连接器,除非你外接了一个支持Aurora的模块,否则从FPGA引脚到连接器之间可能根本没有任何差分信号。上板前先仔细看原理图,确认链路从FPGA到对端设备是完整的。
5.2 数据能通但错误率高的排查思路
channel_up拉高但接收数据偶尔出错,这个问题比完全不亮更让人头疼。我的排查顺序是:
先确认是不是时钟修正导致的问题。在ILA里抓m_axi_rx_tvalid,如果它周期性出现短暂拉低,说明时钟修正正常工作,此时出错大概率不是时钟修正的问题,而是信号完整性问题或PLL抖动超标。
再查用户时钟频率是否准确。如果用户时钟频率与IP核配置计算值不一致,会导致数据速率不匹配,时间越长数据堆积错误越严重。可以用频率计或ILA测量用户时钟周期,确认与理论值一致。
然后确认数据顺序。如果用的是多lane模式,检查接收端数据是否按lane顺序正确排列。Aurora IP核在通道绑定时已经处理了lane对齐,但如果你在用户逻辑里手动重新排列了数据,顺序很容易搞反。
最后,考虑是不是上板后电源噪声导致的偶发错误。可以在ILA里统计错误发生的频率,如果错误集中出现且带周期性,多半是电源或时钟抖动的锅;如果错误完全随机,则要考虑信号反射或参考时钟质量。
5.3 上板调试中的ILA使用技巧
ILA(Integrated Logic Analyzer)是调试Aurora链路的神器。我的经验是:把channel_up、lane_up、m_axi_rx_tvalid、m_axi_rx_tlast、用户数据的特征值检测信号都加进ILA,触发条件设为channel_up上升沿或数据错误标志拉高。这样能把链路建立的瞬间和后期的数据交互都抓下来。
抓波形时注意采样深度和采样频率的平衡。Aurora用户时钟通常在一百多兆赫兹,ILA的采样深度建议至少设到16384,否则抓到的数据太短,看不出周期性问题的规律。
还有一个技巧:用Vivado的Hardware Manager在线修改ILA触发条件,不要每次改动都重新综合。触发条件可以先设为channel_up上升沿,等确认链路能建立后,再改为错误标志触发,这样可以分阶段排查问题。
5.4 不同FPGA型号之间Aurora互联时的注意事项
如果你在做多板卡互联,两块板子用的FPGA型号可能不同,比如一边是Kintex-7,一边是Artix-7。Aurora 8B/10B协议本身是通用的,但两端GT的线速率支持范围不同。比如Artix-7的GTX最高支持到6.6Gbps,而Kintex-7支持的速率更高。互联时必须以低速一端的能力为准,选择两端都支持的线速率。
另外,不同GT的参考时钟选择也不同。有的板子参考时钟是100MHz,有的是125MHz。Aurora两端不需要相同的参考时钟频率,也不需要相同的用户时钟频率,只要线速率一致就行。这是因为Aurora协议靠时钟修正来吸收频偏,两端时钟不同步是允许的。
这点很多新手不理解,他们总想着两端要用完全一样的时钟频率,导致配置时束手束脚。实际上,Aurora的时钟修正就是专门解决这个问题的,只要两端线速率相同,哪怕时钟有几百ppm的频偏,也能正常通信。
6. 复位与Power Down信号的处理细节
复位是Aurora调试中出问题最多的环节,这里我单独拿出来细讲。Aurora IP核涉及三个复位相关信号:gt_reset、reset、power_down,它们的作用范围和时序要求完全不同。
6.1 gt_reset:GT收发器的复位
gt_reset是GT层的复位信号,它的作用域只限于GTX/GTH内部,包括PMA和PCS。这个信号拉高时,GT会重新进行PLL锁定、时钟恢复等操作,释放后需要等待gt_reset_done信号拉高,表示GT已经就绪。
gt_reset的释放条件里有一个不少人都忽略的细节:如果GT参考时钟在gt_reset释放后又发生了变化(比如时钟芯片重新配置),可能导致PLL锁定失败。所以建议把gt_reset和参考时钟的稳定标志信号联动,避免在时钟不稳定时释放复位。
6.2 reset:用户逻辑复位
reset信号作用域是Aurora协议层和用户接口逻辑,不影响GT。它通常在gt_reset_done拉高之后才能释放,否则协议层的状态机可能初始化不完整。
我在项目里遇到过一种情况:gt_reset和reset同时释放,仿真看着没问题,但上板后偶尔出现第一个帧丢失。仔细分析发现,reset释放时协议层状态机还在初始化,此时用户FIFO已经开始输出数据,导致前几个数据被丢弃。解决方法是把reset释放信号用channel_up来级联:channel_up拉高后再释放reset,保证协议层初始化完成之后用户逻辑才开始工作。
6.3 power_down:低功耗控制
power_down信号拉高时,GT会进入低功耗状态,链路断开。如果不需要动态电源管理,建议把这个信号固定拉低。有些用户为了省功耗在空闲时拉高power_down,但重新恢复链路的时间可能长达几十毫秒,对实时性要求高的场景不可接受。
6.4 一套实用的复位时序方案
综合实际项目经验,我总结了一套在大部分场景下都能稳定工作的复位时序方案:
上电后先等板卡全局复位释放,然后检查参考时钟是否就绪(可以通过MMCM locked信号或者自定义的时钟检测逻辑),参考时钟就绪后拉低gt_reset,等待gt_reset_done拉高,再拉低reset,等待channel_up拉高,最后拉低用户逻辑的复位信号,开始正常收发。
这套方案的优点是每个复位信号的释放都建立在前一个阶段完成的基础之上,层层递进,从根源上避免了“复位没准备好就干活”的问题。缺点是链路建立时间会稍长一些,但从可靠性角度考虑,这点延迟完全值得。
7. 经验总结:项目落地前再提醒几句
最后聊点实际项目中的体会,希望能帮你在遇到问题时少走弯路。
Aurora 8B/10B这套东西,最大的特点就是看着简单、用起来细节多。配置界面上每个参数后面都藏着一条链路要求:线速率定了,参考时钟和用户时钟就跟着定了;用户数据宽度定了,布线资源和时序约束也跟着变了;复位时序没处理好,上板后连link都建立不起来。把数据手册翻熟不如把Example Design跑通一次来得实在,因为只有真正在仿真里看到waveform,你对channel_up和gt_reset_done这些信号的理解才会从文字变成直觉。
如果你现在正卡在某个环节,我建议你按这个顺序排查:先确认GT参考时钟频率对不对,再确认复位释放顺序对不对,然后确认channel_up能不能起来,最后再调用户逻辑。前面任何一步没做好,后面都是白忙活。
还有一点想提醒你:Vivado版本不同,Aurora IP核的默认配置可能略有差异,比如某些版本默认开启AXI4-Stream接口,某些版本默认使用native接口。版本升级后请务必重新检查IP核配置,不要想当然地认为旧工程能直接平移到新版本。
仿真和上板是两回事,这句话做FPGA的人天天听,但每次都会用教训来复习它。我只希望你下一次项目里,能少踩一个坑,多省一晚上加班时间。