一、前言
在之前我们已经介绍了Aurora IP核的基本概念以及相关配置参数,现在开始搭建Aurora module。
整个Aurora module整体架构如下:
主要由GT_COMMON原语和 Aurora_Channel组成。
GT_COMMON主要负责给Aurora IP核提供时钟以及一些锁定信号,此模块可以直接从Aurora例子工程中迁移。
Aurora_Channel主要包括时钟模块、复位模块、Aurora IP核,其中时钟模块、复位模块可以直接从Aurora例子工程中迁移。
二、工程搭建
Aurora Channel
首先例化之前配置的Aurora IP核(具体可参考:Aurora 8b/10b IP核使用-CSDN博客),并将相关信号进行整理,此处可以参考例子工程的使用。
aurora_8b10b_0 u_aurora_8b10b_0 (
.s_axi_tx_tdata (i_s_axi_tx_tdata ), // input wire [31 : 0] s_axi_tx_tdata
.s_axi_tx_tkeep (i_s_axi_tx_tkeep ), // input wire [3 : 0] s_axi_tx_tkeep
.s_axi_tx_tlast (i_s_axi_tx_tlast ), // input wire s_axi_tx_tlast
.s_axi_tx_tvalid (i_s_axi_tx_tvalid ), // input wire s_axi_tx_tvalid
.s_axi_tx_tready (o_s_axi_tx_tready ), // output wire s_axi_tx_tready
.m_axi_rx_tdata (o_m_axi_rx_tdata ), // output wire [31 : 0] m_axi_rx_tdata
.m_axi_rx_tkeep (o_m_axi_rx_tkeep ), // output wire [3 : 0] m_axi_rx_tkeep
.m_axi_rx_tlast (o_m_axi_rx_tlast ), // output wire m_axi_rx_tlast
.m_axi_rx_tvalid (o_m_axi_rx_tvalid ), // output wire m_axi_rx_tvalid
.hard_err (o_hard_err ), // output wire hard_err
.soft_err (o_soft_err ), // output wire soft_err
.frame_err (o_frame_err ), // output wire frame_err
.channel_up (o_channel_up ), // output wire channel_up
.lane_up ( ), // output wire [0 : 0] lane_up
.txp (o_txp ), // output wire [0 : 0] txp
.txn (o_txn ), // output wire [0 : 0] txn
.reset (w_sys_rst ), // input wire reset
.gt_reset (w_gt_reset ), // input wire gt_reset
.loopback (i_loopback ), // input wire [2 : 0] loopback
.rxp (i_rxp ), // input wire [0 : 0] rxp
.rxn (i_rxn ), // input wire [0 : 0] rxn
.drpclk_in (i_drpclk_in ), // input wire drpclk_in
.drpaddr_in (i_drpaddr_in ), // input wire [8 : 0] drpaddr_in
.drpen_in (i_drpen_in ), // input wire drpen_in
.drpdi_in (i_drpdi_in ), // input wire [15 : 0] drpdi_in
.drprdy_out (i_drprdy_out ), // output wire drprdy_out
.drpdo_out (i_drpdo_out ), // output wire [15 : 0] drpdo_out
.drpwe_in (i_drpwe_in ), // input wire drpwe_in
.power_down (0 ), // input wire power_down
.tx_lock (w_tx_lock ), // output wire tx_lock
.tx_resetdone_out ( ), // output wire tx_resetdone_out
.rx_resetdone_out ( ), // output wire rx_resetdone_out
.link_reset_out ( ), // output wire link_reset_out
.gt0_qplllock_in (i_gt0_qplllock ), // input wire gt0_qplllock_in
.gt0_qpllrefclklost_in (i_gt0_qpllrefclklost ), // input wire gt0_qpllrefclklost_in
.gt0_qpllreset_out (o_gt0_qpllreset ), // output wire gt0_qpllreset_out
.gt_qpllclk_quad1_in (i_gt_qpllclk_quad1 ), // input wire gt_qpllclk_quad1_in
.gt_qpllrefclk_quad1_in (i_gt_qpllrefclk_quad1), // input wire gt_qpllrefclk_quad1_in
.init_clk_in (i_clk_100m ), // input wire init_clk_in
.pll_not_locked (w_pll_not_lock ), // input wire pll_not_locked
.tx_out_clk (w_tx_out_clk ), // output wire tx_out_clk
.sys_reset_out (o_sys_reset_out ), // output wire sys_reset_out
.user_clk (w_user_clk ), // input wire user_clk
.sync_clk (w_sync_clk ), // input wire sync_clk
.gt_refclk1 (i_gtrefclk ) // input wire gt_refclk1
);
加入时钟模块,此处可以参考例子工程。
aurora_8b10b_0_CLOCK_MODULE clock_module_i
(
.GT_CLK (w_tx_out_clk ),
.GT_CLK_LOCKED (w_tx_lock ),
.USER_CLK (w_user_clk ),
.SYNC_CLK (w_sync_clk ),
.PLL_NOT_LOCKED (w_pll_not_lock )
);
此时钟模块就是将GT Transceiver的TXCLKOUT转换为用户时钟。如下图。
加入复位逻辑,此复位模块就是将外部输入的复位跨时钟域到相应的时钟域内,比如USER_CLK,INIT_CLK。此处可以参考例子工程中的复位连接关系。
aurora_8b10b_0_SUPPORT_RESET_LOGIC support_reset_logic_i
(
.RESET (i_rst ),
.USER_CLK (w_user_clk ),
.INIT_CLK_IN (i_clk_100m ),
.GT_RESET_IN (i_rst ),
.SYSTEM_RESET (w_sys_rst ),
.GT_RESET_OUT (w_gt_reset )
);
GT_COMMON
例子工程中是将GT_COMMON与通道的时钟模块、复位模块放在一起,但是由于一个Quad中只有一个COMMON,当需要多个通道时,这种的放置方式,便会出现错误。一次我们将GT_COMMON单独取出,使其控制多个通道。示意图如下:
GT_COMMON的代码可从例子工程中移植:
aurora_8b10b_0_gt_common_wrapper gt_common_support
(
.gt_qpllclk_quad1_i (w_gt_qpllclk_quad1 ),
.gt_qpllrefclk_quad1_i (w_gt_qpllrefclk_quad1 ),
.gt0_gtrefclk0_common_in (i_gtrefclk ),
.gt0_qplllock_out (w_gt0_qplllock_out ),
.gt0_qplllockdetclk_in (i_clk_100m ),
.gt0_qpllrefclklost_out (w_gt0_qpllrefclklost ),
.gt0_qpllreset_in (w_gt0_qpllreset )
);
GT_MODULE
GT_Module的部分代表结构连接代码如下
IBUFDS_GTE2 u_IBUFDS_GTE2
(
.O (w_gtrefclk ),
.ODIV2 (),
.CEB (0 ),
.I (i_gtrefclk_p ),
.IB (i_gtrefclk_n )
);
aurora_8b10b_0_gt_common_wrapper gt_common_support
(
.gt_qpllclk_quad1_i (w_gt_qpllclk_quad1 ),
.gt_qpllrefclk_quad1_i (w_gt_qpllrefclk_quad1 ),
.gt0_gtrefclk0_common_in (i_gtrefclk ),
.gt0_qplllock_out (w_gt0_qplllock_out ),
.gt0_qplllockdetclk_in (i_clk_100m ),
.gt0_qpllrefclklost_out (w_gt0_qpllrefclklost ),
.gt0_qpllreset_in (w_gt0_qpllreset )
);
Aurora_channel u0_Aurora_channel(
.i_clk_100m (i_clk_100m ),
.i_gtrefclk (w_gtrefclk ),
.i_rst (i_rst ),
.o_user_clk (o_user0_clk ),
.i_s_axi_tx_tdata (i_s0_axi_tx_tdata ),
.i_s_axi_tx_tkeep (i_s0_axi_tx_tkeep ),
.i_s_axi_tx_tlast (i_s0_axi_tx_tlast ),
.i_s_axi_tx_tvalid (i_s0_axi_tx_tvalid ),
.o_s_axi_tx_tready (o_s0_axi_tx_tready ),
.o_m_axi_rx_tdata (o_m0_axi_rx_tdata ),
.o_m_axi_rx_tkeep (o_m0_axi_rx_tkeep ),
.o_m_axi_rx_tlast (o_m0_axi_rx_tlast ),
.o_m_axi_rx_tvalid (o_m0_axi_rx_tvalid ),
.o_hard_err (o_c0_hard_err ),
.o_soft_err (o_c0_soft_err ),
.o_frame_err (o_c0_frame_err ),
.i_loopback (i_c0_loopback ),
.o_channel_up (o_c0_channel_up ),
.i_drpclk_in (i_clk_100m ),
.i_drpaddr_in (0 ),
.i_drpen_in (0 ),
.i_drpdi_in (0 ),
.i_drprdy_out (),
.i_drpdo_out (),
.i_drpwe_in (0 ),
.i_gt0_qplllock (w_gt0_qplllock_out ),
.i_gt0_qpllrefclklost (w_gt0_qpllrefclklost ),
.o_gt0_qpllreset (w_gt0_qpllreset ),
.i_gt_qpllclk_quad1 (w_gt_qpllclk_quad1 ),
.i_gt_qpllrefclk_quad1 (w_gt_qpllrefclk_quad1 ),
.o_sys_reset_out (o_sys0_reset_out ),
.o_txp (o_txp[0] ),
.o_txn (o_txn[0] ),
.i_rxp (i_rxp[0] ),
.i_rxn (i_rxn[0] )
);
Aurora_channel u1_Aurora_channel(
.i_clk_100m (i_clk_100m ),
.i_gtrefclk (w_gtrefclk ),
.i_rst (i_rst ),
.o_user_clk (o_user1_clk ),
.i_s_axi_tx_tdata (i_s1_axi_tx_tdata ),
.i_s_axi_tx_tkeep (i_s1_axi_tx_tkeep ),
.i_s_axi_tx_tlast (i_s1_axi_tx_tlast ),
.i_s_axi_tx_tvalid (i_s1_axi_tx_tvalid ),
.o_s_axi_tx_tready (o_s1_axi_tx_tready ),
.o_m_axi_rx_tdata (o_m1_axi_rx_tdata ),
.o_m_axi_rx_tkeep (o_m1_axi_rx_tkeep ),
.o_m_axi_rx_tlast (o_m1_axi_rx_tlast ),
.o_m_axi_rx_tvalid (o_m1_axi_rx_tvalid ),
.o_hard_err (o_c1_hard_err ),
.o_soft_err (o_c1_soft_err ),
.o_frame_err (o_c1_frame_err ),
.i_loopback (i_c1_loopback ),
.o_channel_up (o_c1_channel_up ),
.i_drpclk_in (i_clk_100m ),
.i_drpaddr_in (0 ),
.i_drpen_in (0 ),
.i_drpdi_in (0 ),
.i_drprdy_out (),
.i_drpdo_out (),
.i_drpwe_in (0 ),
.i_gt0_qplllock (w_gt0_qplllock_out ),
.i_gt0_qpllrefclklost (w_gt0_qpllrefclklost ),
.o_gt0_qpllreset (),
.i_gt_qpllclk_quad1 (w_gt_qpllclk_quad1 ),
.i_gt_qpllrefclk_quad1 (w_gt_qpllrefclk_quad1 ),
.o_sys_reset_out (o_sys1_reset_out ),
.o_txp (o_txp[1] ),
.o_txn (o_txn[1] ),
.i_rxp (i_rxp[1] ),
.i_rxn (i_rxn[1] )
);
三、总结
Aurora高速收发的搭建比较简单,参考例子工程的连接关系即可,下一篇将上板测试。