当前位置: 首页 > news >正文

GT IP核仿真测试

GT IP核仿真测试

  • 1. 前言
  • 2. 概述
  • 3. IP核配置
    • 第一页
    • 第二页
    • 第三页
    • 第四页
    • 第五页
    • 第六页
    • 第七页
  • 4. 代码框架分析
    • 4.1 gtwizard_exdes.v
    • 4.2 gtwizard_0_GT_FRAME_GEN.v
    • 4.3 gtwizard_0_GT_FRAME_CHECK.v
  • 5. 仿真测试


1. 前言

由于关于GT IP的相关博客太多了,所以我就以我自己的仿真调试经验取讲解下GT IP的使用方法。一开始我接触GT的时钟,第一眼望去,打开IP,有几页的配置,特别多的参数勾选,头都要晕掉了,因此我也是先找了一些技术文章先了解了下GT的大致原理以及流程,对GT有了基本的了解后再去配置使用,就轻松多了。不要怕,一开始的路都是崎岖艰辛的,只要坚持学习消化,终会迎来胜利的曙光,加油!好了,废话完毕,我们开始吧!

2. 概述

首先在vivado中,我们打开IP Catalog,在搜索框中搜索GT,就会弹出GT的IP核,可以看到有两个IP,一个叫IBERT 7 Series GTX,一个叫7 Series FPGAs Transceivers Wizard。第一个是眼图,是用来测试误码率以及GTX的硬件链路的。第二个是我们要用的GTx IP核,用来传输传输高速信号的,K7系列芯片的最大线速率可以达到10.3125Gbps。

3. IP核配置

第一页

在这里插入图片描述

因为我的FPGA型号是XC7K325T,所以使用的是GTX。我们要使用官方例程example design,所以勾选Include Shared Logic in example design。

第二页

在这里插入图片描述

  • Protocol:Start from scratch,意思是不使用协议;它支持各种的协议包括SDI/10Gbase/Aurora/PCIE/HDMI/204B/,很多我就不一一列举了,由于我们这里不使用协议,因此默认就行;
  • line Rate:线速率,默认是3.125Gbps;
  • Reference Clock(MHz):156.250MHz,这个是根据你原理图上的时钟来配置的,一般GT的参考时钟为156.250,跟原理图对应;
  • PLL Selection:CPLL。线速率大于6Gbps时必须选择QPLL,我这里选择的是CPLL;
  • Transceiverr Selection:
  • Use GTX X0Y0:勾选,这也是跟你的原理图对应,参考其他博客可以在Implement中查看你的GT bank
  • TX Clock Source:跟你的原理图对应,看你接的是参考时钟0还是参考时钟1
  • RX Clock Source:跟你的原理图对应,看你接的是参考时钟0还是参考时钟1,TX选择后RX自动改变,无需配置;
  • Advanced Clocking Option:默认,没用过;
  • PRBS pattern generator and checker:默认,没用过
  • Vivado Lab Tools:默认不勾选,没用过

第三页

在这里插入图片描述
参数太多了,说下主要配置的部分吧,也就是TX和RX

  1. TX
    External Data width(bits):外部数据宽度,可配置,我配的20bit,这个看个人的;
    Encoding:编码方式,可选择8B/10B,我选择的NONE
    Internal Data with(bits);内部数据宽度,也就是IP核内部的数据宽度
  2. RX
    External Data width(bits):外部数据宽度,可配置,我配的20bit,这个看个人的;
    Encoding:编码方式,可选择8B/10B,我选择的NONE
    Internal Data with(bits);内部数据宽度,也就是IP核内部的数据宽度
  3. Synchronization and Clocking
    勾选Enable TX buffer和Enable RX buffer,勾选后代表增加了一个FIFO去缓存发送的数据,不知道我这样理解对不对,勾选就对了。
  4. Optional Ports
    这些应该就是高级配置了,小白刚开始接触GT时不需要关注,默认即可。

第四页

在这里插入图片描述
这一页配置是逗号对齐检测和K码的设置,K码是28.5,勾选Use comma detection,表示使用逗号检测
Align to:选择Any Byte Boundary或者两字节,我选择两字节;
其他参数默认即可,想了解更多的就去啃手册或者其他技术博客,我暂时还没深入到这里;

第五页

在这里插入图片描述
默认即可,我没使用PCIe协议。

第六页

在这里插入图片描述
默认即可,这页应该是时钟校准配置,我还是默默看手册去吧,不懂。

第七页

