前文对官方Aurora 64B66B的官方示例工程做了简要讲解,本文将整理该IP,并且实现UFC和NFC流控测试。
为了测试简单,当接收端接收到一定数据时,通过NFC让发送端暂停数据发送。当按键按下时,通过UFC向接收端发送一帧指定长度的数据。
1、整理Aurora 64B66B工程
首先跟前面几个工程一样,整理底层IP的通道文件,便于后续扩展,整理过程参考示例工程,整理后的通道模块的RTL视图如下所示。
上图的相关模块表示一个高速收发器内部所需要的模块,在上层多次调用该模块,即可例化多个高速收发器。
参考代码如下所示:
//--###############################################################################################
//--#
//--# File Name : aurora_64b66b_channel
//--# Designer : 数字站
//--# Tool : Vivado 2021.1
//--# Design Date : 2024.5.25
//--# Description : aurora_64b66b的通道模块设计
//--# Version : 0.0
//--# Coding scheme : GBK(If the Chinese comment of the file is garbled, please do not save it and check whether the file is opened in GBK encoding mode)
//--#
//--###############################################################################################
module aurora_64b66b_channel (
input gt_refclk ,//GT参考时钟,IP设置为156.25MHZ;
input system_rst ,//将系统复位作为GT复位;
output user_clk ,//输入用户时钟信号,频率与txusrclk2一致;
output user_reset ,//输出用户端的系统复位信号;
input ufc_tx_req ,//用户流量控制请求信号,高电平有效;
input [7 : 0] ufc_tx_ms ,//用户流量控制的发送数据长度信号,发送数据长度等于该数据加1,单位字节。
output ufc_in_progress ,//低电平表示高速收发器正在接收用户流量控制数据;
input gt_rx_p ,//高速收发器的接收差分引脚;
input gt_rx_n ,//高速收发器的接收差分引脚;
input [2 : 0] loopback ,//回环模式控制信号;
output gt_tx_p ,//高速收发器的发送差分引脚;
output gt_tx_n ,//高速收发器的发送差分引脚;
output hard_err ,//硬件错误指示信号;
output soft_err ,//软件错误指示信号;
output channel_up ,//通道和内核初始化完成指示信号;
output lane_up ,//通道初始化完成指示信号;
input [63 : 0] s_axi_tx_data ,//用户发送数据端口的数据信号;
input [7 : 0] s_axi_tx_keep ,//用户发送数据端口的尾端数据掩码信号;
input s_axi_tx_last ,//用户发送数据端口的尾端数据指示信号;
input s_axi_tx_valid ,//用户发送数据端口的有效数据指示信号;
output s_axi_tx_ready ,//用户发送数据端口的接收数据应答信号;
input s_axi_nfc_valid ,//本地流量控制的数据有效指示信号;
input [15 : 0] s_axi_nfc_data ,//本地流量控制的数据信号,[8]表示是否停止发送数据,[7:0]表示停止发送数据的周期数据;
output s_axi_nfc_ready ,//本地流量控制的接收数据应答指示信号;
input [63 : 0] s_axi_ufc_tx_data ,//用户流量控制发送端口的数据信号;
input s_axi_ufc_tx_valid ,//用户流量控制发送端口的数据有效指示信号;
output s_axi_ufc_tx_ready ,//用户流量控制发送端口的接收数据应答指示信号;
output [63 : 0] m_axi_rx_data ,//用户接收数据端口的数据信号;
output [7 : 0] m_axi_rx_keep ,//用户接收数据端口的尾端数据掩码信号;
output m_axi_rx_last ,//用户接收数据端口的尾端数据指示信号;
output m_axi_rx_valid ,//用户接收数据端口的有效数据指示信号;
output [63 : 0] m_axi_ufc_rx_data ,//用户流量控制接收端口的数据信号;
output [7 : 0] m_axi_ufc_rx_keep ,//用户流量控制接收端口的尾端数据掩码信号;
output m_axi_ufc_rx_last ,//用户流量控制接收端口的尾端数据指示信号;
output m_axi_ufc_rx_valid ,//用户流量控制接收端口的数据有效指示信号;
input init_clk ,//初始化时钟信号,频率设置为100MHz;
input drp_clk ,//DRP时钟信号,频率设置为100MHz;
input [8 : 0] gt_drpaddr ,//高速收发器动态配置端口的地址信号;
input [15 : 0] gt_drpdi ,//高速收发器动态配置端口的输入数据信号;
output gt_drprdy ,//高速收发器动态配置端口的忙闲信号;
input gt_drpen ,//高速收发器动态配置端口的使能信号;
input gt_drpwe ,//高速收发器动态配置端口的读写指示信号;
output [15 : 0] gt_drpdo ,//高速收发器动态配置端口的输出数据信号;
input [7 : 0] qpll_drpaddr ,//QPLL动态重配置端口的地址信号;
input [15 : 0] qpll_drpdi ,//QPLL动态重配置端口的输入数据信号;
input qpll_drpen ,//QPLL动态重配置端口的使能信号;
input qpll_drpwe ,//QPLL动态重配置端口的读写指示信号;
input gt_qpllclk ,//QPLL的输出时钟信号;
input gt_qpllrefclk ,//QPLL的参考时钟输入信号;
output gt_qpllreset ,//QPLL复位信号;
input gt_qplllock ,//QPLL锁定信号;
input gt_qpllrefclklost //QPLL失锁信号;
);
wire tx_out_clk ;//发送通道的参考时钟信号;
wire gt_pll_lock ;//MMCM锁定信号;
wire sync_clk ;//同步时钟信号;
wire mmcm_not_locked ;//MMCM没有锁定信号;
wire reset_pb ;//内核复位信号;
wire gt_rst ;//GT收发器复位信号;
//例化复位模块;
aurora_64b66b_0_SUPPORT_RESET_LOGIC support_reset_logic(
.RESET ( 1'b0 ),//将系统复位作为内核复位;
.USER_CLK ( user_clk ),//用户时钟信号;
.INIT_CLK ( init_clk ),//初始化时钟;
.GT_RESET_IN ( system_rst ),//将高速收发器复位设置为无效;
.SYSTEM_RESET ( reset_pb ),//内核复位信号;
.GT_RESET_OUT ( gt_rst ) //GT收发器复位信号;
);
//例化MMCM模块,通过tx_out_clk生成用户时钟信号;
aurora_64b66b_0_CLOCK_MODULE clock_module(
.CLK ( tx_out_clk ),//GT收发器输出的用户时钟信号;
.CLK_LOCKED ( gt_pll_lock ),//MMCM锁定信号;
.USER_CLK ( user_clk ),//用户时钟信号;
.SYNC_CLK ( sync_clk ),//同步时钟信号;
.MMCM_NOT_LOCKED ( mmcm_not_locked ) //MMCM没有锁定信号;
);
//例化IP;
aurora_64b66b_0 u_aurora_64b66b(
.ufc_tx_req ( ufc_tx_req ),//用户流量控制请求信号,高电平有效;
.ufc_tx_ms ( ufc_tx_ms ),//用户流量控制的发送数据长度信号,发送数据长度等于该数据加1,单位字节。
.ufc_in_progress ( ufc_in_progress ),//低电平表示高速收发器正在接收用户流量控制数据;
.rxp ( gt_rx_p ),//高速收发器的接收差分引脚;
.rxn ( gt_rx_n ),//高速收发器的接收差分引脚;
.refclk1_in ( gt_refclk ),//高速收发器的参考时钟信号;
.user_clk ( user_clk ),//输入用户时钟信号,频率与txusrclk2一致;
.sync_clk ( sync_clk ),//输入同步时钟信号;
.reset_pb ( reset_pb ),//内核复位信号;
.power_down ( 1'b0 ),//掉电模式控制信号;
.pma_init ( gt_rst ),//高速收发器复位信号;
.loopback ( loopback ),//回环模式控制信号;
.txp ( gt_tx_p ),//高速收发器的发送差分引脚;
.txn ( gt_tx_n ),//高速收发器的发送差分引脚;
.hard_err ( hard_err ),//硬件错误指示信号;
.soft_err ( soft_err ),//软件错误指示信号;
.channel_up ( channel_up ),//通道和内核初始化完成指示信号;
.lane_up ( lane_up ),//通道初始化完成指示信号;
.tx_out_clk ( tx_out_clk ),//发送通道的参考时钟信号;
.drp_clk_in ( drp_clk ),//DRP时钟信号,频率设置为100MHz;
.gt_pll_lock ( gt_pll_lock ),//高速收发器的QPLL锁定信号;
.s_axi_tx_tdata ( s_axi_tx_data ),//用户发送数据端口的数据信号;
.s_axi_tx_tkeep ( s_axi_tx_keep ),//用户发送数据端口的尾端数据掩码信号;
.s_axi_tx_tlast ( s_axi_tx_last ),//用户发送数据端口的尾端数据指示信号;
.s_axi_tx_tvalid ( s_axi_tx_valid ),//用户发送数据端口的有效数据指示信号;
.s_axi_tx_tready ( s_axi_tx_ready ),//用户发送数据端口的接收数据应答信号;
.s_axi_nfc_tvalid ( s_axi_nfc_valid ),//本地流量控制的数据有效指示信号;
.s_axi_nfc_tdata ( s_axi_nfc_data ),//本地流量控制的数据信号,[8]表示是否停止发送数据,[7:0]表示停止发送数据的周期数据;
.s_axi_nfc_tready ( s_axi_nfc_ready ),//本地流量控制的接收数据应答指示信号;
.s_axi_ufc_tx_tdata ( s_axi_ufc_tx_data ),//用户流量控制发送端口的数据信号;
.s_axi_ufc_tx_tvalid ( s_axi_ufc_tx_valid ),//用户流量控制发送端口的数据有效指示信号;
.s_axi_ufc_tx_tready ( s_axi_ufc_tx_ready ),//用户流量控制发送端口的接收数据应答指示信号;
.m_axi_rx_tdata ( m_axi_rx_data ),//用户接收数据端口的数据信号;
.m_axi_rx_tkeep ( m_axi_rx_keep ),//用户接收数据端口的尾端数据掩码信号;
.m_axi_rx_tlast ( m_axi_rx_last ),//用户接收数据端口的尾端数据指示信号;
.m_axi_rx_tvalid ( m_axi_rx_valid ),//用户接收数据端口的有效数据指示信号;
.m_axi_ufc_rx_tdata ( m_axi_ufc_rx_data ),//用户流量控制接收端口的数据信号;
.m_axi_ufc_rx_tkeep ( m_axi_ufc_rx_keep ),//用户流量控制接收端口的尾端数据掩码信号;
.m_axi_ufc_rx_tlast ( m_axi_ufc_rx_last ),//用户流量控制接收端口的尾端数据指示信号;
.m_axi_ufc_rx_tvalid ( m_axi_ufc_rx_valid ),//用户流量控制接收端口的数据有效指示信号;
.mmcm_not_locked ( mmcm_not_locked ),//MMCM失锁信号;
.drpaddr_in ( gt_drpaddr ),//高速收发器动态配置端口的地址信号;
.drpdi_in ( gt_drpdi ),//高速收发器动态配置端口的输入数据信号;
.drprdy_out ( gt_drprdy ),//高速收发器动态配置端口的忙闲信号;
.drpen_in ( gt_drpen ),//高速收发器动态配置端口的使能信号;
.drpwe_in ( gt_drpwe ),//高速收发器动态配置端口的读写指示信号;
.drpdo_out ( gt_drpdo ),//高速收发器动态配置端口的输出数据信号;
.qpll_drpaddr_in ( qpll_drpaddr ),//QPLL动态重配置端口的地址信号;
.qpll_drpdi_in ( qpll_drpdi ),//QPLL动态重配置端口的输入数据信号;
.qpll_drprdy_out ( ),//QPLL动态重配置端口的忙闲信号;
.qpll_drpen_in ( qpll_drpen ),//QPLL动态重配置端口的使能信号;
.qpll_drpwe_in ( qpll_drpwe ),//QPLL动态重配置端口的读写指示信号;
.qpll_drpdo_out ( ),//QPLL动态重配置端口的输出数据信号;
.init_clk ( init_clk ),//初始化时钟信号,频率设置为100MHz;
.link_reset_out ( ),//高电平表示热插拔计数到期;
.gt_qpllclk_quad1_in ( gt_qpllclk ),//QPLL的输出时钟信号;
.gt_qpllrefclk_quad1_in ( gt_qpllrefclk ),//QPLL的参考时钟输入信号;
.gt_to_common_qpllreset_out ( gt_qpllreset ),//QPLL复位信号;
.gt_qplllock_in ( gt_qplllock ),//QPLL锁定信号;
.gt_qpllrefclklost_in ( gt_qpllrefclklost ),//QPLL失锁信号;
.gt_rxcdrovrden_in ( 1'b0 ),//input wire gt_rxcdrovrden_in
.sys_reset_out ( user_reset ) //输出用户端的系统复位信号;
);
endmodule
下图是高速收发器顶层模块,内部例化两个高速收发器,共用同一个QPLL,但是只有高速收发器0能够复位QPLL。如果要使用更多的高速收发器,只需要多次例化图1模块即可。
高速收发器的顶层模块参考代码如下所示:
//--###############################################################################################
//--#
//--# File Name : aurora_64b66b_module
//--# Designer : 数字站
//--# Tool : Vivado 2021.1
//--# Design Date : 2024.5.26
//--# Description : 编写收发器顶层模块;
//--# Version : 0.0
//--# Coding scheme : GBK(If the Chinese comment of the file is garbled, please do not save it and check whether the file is opened in GBK encoding mode)
//--#
//--###############################################################################################
module aurora_64b66b_module (
input gt_refclk_p ,//GT差分参考时钟,IP设置为156.25MHZ;
input gt_refclk_n ,//GT差分参考时钟,IP设置为156.25MHZ;
input system_rst ,//将系统复位作为GT复位;
input init_clk ,//初始化时钟,IP设置为100MHz。
input drp_clk ,//DRP时钟信号,IP设置为100MHz。
//QPLL的DRP接口;
input [7 : 0] qpll_drpaddr ,//QPLL动态重配置端口的地址信号;
input [15 : 0] qpll_drpdi ,//QPLL动态重配置端口的输入数据信号;
output qpll_drprdy ,//QPLL动态重配置端口的忙闲信号;
input qpll_drpen ,//QPLL动态重配置端口的使能信号;
input qpll_drpwe ,//QPLL动态重配置端口的读写指示信号;
output [15 : 0] qpll_drpdo ,//QPLL动态重配置端口的输出数据信号;
//高速收发器0相关信号;
output user_clk_0 ,//输入用户时钟信号,频率与txusrclk2一致;
output user_reset_0 ,//输出用户端的系统复位信号;
input ufc_tx_req_0 ,//用户流量控制请求信号,高电平有效;
input [7 : 0] ufc_tx_ms_0 ,//用户流量控制的发送数据长度信号,发送数据长度等于该数据加1,单位字节。
output ufc_in_progress_0 ,//低电平表示高速收发器正在接收用户流量控制数据;
input gt_rx_p_0 ,//高速收发器的接收差分引脚;
input gt_rx_n_0 ,//高速收发器的接收差分引脚;
input [2 : 0] loopback_0 ,//回环模式控制信号;
output gt_tx_p_0 ,//高速收发器的发送差分引脚;
output gt_tx_n_0 ,//高速收发器的发送差分引脚;
output hard_err_0 ,//硬件错误指示信号;
output soft_err_0 ,//软件错误指示信号;
output channel_up_0 ,//通道和内核初始化完成指示信号;
output lane_up_0 ,//通道初始化完成指示信号;
input [63 : 0] s_axi_tx_data_0 ,//用户发送数据端口的数据信号;
input [7 : 0] s_axi_tx_keep_0 ,//用户发送数据端口的尾端数据掩码信号;
input s_axi_tx_last_0 ,//用户发送数据端口的尾端数据指示信号;
input s_axi_tx_valid_0 ,//用户发送数据端口的有效数据指示信号;
output s_axi_tx_ready_0 ,//用户发送数据端口的接收数据应答信号;
input s_axi_nfc_valid_0 ,//本地流量控制的数据有效指示信号;
input [15 : 0] s_axi_nfc_data_0 ,//本地流量控制的数据信号,[8]表示是否停止发送数据,[7:0]表示停止发送数据的周期数据;
output s_axi_nfc_ready_0 ,//本地流量控制的接收数据应答指示信号;
input [63 : 0] s_axi_ufc_tx_data_0 ,//用户流量控制发送端口的数据信号;
input s_axi_ufc_tx_valid_0 ,//用户流量控制发送端口的数据有效指示信号;
output s_axi_ufc_tx_ready_0 ,//用户流量控制发送端口的接收数据应答指示信号;
output [63 : 0] m_axi_rx_data_0 ,//用户接收数据端口的数据信号;
output [7 : 0] m_axi_rx_keep_0 ,//用户接收数据端口的尾端数据掩码信号;
output m_axi_rx_last_0 ,//用户接收数据端口的尾端数据指示信号;
output m_axi_rx_valid_0 ,//用户接收数据端口的有效数据指示信号;
output [63 : 0] m_axi_ufc_rx_data_0 ,//用户流量控制接收端口的数据信号;
output [7 : 0] m_axi_ufc_rx_keep_0 ,//用户流量控制接收端口的尾端数据掩码信号;
output m_axi_ufc_rx_last_0 ,//用户流量控制接收端口的尾端数据指示信号;
output m_axi_ufc_rx_valid_0 ,//用户流量控制接收端口的数据有效指示信号;
input [8 : 0] gt_drpaddr_0 ,//高速收发器动态配置端口的地址信号;
input [15 : 0] gt_drpdi_0 ,//高速收发器动态配置端口的输入数据信号;
output gt_drprdy_0 ,//高速收发器动态配置端口的忙闲信号;
input gt_drpen_0 ,//高速收发器动态配置端口的使能信号;
input gt_drpwe_0 ,//高速收发器动态配置端口的读写指示信号;
output [15 : 0] gt_drpdo_0 ,//高速收发器动态配置端口的输出数据信号;
//高速收发器1相关信号;
output user_clk_1 ,//输入用户时钟信号,频率与txusrclk2一致;
output user_reset_1 ,//输出用户端的系统复位信号;
input ufc_tx_req_1 ,//用户流量控制请求信号,高电平有效;
input [7 : 0] ufc_tx_ms_1 ,//用户流量控制的发送数据长度信号,发送数据长度等于该数据加1,单位字节。
output ufc_in_progress_1 ,//低电平表示高速收发器正在接收用户流量控制数据;
input gt_rx_p_1 ,//高速收发器的接收差分引脚;
input gt_rx_n_1 ,//高速收发器的接收差分引脚;
input [2 : 0] loopback_1 ,//回环模式控制信号;
output gt_tx_p_1 ,//高速收发器的发送差分引脚;
output gt_tx_n_1 ,//高速收发器的发送差分引脚;
output hard_err_1 ,//硬件错误指示信号;
output soft_err_1 ,//软件错误指示信号;
output channel_up_1 ,//通道和内核初始化完成指示信号;
output lane_up_1 ,//通道初始化完成指示信号;
input [63 : 0] s_axi_tx_data_1 ,//用户发送数据端口的数据信号;
input [7 : 0] s_axi_tx_keep_1 ,//用户发送数据端口的尾端数据掩码信号;
input s_axi_tx_last_1 ,//用户发送数据端口的尾端数据指示信号;
input s_axi_tx_valid_1 ,//用户发送数据端口的有效数据指示信号;
output s_axi_tx_ready_1 ,//用户发送数据端口的接收数据应答信号;
input s_axi_nfc_valid_1 ,//本地流量控制的数据有效指示信号;
input [15 : 0] s_axi_nfc_data_1 ,//本地流量控制的数据信号,[8]表示是否停止发送数据,[7:0]表示停止发送数据的周期数据;
output s_axi_nfc_ready_1 ,//本地流量控制的接收数据应答指示信号;
input [63 : 0] s_axi_ufc_tx_data_1 ,//用户流量控制发送端口的数据信号;
input s_axi_ufc_tx_valid_1 ,//用户流量控制发送端口的数据有效指示信号;
output s_axi_ufc_tx_ready_1 ,//用户流量控制发送端口的接收数据应答指示信号;
output [63 : 0] m_axi_rx_data_1 ,//用户接收数据端口的数据信号;
output [7 : 0] m_axi_rx_keep_1 ,//用户接收数据端口的尾端数据掩码信号;
output m_axi_rx_last_1 ,//用户接收数据端口的尾端数据指示信号;
output m_axi_rx_valid_1 ,//用户接收数据端口的有效数据指示信号;
output [63 : 0] m_axi_ufc_rx_data_1 ,//用户流量控制接收端口的数据信号;
output [7 : 0] m_axi_ufc_rx_keep_1 ,//用户流量控制接收端口的尾端数据掩码信号;
output m_axi_ufc_rx_last_1 ,//用户流量控制接收端口的尾端数据指示信号;
output m_axi_ufc_rx_valid_1 ,//用户流量控制接收端口的数据有效指示信号;
input [8 : 0] gt_drpaddr_1 ,//高速收发器动态配置端口的地址信号;
input [15 : 0] gt_drpdi_1 ,//高速收发器动态配置端口的输入数据信号;
output gt_drprdy_1 ,//高速收发器动态配置端口的忙闲信号;
input gt_drpen_1 ,//高速收发器动态配置端口的使能信号;
input gt_drpwe_1 ,//高速收发器动态配置端口的读写指示信号;
output [15 : 0] gt_drpdo_1 //高速收发器动态配置端口的输出数据信号;
);
wire gt_refclk ;//GT收发器的单端时钟信号,频率为156.25MHz。
wire gt_qpllclk ;//QPLL的输出时钟信号;
wire gt_qpllrefclk ;//QPLL的参考时钟输入信号;
wire gt_qpllreset ;//QPLL复位信号;
wire gt_qplllock ;//QPLL锁定信号;
wire gt_qpllrefclklost ;//QPLL失锁信号;
//例化IBUFGDS_GTE2,将差分时钟转换为单端时钟;
IBUFDS_GTE2 IBUFDS_GTXE2_CLK1 (
.O ( gt_refclk ),//单端时钟输出信号;
.ODIV2 ( ),//单端时钟二分频输出信号;
.CEB ( 1'b0 ),//IBUFDS_GTE2使能信号;
.I ( gt_refclk_p ),//差分时钟输入信号;
.IB ( gt_refclk_n ) //差分时钟输入信号;
);
//例化GT_COMMON
aurora_64b66b_0_gt_common_wrapper gt_common_wrapper(
.gt_qpllclk_quad1_out ( gt_qpllclk ),//QPLL的输出时钟信号;
.gt_qpllrefclk_quad1_out ( gt_qpllrefclk ),//QPLL的参考时钟输入信号;
.GT0_GTREFCLK0_COMMON_IN ( gt_refclk ),//单端时钟输出信号;
.GT0_QPLLLOCK_OUT ( gt_qplllock ),//QPLL锁定信号;
.GT0_QPLLRESET_IN ( gt_qpllreset ),//QPLL复位信号;
.GT0_QPLLLOCKDETCLK_IN ( init_clk ),//初始化时钟,100MHz。
.GT0_QPLLREFCLKLOST_OUT ( gt_qpllrefclklost ),//QPLL失锁信号;
.qpll_drpaddr_in ( qpll_drpaddr ),//QPLL动态重配置端口的地址信号;
.qpll_drpdi_in ( qpll_drpdi ),//QPLL动态重配置端口的输入数据信号;
.qpll_drpclk_in ( drp_clk ),//DRP时钟信号,频率设置为100MHz;
.qpll_drpen_in ( qpll_drpen ),//QPLL动态重配置端口的使能信号;
.qpll_drpwe_in ( qpll_drpwe ),//QPLL动态重配置端口的读写指示信号;
.qpll_drpdo_out ( qpll_drpdo ),//QPLL动态重配置端口的输出数据信号;
.qpll_drprdy_out ( qpll_drprdy ) //QPLL动态重配置端口的忙闲信号;
);
//例化高速收发器0
aurora_64b66b_channel u_aurora_64b66b_channel_0(
.gt_refclk ( gt_refclk ),//GT参考时钟,IP设置为156.25MHZ;
.system_rst ( system_rst ),//将系统复位作为GT复位;
.user_clk ( user_clk_0 ),//输入用户时钟信号,频率与txusrclk2一致;
.user_reset ( user_reset_0 ),//输出用户端的系统复位信号;
.ufc_tx_req ( ufc_tx_req_0 ),//用户流量控制请求信号,高电平有效;
.ufc_tx_ms ( ufc_tx_ms_0 ),//用户流量控制的发送数据长度信号,发送数据长度等于该数据加1,单位字节。
.ufc_in_progress ( ufc_in_progress_0 ),//低电平表示高速收发器正在接收用户流量控制数据;
.gt_rx_p ( gt_rx_p_0 ),//高速收发器的接收差分引脚;
.gt_rx_n ( gt_rx_n_0 ),//高速收发器的接收差分引脚;
.loopback ( loopback_0 ),//回环模式控制信号;
.gt_tx_p ( gt_tx_p_0 ),//高速收发器的发送差分引脚;
.gt_tx_n ( gt_tx_n_0 ),//高速收发器的发送差分引脚;
.hard_err ( hard_err_0 ),//硬件错误指示信号;
.soft_err ( soft_err_0 ),//软件错误指示信号;
.channel_up ( channel_up_0 ),//通道和内核初始化完成指示信号;
.lane_up ( lane_up_0 ),//通道初始化完成指示信号;
.s_axi_tx_data ( s_axi_tx_data_0 ),//用户发送数据端口的数据信号;
.s_axi_tx_keep ( s_axi_tx_keep_0 ),//用户发送数据端口的尾端数据掩码信号;
.s_axi_tx_last ( s_axi_tx_last_0 ),//用户发送数据端口的尾端数据指示信号;
.s_axi_tx_valid ( s_axi_tx_valid_0 ),//用户发送数据端口的有效数据指示信号;
.s_axi_tx_ready ( s_axi_tx_ready_0 ),//用户发送数据端口的接收数据应答信号;
.s_axi_nfc_valid ( s_axi_nfc_valid_0 ),//本地流量控制的数据有效指示信号;
.s_axi_nfc_data ( s_axi_nfc_data_0 ),//本地流量控制的数据信号,[8]表示是否停止发送数据,[7:0]表示停止发送数据的周期数据;
.s_axi_nfc_ready ( s_axi_nfc_ready_0 ),//本地流量控制的接收数据应答指示信号;
.s_axi_ufc_tx_data ( s_axi_ufc_tx_data_0 ),//用户流量控制发送端口的数据信号;
.s_axi_ufc_tx_valid ( s_axi_ufc_tx_valid_0 ),//用户流量控制发送端口的数据有效指示信号;
.s_axi_ufc_tx_ready ( s_axi_ufc_tx_ready_0 ),//用户流量控制发送端口的接收数据应答指示信号;
.m_axi_rx_data ( m_axi_rx_data_0 ),//用户接收数据端口的数据信号;
.m_axi_rx_keep ( m_axi_rx_keep_0 ),//用户接收数据端口的尾端数据掩码信号;
.m_axi_rx_last ( m_axi_rx_last_0 ),//用户接收数据端口的尾端数据指示信号;
.m_axi_rx_valid ( m_axi_rx_valid_0 ),//用户接收数据端口的有效数据指示信号;
.m_axi_ufc_rx_data ( m_axi_ufc_rx_data_0 ),//用户流量控制接收端口的数据信号;
.m_axi_ufc_rx_keep ( m_axi_ufc_rx_keep_0 ),//用户流量控制接收端口的尾端数据掩码信号;
.m_axi_ufc_rx_last ( m_axi_ufc_rx_last_0 ),//用户流量控制接收端口的尾端数据指示信号;
.m_axi_ufc_rx_valid ( m_axi_ufc_rx_valid_0 ),//用户流量控制接收端口的数据有效指示信号;
.init_clk ( init_clk ),//初始化时钟信号,频率设置为100MHz;
.drp_clk ( drp_clk ),//DRP时钟信号,频率设置为100MHz;
.gt_drpaddr ( gt_drpaddr_0 ),//高速收发器动态配置端口的地址信号;
.gt_drpdi ( gt_drpdi_0 ),//高速收发器动态配置端口的输入数据信号;
.gt_drprdy ( gt_drprdy_0 ),//高速收发器动态配置端口的忙闲信号;
.gt_drpen ( gt_drpen_0 ),//高速收发器动态配置端口的使能信号;
.gt_drpwe ( gt_drpwe_0 ),//高速收发器动态配置端口的读写指示信号;
.gt_drpdo ( gt_drpdo_0 ),//高速收发器动态配置端口的输出数据信号;
.qpll_drpaddr ( qpll_drpaddr ),//QPLL动态重配置端口的地址信号;
.qpll_drpdi ( qpll_drpdi ),//QPLL动态重配置端口的输入数据信号;
.qpll_drpen ( qpll_drpen ),//QPLL动态重配置端口的使能信号;
.qpll_drpwe ( qpll_drpwe ),//QPLL动态重配置端口的读写指示信号;
.gt_qpllclk ( gt_qpllclk ),//QPLL的输出时钟信号;
.gt_qpllrefclk ( gt_qpllrefclk ),//QPLL的参考时钟输入信号;
.gt_qpllreset ( gt_qpllreset ),//QPLL复位信号;
.gt_qplllock ( gt_qplllock ),//QPLL锁定信号;
.gt_qpllrefclklost ( gt_qpllrefclklost ) //QPLL失锁信号;
);
//例化高速收发器1
aurora_64b66b_channel u_aurora_64b66b_channel_1(
.gt_refclk ( gt_refclk ),//GT参考时钟,IP设置为156.25MHZ;
.system_rst ( system_rst ),//将系统复位作为GT复位;
.user_clk ( user_clk_1 ),//输入用户时钟信号,频率与txusrclk2一致;
.user_reset ( user_reset_1 ),//输出用户端的系统复位信号;
.ufc_tx_req ( ufc_tx_req_1 ),//用户流量控制请求信号,高电平有效;
.ufc_tx_ms ( ufc_tx_ms_1 ),//用户流量控制的发送数据长度信号,发送数据长度等于该数据加1,单位字节。
.ufc_in_progress ( ufc_in_progress_1 ),//低电平表示高速收发器正在接收用户流量控制数据;
.gt_rx_p ( gt_rx_p_1 ),//高速收发器的接收差分引脚;
.gt_rx_n ( gt_rx_n_1 ),//高速收发器的接收差分引脚;
.loopback ( loopback_1 ),//回环模式控制信号;
.gt_tx_p ( gt_tx_p_1 ),//高速收发器的发送差分引脚;
.gt_tx_n ( gt_tx_n_1 ),//高速收发器的发送差分引脚;
.hard_err ( hard_err_1 ),//硬件错误指示信号;
.soft_err ( soft_err_1 ),//软件错误指示信号;
.channel_up ( channel_up_1 ),//通道和内核初始化完成指示信号;
.lane_up ( lane_up_1 ),//通道初始化完成指示信号;
.s_axi_tx_data ( s_axi_tx_data_1 ),//用户发送数据端口的数据信号;
.s_axi_tx_keep ( s_axi_tx_keep_1 ),//用户发送数据端口的尾端数据掩码信号;
.s_axi_tx_last ( s_axi_tx_last_1 ),//用户发送数据端口的尾端数据指示信号;
.s_axi_tx_valid ( s_axi_tx_valid_1 ),//用户发送数据端口的有效数据指示信号;
.s_axi_tx_ready ( s_axi_tx_ready_1 ),//用户发送数据端口的接收数据应答信号;
.s_axi_nfc_valid ( s_axi_nfc_valid_1 ),//本地流量控制的数据有效指示信号;
.s_axi_nfc_data ( s_axi_nfc_data_1 ),//本地流量控制的数据信号,[8]表示是否停止发送数据,[7:0]表示停止发送数据的周期数据;
.s_axi_nfc_ready ( s_axi_nfc_ready_1 ),//本地流量控制的接收数据应答指示信号;
.s_axi_ufc_tx_data ( s_axi_ufc_tx_data_1 ),//用户流量控制发送端口的数据信号;
.s_axi_ufc_tx_valid ( s_axi_ufc_tx_valid_1 ),//用户流量控制发送端口的数据有效指示信号;
.s_axi_ufc_tx_ready ( s_axi_ufc_tx_ready_1 ),//用户流量控制发送端口的接收数据应答指示信号;
.m_axi_rx_data ( m_axi_rx_data_1 ),//用户接收数据端口的数据信号;
.m_axi_rx_keep ( m_axi_rx_keep_1 ),//用户接收数据端口的尾端数据掩码信号;
.m_axi_rx_last ( m_axi_rx_last_1 ),//用户接收数据端口的尾端数据指示信号;
.m_axi_rx_valid ( m_axi_rx_valid_1 ),//用户接收数据端口的有效数据指示信号;
.m_axi_ufc_rx_data ( m_axi_ufc_rx_data_1 ),//用户流量控制接收端口的数据信号;
.m_axi_ufc_rx_keep ( m_axi_ufc_rx_keep_1 ),//用户流量控制接收端口的尾端数据掩码信号;
.m_axi_ufc_rx_last ( m_axi_ufc_rx_last_1 ),//用户流量控制接收端口的尾端数据指示信号;
.m_axi_ufc_rx_valid ( m_axi_ufc_rx_valid_1 ),//用户流量控制接收端口的数据有效指示信号;
.init_clk ( init_clk ),//初始化时钟信号,频率设置为100MHz;
.drp_clk ( drp_clk ),//DRP时钟信号,频率设置为100MHz;
.gt_drpaddr ( gt_drpaddr_1 ),//高速收发器动态配置端口的地址信号;
.gt_drpdi ( gt_drpdi_1 ),//高速收发器动态配置端口的输入数据信号;
.gt_drprdy ( gt_drprdy_1 ),//高速收发器动态配置端口的忙闲信号;
.gt_drpen ( gt_drpen_1 ),//高速收发器动态配置端口的使能信号;
.gt_drpwe ( gt_drpwe_1 ),//高速收发器动态配置端口的读写指示信号;
.gt_drpdo ( gt_drpdo_1 ),//高速收发器动态配置端口的输出数据信号;
.qpll_drpaddr ( qpll_drpaddr ),//QPLL动态重配置端口的地址信号;
.qpll_drpdi ( qpll_drpdi ),//QPLL动态重配置端口的输入数据信号;
.qpll_drpen ( qpll_drpen ),//QPLL动态重配置端口的使能信号;
.qpll_drpwe ( qpll_drpwe ),//QPLL动态重配置端口的读写指示信号;
.gt_qpllclk ( gt_qpllclk ),//QPLL的输出时钟信号;
.gt_qpllrefclk ( gt_qpllrefclk ),//QPLL的参考时钟输入信号;
.gt_qpllreset ( ),//QPLL复位信号;
.gt_qplllock ( gt_qplllock ),//QPLL锁定信号;
.gt_qpllrefclklost ( gt_qpllrefclklost ) //QPLL失锁信号;
);
endmodule
2、测试数据生成模块
该模块用于生成测试数,用户数据发送端口一直生成固定的数据帧,当接收端接收到指定数据(模仿接收端的FIFO溢出)时,向发送端发送nfc,让发送端暂停发送数据。
不管任何状态下,当检测到按键被按下时,发送一帧数据。这个功能使用ufc数据帧实现。要求用户数据帧长度、nfc暂停时间长度、ufc数据帧长度均可以设置。
该模块的端口信号和相关参数如下所示,包含接收和发送数据端口,ufc和nfc数据端口信号。
module user_test_data #(
parameter TX_DATA_LEN = 40 ,//发送一帧数据的长度,单位字节;
parameter UFC_TX_DATA_LEN = 40 ,//用户流量控制发送一帧数据的长度,单位字节;
parameter NFC_TX_LEN = 40 //本地流量控制暂停发送数据长度,单位时钟周期;
)(
input clk ,//系统时钟信号;
input rst ,//系统复位信号,高电平有效;
input key ,//按键输入信号;
//用户发送数据端口;
output reg [63 : 0] m_axi_tx_data ,//发送数据的数据信号,大端对齐;
output reg [7 : 0] m_axi_tx_keep ,//发送数据的数据掩码信号,低电平有效;
output reg m_axi_tx_last ,//发送一帧数据的最后一个数据指示信号;
output reg m_axi_tx_valid ,//发送数据的有效指示信号;
input m_axi_tx_ready ,//发送数据的应答信号;
//用户接收数据端口;
input [63 : 0] s_axi_rx_data ,//接收数据的数据信号;
input [7 : 0] s_axi_rx_keep ,//接收数据的数据掩码信号;
input s_axi_rx_last ,//接收一帧数据的最后一个数据指示信号;
input s_axi_rx_valid ,//接收数据的有效指示信号;
//本地流量控制端口;
output reg m_axi_nfc_valid ,//本地流量控制的数据有效指示信号;
output reg [15 : 0] m_axi_nfc_data ,//本地流量控制的数据信号,[8]表示是否停止发送数据,[7:0]表示停止发送数据的周期数据;
input m_axi_nfc_ready ,//本地流量控制的接收数据应答指示信号;
//用户流量发送控制端口;
output reg ufc_tx_req ,//用户流量控制请求信号,高电平有效;
output reg [7 : 0] ufc_tx_ms ,//用户流量控制的发送数据长度信号,发送数据长度等于该数据加1,单位字节。
output reg [63 : 0] m_axi_ufc_tx_data ,//用户流量控制发送端口的数据信号;
output reg m_axi_ufc_tx_valid ,//用户流量控制发送端口的数据有效指示信号;
input m_axi_ufc_tx_ready ,//用户流量控制发送端口的接收数据应答指示信号;
//用户流量接收控制端口;
input [63 : 0] s_axi_ufc_rx_data ,//用户流量控制接收端口的数据信号;
input [7 : 0] s_axi_ufc_rx_keep ,//用户流量控制接收端口的尾端数据掩码信号;
input s_axi_ufc_rx_last ,//用户流量控制接收端口的尾端数据指示信号;
input s_axi_ufc_rx_valid ,//用户流量控制接收端口的数据有效指示信号;
output reg [8 : 0] ready_cnt //用户记录主机暂停发送数据的时间;
);
localparam TX_DATA_BYTE_LEN = (TX_DATA_LEN / 8 ) ;//计算一帧数据对应的数据长度,每个数据包含8字节;
localparam UFC_TX_DATA_BYTE_LEN = UFC_TX_DATA_LEN[2:0] ? ((UFC_TX_DATA_LEN / 8) + 1) : (UFC_TX_DATA_LEN / 8);//计算一帧用户流量控制数据对应的数据长度,每个数据包含8字节;
localparam KEEP = (8'hff << (3'd7 - TX_DATA_LEN[2:0]));//计算一帧数据的尾端掩码信号;
以下代码用于生成待发送的数据帧,每隔8个时钟周期,发送一帧指定长度的数据,代码比较简单,而且都有注释,就不再详述。
/************* 生成用户发送数据的时序开始 *********************/
//用于记录两帧数据之间的时钟个数,初始值为0,之后对时钟计数;
always@(posedge clk)begin
if(rst)begin//初始值为0;
rdy_cnt <= 'd0;
end
else if(m_axi_tx_valid)begin//当处于发送数据时清零;
rdy_cnt <= 'd0;
end
else begin//如果不处于发送数据阶段,则计数器清零;
rdy_cnt <= rdy_cnt + 'd1;
end
end
//发送数据有效指示信号,初始值为0;
always@(posedge clk)begin
if(rst)begin//初始值为0;
m_axi_tx_valid <= 1'b0;
end
else if(m_axi_tx_last && m_axi_tx_ready)begin//发送最后一个后拉低;
m_axi_tx_valid <= 1'b0;
end
else if(&rdy_cnt)begin//当计数器计数到最大值时发送一帧数据,此时拉高;
m_axi_tx_valid <= 1'b1;
end
end
//用于生成产生数据个数的计数器,初始值为0,当发送指定个数数据时清零
always@(posedge clk)begin
if(rst)begin//初始值为0;
tx_data_cnt <= 'd0;
end
else if(m_axi_tx_valid && m_axi_tx_ready)begin//当发送端和接收端握手时
if(tx_data_cnt == TX_DATA_BYTE_LEN - 1)//如果发完指定数据则清零;
tx_data_cnt <= 'd0;
else//否则计数器加1;
tx_data_cnt <= tx_data_cnt + 'd1;
end
end
//生成测试数据;
always@(posedge clk)begin
if(rst)begin//初始值为0;
m_axi_tx_data <= 32'd0;
end
else if(m_axi_tx_last && m_axi_tx_valid)begin//当发送完最后一个数据时清零;
m_axi_tx_data <= 32'd0;
end
else if(m_axi_tx_valid && m_axi_tx_ready)begin
m_axi_tx_data <= {{tx_data_cnt[4:0],3'd0},{tx_data_cnt[4:0],3'd1},{tx_data_cnt[4:0],3'd2},{tx_data_cnt[4:0],3'd3},
{tx_data_cnt[4:0],3'd4},{tx_data_cnt[4:0],3'd5},{tx_data_cnt[4:0],3'd6},{tx_data_cnt[4:0],3'd7}};
end
end
//一帧数据最后一个指示信号,初始值为0;
always@(posedge clk)begin
if(rst)begin//初始值为0;
m_axi_tx_last <= 1'b0;
end
else if(m_axi_tx_valid && m_axi_tx_ready)begin//当发送最后一个数据时拉高,其余时间保持不变;
if(tx_data_cnt == TX_DATA_BYTE_LEN - 2)
m_axi_tx_last <= 1'b1;
else if(tx_data_cnt == TX_DATA_BYTE_LEN - 1)
m_axi_tx_last <= 1'b0;
end
end
//生成数据掩码信号
always@(posedge clk)begin
if(rst)begin//初始值为4'b1111;
m_axi_tx_keep <= 8'hff;
end
else if(m_axi_tx_valid && m_axi_tx_ready)begin
if(tx_data_cnt == TX_DATA_BYTE_LEN - 2)//最后一个数据的掩码信号;
m_axi_tx_keep <= KEEP;
else if(tx_data_cnt == TX_DATA_BYTE_LEN - 1)
m_axi_tx_keep <= 8'hff;
end
else begin
m_axi_tx_keep <= 8'hff;
end
end
接收端口每接收128个数据,会向发送端发送一个nfc数据帧,让发送端在接下来的NFC_TX_LEN个时钟内暂停发送数据,对应代码如下所示。
//本地流量控制一般用于当接收端处理不了数据时,让发送端暂停发送数据。
//因此此处每当接收端接收到128个数据,就让发送端停止发送一段时间的数据;
//rx_data_cnt计数器,对接收数据个数进行计数,溢出时表示收到128个数据;
always@(posedge clk)begin
if(rst)begin//初始值为0;
rx_data_cnt <= 'd0;
end
else if(s_axi_rx_valid)begin
rx_data_cnt <= rx_data_cnt + 'd1;
end
end
//生成本地流量控制信号;
always@(posedge clk)begin
if(rst)begin//初始值为0;
m_axi_nfc_valid <= 'd0;
end
else if(m_axi_nfc_ready)begin
m_axi_nfc_valid <= 'd0;//当IP应答时拉低;
end
else if(&rx_data_cnt)begin//当计数器计数到127时拉高;
m_axi_nfc_valid <= 1'b1;
end
end
//发送端暂停发送数据时间设置,单位是字节。
always@(posedge clk)begin
if(rst)begin//初始值为0;
m_axi_nfc_data <= 'd0;
end
else begin//暂停发送NFC_TX_LEN个字节数据对应的时间。
m_axi_nfc_data <= {8'd0,(NFC_TX_LEN[7:0] - 8'd1)};
end
end
为了便于统计发送端每次暂停的时间,通过一个计数器ready_cnt对发送端口的应答信号进行计数。
//为了便于后续查看本地流量控制暂停时间,通过一个计数器来对应答信号的低电平持续时间进行计数。
always@(posedge clk)begin
if(rst)begin//初始值为1;
ready_cnt <= 'd1;
end
else if(~m_axi_tx_ready)begin
ready_cnt <= ready_cnt + 'd1;
end
else begin
ready_cnt <= 'd1;
end
end
最后是ufc数据帧的产生,首先当按键被按下后,将ufc_tx_req拉高,并且将ufc的数据帧长度通过ufc_tx_ms发出。
//用户流量控制用于发送优先级较高的数据。
//因此当按键被按下时,立即通过该接口向接收端发送一帧数据;
always@(posedge clk)begin
if(rst)begin//初始值为0;
ufc_tx_req <= 'd0;
ufc_tx_ms <= UFC_TX_DATA_LEN[8:0] - 9'd1;
end
else begin
ufc_tx_req <= key;//当按键按下时,发送一个UFC请求;
ufc_tx_ms <= UFC_TX_DATA_LEN[8:0] - 9'd1;//发送数据长度,单位字节;
end
end
然后将ufc数据有效指示信号拉高,并且使用一个计数器记录已经发送数据的长度,直到发送完指定数据为止。
//生成数据有效指示信号;
always@(posedge clk)begin
if(rst)begin//初始值为0;
m_axi_ufc_tx_valid <= 'd0;
end
else if(end_ufc_tx_cnt)begin
m_axi_ufc_tx_valid <= 1'b0;//发送完一帧数据时清零;
end
else if(ufc_tx_req)begin
m_axi_ufc_tx_valid <= 1'b1;//按键按下时拉高;
end
end
//用于记录发送数据个数的计数器;
always@(posedge clk)begin
if(rst)begin//
ufc_tx_cnt <= 0;
end
else if(add_ufc_tx_cnt)begin
if(end_ufc_tx_cnt)
ufc_tx_cnt <= 0;
else
ufc_tx_cnt <= ufc_tx_cnt + 1;
end
end
assign add_ufc_tx_cnt = (m_axi_ufc_tx_valid && m_axi_ufc_tx_ready);//发送完一个数据时加一,其余时间保持不变;
assign end_ufc_tx_cnt = add_ufc_tx_cnt && (ufc_tx_cnt == UFC_TX_DATA_BYTE_LEN - 1);//发送完一帧数据时拉低;
//生成用户数据;
always@(posedge clk)begin
if(rst)begin//初始值为0;
m_axi_ufc_tx_data <= 'd0;
end
else begin
m_axi_ufc_tx_data <= {{ufc_tx_cnt[4:0],3'd0},{ufc_tx_cnt[4:0],3'd1},{ufc_tx_cnt[4:0],3'd2},{ufc_tx_cnt[4:0],3'd3},
{ufc_tx_cnt[4:0],3'd4},{ufc_tx_cnt[4:0],3'd5},{ufc_tx_cnt[4:0],3'd6},{ufc_tx_cnt[4:0],3'd7}};
end
end
3、顶层模块
顶层模块就是将测试数据生成模块、复位同步模块、按键消抖模块、高速收发器顶层模块的各个端口连接,对应的RTL视图如下所示。
顶层模块的参考代码如下所示:
//--###############################################################################################
//--#
//--# File Name : top
//--# Designer : 数字站
//--# Tool : Vivado 2021.1
//--# Design Date : 2024.5.26
//--# Description : aurora 64B66B的流控测试
//--# Version : 0.0
//--# Coding scheme : GBK(If the Chinese comment of the file is garbled, please do not save it and check whether the file is opened in GBK encoding mode)
//--#
//--###############################################################################################
module top #(
parameter TIME_20MS = 20_000_000 //按键抖动持续的最长时间,默认最长持续时间为20ms。
)(
input clk ,//系统时钟信号;
input rst_n ,//系统复位信号,低电平有效;
input key_in ,//按键输入信号,低电平有效;
input gt_refclk_p ,//gt差分参考时钟信号;
input gt_refclk_n ,//gt差分参考时钟信号;
input gt_rx_p_0 ,//gt接收差分数据线;
input gt_rx_n_0 ,//gt接收差分数据线;
output gt_tx_p_0 ,//gt发送差分数据线;
output gt_tx_n_0 ,//gt发送差分数据线;
input gt_rx_p_1 ,//gt接收差分数据线;
input gt_rx_n_1 ,//gt接收差分数据线;
output gt_tx_p_1 ,//gt发送差分数据线;
output gt_tx_n_1 ,//gt发送差分数据线;
output [1 : 0] dislabe //光电转换模块失能信号;
);
wire system_rst ;//系统复位信号;
wire key_out_0 ;
wire key_out_1 ;
//高速收发器0相关信号;
wire user_clk_0 ;//输入用户时钟信号,频率与txusrclk2一致;
wire user_reset_0 ;//输出用户端的系统复位信号;
(* MARK_DEBUG = "TRUE" *)wire ufc_tx_req_0 ;//用户流量控制请求信号,高电平有效;
(* MARK_DEBUG = "TRUE" *)wire [7 : 0] ufc_tx_ms_0 ;//用户流量控制的发送数据长度信号,发送数据长度等于该数据加1,单位字节。
(* MARK_DEBUG = "TRUE" *)wire ufc_in_progress_0 ;//低电平表示高速收发器正在接收用户流量控制数据;
wire gt_rx_p_0 ;//高速收发器的接收差分引脚;
wire gt_rx_n_0 ;//高速收发器的接收差分引脚;
wire gt_tx_p_0 ;//高速收发器的发送差分引脚;
wire gt_tx_n_0 ;//高速收发器的发送差分引脚;
(* MARK_DEBUG = "TRUE" *)wire hard_err_0 ;//硬件错误指示信号;
(* MARK_DEBUG = "TRUE" *)wire soft_err_0 ;//软件错误指示信号;
(* MARK_DEBUG = "TRUE" *)wire channel_up_0 ;//通道和内核初始化完成指示信号;
(* MARK_DEBUG = "TRUE" *)wire lane_up_0 ;//通道初始化完成指示信号;
(* MARK_DEBUG = "TRUE" *)wire [63 : 0] s_axi_tx_data_0 ;//用户发送数据端口的数据信号;
(* MARK_DEBUG = "TRUE" *)wire [7 : 0] s_axi_tx_keep_0 ;//用户发送数据端口的尾端数据掩码信号;
(* MARK_DEBUG = "TRUE" *)wire s_axi_tx_last_0 ;//用户发送数据端口的尾端数据指示信号;
(* MARK_DEBUG = "TRUE" *)wire s_axi_tx_valid_0 ;//用户发送数据端口的有效数据指示信号;
(* MARK_DEBUG = "TRUE" *)wire s_axi_tx_ready_0 ;//用户发送数据端口的接收数据应答信号;
(* MARK_DEBUG = "TRUE" *)wire s_axi_nfc_valid_0 ;//本地流量控制的数据有效指示信号;
(* MARK_DEBUG = "TRUE" *)wire [15 : 0] s_axi_nfc_data_0 ;//本地流量控制的数据信号,[8]表示是否停止发送数据,[7:0]表示停止发送数据的周期数据;
(* MARK_DEBUG = "TRUE" *)wire s_axi_nfc_ready_0 ;//本地流量控制的接收数据应答指示信号;
(* MARK_DEBUG = "TRUE" *)wire [63 : 0] s_axi_ufc_tx_data_0 ;//用户流量控制发送端口的数据信号;
(* MARK_DEBUG = "TRUE" *)wire s_axi_ufc_tx_valid_0 ;//用户流量控制发送端口的数据有效指示信号;
(* MARK_DEBUG = "TRUE" *)wire s_axi_ufc_tx_ready_0 ;//用户流量控制发送端口的接收数据应答指示信号;
(* MARK_DEBUG = "TRUE" *)wire [63 : 0] m_axi_rx_data_0 ;//用户接收数据端口的数据信号;
(* MARK_DEBUG = "TRUE" *)wire [7 : 0] m_axi_rx_keep_0 ;//用户接收数据端口的尾端数据掩码信号;
(* MARK_DEBUG = "TRUE" *)wire m_axi_rx_last_0 ;//用户接收数据端口的尾端数据指示信号;
(* MARK_DEBUG = "TRUE" *)wire m_axi_rx_valid_0 ;//用户接收数据端口的有效数据指示信号;
(* MARK_DEBUG = "TRUE" *)wire [63 : 0] m_axi_ufc_rx_data_0 ;//用户流量控制接收端口的数据信号;
(* MARK_DEBUG = "TRUE" *)wire [7 : 0] m_axi_ufc_rx_keep_0 ;//用户流量控制接收端口的尾端数据掩码信号;
(* MARK_DEBUG = "TRUE" *)wire m_axi_ufc_rx_last_0 ;//用户流量控制接收端口的尾端数据指示信号;
(* MARK_DEBUG = "TRUE" *)wire m_axi_ufc_rx_valid_0 ;//用户流量控制接收端口的数据有效指示信号;
(* MARK_DEBUG = "TRUE" *)wire [8 : 0] ready_cnt_0 ;//用户记录主机暂停发送数据的时间;
//高速收发器1相关信号;
wire user_clk_1 ;//输入用户时钟信号,频率与txusrclk2一致;
wire user_reset_1 ;//输出用户端的系统复位信号;
(* MARK_DEBUG = "TRUE" *)wire ufc_tx_req_1 ;//用户流量控制请求信号,高电平有效;
(* MARK_DEBUG = "TRUE" *)wire [7 : 0] ufc_tx_ms_1 ;//用户流量控制的发送数据长度信号,发送数据长度等于该数据加1,单位字节。
(* MARK_DEBUG = "TRUE" *)wire ufc_in_progress_1 ;//低电平表示高速收发器正在接收用户流量控制数据;
wire gt_rx_p_1 ;//高速收发器的接收差分引脚;
wire gt_rx_n_1 ;//高速收发器的接收差分引脚;
wire gt_tx_p_1 ;//高速收发器的发送差分引脚;
wire gt_tx_n_1 ;//高速收发器的发送差分引脚;
(* MARK_DEBUG = "TRUE" *)wire hard_err_1 ;//硬件错误指示信号;
(* MARK_DEBUG = "TRUE" *)wire soft_err_1 ;//软件错误指示信号;
(* MARK_DEBUG = "TRUE" *)wire channel_up_1 ;//通道和内核初始化完成指示信号;
(* MARK_DEBUG = "TRUE" *)wire lane_up_1 ;//通道初始化完成指示信号;
(* MARK_DEBUG = "TRUE" *)wire [63 : 0] s_axi_tx_data_1 ;//用户发送数据端口的数据信号;
(* MARK_DEBUG = "TRUE" *)wire [7 : 0] s_axi_tx_keep_1 ;//用户发送数据端口的尾端数据掩码信号;
(* MARK_DEBUG = "TRUE" *)wire s_axi_tx_last_1 ;//用户发送数据端口的尾端数据指示信号;
(* MARK_DEBUG = "TRUE" *)wire s_axi_tx_valid_1 ;//用户发送数据端口的有效数据指示信号;
(* MARK_DEBUG = "TRUE" *)wire s_axi_tx_ready_1 ;//用户发送数据端口的接收数据应答信号;
(* MARK_DEBUG = "TRUE" *)wire s_axi_nfc_valid_1 ;//本地流量控制的数据有效指示信号;
(* MARK_DEBUG = "TRUE" *)wire [15 : 0] s_axi_nfc_data_1 ;//本地流量控制的数据信号,[8]表示是否停止发送数据,[7:0]表示停止发送数据的周期数据;
(* MARK_DEBUG = "TRUE" *)wire s_axi_nfc_ready_1 ;//本地流量控制的接收数据应答指示信号;
(* MARK_DEBUG = "TRUE" *)wire [63 : 0] s_axi_ufc_tx_data_1 ;//用户流量控制发送端口的数据信号;
(* MARK_DEBUG = "TRUE" *)wire s_axi_ufc_tx_valid_1 ;//用户流量控制发送端口的数据有效指示信号;
(* MARK_DEBUG = "TRUE" *)wire s_axi_ufc_tx_ready_1 ;//用户流量控制发送端口的接收数据应答指示信号;
(* MARK_DEBUG = "TRUE" *)wire [63 : 0] m_axi_rx_data_1 ;//用户接收数据端口的数据信号;
(* MARK_DEBUG = "TRUE" *)wire [7 : 0] m_axi_rx_keep_1 ;//用户接收数据端口的尾端数据掩码信号;
(* MARK_DEBUG = "TRUE" *)wire m_axi_rx_last_1 ;//用户接收数据端口的尾端数据指示信号;
(* MARK_DEBUG = "TRUE" *)wire m_axi_rx_valid_1 ;//用户接收数据端口的有效数据指示信号;
(* MARK_DEBUG = "TRUE" *)wire [63 : 0] m_axi_ufc_rx_data_1 ;//用户流量控制接收端口的数据信号;
(* MARK_DEBUG = "TRUE" *)wire [7 : 0] m_axi_ufc_rx_keep_1 ;//用户流量控制接收端口的尾端数据掩码信号;
(* MARK_DEBUG = "TRUE" *)wire m_axi_ufc_rx_last_1 ;//用户流量控制接收端口的尾端数据指示信号;
(* MARK_DEBUG = "TRUE" *)wire m_axi_ufc_rx_valid_1 ;//用户流量控制接收端口的数据有效指示信号;
(* MARK_DEBUG = "TRUE" *)wire [8 : 0] ready_cnt_1 ;//用户记录主机暂停发送数据的时间;
assign dislabe = 2'd0;
//例化复位同步模块;
rst_syc_module #(
.RST_IN_VLD ( 1'b0 ),//复位输入有效电平,默认低电平;
.RST_OUT_VLD ( 1'b1 ),//复位输出有效电平,默认高电平;
.RST_CYCLE ( 8 ) //同步时钟个数;
)
rst_syc_module (
.clk ( clk ),//系统时钟信号;
.rst_n_in ( rst_n ),//复位输入信号,默认低电平有效;
.rst_out ( system_rst) //复位输出信号,默认高电平有效;
);
//例化按键消抖模块;
key #(
.TIME_20MS ( TIME_20MS ) //按键抖动持续的最长时间,默认最长持续时间为20ms。
)
u_key_0 (
.clk ( user_clk_0 ),//系统时钟,125MHz。
.rst ( user_reset_0 ),//系统复位,低电平有效。
.key_in ( key_in ),//待输入的按键输入信号,默认低电平有效;
.key_out ( key_out_0 ) //按键消抖后输出信号,当按键按下一次时,输出一个时钟宽度的高电平;
);
//例化按键消抖模块1;
key #(
.TIME_20MS ( TIME_20MS ) //按键抖动持续的最长时间,默认最长持续时间为20ms。
)
u_key_1 (
.clk ( user_clk_1 ),//系统时钟,125MHz。
.rst ( user_reset_1 ),//系统复位,低电平有效。
.key_in ( key_in ),//待输入的按键输入信号,默认低电平有效;
.key_out ( key_out_1 ) //按键消抖后输出信号,当按键按下一次时,输出一个时钟宽度的高电平;
);
//例化高速收发器0的测试数据产生模块
user_test_data #(
.TX_DATA_LEN ( 127 ),//发送一帧数据的长度,单位字节;
.UFC_TX_DATA_LEN ( 256 ),//用户流量控制发送一帧数据的长度,单位字节;
.NFC_TX_LEN ( 65 ) //本地流量控制暂停发送数据长度,单位字节;
)
u_user_test_data_0 (
.clk ( user_clk_0 ),//系统时钟信号;
.rst ( user_reset_0 ),//系统复位信号,高电平有效;
.key ( key_out_0 ),//按键输入信号;
//用户发送数据端口;
.m_axi_tx_data ( s_axi_tx_data_0 ),//发送数据的数据信号,大端对齐;
.m_axi_tx_keep ( s_axi_tx_keep_0 ),//发送数据的数据掩码信号,低电平有效;
.m_axi_tx_last ( s_axi_tx_last_0 ),//发送一帧数据的最后一个数据指示信号;
.m_axi_tx_valid ( s_axi_tx_valid_0 ),//发送数据的有效指示信号;
.m_axi_tx_ready ( s_axi_tx_ready_0 ),//发送数据的应答信号;
//用户接收数据端口;
.s_axi_rx_data ( m_axi_rx_data_0 ),//接收数据的数据信号;
.s_axi_rx_keep ( m_axi_rx_keep_0 ),//接收数据的数据掩码信号;
.s_axi_rx_last ( m_axi_rx_last_0 ),//接收一帧数据的最后一个数据指示信号;
.s_axi_rx_valid ( m_axi_rx_valid_0 ),//接收数据的有效指示信号;
//本地流量控制端口;
.m_axi_nfc_valid ( s_axi_nfc_valid_0 ),//本地流量控制的数据有效指示信号;
.m_axi_nfc_data ( s_axi_nfc_data_0 ),//本地流量控制的数据信号,[8]表示是否停止发送数据,[7:0]表示停止发送数据的周期数据;
.m_axi_nfc_ready ( s_axi_nfc_ready_0 ),//本地流量控制的接收数据应答指示信号;
//用户流量发送控制端口;
.ufc_tx_req ( ufc_tx_req_0 ),//用户流量控制请求信号,高电平有效;
.ufc_tx_ms ( ufc_tx_ms_0 ),//用户流量控制的发送数据长度信号,发送数据长度等于该数据加1,单位字节。
.m_axi_ufc_tx_data ( s_axi_ufc_tx_data_0 ),//用户流量控制发送端口的数据信号;
.m_axi_ufc_tx_valid ( s_axi_ufc_tx_valid_0 ),//用户流量控制发送端口的数据有效指示信号;
.m_axi_ufc_tx_ready ( s_axi_ufc_tx_ready_0 ),//用户流量控制发送端口的接收数据应答指示信号;
//用户流量接收控制端口;
.s_axi_ufc_rx_data ( m_axi_ufc_rx_data_0 ),//用户流量控制接收端口的数据信号;
.s_axi_ufc_rx_keep ( m_axi_ufc_rx_keep_0 ),//用户流量控制接收端口的尾端数据掩码信号;
.s_axi_ufc_rx_last ( m_axi_ufc_rx_last_0 ),//用户流量控制接收端口的尾端数据指示信号;
.s_axi_ufc_rx_valid ( m_axi_ufc_rx_valid_0 ),//用户流量控制接收端口的数据有效指示信号;
.ready_cnt ( ready_cnt_0 )
);
//例化高速收发器1的测试数据产生模块
user_test_data #(
.TX_DATA_LEN ( 81 ),//发送一帧数据的长度,单位字节;
.UFC_TX_DATA_LEN ( 88 ),//用户流量控制发送一帧数据的长度,单位字节;
.NFC_TX_LEN ( 128 ) //本地流量控制暂停发送数据长度,单位字节;
)
u_user_test_data_1 (
.clk ( user_clk_1 ),//系统时钟信号;
.rst ( user_reset_1 ),//系统复位信号,高电平有效;
.key ( key_out_1 ),//按键输入信号;
//用户发送数据端口;
.m_axi_tx_data ( s_axi_tx_data_1 ),//发送数据的数据信号,大端对齐;
.m_axi_tx_keep ( s_axi_tx_keep_1 ),//发送数据的数据掩码信号,低电平有效;
.m_axi_tx_last ( s_axi_tx_last_1 ),//发送一帧数据的最后一个数据指示信号;
.m_axi_tx_valid ( s_axi_tx_valid_1 ),//发送数据的有效指示信号;
.m_axi_tx_ready ( s_axi_tx_ready_1 ),//发送数据的应答信号;
//用户接收数据端口;
.s_axi_rx_data ( m_axi_rx_data_1 ),//接收数据的数据信号;
.s_axi_rx_keep ( m_axi_rx_keep_1 ),//接收数据的数据掩码信号;
.s_axi_rx_last ( m_axi_rx_last_1 ),//接收一帧数据的最后一个数据指示信号;
.s_axi_rx_valid ( m_axi_rx_valid_1 ),//接收数据的有效指示信号;
//本地流量控制端口;
.m_axi_nfc_valid ( s_axi_nfc_valid_1 ),//本地流量控制的数据有效指示信号;
.m_axi_nfc_data ( s_axi_nfc_data_1 ),//本地流量控制的数据信号,[8]表示是否停止发送数据,[7:0]表示停止发送数据的周期数据;
.m_axi_nfc_ready ( s_axi_nfc_ready_1 ),//本地流量控制的接收数据应答指示信号;
//用户流量发送控制端口;
.ufc_tx_req ( ufc_tx_req_1 ),//用户流量控制请求信号,高电平有效;
.ufc_tx_ms ( ufc_tx_ms_1 ),//用户流量控制的发送数据长度信号,发送数据长度等于该数据加1,单位字节。
.m_axi_ufc_tx_data ( s_axi_ufc_tx_data_1 ),//用户流量控制发送端口的数据信号;
.m_axi_ufc_tx_valid ( s_axi_ufc_tx_valid_1 ),//用户流量控制发送端口的数据有效指示信号;
.m_axi_ufc_tx_ready ( s_axi_ufc_tx_ready_1 ),//用户流量控制发送端口的接收数据应答指示信号;
//用户流量接收控制端口;
.s_axi_ufc_rx_data ( m_axi_ufc_rx_data_1 ),//用户流量控制接收端口的数据信号;
.s_axi_ufc_rx_keep ( m_axi_ufc_rx_keep_1 ),//用户流量控制接收端口的尾端数据掩码信号;
.s_axi_ufc_rx_last ( m_axi_ufc_rx_last_1 ),//用户流量控制接收端口的尾端数据指示信号;
.s_axi_ufc_rx_valid ( m_axi_ufc_rx_valid_1 ),//用户流量控制接收端口的数据有效指示信号;
.ready_cnt ( ready_cnt_1 )
);
//例化两路高速收发器
aurora_64b66b_module u_aurora_64b66b_module(
.gt_refclk_p ( gt_refclk_p ),//GT差分参考时钟,IP设置为156.25MHZ;
.gt_refclk_n ( gt_refclk_n ),//GT差分参考时钟,IP设置为156.25MHZ;
.system_rst ( system_rst ),//将系统复位作为GT复位;
.init_clk ( clk ),//初始化时钟,IP设置为100MHz。
.drp_clk ( clk ),//DRP时钟信号,IP设置为100MHz。
//QPLL的DRP接口;
.qpll_drpaddr ( 0 ),//QPLL动态重配置端口的地址信号;
.qpll_drpdi ( 0 ),//QPLL动态重配置端口的输入数据信号;
.qpll_drprdy ( ),//QPLL动态重配置端口的忙闲信号;
.qpll_drpen ( 0 ),//QPLL动态重配置端口的使能信号;
.qpll_drpwe ( 0 ),//QPLL动态重配置端口的读写指示信号;
.qpll_drpdo ( ),//QPLL动态重配置端口的输出数据信号;
//高速收发器0相关信号;
.user_clk_0 ( user_clk_0 ),//输入用户时钟信号,频率与txusrclk2一致;
.user_reset_0 ( user_reset_0 ),//输出用户端的系统复位信号;
.ufc_tx_req_0 ( ufc_tx_req_0 ),//用户流量控制请求信号,高电平有效;
.ufc_tx_ms_0 ( ufc_tx_ms_0 ),//用户流量控制的发送数据长度信号,发送数据长度等于该数据加1,单位字节。
.ufc_in_progress_0 ( ufc_in_progress_0 ),//低电平表示高速收发器正在接收用户流量控制数据;
.gt_rx_p_0 ( gt_rx_p_0 ),//高速收发器的接收差分引脚;
.gt_rx_n_0 ( gt_rx_n_0 ),//高速收发器的接收差分引脚;
.loopback_0 ( 3'b000 ),//回环模式控制信号;
.gt_tx_p_0 ( gt_tx_p_0 ),//高速收发器的发送差分引脚;
.gt_tx_n_0 ( gt_tx_n_0 ),//高速收发器的发送差分引脚;
.hard_err_0 ( hard_err_0 ),//硬件错误指示信号;
.soft_err_0 ( soft_err_0 ),//软件错误指示信号;
.channel_up_0 ( channel_up_0 ),//通道和内核初始化完成指示信号;
.lane_up_0 ( lane_up_0 ),//通道初始化完成指示信号;
.s_axi_tx_data_0 ( s_axi_tx_data_0 ),//用户发送数据端口的数据信号;
.s_axi_tx_keep_0 ( s_axi_tx_keep_0 ),//用户发送数据端口的尾端数据掩码信号;
.s_axi_tx_last_0 ( s_axi_tx_last_0 ),//用户发送数据端口的尾端数据指示信号;
.s_axi_tx_valid_0 ( s_axi_tx_valid_0 ),//用户发送数据端口的有效数据指示信号;
.s_axi_tx_ready_0 ( s_axi_tx_ready_0 ),//用户发送数据端口的接收数据应答信号;
.s_axi_nfc_valid_0 ( s_axi_nfc_valid_0 ),//本地流量控制的数据有效指示信号;
.s_axi_nfc_data_0 ( s_axi_nfc_data_0 ),//本地流量控制的数据信号,[8]表示是否停止发送数据,[7:0]表示停止发送数据的周期数据;
.s_axi_nfc_ready_0 ( s_axi_nfc_ready_0 ),//本地流量控制的接收数据应答指示信号;
.s_axi_ufc_tx_data_0 ( s_axi_ufc_tx_data_0 ),//用户流量控制发送端口的数据信号;
.s_axi_ufc_tx_valid_0 ( s_axi_ufc_tx_valid_0 ),//用户流量控制发送端口的数据有效指示信号;
.s_axi_ufc_tx_ready_0 ( s_axi_ufc_tx_ready_0 ),//用户流量控制发送端口的接收数据应答指示信号;
.m_axi_rx_data_0 ( m_axi_rx_data_0 ),//用户接收数据端口的数据信号;
.m_axi_rx_keep_0 ( m_axi_rx_keep_0 ),//用户接收数据端口的尾端数据掩码信号;
.m_axi_rx_last_0 ( m_axi_rx_last_0 ),//用户接收数据端口的尾端数据指示信号;
.m_axi_rx_valid_0 ( m_axi_rx_valid_0 ),//用户接收数据端口的有效数据指示信号;
.m_axi_ufc_rx_data_0 ( m_axi_ufc_rx_data_0 ),//用户流量控制接收端口的数据信号;
.m_axi_ufc_rx_keep_0 ( m_axi_ufc_rx_keep_0 ),//用户流量控制接收端口的尾端数据掩码信号;
.m_axi_ufc_rx_last_0 ( m_axi_ufc_rx_last_0 ),//用户流量控制接收端口的尾端数据指示信号;
.m_axi_ufc_rx_valid_0 ( m_axi_ufc_rx_valid_0 ),//用户流量控制接收端口的数据有效指示信号;
.gt_drpaddr_0 ( 0 ),//高速收发器动态配置端口的地址信号;
.gt_drpdi_0 ( 0 ),//高速收发器动态配置端口的输入数据信号;
.gt_drprdy_0 ( ),//高速收发器动态配置端口的忙闲信号;
.gt_drpen_0 ( 0 ),//高速收发器动态配置端口的使能信号;
.gt_drpwe_0 ( 0 ),//高速收发器动态配置端口的读写指示信号;
.gt_drpdo_0 ( ),//高速收发器动态配置端口的输出数据信号;
//高速收发器1相关信号;
.user_clk_1 ( user_clk_1 ),//输入用户时钟信号,频率与txusrclk2一致;
.user_reset_1 ( user_reset_1 ),//输出用户端的系统复位信号;
.ufc_tx_req_1 ( ufc_tx_req_1 ),//用户流量控制请求信号,高电平有效;
.ufc_tx_ms_1 ( ufc_tx_ms_1 ),//用户流量控制的发送数据长度信号,发送数据长度等于该数据加1,单位字节。
.ufc_in_progress_1 ( ufc_in_progress_1 ),//低电平表示高速收发器正在接收用户流量控制数据;
.gt_rx_p_1 ( gt_rx_p_1 ),//高速收发器的接收差分引脚;
.gt_rx_n_1 ( gt_rx_n_1 ),//高速收发器的接收差分引脚;
.loopback_1 ( 3'b000 ),//回环模式控制信号;
.gt_tx_p_1 ( gt_tx_p_1 ),//高速收发器的发送差分引脚;
.gt_tx_n_1 ( gt_tx_n_1 ),//高速收发器的发送差分引脚;
.hard_err_1 ( hard_err_1 ),//硬件错误指示信号;
.soft_err_1 ( soft_err_1 ),//软件错误指示信号;
.channel_up_1 ( channel_up_1 ),//通道和内核初始化完成指示信号;
.lane_up_1 ( lane_up_1 ),//通道初始化完成指示信号;
.s_axi_tx_data_1 ( s_axi_tx_data_1 ),//用户发送数据端口的数据信号;
.s_axi_tx_keep_1 ( s_axi_tx_keep_1 ),//用户发送数据端口的尾端数据掩码信号;
.s_axi_tx_last_1 ( s_axi_tx_last_1 ),//用户发送数据端口的尾端数据指示信号;
.s_axi_tx_valid_1 ( s_axi_tx_valid_1 ),//用户发送数据端口的有效数据指示信号;
.s_axi_tx_ready_1 ( s_axi_tx_ready_1 ),//用户发送数据端口的接收数据应答信号;
.s_axi_nfc_valid_1 ( s_axi_nfc_valid_1 ),//本地流量控制的数据有效指示信号;
.s_axi_nfc_data_1 ( s_axi_nfc_data_1 ),//本地流量控制的数据信号,[8]表示是否停止发送数据,[7:0]表示停止发送数据的周期数据;
.s_axi_nfc_ready_1 ( s_axi_nfc_ready_1 ),//本地流量控制的接收数据应答指示信号;
.s_axi_ufc_tx_data_1 ( s_axi_ufc_tx_data_1 ),//用户流量控制发送端口的数据信号;
.s_axi_ufc_tx_valid_1 ( s_axi_ufc_tx_valid_1 ),//用户流量控制发送端口的数据有效指示信号;
.s_axi_ufc_tx_ready_1 ( s_axi_ufc_tx_ready_1 ),//用户流量控制发送端口的接收数据应答指示信号;
.m_axi_rx_data_1 ( m_axi_rx_data_1 ),//用户接收数据端口的数据信号;
.m_axi_rx_keep_1 ( m_axi_rx_keep_1 ),//用户接收数据端口的尾端数据掩码信号;
.m_axi_rx_last_1 ( m_axi_rx_last_1 ),//用户接收数据端口的尾端数据指示信号;
.m_axi_rx_valid_1 ( m_axi_rx_valid_1 ),//用户接收数据端口的有效数据指示信号;
.m_axi_ufc_rx_data_1 ( m_axi_ufc_rx_data_1 ),//用户流量控制接收端口的数据信号;
.m_axi_ufc_rx_keep_1 ( m_axi_ufc_rx_keep_1 ),//用户流量控制接收端口的尾端数据掩码信号;
.m_axi_ufc_rx_last_1 ( m_axi_ufc_rx_last_1 ),//用户流量控制接收端口的尾端数据指示信号;
.m_axi_ufc_rx_valid_1 ( m_axi_ufc_rx_valid_1 ),//用户流量控制接收端口的数据有效指示信号;
.gt_drpaddr_1 ( 0 ),//高速收发器动态配置端口的地址信号;
.gt_drpdi_1 ( 0 ),//高速收发器动态配置端口的输入数据信号;
.gt_drprdy_1 ( ),//高速收发器动态配置端口的忙闲信号;
.gt_drpen_1 ( 0 ),//高速收发器动态配置端口的使能信号;
.gt_drpwe_1 ( 0 ),//高速收发器动态配置端口的读写指示信号;
.gt_drpdo_1 ( ) //高速收发器动态配置端口的输出数据信号;
);
endmodule
4、模块仿真
顶层模块的仿真激励文件如下所示。
//--###############################################################################################
//--#
//--# File Name : test
//--# Designer : 数字站
//--# Tool : Vivado 2021.1
//--# Design Date : 2024.5.26
//--# Description : 顶层测试模块
//--# Version : 0.0
//--# Coding scheme : GBK(If the Chinese comment of the file is garbled, please do not save it and check whether the file is opened in GBK encoding mode)
//--#
//--###############################################################################################
`timescale 1ns / 1ps
module test ();
localparam CYCLE = 10 ;//系统时钟周期,单位ns,默认10ns;
localparam RST_TIME = 10 ;//系统复位持续时间,默认10个系统时钟周期;
localparam TIME_20MS = 500 ;//按键抖动持续的最长时间,默认最长持续时间为20ms。
reg clk ;//系统时钟,默认100MHz;
reg rst_n ;//系统复位,默认低电平有效;
reg key_in ;//按键输入信号,低电平有效;
reg gt_refclk_p ;//gt差分参考时钟信号;
reg gt_refclk_n ;//gt差分参考时钟信号;
wire gt_tx_p_0 ;//gt发送差分数据线;
wire gt_tx_n_0 ;//gt发送差分数据线;
wire gt_tx_p_1 ;//gt发送差分数据线;
wire gt_tx_n_1 ;//gt发送差分数据线;
wire [1 : 0] dislabe ;//光电转换模块失能信号;
//例化待测试模块
top #(
.TIME_20MS ( TIME_20MS ) //按键抖动持续的最长时间,默认最长持续时间为20ms。
)
u_top (
.clk ( clk ),//系统时钟信号;
.rst_n ( rst_n ),//系统复位信号,低电平有效;
.key_in ( key_in ),//按键输入信号,低电平有效;
.gt_refclk_p ( gt_refclk_p ),//gt差分参考时钟信号;
.gt_refclk_n ( gt_refclk_n ),//gt差分参考时钟信号;
.gt_rx_p_0 ( gt_tx_p_1 ),//gt接收差分数据线;
.gt_rx_n_0 ( gt_tx_n_1 ),//gt接收差分数据线;
.gt_tx_p_0 ( gt_tx_p_0 ),//gt发送差分数据线;
.gt_tx_n_0 ( gt_tx_n_0 ),//gt发送差分数据线;
.gt_rx_p_1 ( gt_tx_p_0 ),//gt接收差分数据线;
.gt_rx_n_1 ( gt_tx_n_0 ),//gt接收差分数据线;
.gt_tx_p_1 ( gt_tx_p_1 ),//gt发送差分数据线;
.gt_tx_n_1 ( gt_tx_n_1 ),//gt发送差分数据线;
.dislabe ( dislabe ) //光电转换模块失能信号;
);
//生成周期为CYCLE数值的系统时钟;
initial begin
clk = 0;
forever #(CYCLE/2) clk = ~clk;
end
initial begin
gt_refclk_p = 0;
forever #3.2 gt_refclk_p = ~gt_refclk_p;
end
initial begin
gt_refclk_n = 1;
forever #3.2 gt_refclk_n = ~gt_refclk_n;
end
//生成复位信号;
initial begin
key_in = 1'b1;
rst_n = 1;
#2;
rst_n = 0;//开始时复位10个时钟;
#(RST_TIME*CYCLE);
rst_n = 1;
repeat(2000)@(posedge clk);
forever begin
key_i();
repeat(300)@(posedge gt_refclk_p);
end
end
//按键信号产生任务;
task key_i();
begin : KEY_I
key_in <= 1'b1;
@(posedge gt_refclk_p);
repeat({$random} % 10)begin
key_in <= ~key_in;
repeat({$random} % (2*TIME_20MS))@(posedge gt_refclk_p);
end
key_in <= 1'b0;
repeat(TIME_20MS + 200)@(posedge gt_refclk_p);
repeat({$random} % 10)begin
key_in <= ~key_in;
repeat({$random} % (2*TIME_20MS))@(posedge gt_refclk_p);
end
key_in <= 1'b1;
@(posedge gt_refclk_p);
end
endtask
endmodule
将顶层模块的信号添加到仿真列表,然后运行仿真,结果如下所示:
首先高速收发器0向高速收发器1正常发送数据,如下图所示:
高速收发器1向高速收发器0发送一帧数据,如下图所示:
当高速收发器0接收到高速收发器1发送的128个数据后,向高速收发器1发送NFC数据帧,使得高速收发器1暂停发送64个时钟的数据。
高速收发器1在接收到NFC数据帧之后,将用户发送数据端口的应答信号拉低64个时钟周期,来暂停发送数据。
当高速收发器1接收到高速收发器0发送的128个数据后,向高速收发器0发送NFC数据帧,使得高速收发器0暂停发送127个时钟的数据。
高速收发器0在接收到NFC数据帧之后,将用户发送数据端口的应答信号拉低127个时钟周期,来暂停发送数据。
当检测到按键按下时,高速收发器0向高速收发器1发送一帧长度为256字节的UFC数据,最后一个有效字节数据为8’hf7。
如下图所示,高速收发器1接收到的UFC数据帧的最后一个有效字节数据为8’hf7。
按键按下时,高速收发器1向高速收发器0发送一帧长为88字节的UFC数据,如下图所示,发送的最后一字节有效数据为8’h4f。
如下图所示,高速收发器0接收到的UFC数据帧的最后一个有效字节数据为8’h4f,与发送的数据一致。
上述仿真完成两种流控模式的仿真,可能发送数据的长度会存在一点问题,但是不影响结果。
5、上板测试
然后综合工程,并且分配管脚,如下图所示,然后引入ILA调试信号,最后生成比特流。
然后将比特流下载到开发板,开发板的两个光口通过光纤回环,然后使用ILA抓取数据。
如下图所示,时高速收发器0发送和接收的一帧数据,接收一帧数据的最后一个有效字节数据为8’h43。
下图是高速收发器1收发一帧数据的时序,由图可知发送一帧数据的最后一个有效字节数据为8’h43,与高速收发器0接收的数据帧一致。
下图是高速收发器1向高速收发器0发送的一帧NFC数据,让高速收发器0在接下来的127个时钟周期内停止发送数据。
下图是高速收发器0收到高速收发器1发送的NFC数据帧之后,将用户发送数据端口的应答信号拉低127个时钟周期,来达到暂停发送数据的目的。
下图是高速收发器0向高速收发器1发送NFC数据帧时序,让高速收发器在接下来的64个时钟内暂停发送数据。
当高速收发器1接收到高速收发器0发送的NFC数据帧之后,将用户发送数据端口的应答信号拉低64个时钟来暂停数据的发送。
下面对UFC数据帧进行测试,首先将ILA把ufc_tx_req高电平作为触发条件,然后按下开发板的按键,抓取以下数据。
按键被按下时,高速收发器0会向高速收发器1发送一帧长度为256字节的UFC数据帧。如下图所示,最后一个有效字节数据为8’hf7。
下图是高速收发器1接收到上图高速收发器0发出的UFC数据帧,最后一个有效字节数据为8’hf7,证明收发数据正常。
当按键被按下时,高速收发器1同样会向高速收发器0发送一帧长度为88字节的UFC数据,对应时序如下图所示,最后一个有效字节数据为8’h4f。
高速收发器0接收到高速收发器1发送的UFC数据帧,对应时序如下图所示。最后一个有效字节数据为8’h4f,与上图发送数据一致,证明收发数据正常。
综上,通过仿真和上板测试,完成了对Aurora 64B66B的UFC和NFC的测试,前面的Aurora 8B10B的流控模式使用方式相同,有兴趣的读者可以自己试试。
至此,GTX关于8B10B,64B66B,以及Aurora 8B10B、Aurora 64B66B的使用到此结束了,经过这一路的学习,面对高速收发器的开发,应该不会存在什么问题了吧。
本文工程可以在公众号后台回复“Aurora 64B/66B的流控工程”(不包括引号)获取。