一、概述
Aurora 8B/10B是Xilinx提供的一种轻量级、可扩展的链路层协议,专为FPGA间或FPGA与ASIC之间的高速串行通信而设计。该协议基于GT(Gigabit Transceiver)收发器实现物理层,通过8B/10B编码保证DC平衡,并提供帧起始/结束符插入、空闲字符生成、多通道绑定等链路层服务。
本工程基于Xilinx Zynq-7000系列(XC7Z035)器件,实现了两个独立Aurora 8B/10B通信通道,线速率6.25Gbps,用户接口位宽32bit,采用AXI4-Stream协议,包含完整的时钟管理、复位逻辑、GT资源共享和仿真验证环境。
二、IP核内部架构
Aurora 8B/10B IP核由四个核心逻辑单元构成:
- 通道逻辑:负责8B/10B编解码、逗号检测与字节对齐、K码插入与识别。
- 全局逻辑:多通道时通过FIFO补偿skew,实现通道绑定;管理空闲序列生成和错误监测。
- 用户接口:标准AXI4-Stream,含
tdata、tkeep、tlast、tvalid、tready。 - 收发器封装:将GTX/GTH原语封装为统一接口。
数据流:用户数据 → 协议封装 → 可选扰码/CRC → 8B/10B编码 → GT串行化输出;接收端为逆过程。
三、四个时钟域
| 时钟域 | 来源 | 用途 |
|---|---|---|
| GT Refclk | 外部差分晶振156.25MHz | 驱动GT内部QPLL |
| INIT CLK | 板载100MHz | 初始化与复位逻辑 |
| DRP CLK | 接地(本工程未使用) | 动态重配置 |
| USER CLK | GT的tx_out_clk经BUFG | 用户逻辑与IP核主时钟 |
USER_CLK计算公式:线速率 × 0.8 / 接口位宽,本工程为6.25G×0.8/32=156.25MHz。多核共享GT Refclk和INIT CLK,但USER_CLK各核独立。
四、复位序列
IP核提供两个复位输入:
reset(协议层复位):最小脉宽6个USER_CLK周期。gt_reset生效前须保持高电平至少128个USER_CLK周期。gt_reset(物理层复位):复位GT收发器,须在INIT CLK域去抖(4级移位寄存器)并展宽至≥6周期。
工程中通过SUPPORT_RESET_LOGIC模块实现外部复位信号去抖和CDC同步。
五、GT资源共享
- CPLL:1.6~3.3GHz,单Lane私有。
- QPLL:5.93~12.5GHz,整个Quad共享。
本工程线速率6.25Gbps,使用QPLL。GTXE2_COMMON原语配置QPLL,输出gt_qpllclk_quad3和gt_qpllrefclk_quad3同时供给两个通道。多核场景须将Shared Logic置于外部,避免资源浪费。
六、用户数据接口与环回
- 发送端产生递增数据流,便于接收端比对校验。
tlast在包尾倒数第二拍置位,确保与最后一个数据同时有效。- 仿真中设置
loopback=3'b010(近端PCS环回),发送差分对短接到接收端,实现全内部验证。
七、CDC同步器
工程包含参数化CDC模块,支持三种模式:
- 脉冲同步:源域异或翻转,目的域多级同步后检测边沿异或。
- 电平同步:目的域多级打拍输出(本工程用于复位信号传递,5级同步)。
- 带应答同步:增加握手确认。
关键属性:(* ASYNC_REG = "true" *)强制使用触发器,(* shift_extract = "{no}" *)防止综合为SRL。XDC约束:set_false_path -to [get_pins -hier *cdc_to*/D]。
八、工程文件列表
| 文件名 | 功能 |
|---|---|
XC7Z035_TOP.v | 顶层模块 |
aurora_module.v | 双通道管理、GT参考时钟缓冲、QPLL共享 |
aurora_channel.v | 单通道封装(时钟+复位+IP核) |
aurora_8b10b_0_CLOCK_MODULE.v | 用户时钟生成 |
aurora_8b10b_0_SUPPORT_RESET_LOGIC.v | 复位去抖与CDC同步 |
aurora_8b10b_0_gt_common_wrapper.v | QPLL共享逻辑 |
aurora_8b10b_0_cdc_sync_exdes.v | 参数化CDC同步器 |
user_data_gen.v | 用户数据产生与校验 |
rst_gen_module.v | 上电复位产生器 |
tb.v | 仿真测试平台 |
九、仿真与验证
测试平台特点:
- 生成100MHz和156.25MHz差分时钟。
- 发送差分对短接到接收端实现物理环回。
- 以收到10个完整数据包作为仿真结束条件,总耗时约50μs。
- 自动比对收发数据并输出PASS/FAIL。
完整源代码
1. XC7Z035_TOP.v
`timescale 1ns / 1ps module XC7Z035_TOP( input i_gtref_clk_p , input i_gtref_clk_n , input i_clk_100M_p , input i_clk_100M_n , output [1 :0] gt_txp , output [1 :0] gt_txn , input [1 :0] gt_rxp , input [1 :0] gt_rxn , output [1 :0] o_sfp_dis ); wire w_clk_100M ; wire w_clk_100M_rst ; wire w_c0_user_clk ; wire w_c0_user_rst ; wire w_c1_user_clk ; wire w_c1_user_rst ; (* MARK_DEBUG = "TRUE" *)wire [31:0] m_c0_axi_tx_tdata ; (* MARK_DEBUG = "TRUE" *)wire [3 :0] m_c0_axi_tx_tkeep ; (* MARK_DEBUG = "TRUE" *)wire m_c0_axi_tx_tlast ; (* MARK_DEBUG = "TRUE" *)wire m_c0_axi_tx_tvalid ; (* MARK_DEBUG = "TRUE" *)wire m_c0_axi_tx_tready ; (* MARK_DEBUG = "TRUE" *)wire [31:0] s_c0_axi_rx_tdata ; (* MARK_DEBUG = "TRUE" *)wire [3 :0] s_c0_axi_rx_tkeep ; (* MARK_DEBUG = "TRUE" *)wire s_c0_axi_rx_tlast ; (* MARK_DEBUG = "TRUE" *)wire s_c0_axi_rx_tvalid ; (* MARK_DEBUG = "TRUE" *)wire [31:0] m_c1_axi_tx_tdata ; (* MARK_DEBUG = "TRUE" *)wire [3 :0] m_c1_axi_tx_tkeep ; (* MARK_DEBUG = "TRUE" *)wire m_c1_axi_tx_tlast ; (* MARK_DEBUG = "TRUE" *)wire m_c1_axi_tx_tvalid ; (* MARK_DEBUG = "TRUE" *)wire m_c1_axi_tx_tready ; (* MARK_DEBUG = "TRUE" *)wire [31:0] s_c1_axi_rx_tdata ; (* MARK_DEBUG = "TRUE" *)wire [3 :0] s_c1_axi_rx_tkeep ; (* MARK_DEBUG = "TRUE" *)wire s_c1_axi_rx_tlast ; (* MARK_DEBUG = "TRUE" *)wire s_c1_axi_rx_tvalid ; (* MARK_DEBUG = "TRUE" *)wire w_c0_hard_err ; (* MARK_DEBUG = "TRUE" *)wire w_c0_soft_err ; (* MARK_DEBUG = "TRUE" *)wire w_c0_frame_err ; (* MARK_DEBUG = "TRUE" *)wire w_c0_channel_up ; (* MARK_DEBUG = "TRUE" *)wire w_c0_lane_up ; (* MARK_DEBUG = "TRUE" *)wire [2 :0] w_c0_loopback ; (* MARK_DEBUG = "TRUE" *)wire w_c1_hard_err ; (* MARK_DEBUG = "TRUE" *)wire w_c1_soft_err ; (* MARK_DEBUG = "TRUE" *)wire w_c1_frame_err ; (* MARK_DEBUG = "TRUE" *)wire w_c1_channel_up ; (* MARK_DEBUG = "TRUE" *)wire w_c1_lane_up ; (* MARK_DEBUG = "TRUE" *)wire [2 :0] w_c1_loopback ; assign w_c0_loopback = 3'b010; assign w_c1_loopback = 3'b010; assign o_sfp_dis = 2'b00 ; IBUFDS #( .DIFF_TERM ("TRUE" ), .IBUF_LOW_PWR ("TRUE" ), .IOSTANDARD ("DEFAULT" ) )IBUFDS_inst( .O (w_clk_100M ), .I (i_clk_100M_p ), .IB (i_clk_100M_n ) ); rst_gen_module#( .P_RST_CYCLE (10 ) ) rst_gen_module_U0 ( .i_clk (w_clk_100M ), .o_rst (w_clk_100M_rst ) ); user_data_gen user_data_gen_u0( .i_clk (w_c0_user_clk ), .i_rst (w_c0_user_rst ), .m_axi_tx_tdata (m_c0_axi_tx_tdata ), .m_axi_tx_tkeep (m_c0_axi_tx_tkeep ), .m_axi_tx_tlast (m_c0_axi_tx_tlast ), .m_axi_tx_tvalid (m_c0_axi_tx_tvalid ), .m_axi_tx_tready (m_c0_axi_tx_tready ), .s_axi_rx_tdata (s_c0_axi_rx_tdata ), .s_axi_rx_tkeep (s_c0_axi_rx_tkeep ), .s_axi_rx_tlast (s_c0_axi_rx_tlast ), .s_axi_rx_tvalid (s_c0_axi_rx_tvalid ) ); user_data_gen user_data_gen_u1( .i_clk (w_c1_user_clk ), .i_rst (w_c1_user_rst ), .m_axi_tx_tdata (m_c1_axi_tx_tdata ), .m_axi_tx_tkeep (m_c1_axi_tx_tkeep ), .m_axi_tx_tlast (m_c1_axi_tx_tlast ), .m_axi_tx_tvalid (m_c1_axi_tx_tvalid ), .m_axi_tx_tready (m_c1_axi_tx_tready ), .s_axi_rx_tdata (s_c1_axi_rx_tdata ), .s_axi_rx_tkeep (s_c1_axi_rx_tkeep ), .s_axi_rx_tlast (s_c1_axi_rx_tlast ), .s_axi_rx_tvalid (s_c1_axi_rx_tvalid ) ); aurora_module aurora_module_u0( .i_gtref_clk_p (i_gtref_clk_p ), .i_gtref_clk_n (i_gtref_clk_n ), .i_clk_100M (w_clk_100M ), .i_rst (w_clk_100M_rst ), .gt_txp (gt_txp ), .gt_txn (gt_txn ), .gt_rxp (gt_rxp ), .gt_rxn (gt_rxn ), .s_axi_c0_tx_tdata (m_c0_axi_tx_tdata ), .s_axi_c0_tx_tkeep (m_c0_axi_tx_tkeep ), .s_axi_c0_tx_tlast (m_c0_axi_tx_tlast ), .s_axi_c0_tx_tvalid (m_c0_axi_tx_tvalid ), .s_axi_c0_tx_tready (m_c0_axi_tx_tready ), .m_axi_c0_rx_tdata (s_c0_axi_rx_tdata ), .m_axi_c0_rx_tkeep (s_c0_axi_rx_tkeep ), .m_axi_c0_rx_tlast (s_c0_axi_rx_tlast ), .m_axi_c0_rx_tvalid (s_c0_axi_rx_tvalid ), .s_axi_c1_tx_tdata (m_c1_axi_tx_tdata ), .s_axi_c1_tx_tkeep (m_c1_axi_tx_tkeep ), .s_axi_c1_tx_tlast (m_c1_axi_tx_tlast ), .s_axi_c1_tx_tvalid (m_c1_axi_tx_tvalid ), .s_axi_c1_tx_tready (m_c1_axi_tx_tready ), .m_axi_c1_rx_tdata (s_c1_axi_rx_tdata ), .m_axi_c1_rx_tkeep (s_c1_axi_rx_tkeep ), .m_axi_c1_rx_tlast (s_c1_axi_rx_tlast ), .m_axi_c1_rx_tvalid (s_c1_axi_rx_tvalid ), .o_c0_hard_err (w_c0_hard_err ), .o_c0_soft_err (w_c0_soft_err ), .o_c0_frame_err (w_c0_frame_err ), .o_c0_channel_up (w_c0_channel_up ), .o_c0_lane_up (w_c0_lane_up ), .i_c0_loopback (w_c0_loopback ), .o_c1_hard_err (w_c1_hard_err ), .o_c1_soft_err (w_c1_soft_err ), .o_c