总结页,总结了前面的配置信息,可以看看跟自己配置的是否一致。在这里插入图片描述
配置完IP核后生成IP核,如图所示。
在这里插入图片描述
生成完IP核后,右击生成的IP
在这里插入图片描述
点击Open IP Example Design,然后会自动创建一个工程,工程的代码框架如下:
在这里插入图片描述
别看代码文件很多,核心的代码就三部分,gtwizard_exdes.v,gtwizard_0_support,gtwizard_0_GT_FRAME_GEN.v,gtwizard_0_GT_FRAME_CHECK.v。
接下来分析下代码

4. 代码框架分析

4.1 gtwizard_exdes.v

这是顶层模块,例化了其他三个模块,顶层接口其实很少,就一对差分信号TX、差分信号RX、GT差分参考时钟、动态重配置DRP差分时钟、TRACK_DATA_OUT,这是个检测信号。
配置参考就关注下EXAMPLE_SIM_GTRESET_SPEEDUP这个值,它是用于配置仿真和综合实现的参数,我们功能仿真的时候就改成TRUE

module gtwizard_0_exdes #
(parameter EXAMPLE_CONFIG_INDEPENDENT_LANES     =   1,//configuration for frame gen and checkparameter EXAMPLE_LANE_WITH_START_CHAR         =   0,         // specifies lane with unique start frame charparameter EXAMPLE_WORDS_IN_BRAM                =   512,       // specifies amount of data in BRAMparameter EXAMPLE_SIM_GTRESET_SPEEDUP          =   "TRUE",    // simulation setting for GT SecureIP modelparameter EXAMPLE_USE_CHIPSCOPE                =   0,         // Set to 1 to use Chipscope to drive resetsparameter STABLE_CLOCK_PERIOD                  = 10)
(input wire  Q0_CLK1_GTREFCLK_PAD_N_IN,input wire  Q0_CLK1_GTREFCLK_PAD_P_IN,input wire  DRP_CLK_IN_P,input wire  DRP_CLK_IN_N,output wire TRACK_DATA_OUT,input  wire         RXN_IN,input  wire         RXP_IN,output wire         TXN_OUT,output wire         TXP_OUT
);

接着例化了三个子模块。

  1. support是GT的核心代码,它例化了GTX IP核,一般无需修改。
  2. frame_gen是我们需要发送的数据,在实际应用中,换成自己数据输入源就可以了;
  3. frame_check是用来检测接收的数据和发送的数据是否一致,可以不用或者换成你自己的检测逻辑代码也可以;
gtwizard_0_support #(.EXAMPLE_SIM_GTRESET_SPEEDUP    (EXAMPLE_SIM_GTRESET_SPEEDUP),.STABLE_CLOCK_PERIOD            (STABLE_CLOCK_PERIOD))gtwizard_0_support_i(.soft_reset_tx_in               (soft_reset_i),.soft_reset_rx_in               (soft_reset_i),.dont_reset_on_data_error_in    (tied_to_ground_i),.q0_clk1_gtrefclk_pad_n_in(Q0_CLK1_GTREFCLK_PAD_N_IN),.q0_clk1_gtrefclk_pad_p_in(Q0_CLK1_GTREFCLK_PAD_P_IN),.gt0_tx_fsm_reset_done_out      (gt0_txfsmresetdone_i),.gt0_rx_fsm_reset_done_out      (gt0_rxfsmresetdone_i),.gt0_data_valid_in              (gt0_track_data_i),.gt0_txusrclk_out(gt0_txusrclk_i),.gt0_txusrclk2_out(gt0_txusrclk2_i),.gt0_rxusrclk_out(gt0_rxusrclk_i),.gt0_rxusrclk2_out(gt0_rxusrclk2_i),//_____________________________________________________________________//_____________________________________________________________________//GT0  (X1Y0)//------------------------------- CPLL Ports -------------------------------.gt0_cpllfbclklost_out          (gt0_cpllfbclklost_i),.gt0_cplllock_out               (gt0_cplllock_i),.gt0_cpllreset_in               (tied_to_ground_i),//-------------------------- Channel - DRP Ports  --------------------------.gt0_drpaddr_in                 (gt0_drpaddr_i),.gt0_drpdi_in                   (gt0_drpdi_i),.gt0_drpdo_out                  (gt0_drpdo_i),.gt0_drpen_in                   (gt0_drpen_i),.gt0_drprdy_out                 (gt0_drprdy_i),.gt0_drpwe_in                   (gt0_drpwe_i),//------------------------- Digital Monitor Ports --------------------------.gt0_dmonitorout_out            (gt0_dmonitorout_i),//------------------- RX Initialization and Reset Ports --------------------.gt0_eyescanreset_in            (tied_to_ground_i),.gt0_rxuserrdy_in               (tied_to_vcc_i),//------------------------ RX Margin Analysis Ports ------------------------.gt0_eyescandataerror_out       (gt0_eyescandataerror_i),.gt0_eyescantrigger_in          (tied_to_ground_i),//---------------- Receive Ports - FPGA RX interface Ports -----------------.gt0_rxdata_out                 (gt0_rxdata_i),//---------------- Receive Ports - RX 8B/10B Decoder Ports -----------------.gt0_rxdisperr_out              (gt0_rxdisperr_i),.gt0_rxnotintable_out           (gt0_rxnotintable_i),//------------------------- Receive Ports - RX AFE -------------------------.gt0_gtxrxp_in                  (RXP_IN),//---------------------- Receive Ports - RX AFE Ports ----------------------.gt0_gtxrxn_in                  (RXN_IN),//------------------- Receive Ports - RX Equalizer Ports -------------------.gt0_rxdfelpmreset_in           (tied_to_ground_i),.gt0_rxmonitorout_out           (gt0_rxmonitorout_i),.gt0_rxmonitorsel_in            (2'b00),//------------- Receive Ports - RX Fabric Output Control Ports -------------.gt0_rxoutclkfabric_out         (gt0_rxoutclkfabric_i),//----------- Receive Ports - RX Initialization and Reset Ports ------------.gt0_gtrxreset_in               (tied_to_ground_i),.gt0_rxpmareset_in              (gt0_rxpmareset_i),//-------------------- Receive Ports - RX gearbox ports --------------------.gt0_rxslide_in                 (gt0_rxslide_i),//----------------- Receive Ports - RX8B/10B Decoder Ports -----------------.gt0_rxcharisk_out              (gt0_rxcharisk_i),//------------ Receive Ports -RX Initialization and Reset Ports ------------.gt0_rxresetdone_out            (gt0_rxresetdone_i),//------------------- TX Initialization and Reset Ports --------------------.gt0_gttxreset_in               (tied_to_ground_i),.gt0_txuserrdy_in               (tied_to_vcc_i),//---------------- Transmit Ports - TX Data Path interface -----------------.gt0_txdata_in                  (gt0_txdata_i),//-------------- Transmit Ports - TX Driver and OOB signaling --------------.gt0_gtxtxn_out                 (TXN_OUT),.gt0_gtxtxp_out                 (TXP_OUT),//--------- Transmit Ports - TX Fabric Clock Output Control Ports ----------.gt0_txoutclkfabric_out         (gt0_txoutclkfabric_i),.gt0_txoutclkpcs_out            (gt0_txoutclkpcs_i),//------------------- Transmit Ports - TX Gearbox Ports --------------------.gt0_txcharisk_in               (gt0_txcharisk_i),//----------- Transmit Ports - TX Initialization and Reset Ports -----------.gt0_txresetdone_out            (gt0_txresetdone_i),//____________________________COMMON PORTS________________________________.gt0_qplloutclk_out(),.gt0_qplloutrefclk_out(),.sysclk_in(drpclk_in_i));
gtwizard_0_GT_FRAME_GEN #(.WORDS_IN_BRAM(EXAMPLE_WORDS_IN_BRAM))gt0_frame_gen(// User Interface.TX_DATA_OUT                    ({gt0_txdata_float_i,gt0_txdata_i,gt0_txdata_float16_i}),.TXCTRL_OUT                     ({gt0_txcharisk_float_i,gt0_txcharisk_i}),// System Interface.USER_CLK                        (gt0_txusrclk2_i),.SYSTEM_RESET                   (gt0_tx_system_reset_c));
gtwizard_0_GT_FRAME_CHECK #(
.RX_DATA_WIDTH ( 16 ),
.RXCTRL_WIDTH ( 2 ),
.COMMA_DOUBLE ( 16'h02bc ),.WORDS_IN_BRAM(EXAMPLE_WORDS_IN_BRAM),
.START_OF_PACKET_CHAR ( 16'h02bc ))gt0_frame_check(// GT Interface.RX_DATA_IN                     (gt0_rxdata_i),.RXCTRL_IN                      (gt0_rxcharisk_i),.RXENMCOMMADET_OUT              ( ),.RXENPCOMMADET_OUT              ( ),.RX_ENCHAN_SYNC_OUT             ( ),.RX_CHANBOND_SEQ_IN             (tied_to_ground_i),// Control Interface.INC_IN                         (gt0_inc_in_i),.INC_OUT                        (gt0_inc_out_i),.PATTERN_MATCHB_OUT             (gt0_matchn_i),.RESET_ON_ERROR_IN              (gt0_frame_check_reset_i),// System Interface.USER_CLK                       (gt0_rxusrclk2_i),.SYSTEM_RESET                   (gt0_rx_system_reset_c),.ERROR_COUNT_OUT                (gt0_error_count_i),.RX_SLIDE                       (gt0_rxslide_i),.TRACK_DATA_OUT                 (gt0_track_data_i));

4.2 gtwizard_0_GT_FRAME_GEN.v

数据生成模块,该模块读取文件中的数据到ROM,将ROM中的512个数据发送出去,注意数据宽度为80bit,进行了扩展,实际上只需要你之前配置的外部数据宽度如20bit就可以啦。

`timescale 1ns / 1ps
`define DLY #1//***********************************Entity Declaration*******************************
(* DowngradeIPIdentifiedWarnings="yes" *)
module gtwizard_0_GT_FRAME_GEN #
(// parameter to set the number of words in the BRAMparameter   WORDS_IN_BRAM =   512
)
(// User Interface
output reg  [79:0]  TX_DATA_OUT,
output reg  [7:0]   TXCTRL_OUT,// System Interface
input  wire         USER_CLK,
input  wire         SYSTEM_RESET 
); //********************************* Wire Declarations********************************* wire            tied_to_ground_i;
wire             tied_to_vcc_i;
wire    [31:0]  tied_to_ground_vec_i;
wire    [63:0]  tx_data_bram_i;
wire    [7:0]   tx_ctrl_i;//***************************Internal Register Declarations*************************** reg     [8:0]   read_counter_i;reg     [79:0] rom [0:511];
reg     [79:0]  tx_data_ram_r;
(* ASYNC_REG = "TRUE" *) (* keep = "true" *)    reg     system_reset_r; 
(* ASYNC_REG = "TRUE" *) (* keep = "true" *)    reg     system_reset_r2; //*********************************Main Body of Code**********************************assign tied_to_ground_vec_i  =   32'h00000000;assign tied_to_ground_i      =   1'b0;assign tied_to_vcc_i         =   1'b1;//___________ synchronizing the async reset for ease of timing simulation ________always@(posedge USER_CLK)beginsystem_reset_r <= `DLY SYSTEM_RESET;system_reset_r2 <= `DLY system_reset_r;end//____________________________ Counter to read from BRAM __________________________    always @(posedge USER_CLK)if(system_reset_r2 || (read_counter_i == "111111111"))  beginread_counter_i   <=  `DLY    9'd0;endelse read_counter_i   <=  `DLY    read_counter_i + 9'd1;// Assign TX_DATA_OUT to BRAM outputalways @(posedge USER_CLK)if(system_reset_r2) TX_DATA_OUT <= `DLY 80'h0000000000; else             TX_DATA_OUT <= `DLY {tx_data_bram_i,tx_data_ram_r[15:0]};   // Assign TXCTRL_OUT to BRAM outputalways @(posedge USER_CLK)if(system_reset_r2) TXCTRL_OUT <= `DLY 8'h0; else             TXCTRL_OUT <= `DLY tx_ctrl_i;  //________________________________ BRAM Inference Logic _____________________________    assign tx_data_bram_i      = tx_data_ram_r[79:16];assign tx_ctrl_i           = tx_data_ram_r[15:8];initialbegin$readmemh("gt_rom_init_tx.dat",rom,0,511);endalways @(posedge USER_CLK)tx_data_ram_r <= `DLY rom[read_counter_i];endmodule 

我们打开gt_rom_init_tx.dat文件,可以发现数据源是连接递增的数据
在这里插入图片描述

4.3 gtwizard_0_GT_FRAME_CHECK.v

`timescale 1ns / 1ps
`define DLY #1//***********************************Entity Declaration************************
(* DowngradeIPIdentifiedWarnings="yes" *)
module gtwizard_0_GT_FRAME_CHECK #
(// parameter to set the number of words in the BRAMparameter   RX_DATA_WIDTH            =  64,parameter   RXCTRL_WIDTH             =  2,parameter   WORDS_IN_BRAM            =  512,parameter   CHANBOND_SEQ_LEN         =  1,parameter   COMMA_DOUBLE             =  16'hf628,parameter   START_OF_PACKET_CHAR     =  64'h00000000000000fb
)                            
(// User Interfaceinput  wire [(RX_DATA_WIDTH-1):0] RX_DATA_IN,input  wire [(RXCTRL_WIDTH-1):0] RXCTRL_IN,output reg          RXENPCOMMADET_OUT,output reg          RXENMCOMMADET_OUT,output reg          RX_ENCHAN_SYNC_OUT,input  wire         RX_CHANBOND_SEQ_IN,// Control Interfaceinput  wire         INC_IN,output wire         INC_OUT,output wire         PATTERN_MATCHB_OUT,input  wire         RESET_ON_ERROR_IN,// Error Monitoringoutput wire [7:0]   ERROR_COUNT_OUT,// Track Dataoutput wire         TRACK_DATA_OUT,output wire RX_SLIDE,// System Interfaceinput  wire         USER_CLK,input  wire         SYSTEM_RESET 
);//***************************Internal Register Declarations******************** reg             reset_on_error_in_r;
reg             reset_on_error_in_r2;
(* ASYNC_REG = "TRUE" *) (* keep = "true" *)reg             system_reset_r;
(* ASYNC_REG = "TRUE" *) (* keep = "true" *)reg             system_reset_r2;reg             begin_r;
reg             data_error_detected_r;
reg     [8:0]   error_count_r;
reg             error_detected_r;
reg     [9:0]   read_counter_i;    reg     [79:0] rom [0:511];    reg     [(RX_DATA_WIDTH-1):0] rx_data_r;reg     [(RX_DATA_WIDTH-1):0] rx_data_r_track;reg             start_of_packet_detected_r;    
reg             track_data_r;
reg             track_data_r2;
reg             track_data_r3;
reg     [79:0]  rx_data_ram_r;reg     [(RX_DATA_WIDTH-1):0] rx_data_r2;reg     [(RX_DATA_WIDTH-1):0] rx_data_r3;reg     [(RX_DATA_WIDTH-1):0] rx_data_r4;reg     [(RX_DATA_WIDTH-1):0] rx_data_r5;reg     [(RX_DATA_WIDTH-1):0] rx_data_r6;reg     [(RXCTRL_WIDTH-1):0]  rxctrl_r;reg     [(RXCTRL_WIDTH-1):0]  rxctrl_r2;reg     [(RXCTRL_WIDTH-1):0]  rxctrl_r3;reg             rx_chanbond_seq_r;
reg             rx_chanbond_seq_r2;
reg             rx_chanbond_seq_r3; reg             idle_slip_r;reg             slip_assert_r;reg             wait_state_r;reg             bit_align_r;reg     [6:0]   wait_before_slip_r;reg     [6:0]   wait_before_init_r;    reg     [1:0]   sel;
//*********************************Wire Declarations***************************wire    [(RX_DATA_WIDTH-1):0] bram_data_r;
wire            error_detected_c;
wire            next_begin_c;
wire            next_data_error_detected_c;
wire            next_track_data_c;
wire            start_of_packet_detected_c;
wire            chanbondseq_in_data;
wire            input_to_chanbond_data_i;
wire            input_to_chanbond_reg_i;
wire    [(CHANBOND_SEQ_LEN-1):0]  rx_chanbond_reg;
wire            rxdata_or;
wire            count_slip_complete_c;
wire            next_idle_slip_c;
wire            next_slip_assert_c;
wire            wait_state_c;wire    [(RX_DATA_WIDTH-1):0]  rx_data_aligned;
wire            rx_data_has_start_char_c;
wire            tied_to_ground_i;
wire    [31:0]  tied_to_ground_vec_i;
wire            tied_to_vcc_i;//*********************************Main Body of Code***************************//_______________________  Static signal Assigments _______________________   assign tied_to_ground_i             = 1'b0;assign tied_to_ground_vec_i         = 32'h0000;assign tied_to_vcc_i                = 1'b1;//___________ synchronizing the async reset for ease of timing simulation ________always@(posedge USER_CLK)beginsystem_reset_r <= `DLY SYSTEM_RESET;    system_reset_r2 <= `DLY system_reset_r; end   always@(posedge USER_CLK)beginreset_on_error_in_r <= `DLY RESET_ON_ERROR_IN;    reset_on_error_in_r2 <= `DLY reset_on_error_in_r;    end   //______________________ Register RXDATA once to ease timing ______________   always @(posedge USER_CLK)beginrx_data_r  <= `DLY    RX_DATA_IN;rx_data_r2 <= `DLY    rx_data_r;end always @(posedge USER_CLK)beginrxctrl_r  <= `DLY    RXCTRL_IN;end//________________________________ State machine __________________________    // State registersalways @(posedge USER_CLK)if(system_reset_r2){begin_r,track_data_r,data_error_detected_r}  <=  `DLY    3'b100;elsebeginbegin_r                <=  `DLY    next_begin_c;track_data_r           <=  `DLY    next_track_data_c;data_error_detected_r  <=  `DLY    next_data_error_detected_c;end// Next state logicassign  next_begin_c                =   (begin_r && !start_of_packet_detected_r)|| data_error_detected_r ;assign  next_track_data_c           =   (begin_r && start_of_packet_detected_r)|| (track_data_r && !error_detected_r);assign  next_data_error_detected_c  =   (track_data_r && error_detected_r);                               assign  start_of_packet_detected_c  =   rx_data_has_start_char_c;always @(posedge USER_CLK) start_of_packet_detected_r    <=   `DLY  start_of_packet_detected_c;  // Registering for timingalways @(posedge USER_CLK) track_data_r2    <=   `DLY  track_data_r;  always @(posedge USER_CLK) track_data_r3    <=   `DLY  track_data_r2; //______________________________ Capture incoming data ____________________    always @(posedge USER_CLK)beginif(system_reset_r2)    rx_data_r3 <= 'h0;elsebeginif(sel == 2'b01)beginrx_data_r3   <=  `DLY    {rx_data_r[(RX_DATA_WIDTH/2 - 1):0],rx_data_r2[(RX_DATA_WIDTH-1):RX_DATA_WIDTH/2]};  endelse rx_data_r3  <=  `DLY    rx_data_r2;endendalways @(posedge USER_CLK)beginif(system_reset_r2)  beginrx_data_r4      <=  `DLY   'h0;rx_data_r5      <=  `DLY   'h0;rx_data_r6      <=  `DLY   'h0;rx_data_r_track <=  `DLY   'h0;endelsebeginrx_data_r4      <=  `DLY    rx_data_r3;rx_data_r5      <=  `DLY    rx_data_r4;rx_data_r6      <=  `DLY    rx_data_r5;rx_data_r_track <=  `DLY    rx_data_r6;endendalways @(posedge USER_CLK)beginif(system_reset_r2)  beginrxctrl_r2      <=  `DLY   'h0;rxctrl_r3      <=  `DLY   'h0;endelsebeginrxctrl_r2      <=  `DLY   rxctrl_r;rxctrl_r3      <=  `DLY   rxctrl_r2;endendassign rx_data_aligned = rx_data_r3;//___________________________ Code for Channel bonding ____________________    // code to prevent checking of clock correction sequences for the start of packet charalways @(posedge USER_CLK)beginrx_chanbond_seq_r  <=  `DLY    RX_CHANBOND_SEQ_IN;rx_chanbond_seq_r2 <=  `DLY    rx_chanbond_seq_r;rx_chanbond_seq_r3 <=  `DLY    rx_chanbond_seq_r2;endassign input_to_chanbond_reg_i  = rx_chanbond_seq_r2;assign input_to_chanbond_data_i = tied_to_ground_i;//______________ Code for Bit Slipping Logic______________assign rxdata_or = |(rx_data_r|rx_data_r2|rx_data_r3);// State registersalways @(posedge USER_CLK)if( (system_reset_r2 == 1'b1) | (wait_before_init_r[6] == 1'b0) | (rxdata_or == 1'b0) ){idle_slip_r,slip_assert_r,wait_state_r}  <=  `DLY    3'b100;elsebeginidle_slip_r            <=  `DLY    next_idle_slip_c;slip_assert_r          <=  `DLY    next_slip_assert_c;wait_state_r           <=  `DLY    wait_state_c;end// Next state logicassign  next_idle_slip_c            =   (idle_slip_r & bit_align_r) | (wait_state_r & count_slip_complete_c);assign  next_slip_assert_c          =   (idle_slip_r & !bit_align_r);assign  wait_state_c                =   (slip_assert_r) | (wait_state_r & !count_slip_complete_c);//_______ Counter for waiting clock cycles after RXSLIDE________always @(posedge USER_CLK)beginif (!wait_state_r)wait_before_slip_r  <= `DLY  7'b000000;elsewait_before_slip_r  <= `DLY  wait_before_slip_r + 1'b1;end//_______ Counter for waiting clock cycles before starting RXSLIDE operation________//_______ Wait for 64 clock cycles to see if the RXDATA is already byte aligned. If not, start RXSLIDE operationalways @(posedge USER_CLK)begin	    if( (system_reset_r2 == 1'b1) | (rxdata_or == 1'b0) )wait_before_init_r <= `DLY    7'b0000000;else if (wait_before_init_r[6] == 1'b0)wait_before_init_r <= `DLY    wait_before_init_r + 1'b1;endassign count_slip_complete_c = wait_before_slip_r[6];always @(posedge USER_CLK)beginif( (system_reset_r2 == 1'b1) | (rxdata_or == 1'b0) )   beginbit_align_r <= 1'b0;end else beginif( ({rx_data_r[7:0],rx_data_r2[15:8]} == START_OF_PACKET_CHAR) || (rx_data_r[15:0]== START_OF_PACKET_CHAR) )beginbit_align_r <= 1'b1;endendend// In 2 Byte scenario, when align_comma_word=1, Comma can appear on any of the two bytes// The comma is moved to the lower byte so that error checking can startalways @(posedge USER_CLK)beginif(reset_on_error_in_r2 || system_reset_r2)    sel <= 2'b00;else if (begin_r && !rx_chanbond_seq_r)begin// if Comma appears on BYTE0 ..if((rx_data_r[(RX_DATA_WIDTH/2 - 1):0] == START_OF_PACKET_CHAR[7:0]) && rxctrl_r[0])sel <= 2'b00;// if Comma appears on BYTE1 ..            else if((rx_data_r[(RX_DATA_WIDTH-1):RX_DATA_WIDTH/2] == START_OF_PACKET_CHAR[7:0]) && rxctrl_r[1])beginsel <= 2'b01;endend      end//___________________________ Code for Channel bonding ____________________    // code to prevent checking of clock correction sequences for the start of packet chargenvar i; generatefor (i=0;i<CHANBOND_SEQ_LEN ;i=i+1)begin:register_chan_seqif(i==0)FD rx_chanbond_reg_0  ( .Q (rx_chanbond_reg[i]), .D (input_to_chanbond_reg_i), .C(USER_CLK));elseFD rx_chanbond_reg_i  ( .Q (rx_chanbond_reg[i]), .D (rx_chanbond_reg[i-1]), .C(USER_CLK));endendgenerateassign chanbondseq_in_data = |rx_chanbond_reg || input_to_chanbond_data_i;assign rx_data_has_start_char_c = (rx_data_aligned[7:0] == START_OF_PACKET_CHAR[7:0]) && !chanbondseq_in_data && (|rxctrl_r3);//_____________________________ Assign output ports _______________________    //assign TRACK_DATA_OUT = track_data_r;assign RX_SLIDE = slip_assert_r;// Drive the enpcommaalign port of the gt for alignmentalways @(posedge USER_CLK)if(system_reset_r2)  RXENPCOMMADET_OUT   <=  `DLY    1'b0;else              RXENPCOMMADET_OUT   <=  `DLY    1'b1;// Drive the enmcommaalign port of the gt for alignmentalways @(posedge USER_CLK)if(system_reset_r2)  RXENMCOMMADET_OUT   <=  `DLY    1'b0;else              RXENMCOMMADET_OUT   <=  `DLY    1'b1;assign INC_OUT =  start_of_packet_detected_c;   assign PATTERN_MATCHB_OUT =  data_error_detected_r;// Drive the enchansync port of the mgt for channel bondingalways @(posedge USER_CLK)if(system_reset_r2)  RX_ENCHAN_SYNC_OUT   <=  `DLY    1'b0;else              RX_ENCHAN_SYNC_OUT   <=  `DLY    1'b1;//___________________________ Check incoming data for errors ______________//An error is detected when data read for the BRAM does not match the incoming dataassign  error_detected_c    =  track_data_r3 && (rx_data_r_track != bram_data_r); //We register the error_detected signal for use with the error counter logicalways @(posedge USER_CLK)if(!track_data_r)  error_detected_r    <=  `DLY    1'b0;elseerror_detected_r    <=  `DLY    error_detected_c;  //We count the total number of errors we detect. By keeping a count we make it less likely that we will miss//errors we did not directly observe. always @(posedge USER_CLK)if(system_reset_r2)error_count_r       <=  `DLY    9'd0;else if(error_detected_r)error_count_r       <=  `DLY    error_count_r + 1;    //Here we connect the lower 8 bits of the count (the MSbit is used only to check when the counter reaches//max value) to the module outputassign  ERROR_COUNT_OUT =   error_count_r[7:0];localparam ST_LINK_DOWN = 1'b0;localparam ST_LINK_UP   = 1'b1;reg        sm_link      = ST_LINK_DOWN;reg [6:0]  link_ctr     = 7'd0;always @(posedge USER_CLK) beginif(!track_data_r)  sm_link  <= ST_LINK_DOWN;else       case (sm_link)// The link is considered to be down when the link counter initially has a value less than 67. When the link is// down, the counter is incremented on each cycle where all PRBS bits match, but reset whenever any PRBS mismatch// occurs. When the link counter reaches 67, transition to the link up state.ST_LINK_DOWN: beginif (error_detected_r !== 1'b0) beginlink_ctr <= 7'd0;endelse beginif (link_ctr < 7'd67)link_ctr <= link_ctr + 7'd1;elsesm_link <= ST_LINK_UP;endend// When the link is up, the link counter is decreased by 34 whenever any PRBS mismatch occurs, but is increased by// only 1 on each cycle where all PRBS bits match, up to its saturation point of 67. If the link counter reaches// 0 (including rollover protection), transition to the link down state.ST_LINK_UP: beginif (error_detected_r !== 1'b0) beginif (link_ctr > 7'd33) beginlink_ctr <= link_ctr - 7'd34;if (link_ctr == 7'd34)sm_link  <= ST_LINK_DOWN;endelse beginlink_ctr <= 7'd0;sm_link  <= ST_LINK_DOWN;endendelse beginif (link_ctr < 7'd67)link_ctr <= link_ctr + 7'd1;endendendcaseendassign TRACK_DATA_OUT = sm_link;//____________________________ Counter to read from BRAM __________________________    always @(posedge USER_CLK)if(system_reset_r2 ||  (read_counter_i == (WORDS_IN_BRAM-1)))beginread_counter_i   <=  `DLY    10'd0;endelse if (start_of_packet_detected_r && !track_data_r)beginread_counter_i   <=  `DLY    10'd0;endelsebeginread_counter_i  <=  `DLY    read_counter_i + 10'd1;end//________________________________ BRAM Inference Logic _____________________________    //Array slice from dat file to compare against receive data  
generate
if(RX_DATA_WIDTH==80)
begin : datapath_80assign bram_data_r      = rx_data_ram_r[(RX_DATA_WIDTH-1):0];
end
else
begin : datapath_16_20_32_40_64assign bram_data_r = rx_data_ram_r[(16+RX_DATA_WIDTH-1):16];
end 
endgenerateinitialbegin$readmemh("gt_rom_init_rx.dat",rom,0,511);endalways @(posedge USER_CLK)rx_data_ram_r <= `DLY  rom[read_counter_i];endmodule           

可以换成自己的检测逻辑,或者不修改使用,我这里是使用了。

5. 仿真测试

代码分析完后对整个的GT框架是不是有一定的了解了,接着我们就开始仿真吧。官方的demo例程不需要修改,直接Run Simulation就可以啦!
我们来看下波形,重点关注gt0_txdatagt0_rxdata、就行。
在这里插入图片描述
在这里插入图片描述

发送的数据和接收的数据一致,跑到差不多600us的时候track_data_high_r信号会拉高,仿真结束,打印消息。

最后打印信息中显示test passed
在这里插入图片描述

http://www.lryc.cn/news/585503.html

相关文章:

  • Kubernetes 高级调度特性
  • 基于kafka的分布式日志收集与实时监控平台(原理,框架)
  • Spring MVC中异常处理
  • unity VR linerenderer的线会被UI盖住
  • 博客系统开发全流程解析(前端+后端+数据库)与 AI 协作初体验
  • [electron]升级功能
  • Android 12系统源码_分屏模式(一)从最近任务触发分屏模式
  • 有限状态机FSM(Finite State Machine)自动初始化
  • 提升你的AI交互技能:使用Anthropic互动提示教程
  • 2025年亚太中文赛B题第一版本超详细解题思路
  • CMU15445-2024fall-project1踩坑经历
  • 学弟让我帮忙写一个学生管理系统的后端,我直接上科技
  • 【八股消消乐】浅尝Kafka性能优化
  • IAR携手矽力杰与普华基础软件,共推RISC-V车规芯片高安全应用落地
  • 必备软件推荐:1、Everything:Windows 文件查找的终极利器
  • PyInstaller打包完整指南1
  • 【web应用】若依框架前端报表制作与导出全攻略(ECharts + html2canvas + jsPDF)
  • 8-day06预训练模型
  • CReFT-CAD 笔记 带标注工程图dxf,png数据集
  • 上位机知识篇---常见的文件系统
  • 灰盒级SOA测试工具Parasoft SOAtest重新定义端到端测试
  • QT控件 使用QtServer系统服务实现搭建Aria2下载后台服务,并使用Http请求访问Json-RPC接口调用下载退出
  • 《月亮与六便士》:天才的背叛与凡人救赎的残酷辩证法
  • 【时时三省】(C语言基础)通过指针引用数组元素
  • 计算机网络第三章(6)——数据链路层《网桥交换机》
  • 【中文核心期刊推荐】中国农业科技导报
  • 2025最新版Docker讲解/面试/命令/容器化技术
  • 什么是Podman?能否替代Docker?Podman快速入门
  • 雨污管网智慧监测系统网络建设方案:基于SD-WAN混合架构的最佳实践
  • 第三方渗透测试:范围咋定?需供应商同意吗?