OpenCores
URL https://opencores.org/ocsvn/pcie_sg_dma/pcie_sg_dma/trunk

Subversion Repositories pcie_sg_dma

[/] [pcie_sg_dma/] [trunk/] [sim/] [tf64_pcie_trn.v] - Rev 4

Compare with Previous | Blame | View Log

`timescale 1ns / 1ps
 
////////////////////////////////////////////////////////////////////////////////
// Company:  ziti, Uni. HD
// Engineer:  wgao
//            weng.ziti@gmail.com
// 
// Create Date:   16:54:18 04 Nov 2008
// Design Name:   tlpControl
// Module Name:   tf64_pcie_trn.v
// Project Name:  PCIE_SG_DMA
// Target Device:  
// Tool versions:  
// Description:  PIO and DMA are both simulated.
//
// Verilog Test Fixture created by ISE for module: tlpControl
//
// Dependencies:
// 
// Revision:
// Revision 0.01 - File Created
// 
// Revision 1.00 - Released to OpenCores.org   14.09.2011
// 
// Additional Comments:
// 
////////////////////////////////////////////////////////////////////////////////
 
 
//`define  RANDOM_SEQUENCE
 
  /*  Time parameters  */
`define  T_HALF_CYCLE_CLK                   4.0
`define  T_HALF_CYCLE_MEMCLK                5.0
`define  T_DELAY_AFTER                      0.0
`define  T_DELTA                            0.1
`define  T_PIO_INTERVAL                    50.0
`define  T_DMA_INTERVAL                   300.0
`define  T_RX_NO_FC_PERIOD            1900000.0
`define  T_TX_NO_FC_PERIOD            1500000.0
 
  /* Memory size for simulation */
`define  C_ARRAY_DIMENSION              4096
 
  /* Start indices */
`define  PIO_START_INDEX                'H0300
`define  DMA_START_INDEX                'H0000
 
  /* Request completion boundary */
`define  C_RCB_16_DW                    'H10
`define  C_RCB_32_DW                    'H20
 
  /* BAR */
`define  C_BAR0_HIT                    7'H7E
`define  C_BAR1_HIT                    7'H7D
`define  C_BAR2_HIT                    7'H7B
`define  C_BAR3_HIT                    7'H77
`define  C_BAR4_HIT                    7'H6F
`define  C_BAR5_HIT                    7'H5F
`define  C_BAR6_HIT                    7'H3F
`define  C_NO_BAR_HIT                  7'H7F
 
 
  /* Requester ID and Completer ID */
`define  C_HOST_WRREQ_ID              16'H0ABC
`define  C_HOST_RDREQ_ID              16'HE1E2
`define  C_HOST_CPLD_ID               16'HC01D
 
  /* 1st header */
`define  HEADER0_MWR3_                32'H40000000
`define  HEADER0_MWR4_                32'H60000000
`define  HEADER0_MRD3_                32'H00000000
`define  HEADER0_MRD4_                32'H20000000
`define  HEADER0_CPLD                 32'H4A000000
`define  HEADER0_CPL                  32'H0A000000
`define  HEADER0_MSG                  32'H34000001
 
  /* Message codes */
`define  C_MSG_CODE_INTA               8'H20
`define  C_MSG_CODE_INTA_N             8'H24
 
  /* Payload type */
`define  USE_PRIVATE                    1
`define  USE_PUBLIC                     0
 
  /* General registers */
`define  C_ADDR_VERSION                 32'H0000
`define  C_ADDR_IRQ_STAT                32'H0008
`define  C_ADDR_IRQ_EN                  32'H0010
`define  C_ADDR_GSR                     32'H0020
`define  C_ADDR_GCR                     32'H0028
 
  /* Control registers for special ports */
`define  C_ADDR_MRD_CTRL                32'H0074
`define  C_ADDR_TX_CTRL                 32'H0078
`define  C_ADDR_ICAP                    32'H007C
`define  C_ADDR_EB_STACON               32'H0090
 
  /* Downstream DMA channel registers */
`define  C_ADDR_DMA_DS_PAH              32'H0050
`define  C_ADDR_DMA_DS_CTRL             32'H006C
`define  C_ADDR_DMA_DS_STA              32'H0070
 
  /* Upstream DMA channel registers */
`define  C_ADDR_DMA_US_PAH              32'H002C
`define  C_ADDR_DMA_US_CTRL             32'H0048
`define  C_ADDR_DMA_US_STA              32'H004C
 
  /* DMA-specific constants */
`define  C_DMA_RST_CMD                  32'H0200000A
 
 
module tf64_pcie_trn();
 
   // Inputs
   reg  trn_reset_n;
   reg  trn_lnk_up_n;
   reg  trn_clk;
   reg  trn_rsof_n;
   reg  trn_reof_n;
   reg  [63:0] trn_rd;
   reg  [7:0] trn_rrem_n;
   reg  trn_rsrc_rdy_n;
   wire trn_rdst_rdy_n;
   reg  [6:0] trn_rbar_hit_n;
   wire trn_rnp_ok_n;
   reg  trn_rerrfwd_n;
   reg  trn_rsrc_dsc_n;
   wire trn_tsof_n;
   wire trn_teof_n;
   wire [63:0] trn_td;
   wire [7:0] trn_trem_n;
   wire trn_tsrc_rdy_n;
   reg  trn_tdst_rdy_n;
   wire trn_terrfwd_n;
   wire trn_tsrc_dsc_n;
   reg  trn_tdst_dsc_n;
   reg  [3:0] trn_tbuf_av;
//   reg cfg_interrupt_rdy_n;
//   reg [2:0] cfg_interrupt_mmenable;
//   reg cfg_interrupt_msienable;
//   reg [7:0] cfg_interrupt_do;
   reg [5:0] pcie_link_width;
   reg [15:0] cfg_dcommand;
   reg [15:0] localID;
 
   // Outputs
   wire DDR_wr_v;
   wire DDR_wr_sof;
   wire DDR_wr_eof;
   wire DDR_wr_Shift;
   wire [1:0] DDR_wr_Mask;
   wire [63:0] DDR_wr_din;
   wire DDR_wr_full;
   wire DDR_rdc_v;
   wire DDR_rdc_sof;
   wire DDR_rdc_eof;
   wire DDR_rdc_Shift;
   wire [63:0] DDR_rdc_din;
   wire DDR_rdc_full;
   wire DDR_FIFO_RdEn;
   wire DDR_FIFO_Empty;
   wire [63:0] DDR_FIFO_RdQout;
   reg  mbuf_UserFull;
   wire DDR_Ready;
   wire trn_Blinker;
   reg  mem_clk;
 
   // FIFO
   wire           eb_FIFO_we; 
   wire [64-1:00] eb_FIFO_din;
   wire           eb_FIFO_re; 
   wire [72-1:00] eb_FIFO_qout;
   wire [64-1:00] eb_FIFO_Status;
   wire           eb_FIFO_Rst;
 
   wire           eb_pfull;
   wire           eb_full;
   wire           eb_pempty;
   wire           eb_empty;
 
   wire [27-1:0]  eb_FIFO_Data_Count;
 
   // flow control toggles
   reg            Rx_No_Flow_Control;
   reg            Tx_No_Flow_Control;
 
   // message counters 
   reg  [31:00] Accum_Msg_INTA        = 0;
   reg  [31:00] Accum_Msg_INTA_n      = 0;
 
   // random seed
   reg [127: 0]  Op_Random;
 
   // Generated Array
   reg [15:00]  ii;
   reg [31:00]  D_Array[`C_ARRAY_DIMENSION-1:00];
 
   //
   reg  [ 7: 0] FSM_Trn;
   reg  [31: 0] Hdr_Array[3:0];
   reg  [31: 0] Private_Array[15:0];
   reg  [10: 0] Rx_TLP_Length;
   reg  [ 7: 0] Rx_MWr_Tag;
   reg  [ 4: 0] Rx_MRd_Tag;
   reg  [31:00] Tx_MRd_Addr;
   reg  [31:00] Tx_MRd_Leng;
   reg  [10: 0] tx_MRd_Length;
   reg  [ 7: 0] tx_MRd_Tag;
   reg  [ 7: 0] tx_MRd_Tag_k;
 
   reg  [31:00] DMA_PA;
   reg  [63:00] DMA_HA;
   reg  [63:00] DMA_BDA;
   reg  [31:00] DMA_Leng;
   reg  [31:00] DMA_L1;
   reg  [31:00] DMA_L2;
   reg  [02:00] DMA_bar;
   reg          DMA_ds_is_Last;
   reg          DMA_us_is_Last;
   reg  [31:00] CplD_Index;
 
   reg          Desc_tx_MRd_Valid;
   reg  [10:00] Desc_tx_MRd_Leng;
   reg  [31:00] Desc_tx_MRd_Addr;
   reg  [07:00] Desc_tx_MRd_TAG;
   reg          tx_MRd_come;
 
   reg  [63:00] PIO_Addr;
   reg  [31:00] PIO_Leng;
   reg  [ 3:00] PIO_1st_BE;
   reg  [ 6:00] PIO_bar;
 
   //
   wire           DBG_dma_start;
 
 
 
	// Instantiate the Unit Under Test (UUT)
	tlpControl uut (
		.mbuf_UserFull(mbuf_UserFull), 
		.trn_Blinker(trn_Blinker), 
      .eb_FIFO_we     (eb_FIFO_we    ) , //          : OUT std_logic; 
      .eb_FIFO_din    (eb_FIFO_din   ) , //          : OUT std_logic_vector(C_DBUS_WIDTH-1 downto 0);
      .eb_FIFO_re     (eb_FIFO_re    ) , //          : OUT std_logic; 
      .eb_FIFO_empty  (eb_empty      ) , //          : IN  std_logic; 
      .eb_FIFO_qout   (eb_FIFO_qout[63:0]  ) , //          : IN  std_logic_vector(C_DBUS_WIDTH-1 downto 0);
      .eb_FIFO_Data_Count   (eb_FIFO_Data_Count  ) , //          : IN  std_logic_vector(C_DBUS_WIDTH-1 downto 0);
      .eb_FIFO_Status (eb_FIFO_Status) , //          : IN  std_logic_vector(C_DBUS_WIDTH-1 downto 0);
      .eb_FIFO_Rst    (eb_FIFO_Rst   ) , //          : OUT std_logic;
      .Link_Buf_full  (eb_pfull   ) ,
      .DMA_ds_Start   (DBG_dma_start),
		.DDR_Ready      (DDR_Ready), 
		.DDR_wr_sof(DDR_wr_sof), 
		.DDR_wr_eof(DDR_wr_eof), 
		.DDR_wr_v(DDR_wr_v), 
		.DDR_wr_FA(   ), 
		.DDR_wr_Shift(DDR_wr_Shift), 
		.DDR_wr_Mask(DDR_wr_Mask), 
		.DDR_wr_din(DDR_wr_din), 
		.DDR_wr_full(DDR_wr_full), 
		.DDR_rdc_sof(DDR_rdc_sof), 
		.DDR_rdc_eof(DDR_rdc_eof), 
		.DDR_rdc_v(DDR_rdc_v), 
		.DDR_rdc_FA(   ), 
      .DDR_rdc_Shift(DDR_rdc_Shift),
		.DDR_rdc_din(DDR_rdc_din), 
		.DDR_rdc_full(DDR_rdc_full), 
		.DDR_FIFO_RdEn(DDR_FIFO_RdEn), 
		.DDR_FIFO_Empty(DDR_FIFO_Empty), 
		.DDR_FIFO_RdQout(DDR_FIFO_RdQout), 
		.trn_clk(trn_clk), 
		.trn_reset_n(trn_reset_n), 
		.trn_lnk_up_n(trn_lnk_up_n), 
		.trn_rsof_n(trn_rsof_n), 
		.trn_reof_n(trn_reof_n), 
		.trn_rd(trn_rd), 
      .trn_rrem_n(trn_rrem_n),
		.trn_rerrfwd_n(trn_rerrfwd_n), 
		.trn_rsrc_rdy_n(trn_rsrc_rdy_n), 
		.trn_rdst_rdy_n(trn_rdst_rdy_n), 
		.trn_rnp_ok_n(trn_rnp_ok_n), 
		.trn_rsrc_dsc_n(trn_rsrc_dsc_n), 
		.trn_rbar_hit_n(trn_rbar_hit_n), 
		.trn_tsof_n(trn_tsof_n), 
		.trn_teof_n(trn_teof_n), 
		.trn_td(trn_td), 
      .trn_trem_n(trn_trem_n),
		.trn_terrfwd_n(trn_terrfwd_n), 
		.trn_tsrc_rdy_n(trn_tsrc_rdy_n), 
		.trn_tdst_rdy_n(trn_tdst_rdy_n), 
		.trn_tsrc_dsc_n(trn_tsrc_dsc_n), 
		.trn_tdst_dsc_n(trn_tdst_dsc_n), 
		.trn_tbuf_av(trn_tbuf_av), 
//		.cfg_interrupt_n(cfg_interrupt_n), 
//		.cfg_interrupt_rdy_n(cfg_interrupt_rdy_n), 
//		.cfg_interrupt_mmenable(cfg_interrupt_mmenable), 
//		.cfg_interrupt_msienable(cfg_interrupt_msienable), 
//		.cfg_interrupt_di(cfg_interrupt_di), 
//		.cfg_interrupt_do(cfg_interrupt_do), 
//		.cfg_interrupt_assert_n(cfg_interrupt_assert_n), 
		.pcie_link_width(pcie_link_width), 
		.cfg_dcommand(cfg_dcommand), 
		.localID(localID)
	);
 
 
 
	// Instantiate the BRAM module
   bram_Control
   bram_controller(
    .DDR_wr_sof(DDR_wr_sof), 
    .DDR_wr_eof(DDR_wr_eof), 
    .DDR_wr_v(DDR_wr_v), 
    .DDR_wr_FA(1'b0), 
    .DDR_wr_Shift(DDR_wr_Shift), 
    .DDR_wr_Mask(DDR_wr_Mask), 
    .DDR_wr_din(DDR_wr_din), 
//    .DDR_wr_full(DDR_wr_full), 
    .DDR_rdc_sof(DDR_rdc_sof), 
    .DDR_rdc_eof(DDR_rdc_eof), 
    .DDR_rdc_v(DDR_rdc_v), 
    .DDR_rdc_FA(1'b0), 
    .DDR_rdc_Shift(DDR_rdc_Shift),
    .DDR_rdc_din(DDR_rdc_din), 
    .DDR_rdc_full(DDR_rdc_full), 
    .DDR_FIFO_RdEn(DDR_FIFO_RdEn), 
    .DDR_FIFO_Empty(DDR_FIFO_Empty), 
    .DDR_FIFO_RdQout(DDR_FIFO_RdQout), 
    .DBG_dma_start(DBG_dma_start),
    .DDR_Ready(DDR_Ready), 
    .DDR_blinker(DDR_blinker), 
    .Sim_Zeichen(Sim_Zeichen), 
    .mem_clk(mem_clk), 
    .trn_clk(trn_clk), 
    .trn_reset_n(trn_reset_n)
    );
 
   assign  DDR_wr_full = 0;
 
 
	// Instantiate the FIFO module
   FIFO_wrapper
   queue_buffer(
         .wr_clk     (  trn_clk        ),
         .wr_en      (  eb_FIFO_we     ),
         .din        (  {8'H0, eb_FIFO_din}    ),
         .pfull      (  eb_pfull       ),
         .full       (  eb_full        ),
 
         .rd_clk     (  trn_clk        ),
         .rd_en      (  eb_FIFO_re     ),
         .dout       (  eb_FIFO_qout   ),
         .pempty     (  eb_pempty      ),
         .empty      (  eb_empty       ),
         .data_count (  eb_FIFO_Data_Count[14:1]),
 
         .rst        (  eb_FIFO_Rst    )
         );
 
   assign  eb_FIFO_Data_Count[26:15] = 0;
   assign  eb_FIFO_Data_Count[0] = 0;
   assign  eb_FIFO_Status = {34'H0, eb_FIFO_Data_Count, eb_pfull, eb_empty};
 
 
 
   // initialiation
	initial begin
		// Initialize Inputs
		trn_clk = 0;
      mem_clk = 1;
		trn_reset_n = 0;
		trn_lnk_up_n = 1;
		trn_rerrfwd_n = 1;
		trn_rsrc_dsc_n = 1;
		trn_tdst_dsc_n = 1;
		trn_tbuf_av = -1;
 
//		cfg_interrupt_rdy_n = 0;
//		cfg_interrupt_mmenable = 0;
//		cfg_interrupt_msienable = 0;
//		cfg_interrupt_do = 0;
 
		mbuf_UserFull = 0;
		pcie_link_width = 'H19;
      cfg_dcommand = 'H2000;
		localID = 'HD841;
 
      Rx_No_Flow_Control = 1;    // = 0;  // Set to 0 to enable the Rx throttling
      Tx_No_Flow_Control = 1;    // = 0;  // Set to 0 to enable the Tx throttling
 
		// Wait some nanoseconds for global reset to finish
		#100;
		trn_reset_n = 1;
		trn_lnk_up_n = 0;
 
		#10000;
//      $stop();
 
	end
 
   // trn_clk toggles
   always #`T_HALF_CYCLE_CLK
   trn_clk = ~trn_clk;
 
   // mem_clk toggles
   always #`T_HALF_CYCLE_MEMCLK
   mem_clk = ~mem_clk;
 
   // Randoms generated for process flow
   always @(posedge trn_clk) begin
     Op_Random[ 31:00] = $random();
     Op_Random[ 63:32] = $random();
     Op_Random[ 95:64] = $random();
     Op_Random[127:96] = $random();
   end
 
 
   /// Rx Flow Control
   always # `T_RX_NO_FC_PERIOD
   Rx_No_Flow_Control = ~Rx_No_Flow_Control;
 
   /// Tx Flow Control
   always # `T_TX_NO_FC_PERIOD
   Tx_No_Flow_Control = ~Tx_No_Flow_Control;
 
   // Signal prepared for trn_rsrc_rdy_n
   reg trn_rsrc_rdy_n_seed;
   always @(posedge trn_clk) begin
     trn_rsrc_rdy_n_seed <= Op_Random[8] & Op_Random[10] & ~Rx_No_Flow_Control;
   end
 
   // trn_tdst_rdy_n
   always @(posedge trn_clk )
   begin
     # `T_DELAY_AFTER
      trn_tdst_rdy_n <= (Op_Random[24] & Op_Random[21] & ~Tx_No_Flow_Control) | ~trn_reset_n;
   end
 
 
 
   // Initialization mem in host
   initial begin
     for (ii = 0; ii< `C_ARRAY_DIMENSION; ii= ii+1) begin
`ifdef  RANDOM_SEQUENCE
        D_Array[ii]    <= $random ();
`else
        D_Array[ii]    <= Inv_Endian ('H8760_0000 + ii + 1);
`endif
     end
   end
 
 
  //  Simulation procedure
  initial begin
 
    // Simulation Initialization
    FSM_Trn               <= 'H00;
    Gap_Insert_Rx;
 
    PIO_bar               <= -1;
    DMA_bar               <= 'H1;
    Rx_MWr_Tag            <= 'H80;
    Rx_MRd_Tag            <= 'H10;
 
 
    // Initialization: TLP
    # 400
      Rx_TLP_Length    <= 'H01;
 
    # `T_DELTA    // reset TX module
      Hdr_Array[0] <= `HEADER0_MWR3_ | Rx_TLP_Length[9:0];
      Hdr_Array[1] <= {`C_HOST_WRREQ_ID, Rx_MWr_Tag, 4'Hf, 4'Hf};
      Hdr_Array[2] <= `C_ADDR_TX_CTRL;
      Private_Array[0] <= 'H0000000A;
 
    # `T_DELTA
      TLP_Feed_Rx(`USE_PRIVATE, 'H0, `C_BAR0_HIT);
      Rx_MWr_Tag   <= Rx_MWr_Tag + 1;
      Gap_Insert_Rx;
 
 
    # `T_DELTA     // Test MRd with 4-DW header  BAR[0]
      Hdr_Array[0] <= `HEADER0_MRD4_ | Rx_TLP_Length[9:0];
      Hdr_Array[1] <= {`C_HOST_RDREQ_ID, 8'HA1, 4'Hf, 4'Hf};
      Hdr_Array[2] <= -1;
      Hdr_Array[3] <= `C_ADDR_VERSION;
 
 
    # `T_DELTA
      TLP_Feed_Rx(`USE_PRIVATE, 'H0, `C_BAR0_HIT);
      Gap_Insert_Rx;
 
 
    # 100
      Rx_TLP_Length    <= 'H01;
 
 
    # `T_DELTA    // reset upstream DMA channel
      Hdr_Array[0] <= `HEADER0_MWR3_ | Rx_TLP_Length[9:0];
      Hdr_Array[1] <= {`C_HOST_WRREQ_ID, Rx_MWr_Tag, 4'Hf, 4'Hf};
      Hdr_Array[2] <= `C_ADDR_DMA_US_CTRL;
      Private_Array[0] <= `C_DMA_RST_CMD;
 
    # `T_DELTA
      TLP_Feed_Rx(`USE_PRIVATE, 'H0, `C_BAR0_HIT);
      Rx_MWr_Tag   <= Rx_MWr_Tag + 1;
      Gap_Insert_Rx;
 
    # `T_DELTA    // reset downstream DMA channel
      Hdr_Array[0] <= `HEADER0_MWR4_ | Rx_TLP_Length[9:0];
      Hdr_Array[1] <= {`C_HOST_WRREQ_ID, Rx_MWr_Tag, 4'Hf, 4'Hf};
      Hdr_Array[2] <= -1;
      Hdr_Array[3] <= `C_ADDR_DMA_DS_CTRL;
      Private_Array[0] <= `C_DMA_RST_CMD;
 
    # `T_DELTA
      TLP_Feed_Rx(`USE_PRIVATE, 'H0, `C_BAR0_HIT);
      Rx_MWr_Tag   <= Rx_MWr_Tag + 1;
      Gap_Insert_Rx;
 
 
    # `T_DELTA    // reset Event Buffer FIFO
      Hdr_Array[0] <= `HEADER0_MWR3_ | Rx_TLP_Length[9:0];
      Hdr_Array[1] <= {`C_HOST_WRREQ_ID, Rx_MWr_Tag, 4'Hf, 4'Hf};
      Hdr_Array[2] <= `C_ADDR_EB_STACON;
      Private_Array[0] <= 'H0000000A;
 
    # `T_DELTA
      TLP_Feed_Rx(`USE_PRIVATE, 'H0, `C_BAR0_HIT);
      Rx_MWr_Tag   <= Rx_MWr_Tag + 1;
      Gap_Insert_Rx;
 
 
    # `T_DELTA    // Enable INTerrupts
      Hdr_Array[0] <= `HEADER0_MWR3_ | Rx_TLP_Length[9:0];
      Hdr_Array[1] <= {`C_HOST_WRREQ_ID, Rx_MWr_Tag, 4'Hf, 4'Hf};
      Hdr_Array[2] <= `C_ADDR_IRQ_EN;
      Private_Array[0] <= 'H0000_0003;
 
    # `T_DELTA
      TLP_Feed_Rx(`USE_PRIVATE, 'H0, `C_BAR0_HIT);
      Rx_MWr_Tag   <= Rx_MWr_Tag + 1;
      Gap_Insert_Rx;
 
 
 
 
    /////////////////////////////////////////////////////////////////////
    //                       PIO simulation                            //
    /////////////////////////////////////////////////////////////////////
 
 
     # `T_PIO_INTERVAL
       ;
 
       FSM_Trn          <= 'H04;
 
    //  ///////////////////////////////////////////////////////////////////
    //  PIO write & read BAR[0]
 
       PIO_Addr         <= `C_ADDR_DMA_US_PAH + 'H8;
       PIO_bar          <= `C_BAR0_HIT;
       PIO_1st_BE       <= 4'Hf;
       Gap_Insert_Rx;
       Hdr_Array[0]     <= `HEADER0_MWR3_ | Rx_TLP_Length[9:0];
       Hdr_Array[1]     <= {`C_HOST_WRREQ_ID, Rx_MWr_Tag, 4'Hf, PIO_1st_BE};
       Hdr_Array[2]     <= {PIO_Addr[31:2], 2'b00};
       Private_Array[0] <= 'HF000_8888;
       Rx_TLP_Length    <= 'H01;
     # `T_DELTA
       TLP_Feed_Rx(`USE_PRIVATE, 'H0, PIO_bar);
       Rx_MWr_Tag   <= Rx_MWr_Tag + 1;
       Gap_Insert_Rx;
 
     # `T_PIO_INTERVAL
       ;
 
     # `T_DELTA
       Hdr_Array[0]     <= `HEADER0_MRD3_ | Rx_TLP_Length[9:0];
       Hdr_Array[1]     <= {`C_HOST_RDREQ_ID, 3'H3, Rx_MRd_Tag, 4'Hf, PIO_1st_BE};
       Hdr_Array[2]     <= {PIO_Addr[31:2], 2'b00};
 
     # `T_DELTA
       TLP_Feed_Rx(`USE_PUBLIC, `PIO_START_INDEX, PIO_bar);
       Rx_MRd_Tag       <= Rx_MRd_Tag + 1;
       Gap_Insert_Rx;
 
       FSM_Trn          <= 'H08;
 
 
 
    //  ///////////////////////////////////////////////////////////////////
    //  PIO write & read BAR[1]
       PIO_Addr         <= 'H8000;
       PIO_bar          <= `C_BAR1_HIT;
       PIO_1st_BE       <= 4'Hf;
       Gap_Insert_Rx;
       Hdr_Array[0]     <= `HEADER0_MWR3_ | Rx_TLP_Length[9:0];
       Hdr_Array[1]     <= {`C_HOST_WRREQ_ID, Rx_MWr_Tag, 4'Hf, PIO_1st_BE};
       Hdr_Array[2]     <= {PIO_Addr[31:2], 2'b00};
       Private_Array[0] <= 'HA1111111;
       Rx_TLP_Length    <= 'H01;
     # `T_DELTA
       TLP_Feed_Rx(`USE_PRIVATE, 'H0, PIO_bar);
       Rx_MWr_Tag   <= Rx_MWr_Tag + 1;
       Gap_Insert_Rx;
 
     # `T_PIO_INTERVAL
       ;
 
     # `T_DELTA
       Hdr_Array[0]     <= `HEADER0_MRD3_ | Rx_TLP_Length[9:0];
       Hdr_Array[1]     <= {`C_HOST_RDREQ_ID, 3'H3, Rx_MRd_Tag, 4'Hf, PIO_1st_BE};
       Hdr_Array[2]     <= {PIO_Addr[31:2], 2'b00};
 
     # `T_DELTA
       TLP_Feed_Rx(`USE_PRIVATE, `PIO_START_INDEX, PIO_bar);
       Rx_MRd_Tag       <= Rx_MRd_Tag + 1;
       Gap_Insert_Rx;
 
       FSM_Trn          <= 'H10;
 
 
 
    //  ///////////////////////////////////////////////////////////////////
    //  PIO write & read BAR[2]
    //  NOTE:  FIFO address is 64-bit aligned, only the lower 32-bit is
    //         accessible by BAR[2] PIO write and is returned in BAR[2] 
    //         PIO read.
       PIO_Addr         <= 'H0;
       PIO_bar          <= `C_BAR2_HIT;
       PIO_1st_BE       <= 4'Hf;
       Gap_Insert_Rx;
       Hdr_Array[0]     <= `HEADER0_MWR3_ | Rx_TLP_Length[9:0];
       Hdr_Array[1]     <= {`C_HOST_WRREQ_ID, Rx_MWr_Tag, 4'Hf, PIO_1st_BE};
       Hdr_Array[2]     <= {PIO_Addr[31:2], 2'b00};
       Private_Array[0] <= 'HB222_2222;
       Rx_TLP_Length    <= 'H01;
     # `T_DELTA
       TLP_Feed_Rx(`USE_PRIVATE, 'H0, PIO_bar);
       Rx_MWr_Tag   <= Rx_MWr_Tag + 1;
       Gap_Insert_Rx;
 
     # `T_PIO_INTERVAL
       ;
 
     # `T_DELTA
       Hdr_Array[0]     <= `HEADER0_MRD3_ | Rx_TLP_Length[9:0];
       Hdr_Array[1]     <= {`C_HOST_RDREQ_ID, 3'H3, Rx_MRd_Tag, 4'Hf, PIO_1st_BE};
       Hdr_Array[2]     <= {PIO_Addr[31:2], 2'b00};
 
     # `T_DELTA
       TLP_Feed_Rx(`USE_PUBLIC, `PIO_START_INDEX, PIO_bar);
       Rx_MRd_Tag       <= Rx_MRd_Tag + 1;
       Gap_Insert_Rx;
 
       FSM_Trn          <= 'H14;
 
 
 
     # `T_DMA_INTERVAL
       ;
 
 
    //  ///////////////////////////////////////////////////////////////////
    //  DMA write & read BAR[1]
    //  Single-descriptor case
 
       DMA_PA   <= 'H1234;
       DMA_HA   <= 'H5000;
       DMA_BDA  <= 'Hffff;
		 DMA_Leng <= 'H0100;
       DMA_bar  <= 'H1;
       DMA_ds_is_Last  <= 'B1;
 
     # `T_DELTA
       // Initial DMA descriptor
       Private_Array[0] <= -1;
       Private_Array[1] <= DMA_PA[31:00];       //'H0300;
       Private_Array[2] <= DMA_HA[63:32];       // 0;
       Private_Array[3] <= DMA_HA[31:00];       // 'H4000;
       Private_Array[4] <= DMA_BDA[63:32];      // 0;
       Private_Array[5] <= DMA_BDA[31:00];      //'H0BDA0090;
       Private_Array[6] <= DMA_Leng;            //'H100;
       Private_Array[7] <=  {4'H0
                            ,3'H1, DMA_ds_is_Last
                            ,3'H0, 1'B1
                            ,1'B0, DMA_bar
                            ,1'B1
                            ,15'H0
                            };
 
 
       //  DMA write
 
       Rx_TLP_Length    <= 'H01;
 
     # `T_DELTA
       Hdr_Array[0] <= `HEADER0_MWR3_ | Rx_TLP_Length[9:0];
       Hdr_Array[1] <= {`C_HOST_WRREQ_ID, Rx_MWr_Tag, 4'Hf, 4'Hf};
       Hdr_Array[2] <= `C_ADDR_DMA_DS_PAH;
 
       //  Write PA_H
     # `T_DELTA
       TLP_Feed_Rx(`USE_PRIVATE, 'H0, `C_BAR0_HIT);
       Rx_MWr_Tag   <= Rx_MWr_Tag + 1;
       Gap_Insert_Rx;
       Gap_Insert_Rx;
 
       //  Write PA_L
       Hdr_Array[2] <= Hdr_Array[2] + 'H4;
     # `T_DELTA
       TLP_Feed_Rx(`USE_PRIVATE, 'H1, `C_BAR0_HIT);
       Rx_MWr_Tag   <= Rx_MWr_Tag + 1;
       Gap_Insert_Rx;
       Gap_Insert_Rx;
 
       //  Write HA_H
       Hdr_Array[2] <= Hdr_Array[2] + 'H4;
     # `T_DELTA
       TLP_Feed_Rx(`USE_PRIVATE, 'H2, `C_BAR0_HIT);
       Rx_MWr_Tag   <= Rx_MWr_Tag + 1;
       Gap_Insert_Rx;
       Gap_Insert_Rx;
 
       //  Write HA_L
       Hdr_Array[2] <= Hdr_Array[2] + 'H4;
     # `T_DELTA
       TLP_Feed_Rx(`USE_PRIVATE, 'H3, `C_BAR0_HIT);
       Rx_MWr_Tag   <= Rx_MWr_Tag + 1;
       Gap_Insert_Rx;
       Gap_Insert_Rx;
 
       //  Write BDA_H
       Hdr_Array[2] <= Hdr_Array[2] + 'H4;
     # `T_DELTA
       TLP_Feed_Rx(`USE_PRIVATE, 'H4, `C_BAR0_HIT);
       Rx_MWr_Tag   <= Rx_MWr_Tag + 1;
       Gap_Insert_Rx;
       Gap_Insert_Rx;
 
       //  Write BDA_L
       Hdr_Array[2] <= Hdr_Array[2] + 'H4;
     # `T_DELTA
       TLP_Feed_Rx(`USE_PRIVATE, 'H5, `C_BAR0_HIT);
       Rx_MWr_Tag   <= Rx_MWr_Tag + 1;
       Gap_Insert_Rx;
       Gap_Insert_Rx;
 
       //  Write LENG
       Hdr_Array[2] <= Hdr_Array[2] + 'H4;
     # `T_DELTA
       TLP_Feed_Rx(`USE_PRIVATE, 'H6, `C_BAR0_HIT);
       Rx_MWr_Tag   <= Rx_MWr_Tag + 1;
       Gap_Insert_Rx;
       Gap_Insert_Rx;
 
       //  Write CTRL and start the DMA
       Hdr_Array[2] <= Hdr_Array[2] + 'H4;
     # `T_DELTA
       TLP_Feed_Rx(`USE_PRIVATE, 'H7, `C_BAR0_HIT);
       Rx_MWr_Tag   <= Rx_MWr_Tag + 1;
       Gap_Insert_Rx;
       Gap_Insert_Rx;
 
 
     # `T_DELTA     // Polling the DMA status
       Hdr_Array[0] <= `HEADER0_MRD3_ | Rx_TLP_Length[9:0];
       Hdr_Array[1] <= {`C_HOST_RDREQ_ID, 3'H3, Rx_MRd_Tag, 4'Hf, 4'Hf};
       Hdr_Array[2] <= `C_ADDR_DMA_DS_STA;
 
 
     # `T_DELTA
       TLP_Feed_Rx(`USE_PRIVATE, 'H0, `C_BAR0_HIT);
       Rx_MRd_Tag       <= Rx_MRd_Tag + 1;
       Gap_Insert_Rx;
 
       FSM_Trn          <= 'H18;
 
 
       // feeding the payload CplD
       wait (tx_MRd_come);
       Gap_Insert_Rx;
       tx_MRd_come  <= 'B0;
       Tx_MRd_Leng  <= DMA_Leng>>2;
       Tx_MRd_Addr  <= DMA_HA[31:0];
       tx_MRd_Tag_k <= tx_MRd_Tag;
       CplD_Index   <= 'H0;
 
       Gap_Insert_Rx;
       Rx_TLP_Length    <= 'H10;
 
     # `T_DELTA
       Hdr_Array[0] <= `HEADER0_CPLD | Rx_TLP_Length[9:0];
       Hdr_Array[1] <= {`C_HOST_CPLD_ID, 4'H0, Tx_MRd_Leng[9:0], 2'b00};
       Hdr_Array[2] <= {localID, tx_MRd_Tag_k, 1'b0, Tx_MRd_Addr[6:0]};
       Tx_MRd_Leng  <= Tx_MRd_Leng - Rx_TLP_Length;
       Tx_MRd_Addr  <= Tx_MRd_Addr + Rx_TLP_Length;
     # `T_DELTA
       TLP_Feed_Rx(`USE_PUBLIC, CplD_Index, `C_NO_BAR_HIT);
       CplD_Index   <= CplD_Index + Rx_TLP_Length;
       Gap_Insert_Rx;
 
       Hdr_Array[0] <= `HEADER0_CPLD | Rx_TLP_Length[9:0];
       Hdr_Array[1] <= {`C_HOST_CPLD_ID, 4'H0, Tx_MRd_Leng[9:0], 2'b00};
       Hdr_Array[2] <= {localID, tx_MRd_Tag_k, 1'b0, Tx_MRd_Addr[6:0]};
       Tx_MRd_Leng  <= Tx_MRd_Leng - Rx_TLP_Length;
       Tx_MRd_Addr  <= Tx_MRd_Addr + Rx_TLP_Length;
     # `T_DELTA
       TLP_Feed_Rx(`USE_PUBLIC, CplD_Index, `C_NO_BAR_HIT);
       CplD_Index   <= CplD_Index + Rx_TLP_Length;
//       Gap_Insert_Rx;
 
       Hdr_Array[0] <= `HEADER0_CPLD | Rx_TLP_Length[9:0];
       Hdr_Array[1] <= {`C_HOST_CPLD_ID, 4'H0, Tx_MRd_Leng[9:0], 2'b00};
       Hdr_Array[2] <= {localID, tx_MRd_Tag_k, 1'b0, Tx_MRd_Addr[6:0]};
       Tx_MRd_Leng  <= Tx_MRd_Leng - Rx_TLP_Length;
       Tx_MRd_Addr  <= Tx_MRd_Addr + Rx_TLP_Length;
     # `T_DELTA
       TLP_Feed_Rx(`USE_PUBLIC, CplD_Index, `C_NO_BAR_HIT);
       CplD_Index   <= CplD_Index + Rx_TLP_Length;
       Gap_Insert_Rx;
 
       Hdr_Array[0] <= `HEADER0_CPLD | Rx_TLP_Length[9:0];
       Hdr_Array[1] <= {`C_HOST_CPLD_ID, 4'H0, Tx_MRd_Leng[9:0], 2'b00};
       Hdr_Array[2] <= {localID, tx_MRd_Tag_k, 1'b0, Tx_MRd_Addr[6:0]};
       Tx_MRd_Leng  <= Tx_MRd_Leng - Rx_TLP_Length;
       Tx_MRd_Addr  <= Tx_MRd_Addr + Rx_TLP_Length;
     # `T_DELTA
       TLP_Feed_Rx(`USE_PUBLIC, CplD_Index, `C_NO_BAR_HIT);
       CplD_Index   <= CplD_Index + Rx_TLP_Length;
       Gap_Insert_Rx;
 
 
       Rx_TLP_Length    <= 'H01;
     # `T_DELTA     // Polling the DMA status
       Hdr_Array[0] <= `HEADER0_MRD3_ | Rx_TLP_Length[9:0];
       Hdr_Array[1] <= {`C_HOST_RDREQ_ID, 3'H3, Rx_MRd_Tag, 4'Hf, 4'Hf};
       Hdr_Array[2] <= `C_ADDR_DMA_DS_STA;
 
 
     # `T_DELTA
       TLP_Feed_Rx(`USE_PRIVATE, 'H0, `C_BAR0_HIT);
       Rx_MRd_Tag       <= Rx_MRd_Tag + 1;
       Gap_Insert_Rx;
 
 
       FSM_Trn          <= 'H1C;
 
     # `T_DMA_INTERVAL
       ;
 
 
 
       //  DMA read
 
       Rx_TLP_Length    <= 'H01;
 
     # `T_DELTA
       Hdr_Array[0] <= `HEADER0_MWR3_ | Rx_TLP_Length[9:0];
       Hdr_Array[1] <= {`C_HOST_WRREQ_ID, Rx_MWr_Tag, 4'Hf, 4'Hf};
       Hdr_Array[2] <= `C_ADDR_DMA_US_PAH;
 
       //  Write PA_H
     # `T_DELTA
       TLP_Feed_Rx(`USE_PRIVATE, 'H0, `C_BAR0_HIT);
       Rx_MWr_Tag   <= Rx_MWr_Tag + 1;
       Gap_Insert_Rx;
       Gap_Insert_Rx;
 
       //  Write PA_L
       Hdr_Array[2] <= Hdr_Array[2] + 'H4;
     # `T_DELTA
       TLP_Feed_Rx(`USE_PRIVATE, 'H1, `C_BAR0_HIT);
       Rx_MWr_Tag   <= Rx_MWr_Tag + 1;
       Gap_Insert_Rx;
       Gap_Insert_Rx;
 
       //  Write HA_H
       Hdr_Array[2] <= Hdr_Array[2] + 'H4;
     # `T_DELTA
       TLP_Feed_Rx(`USE_PRIVATE, 'H2, `C_BAR0_HIT);
       Rx_MWr_Tag   <= Rx_MWr_Tag + 1;
       Gap_Insert_Rx;
       Gap_Insert_Rx;
 
       //  Write HA_L
       Hdr_Array[2] <= Hdr_Array[2] + 'H4;
     # `T_DELTA
       TLP_Feed_Rx(`USE_PRIVATE, 'H3, `C_BAR0_HIT);
       Rx_MWr_Tag   <= Rx_MWr_Tag + 1;
       Gap_Insert_Rx;
       Gap_Insert_Rx;
 
       //  Write BDA_H
       Hdr_Array[2] <= Hdr_Array[2] + 'H4;
     # `T_DELTA
       TLP_Feed_Rx(`USE_PRIVATE, 'H4, `C_BAR0_HIT);
       Rx_MWr_Tag   <= Rx_MWr_Tag + 1;
       Gap_Insert_Rx;
       Gap_Insert_Rx;
 
       //  Write BDA_L
       Hdr_Array[2] <= Hdr_Array[2] + 'H4;
     # `T_DELTA
       TLP_Feed_Rx(`USE_PRIVATE, 'H5, `C_BAR0_HIT);
       Rx_MWr_Tag   <= Rx_MWr_Tag + 1;
       Gap_Insert_Rx;
       Gap_Insert_Rx;
 
       //  Write LENG
       Hdr_Array[2] <= Hdr_Array[2] + 'H4;
     # `T_DELTA
       TLP_Feed_Rx(`USE_PRIVATE, 'H6, `C_BAR0_HIT);
       Rx_MWr_Tag   <= Rx_MWr_Tag + 1;
       Gap_Insert_Rx;
       Gap_Insert_Rx;
 
       //  Write CTRL and start the DMA
       Hdr_Array[2] <= Hdr_Array[2] + 'H4;
     # `T_DELTA
       TLP_Feed_Rx(`USE_PRIVATE, 'H7, `C_BAR0_HIT);
       Rx_MWr_Tag   <= Rx_MWr_Tag + 1;
       Gap_Insert_Rx;
       Gap_Insert_Rx;
 
 
       Rx_TLP_Length    <= 'H01;
     # `T_DELTA     // Polling the DMA status
       Hdr_Array[0] <= `HEADER0_MRD3_ | Rx_TLP_Length[9:0];
       Hdr_Array[1] <= {`C_HOST_RDREQ_ID, 3'H3, Rx_MRd_Tag, 4'Hf, 4'Hf};
       Hdr_Array[2] <= `C_ADDR_DMA_US_STA;
 
 
     # `T_DELTA
       TLP_Feed_Rx(`USE_PRIVATE, 'H0, `C_BAR0_HIT);
       Rx_MRd_Tag       <= Rx_MRd_Tag + 1;
       Gap_Insert_Rx;
 
       FSM_Trn          <= 'H20;
 
     # (`T_DMA_INTERVAL*4)
       ;
 
 
  //////////////////////////////////////////////////////////////////////////////////
 
       Rx_TLP_Length    <= 'H01;
     # `T_DELTA    // reset downstream DMA channel
       Hdr_Array[0] <= `HEADER0_MWR3_ | Rx_TLP_Length[9:0];
       Hdr_Array[1] <= {`C_HOST_WRREQ_ID, Rx_MWr_Tag, 4'Hf, 4'Hf};
       Hdr_Array[2] <= `C_ADDR_DMA_DS_CTRL;
       Private_Array[0] <= `C_DMA_RST_CMD;
 
     # `T_DELTA
       TLP_Feed_Rx(`USE_PRIVATE, 'H0, `C_BAR0_HIT);
       Rx_MWr_Tag   <= Rx_MWr_Tag + 1;
       Gap_Insert_Rx;
 
       Rx_TLP_Length    <= 'H01;
     # `T_DELTA    // reset upstream DMA channel
       Hdr_Array[0] <= `HEADER0_MWR3_ | Rx_TLP_Length[9:0];
       Hdr_Array[1] <= {`C_HOST_WRREQ_ID, Rx_MWr_Tag, 4'Hf, 4'Hf};
       Hdr_Array[2] <= `C_ADDR_DMA_US_CTRL;
       Private_Array[0] <= `C_DMA_RST_CMD;
 
     # `T_DELTA
       TLP_Feed_Rx(`USE_PRIVATE, 'H0, `C_BAR0_HIT);
       Rx_MWr_Tag   <= Rx_MWr_Tag + 1;
       Gap_Insert_Rx;
 
  //////////////////////////////////////////////////////////////////////////////////
 
 
       FSM_Trn          <= 'H24;
 
 
     # `T_PIO_INTERVAL
       ;
 
 
 
    //  ///////////////////////////////////////////////////////////////////
    //  DMA write & read BAR[2]
    //  Multiple-descriptor case
    //  
 
       DMA_PA   <= 'H789ABC;
       DMA_HA   <= 'HDF0000;
       DMA_BDA  <= 'H0BDABDA0;
		 DMA_Leng <= 'H0208;
     # `T_DELTA
		 DMA_L1   <= 'H0100;
     # `T_DELTA
		 DMA_L2   <= DMA_Leng - DMA_L1;
       DMA_bar  <= 'H2;
       DMA_ds_is_Last  <= 'B0;
 
     # `T_DELTA
       // Initial DMA descriptor
       Private_Array[0] <= -1;
       Private_Array[1] <= DMA_PA[31:00];
       Private_Array[2] <= DMA_HA[63:32];       // 0;
       Private_Array[3] <= DMA_HA[31:00];
       Private_Array[4] <= DMA_BDA[63:32];      // 0;
       Private_Array[5] <= DMA_BDA[31:00];
       Private_Array[6] <= DMA_L1;
       Private_Array[7] <=  {4'H0
                            ,3'H1, DMA_ds_is_Last
                            ,3'H0, 1'B1
                            ,1'B0, DMA_bar
                            ,1'B1
                            ,15'H0
                            };
 
       Rx_TLP_Length    <= 'H01;
 
     # `T_DELTA
       Hdr_Array[0] <= `HEADER0_MWR3_ | Rx_TLP_Length[9:0];
       Hdr_Array[1] <= {`C_HOST_WRREQ_ID, Rx_MWr_Tag, 4'Hf, 4'Hf};
       Hdr_Array[2] <= `C_ADDR_DMA_DS_PAH;
 
       //  Write PA_H
     # `T_DELTA
       TLP_Feed_Rx(`USE_PRIVATE, 'H0, `C_BAR0_HIT);
       Rx_MWr_Tag   <= Rx_MWr_Tag + 1;
       Gap_Insert_Rx;
       Gap_Insert_Rx;
 
       //  Write PA_L
       Hdr_Array[2] <= Hdr_Array[2] + 'H4;
     # `T_DELTA
       TLP_Feed_Rx(`USE_PRIVATE, 'H1, `C_BAR0_HIT);
       Rx_MWr_Tag   <= Rx_MWr_Tag + 1;
       Gap_Insert_Rx;
       Gap_Insert_Rx;
 
       //  Write HA_H
       Hdr_Array[2] <= Hdr_Array[2] + 'H4;
     # `T_DELTA
       TLP_Feed_Rx(`USE_PRIVATE, 'H2, `C_BAR0_HIT);
       Rx_MWr_Tag   <= Rx_MWr_Tag + 1;
       Gap_Insert_Rx;
       Gap_Insert_Rx;
 
       //  Write HA_L
       Hdr_Array[2] <= Hdr_Array[2] + 'H4;
     # `T_DELTA
       TLP_Feed_Rx(`USE_PRIVATE, 'H3, `C_BAR0_HIT);
       Rx_MWr_Tag   <= Rx_MWr_Tag + 1;
       Gap_Insert_Rx;
       Gap_Insert_Rx;
 
       //  Write BDA_H
       Hdr_Array[2] <= Hdr_Array[2] + 'H4;
     # `T_DELTA
       TLP_Feed_Rx(`USE_PRIVATE, 'H4, `C_BAR0_HIT);
       Rx_MWr_Tag   <= Rx_MWr_Tag + 1;
       Gap_Insert_Rx;
       Gap_Insert_Rx;
 
       //  Write BDA_L
       Hdr_Array[2] <= Hdr_Array[2] + 'H4;
     # `T_DELTA
       TLP_Feed_Rx(`USE_PRIVATE, 'H5, `C_BAR0_HIT);
       Rx_MWr_Tag   <= Rx_MWr_Tag + 1;
       Gap_Insert_Rx;
       Gap_Insert_Rx;
 
       //  Write LENG
       Hdr_Array[2] <= Hdr_Array[2] + 'H4;
     # `T_DELTA
       TLP_Feed_Rx(`USE_PRIVATE, 'H6, `C_BAR0_HIT);
       Rx_MWr_Tag   <= Rx_MWr_Tag + 1;
       Gap_Insert_Rx;
       Gap_Insert_Rx;
 
       //  Write CTRL and start the DMA
       Hdr_Array[2] <= Hdr_Array[2] + 'H4;
     # `T_DELTA
       TLP_Feed_Rx(`USE_PRIVATE, 'H7, `C_BAR0_HIT);
       Rx_MWr_Tag   <= Rx_MWr_Tag + 1;
       Gap_Insert_Rx;
       Gap_Insert_Rx;
 
 
       FSM_Trn          <= 'H28;
 
 
       // feeding the descriptor CplD
       wait (Desc_tx_MRd_Valid);
       Gap_Insert_Rx;
       Desc_tx_MRd_Valid <= 'B0;
       DMA_ds_is_Last    <= 'B1;
       Gap_Insert_Rx;
 
       // Initial DMA descriptor
       Private_Array[0] <= 0;
       Private_Array[1] <= DMA_PA[31:00] + 'H500;
       Private_Array[2] <= DMA_HA[63:32];          // 0;
       Private_Array[3] <= DMA_HA[31:00] + 'H500;
       Private_Array[4] <= -1;                     // dont-care
       Private_Array[5] <= -1;                     // dont-care
       Private_Array[6] <= DMA_L2;
       Private_Array[7] <=  {4'H0
                            ,3'H1, DMA_ds_is_Last
                            ,3'H0, 1'B1
                            ,1'B0, DMA_bar
                            ,1'B1
                            ,15'H0
                            };
 
       Rx_TLP_Length    <= 'H08;
       Gap_Insert_Rx;
       Hdr_Array[0] <= `HEADER0_CPLD | Rx_TLP_Length[9:0];
       Hdr_Array[1] <= {`C_HOST_CPLD_ID, 4'H0, Rx_TLP_Length[9:0], 2'b00};
       Hdr_Array[2] <= {localID, Desc_tx_MRd_TAG, 1'b0, DMA_BDA[6:0]};
     # `T_DELTA
       TLP_Feed_Rx(`USE_PRIVATE, 0, `C_NO_BAR_HIT);
       Gap_Insert_Rx;
 
 
       // feeding the payload CplD
       wait (tx_MRd_come);
       Gap_Insert_Rx;
       tx_MRd_come  <= 'B0;
       Tx_MRd_Leng  <= DMA_L1>>2;
       Tx_MRd_Addr  <= DMA_HA[31:0];
       tx_MRd_Tag_k <= tx_MRd_Tag;
       CplD_Index   <= 'H0;
 
       Gap_Insert_Rx;
       Rx_TLP_Length    <= 'H10;
 
     # `T_DELTA
       Hdr_Array[0] <= `HEADER0_CPLD | Rx_TLP_Length[9:0];
       Hdr_Array[1] <= {`C_HOST_CPLD_ID, 4'H0, Tx_MRd_Leng[9:0], 2'b00};
       Hdr_Array[2] <= {localID, tx_MRd_Tag_k, 1'b0, Tx_MRd_Addr[6:0]};
       Tx_MRd_Leng  <= Tx_MRd_Leng - Rx_TLP_Length;
       Tx_MRd_Addr  <= Tx_MRd_Addr + Rx_TLP_Length;
     # `T_DELTA
       TLP_Feed_Rx(`USE_PUBLIC, CplD_Index, `C_NO_BAR_HIT);
       CplD_Index   <= CplD_Index + Rx_TLP_Length;
       Gap_Insert_Rx;
 
       Hdr_Array[0] <= `HEADER0_CPLD | Rx_TLP_Length[9:0];
       Hdr_Array[1] <= {`C_HOST_CPLD_ID, 4'H0, Tx_MRd_Leng[9:0], 2'b00};
       Hdr_Array[2] <= {localID, tx_MRd_Tag_k, 1'b0, Tx_MRd_Addr[6:0]};
       Tx_MRd_Leng  <= Tx_MRd_Leng - Rx_TLP_Length;
       Tx_MRd_Addr  <= Tx_MRd_Addr + Rx_TLP_Length;
     # `T_DELTA
       TLP_Feed_Rx(`USE_PUBLIC, CplD_Index, `C_NO_BAR_HIT);
       CplD_Index   <= CplD_Index + Rx_TLP_Length;
//       Gap_Insert_Rx;
 
       Hdr_Array[0] <= `HEADER0_CPLD | Rx_TLP_Length[9:0];
       Hdr_Array[1] <= {`C_HOST_CPLD_ID, 4'H0, Tx_MRd_Leng[9:0], 2'b00};
       Hdr_Array[2] <= {localID, tx_MRd_Tag_k, 1'b0, Tx_MRd_Addr[6:0]};
       Tx_MRd_Leng  <= Tx_MRd_Leng - Rx_TLP_Length;
       Tx_MRd_Addr  <= Tx_MRd_Addr + Rx_TLP_Length;
     # `T_DELTA
       TLP_Feed_Rx(`USE_PUBLIC, CplD_Index, `C_NO_BAR_HIT);
       CplD_Index   <= CplD_Index + Rx_TLP_Length;
//       Gap_Insert_Rx;
 
       Hdr_Array[0] <= `HEADER0_CPLD | Rx_TLP_Length[9:0];
       Hdr_Array[1] <= {`C_HOST_CPLD_ID, 4'H0, Tx_MRd_Leng[9:0], 2'b00};
       Hdr_Array[2] <= {localID, tx_MRd_Tag_k, 1'b0, Tx_MRd_Addr[6:0]};
       Tx_MRd_Leng  <= Tx_MRd_Leng - Rx_TLP_Length;
       Tx_MRd_Addr  <= Tx_MRd_Addr + Rx_TLP_Length;
     # `T_DELTA
       TLP_Feed_Rx(`USE_PUBLIC, CplD_Index, `C_NO_BAR_HIT);
       CplD_Index   <= CplD_Index + Rx_TLP_Length;
       Gap_Insert_Rx;
 
 
       Rx_TLP_Length    <= 'H01;
     # `T_DELTA     // Polling the DMA status
       Hdr_Array[0] <= `HEADER0_MRD3_ | Rx_TLP_Length[9:0];
       Hdr_Array[1] <= {`C_HOST_RDREQ_ID, 3'H3, Rx_MRd_Tag, 4'Hf, 4'Hf};
       Hdr_Array[2] <= `C_ADDR_DMA_DS_STA;
 
 
     # `T_DELTA
       TLP_Feed_Rx(`USE_PRIVATE, 'H0, `C_BAR0_HIT);
       Rx_MRd_Tag       <= Rx_MRd_Tag + 1;
       Gap_Insert_Rx;
 
 
       FSM_Trn          <= 'H2C;
 
 
       // feeding the payload CplD (2nd descriptor)
       wait (tx_MRd_come);
       Gap_Insert_Rx;
       tx_MRd_come  <= 'B0;
       Tx_MRd_Leng  <= (DMA_L2>>2) - 'H2;
       Tx_MRd_Addr  <= DMA_HA[31:0] + 'H500;
       tx_MRd_Tag_k <= tx_MRd_Tag_k + 'H1;
       CplD_Index   <= 'H40;
 
       Gap_Insert_Rx;
       Rx_TLP_Length    <= 'H10;
 
     # `T_DELTA
       Hdr_Array[0] <= `HEADER0_CPLD | Rx_TLP_Length[9:0];
       Hdr_Array[1] <= {`C_HOST_CPLD_ID, 4'H0, Tx_MRd_Leng[9:0], 2'b00};
       Hdr_Array[2] <= {localID, tx_MRd_Tag_k, 1'b0, Tx_MRd_Addr[6:0]};
       Tx_MRd_Leng  <= Tx_MRd_Leng - Rx_TLP_Length;
       Tx_MRd_Addr  <= Tx_MRd_Addr + Rx_TLP_Length;
     # `T_DELTA
       TLP_Feed_Rx(`USE_PUBLIC, CplD_Index, `C_NO_BAR_HIT);
       CplD_Index   <= CplD_Index + Rx_TLP_Length;
       Gap_Insert_Rx;
 
       Hdr_Array[0] <= `HEADER0_CPLD | Rx_TLP_Length[9:0];
       Hdr_Array[1] <= {`C_HOST_CPLD_ID, 4'H0, Tx_MRd_Leng[9:0], 2'b00};
       Hdr_Array[2] <= {localID, tx_MRd_Tag_k, 1'b0, Tx_MRd_Addr[6:0]};
       Tx_MRd_Leng  <= Tx_MRd_Leng - Rx_TLP_Length;
       Tx_MRd_Addr  <= Tx_MRd_Addr + Rx_TLP_Length;
     # `T_DELTA
       TLP_Feed_Rx(`USE_PUBLIC, CplD_Index, `C_NO_BAR_HIT);
       CplD_Index   <= CplD_Index + Rx_TLP_Length;
//       Gap_Insert_Rx;
 
       Hdr_Array[0] <= `HEADER0_CPLD | Rx_TLP_Length[9:0];
       Hdr_Array[1] <= {`C_HOST_CPLD_ID, 4'H0, Tx_MRd_Leng[9:0], 2'b00};
       Hdr_Array[2] <= {localID, tx_MRd_Tag_k, 1'b0, Tx_MRd_Addr[6:0]};
       Tx_MRd_Leng  <= Tx_MRd_Leng - Rx_TLP_Length;
       Tx_MRd_Addr  <= Tx_MRd_Addr + Rx_TLP_Length;
     # `T_DELTA
       TLP_Feed_Rx(`USE_PUBLIC, CplD_Index, `C_NO_BAR_HIT);
       CplD_Index   <= CplD_Index + Rx_TLP_Length;
       Gap_Insert_Rx;
 
       Hdr_Array[0] <= `HEADER0_CPLD | Rx_TLP_Length[9:0];
       Hdr_Array[1] <= {`C_HOST_CPLD_ID, 4'H0, Tx_MRd_Leng[9:0], 2'b00};
       Hdr_Array[2] <= {localID, tx_MRd_Tag_k, 1'b0, Tx_MRd_Addr[6:0]};
       Tx_MRd_Leng  <= Tx_MRd_Leng - Rx_TLP_Length;
       Tx_MRd_Addr  <= Tx_MRd_Addr + Rx_TLP_Length;
     # `T_DELTA
       TLP_Feed_Rx(`USE_PUBLIC, CplD_Index, `C_NO_BAR_HIT);
       CplD_Index   <= CplD_Index + Rx_TLP_Length;
       Gap_Insert_Rx;
 
       Rx_TLP_Length    <= 'H02;
       Tx_MRd_Leng      <= 'H2;
       tx_MRd_Tag_k     <= tx_MRd_Tag_k + 'H1;
     # `T_DELTA
       Hdr_Array[0] <= `HEADER0_CPLD | Rx_TLP_Length[9:0];
       Hdr_Array[1] <= {`C_HOST_CPLD_ID, 4'H0, Tx_MRd_Leng[9:0], 2'b00};
       Hdr_Array[2] <= {localID, tx_MRd_Tag_k, 1'b0, Tx_MRd_Addr[6:0]};
       Tx_MRd_Leng  <= Tx_MRd_Leng - Rx_TLP_Length;
       Tx_MRd_Addr  <= Tx_MRd_Addr + Rx_TLP_Length;
     # `T_DELTA
       TLP_Feed_Rx(`USE_PUBLIC, CplD_Index, `C_NO_BAR_HIT);
       CplD_Index   <= CplD_Index + Rx_TLP_Length;
       Gap_Insert_Rx;
 
       FSM_Trn          <= 'H30;
 
 
 
     # (`T_DMA_INTERVAL*2)
       ;
 
       DMA_us_is_Last   <= 'B0;
     # `T_DELTA
       //  DMA read
       Private_Array[0] <= 0;
       Private_Array[1] <= DMA_PA[31:00];
       Private_Array[2] <= DMA_HA[63:32];          // 0;
       Private_Array[3] <= DMA_HA[31:00];
       Private_Array[4] <= DMA_BDA[63:32];         // 0;
       Private_Array[5] <= DMA_BDA[31:00] + 'H10000;
       Private_Array[6] <= DMA_L1;
       Private_Array[7] <=  {4'H0
                            ,3'H1, DMA_us_is_Last
                            ,3'H0, 1'B1
                            ,1'B0, DMA_bar
                            ,1'B1
                            ,15'H0
                            };
       Rx_TLP_Length    <= 'H01;
 
     # `T_DELTA
       Hdr_Array[0] <= `HEADER0_MWR3_ | Rx_TLP_Length[9:0];
       Hdr_Array[1] <= {`C_HOST_WRREQ_ID, Rx_MWr_Tag, 4'Hf, 4'Hf};
       Hdr_Array[2] <= `C_ADDR_DMA_US_PAH;
 
       //  Write PA_H
     # `T_DELTA
       TLP_Feed_Rx(`USE_PRIVATE, 'H0, `C_BAR0_HIT);
       Rx_MWr_Tag   <= Rx_MWr_Tag + 1;
       Gap_Insert_Rx;
       Gap_Insert_Rx;
 
       //  Write PA_L
       Hdr_Array[2] <= Hdr_Array[2] + 'H4;
     # `T_DELTA
       TLP_Feed_Rx(`USE_PRIVATE, 'H1, `C_BAR0_HIT);
       Rx_MWr_Tag   <= Rx_MWr_Tag + 1;
       Gap_Insert_Rx;
       Gap_Insert_Rx;
 
       //  Write HA_H
       Hdr_Array[2] <= Hdr_Array[2] + 'H4;
     # `T_DELTA
       TLP_Feed_Rx(`USE_PRIVATE, 'H2, `C_BAR0_HIT);
       Rx_MWr_Tag   <= Rx_MWr_Tag + 1;
       Gap_Insert_Rx;
       Gap_Insert_Rx;
 
       //  Write HA_L
       Hdr_Array[2] <= Hdr_Array[2] + 'H4;
     # `T_DELTA
       TLP_Feed_Rx(`USE_PRIVATE, 'H3, `C_BAR0_HIT);
       Rx_MWr_Tag   <= Rx_MWr_Tag + 1;
       Gap_Insert_Rx;
       Gap_Insert_Rx;
 
       //  Write BDA_H
       Hdr_Array[2] <= Hdr_Array[2] + 'H4;
     # `T_DELTA
       TLP_Feed_Rx(`USE_PRIVATE, 'H4, `C_BAR0_HIT);
       Rx_MWr_Tag   <= Rx_MWr_Tag + 1;
       Gap_Insert_Rx;
       Gap_Insert_Rx;
 
       //  Write BDA_L
       Hdr_Array[2] <= Hdr_Array[2] + 'H4;
     # `T_DELTA
       TLP_Feed_Rx(`USE_PRIVATE, 'H5, `C_BAR0_HIT);
       Rx_MWr_Tag   <= Rx_MWr_Tag + 1;
       Gap_Insert_Rx;
       Gap_Insert_Rx;
 
       //  Write LENG
       Hdr_Array[2] <= Hdr_Array[2] + 'H4;
     # `T_DELTA
       TLP_Feed_Rx(`USE_PRIVATE, 'H6, `C_BAR0_HIT);
       Rx_MWr_Tag   <= Rx_MWr_Tag + 1;
       Gap_Insert_Rx;
       Gap_Insert_Rx;
 
       //  Write CTRL and start the DMA
       Hdr_Array[2] <= Hdr_Array[2] + 'H4;
     # `T_DELTA
       TLP_Feed_Rx(`USE_PRIVATE, 'H7, `C_BAR0_HIT);
       Rx_MWr_Tag   <= Rx_MWr_Tag + 1;
       Gap_Insert_Rx;
       Gap_Insert_Rx;
 
 
       Rx_TLP_Length    <= 'H01;
     # `T_DELTA     // Polling the DMA status
       Hdr_Array[0] <= `HEADER0_MRD3_ | Rx_TLP_Length[9:0];
       Hdr_Array[1] <= {`C_HOST_RDREQ_ID, 3'H3, Rx_MRd_Tag, 4'Hf, 4'Hf};
       Hdr_Array[2] <= `C_ADDR_DMA_US_STA;
 
 
     # `T_DELTA
       TLP_Feed_Rx(`USE_PRIVATE, 'H0, `C_BAR0_HIT);
       Rx_MRd_Tag       <= Rx_MRd_Tag + 1;
       Gap_Insert_Rx;
 
       FSM_Trn          <= 'H34;
 
 
       // feeding the descriptor CplD
       wait (Desc_tx_MRd_Valid);
       Gap_Insert_Rx;
       Desc_tx_MRd_Valid <= 'B0;
       DMA_us_is_Last    <= 'B1;
       Gap_Insert_Rx;
 
       // Initial DMA descriptor
       Private_Array[0] <= 0;
       Private_Array[1] <= DMA_PA[31:00] + 'H500;
       Private_Array[2] <= DMA_HA[63:32];          // 0;
       Private_Array[3] <= DMA_HA[31:00] + 'H500;
       Private_Array[4] <= -1;                     // dont-care
       Private_Array[5] <= -1;                     // dont-care
       Private_Array[6] <= DMA_L2;
       Private_Array[7] <=  {4'H0
                            ,3'H1, DMA_us_is_Last
                            ,3'H0, 1'B1
                            ,1'B0, DMA_bar
                            ,1'B1
                            ,15'H0
                            };
 
       Rx_TLP_Length    <= 'H08;
       Gap_Insert_Rx;
       Hdr_Array[0] <= `HEADER0_CPLD | Rx_TLP_Length[9:0];
       Hdr_Array[1] <= {`C_HOST_CPLD_ID, 4'H0, Rx_TLP_Length[9:0], 2'b00};
       Hdr_Array[2] <= {localID, Desc_tx_MRd_TAG, 1'b0, DMA_BDA[6:0]};
     # `T_DELTA
       TLP_Feed_Rx(`USE_PRIVATE, 0, `C_NO_BAR_HIT);
       Gap_Insert_Rx;
 
 
       Rx_TLP_Length    <= 'H01;
     # `T_DELTA     // Polling the DMA status
       Hdr_Array[0] <= `HEADER0_MRD3_ | Rx_TLP_Length[9:0];
       Hdr_Array[1] <= {`C_HOST_RDREQ_ID, 3'H3, Rx_MRd_Tag, 4'Hf, 4'Hf};
       Hdr_Array[2] <= `C_ADDR_DMA_US_STA;
 
 
     # `T_DELTA
       TLP_Feed_Rx(`USE_PRIVATE, 'H0, `C_BAR0_HIT);
       Rx_MRd_Tag       <= Rx_MRd_Tag + 1;
       Gap_Insert_Rx;
 
 
     # (`T_DMA_INTERVAL*4)
       ;
 
       Rx_TLP_Length    <= 'H01;
     # `T_DELTA     // Polling the DMA status
       Hdr_Array[0] <= `HEADER0_MRD3_ | Rx_TLP_Length[9:0];
       Hdr_Array[1] <= {`C_HOST_RDREQ_ID, 3'H3, Rx_MRd_Tag, 4'Hf, 4'Hf};
       Hdr_Array[2] <= `C_ADDR_DMA_US_STA;
 
 
     # `T_DELTA
       TLP_Feed_Rx(`USE_PRIVATE, 'H0, `C_BAR0_HIT);
       Rx_MRd_Tag       <= Rx_MRd_Tag + 1;
       Gap_Insert_Rx;
 
       FSM_Trn          <= 'H38;
 
     # (`T_DMA_INTERVAL*4)
       ;
 
 
  //////////////////////////////////////////////////////////////////////////////////
 
       Rx_TLP_Length    <= 'H01;
     # `T_DELTA    // reset downstream DMA channel
       Hdr_Array[0] <= `HEADER0_MWR3_ | Rx_TLP_Length[9:0];
       Hdr_Array[1] <= {`C_HOST_WRREQ_ID, Rx_MWr_Tag, 4'Hf, 4'Hf};
       Hdr_Array[2] <= `C_ADDR_DMA_DS_CTRL;
       Private_Array[0] <= `C_DMA_RST_CMD;
 
     # `T_DELTA
       TLP_Feed_Rx(`USE_PRIVATE, 'H0, `C_BAR0_HIT);
       Rx_MWr_Tag   <= Rx_MWr_Tag + 1;
       Gap_Insert_Rx;
 
       Rx_TLP_Length    <= 'H01;
     # `T_DELTA    // reset upstream DMA channel
       Hdr_Array[0] <= `HEADER0_MWR3_ | Rx_TLP_Length[9:0];
       Hdr_Array[1] <= {`C_HOST_WRREQ_ID, Rx_MWr_Tag, 4'Hf, 4'Hf};
       Hdr_Array[2] <= `C_ADDR_DMA_US_CTRL;
       Private_Array[0] <= `C_DMA_RST_CMD;
 
     # `T_DELTA
       TLP_Feed_Rx(`USE_PRIVATE, 'H0, `C_BAR0_HIT);
       Rx_MWr_Tag   <= Rx_MWr_Tag + 1;
       Gap_Insert_Rx;
 
  //////////////////////////////////////////////////////////////////////////////////
 
 
       FSM_Trn          <= 'H40;
 
 
  end
 
 
 
 
// ========================================== //
//         Checking and verification          //
//                                            //
   reg           Err_signal;
//                                            //
//                                            //
// ========================================== //
 
   // TLP format check out Rx
   //  in case stimuli incorrect: verification over verification
   reg [ 7: 0]   FSM_Rx_Fmt;
   reg [10: 0]   rxchk_TLP_Length;
   reg           rxchk_TLP_Has_Data;
   reg           rxchk_TLP_4DW_Hdr;
   reg           rxchk_Mem_TLP;
   always @(negedge trn_clk )
   if (!trn_reset_n) begin
      FSM_Rx_Fmt      <= 0;
   end
   else begin
 
      case (FSM_Rx_Fmt)
 
        'H00: begin
            FSM_Rx_Fmt    <= 'H010;
         end
 
        'H10: begin
            if ( trn_rsrc_rdy_n | trn_rdst_rdy_n) begin
              FSM_Rx_Fmt        <= 'H10;
            end
            else if (~trn_reof_n) begin
                  $display ("\n %t:\n !! Unexpected trn_reof_n !!", $time);
                  Err_signal <= 1;
            end
            else if (~trn_rsof_n&trn_reof_n) begin
                rxchk_TLP_Has_Data    <= trn_rd[30+32];
                rxchk_TLP_4DW_Hdr     <= trn_rd[29+32];
                rxchk_TLP_Length[10]  <= (trn_rd[9+32:0+32]=='H0);
                rxchk_TLP_Length[9:0] <= trn_rd[9+32:0+32];
                if (trn_rd[28+32:25+32]) rxchk_Mem_TLP    <= 0;    // Msg or MsgD
                else                     rxchk_Mem_TLP    <= 1;    // MWr, MRd or Cpl/D
                FSM_Rx_Fmt        <= 'H12;
            end
            else begin
                $display ("\n %t:\n !! trn_rsof_n error!", $time);
                Err_signal <= 1;
            end
         end
 
 
        'H12: begin
            if ( trn_rsrc_rdy_n | trn_rdst_rdy_n) begin
              FSM_Rx_Fmt        <= 'H12;
            end
            else if (!trn_rsof_n) begin
              $display ("\n %t:\n !! trn_rsof_n error! should be 1.", $time);
              Err_signal <= 1;
            end
            else begin
              if (rxchk_TLP_4DW_Hdr & rxchk_TLP_Has_Data) begin
                if (trn_reof_n) begin
                  Err_signal <= 0;
                  FSM_Rx_Fmt        <= 'H20;
                end
                else begin
                  Err_signal <= 1;
                  $display ("\n %t:\n !! trn_reof_n error (4-Header, with Payload)! should be 1.", $time);
                end
              end
              else if (rxchk_TLP_4DW_Hdr & !rxchk_TLP_Has_Data) begin
                if (trn_reof_n) begin
                  Err_signal <= 1;
                  $display ("\n %t:\n !! trn_reof_n error (4-Header, no Payload)! should be 0.", $time);
                end
                else if (trn_rrem_n=='H00) begin
                    Err_signal <= 0;
                    FSM_Rx_Fmt        <= 'H10;
                end
                else begin
                    Err_signal <= 1;
                    $display ("\n %t:\n !! trn_rrem_n error (4-Header, no Payload)!", $time);
                end
              end
              else if (!rxchk_TLP_4DW_Hdr & !rxchk_TLP_Has_Data) begin
                if (trn_reof_n) begin
                  Err_signal <= 1;
                  $display ("\n %t:\n !! trn_reof_n error (3-Header, with Payload)! should be 0.", $time);
                end
                else if (trn_rrem_n=='H0f) begin
                  Err_signal <= 0;
                  FSM_Rx_Fmt        <= 'H10;
                end
                else begin
                  Err_signal <= 1;
                  $display ("\n %t:\n !! trn_rrem_n error (3-Header, no Payload)!", $time);
                end
              end
              else if (rxchk_TLP_Length=='H1) begin  // (!rxchk_TLP_4DW_Hdr & rxchk_TLP_Has_Data)
                if (trn_reof_n) begin
                  Err_signal <= 1;
                  $display ("\n %t:\n !! trn_reof_n error (3-Header, with Payload)! should be 0.", $time);
                end
                else if (trn_rrem_n=='H00) begin
                  Err_signal <= 0;
                  FSM_Rx_Fmt        <= 'H10;
                end
                else begin
                  Err_signal <= 1;
                  $display ("\n %t:\n !! trn_rrem_n error (3-Header, no Payload)!", $time);
                end
              end
              else begin  // (!rxchk_TLP_4DW_Hdr & rxchk_TLP_Has_Data) & (rxchk_TLP_Length>'H1)
                if (trn_reof_n) begin
                  Err_signal <= 0;
                  rxchk_TLP_Length      <= rxchk_TLP_Length - 1;
                  FSM_Rx_Fmt        <= 'H20;
                end
                else begin
                  Err_signal <= 1;
                  $display ("\n %t:\n !! trn_reof_n error (3-Header, no Payload)! should be 1.", $time);
                end
              end
 
              // Address-Length combination check
              if (rxchk_TLP_4DW_Hdr) begin
                if (({1'b0, trn_rd[11:2]} + rxchk_TLP_Length[9:0])>11'H400) begin
                  $display ("\n\n %t:\n !! Rx 4KB straddled !!", $time);
                  $display ("\n Address=%08X  Length=%04X (%04X bytes)\n\n", trn_rd[31:0], rxchk_TLP_Length, rxchk_TLP_Length<<2);
//                  Err_signal <= 1;
                end
                if (trn_rd[63:32]=='H0 && rxchk_Mem_TLP==1) begin
                  $display ("\n %t:\n !! Rx TLP should not be 4-DW headher !!", $time);
                  Err_signal <= 1;
                end
              end 
              else begin
                if (({1'b0, trn_rd[11+32:2+32]} + rxchk_TLP_Length[9:0])>11'H400) begin
                  $display ("\n\n %t:\n !! Rx 4KB straddled !!", $time);
                  $display ("\n Address=%08X  Length=%04X (%04X bytes)\n\n", trn_rd[63:32], rxchk_TLP_Length, rxchk_TLP_Length<<2);
//                  Err_signal <= 1;
                end
              end
            end
          end
 
 
        'H20: begin
            if ( trn_rsrc_rdy_n | trn_rdst_rdy_n) begin
              FSM_Rx_Fmt        <= 'H20;
            end
            else if (rxchk_TLP_Length==2) begin
              if (trn_rrem_n=='H00 && trn_reof_n==0) begin
                FSM_Rx_Fmt        <= 'H10;
              end
              else begin
                $display ("\n %t:\n !! trn_reof_n/trn_rrem_n error !!", $time);
                Err_signal <= 1;
              end
            end
            else if (rxchk_TLP_Length==1) begin
              if (trn_rrem_n=='H0f && trn_reof_n==0) begin
                FSM_Rx_Fmt        <= 'H10;
              end
              else begin
                $display ("\n %t:\n !! trn_reof_n/trn_rrem_n error !!", $time);
                Err_signal <= 1;
              end
            end
            else if (rxchk_TLP_Length==0) begin
              $display ("\n %t:\n !! Rx TLP Length error !!", $time);
              Err_signal <= 1;
            end
            else if (!trn_reof_n) begin
              $display ("\n %t:\n !! trn_reof_n too early !!", $time);
              Err_signal <= 1;
            end
            else begin
              rxchk_TLP_Length      <= rxchk_TLP_Length - 2;
              FSM_Rx_Fmt        <= 'H20;
            end
         end
 
        default: begin
           FSM_Rx_Fmt     <= 'H00;
         end
 
      endcase
   end
 
 
 
 
   // TLP format check by Tx
   reg [ 7: 0]   FSM_TLP_Fmt;
   reg [10: 0]   tx_TLP_Length;
   reg [12: 0]   tx_TLP_Address;
   reg           tx_TLP_Has_Data;
   reg           tx_TLP_is_CplD;
   reg           tx_TLP_4DW_Hdr;
   reg           tx_Mem_TLP;
   always @(negedge trn_clk )
   if (!trn_reset_n) begin
      FSM_TLP_Fmt      <= 0;
   end
   else begin
 
      case (FSM_TLP_Fmt)
 
        'H00: begin
            FSM_TLP_Fmt    <= 'H010;
         end
 
        'H10: begin
            if ( trn_tsrc_rdy_n | trn_tdst_rdy_n) begin
              FSM_TLP_Fmt        <= 'H10;
            end
            else if (~trn_teof_n) begin
                  $display ("\n %t:\n !! Unexpected trn_teof_n !!", $time);
                  Err_signal <= 1;
            end
            else if (~trn_tsof_n&trn_teof_n) begin
                tx_TLP_Has_Data    <= trn_td[30+32];
                tx_TLP_4DW_Hdr     <= trn_td[29+32];
                tx_TLP_Length[10]  <= (trn_td[9+32:0+32]=='H0);
                tx_TLP_Length[9:0] <= trn_td[9+32:0+32];
                tx_TLP_is_CplD     <= trn_td[27+32];
                if (trn_td[28+32:25+32]) tx_Mem_TLP    <= 0;    // Msg or MsgD
                else                     tx_Mem_TLP    <= 1;    // MWr, MRd or Cpl/D
                FSM_TLP_Fmt        <= 'H12;
                if (trn_td[31:16] == localID) begin
                   Err_signal <= 0;
                end
                else begin
                   $display ("\n %t:\n !! Tx Bad TLP ReqID for TLP !!", $time);
                   Err_signal <= 1;
                end
            end
            else begin
                $display ("\n %t:\n !! trn_tsof_n error!", $time);
                Err_signal <= 1;
            end
         end
 
 
        'H12: begin
            if ( trn_tsrc_rdy_n | trn_tdst_rdy_n) begin
              FSM_TLP_Fmt        <= 'H12;
            end
            else if (!trn_tsof_n) begin
              $display ("\n %t:\n !! trn_tsof_n error! should be 1.", $time);
              Err_signal <= 1;
            end
            else begin
              if (tx_TLP_4DW_Hdr & tx_TLP_Has_Data) begin
                if (trn_teof_n) begin
                  Err_signal   <= 0;
                  FSM_TLP_Fmt        <= 'H20;
                end
                else begin
                  Err_signal   <= 1;
                  $display ("\n %t:\n !! trn_teof_n error (4-Header, with Payload)! should be 1.", $time);
                end
              end
              else if (tx_TLP_4DW_Hdr & !tx_TLP_Has_Data) begin
                if (trn_teof_n) begin
                  Err_signal <= 1;
                  $display ("\n %t:\n !! trn_teof_n error (4-Header, no Payload)! should be 0.", $time);
                end
                else if (trn_trem_n=='H00) begin
                    Err_signal <= 0;
                    FSM_TLP_Fmt        <= 'H10;
                end
                else begin
                    Err_signal <= 1;
                    $display ("\n %t:\n !! trn_trem_n error (4-Header, no Payload)!", $time);
                end
              end
              else if (!tx_TLP_4DW_Hdr & !tx_TLP_Has_Data) begin
                if (trn_teof_n) begin
                  Err_signal <= 1;
                  $display ("\n %t:\n !! trn_teof_n error (3-Header, with Payload)! should be 0.", $time);
                end
                else if (trn_trem_n=='H0f) begin
                  Err_signal <= 0;
                  FSM_TLP_Fmt        <= 'H10;
                end
                else begin
                  Err_signal <= 1;
                  $display ("\n %t:\n !! trn_trem_n error (3-Header, no Payload)!", $time);
                end
              end
              else if (tx_TLP_Length=='H1) begin  // (!tx_TLP_4DW_Hdr & tx_TLP_Has_Data)
                if (trn_teof_n) begin
                  Err_signal <= 1;
                  $display ("\n %t:\n !! trn_teof_n error (3-Header, with Payload)! should be 0.", $time);
                end
                else if (trn_trem_n=='H00) begin
                  if (tx_TLP_is_CplD && (trn_td[31+32:16+32]==`C_HOST_RDREQ_ID)) begin
                    Err_signal    <= 0;
                    FSM_TLP_Fmt      <= 'H10;
                  end
                  else if (tx_TLP_is_CplD) begin
                    Err_signal   <= 1;
                    $display ("\n %t:\n !! Tx CplD Requester ID Wrong (TLP Length ==1 )!! ", $time);
                    FSM_TLP_Fmt      <= 'H10;
                  end
                  else begin
                    Err_signal    <= 0;
                    FSM_TLP_Fmt      <= 'H10;
                  end
                end
                else begin
                  Err_signal <= 1;
                  $display ("\n %t:\n !! trn_trem_n error (3-Header, no Payload)!", $time);
                end
              end
              else begin  // (!tx_TLP_4DW_Hdr & tx_TLP_Has_Data) & (tx_TLP_Length>'H1)
                if (trn_teof_n) begin
                  if (tx_TLP_is_CplD && (trn_td[31+32:16+32]==`C_HOST_RDREQ_ID)) begin
                    tx_TLP_Length      <= tx_TLP_Length - 1;
                    FSM_TLP_Fmt        <= 'H20;
                  end
                  else if (tx_TLP_is_CplD) begin
                    Err_signal   <= 1;
                    $display ("\n %t:\n !! Tx CplD Requester ID Wrong (TLP Length !=1 )!! ", $time);
                    FSM_TLP_Fmt        <= 'H20;
                  end
                  else begin
                    tx_TLP_Length      <= tx_TLP_Length - 1;
                    FSM_TLP_Fmt        <= 'H20;
                  end
                end
                else begin
                  Err_signal <= 1;
                  $display ("\n %t:\n !! trn_teof_n error (3-Header, no Payload)! should be 1.", $time);
                end
              end
 
              // Address-Length combination check
              if (tx_TLP_4DW_Hdr) begin
                if (({1'b0, trn_td[11:2]} + tx_TLP_Length[9:0])>11'H400) begin
                  $display ("\n %t:\n !! Tx 4KB straddled !!", $time);
                  $display ("\n Address=%08X  Length=%04X (%04X bytes)\n", trn_td[31:0], tx_TLP_Length, tx_TLP_Length<<2);
                  Err_signal <= 1;
                end
                if (trn_td[63:32]=='H0 && tx_Mem_TLP==1) begin
                  $display ("\n %t:\n !! Tx TLP should not be 4-DW headher !!", $time);
                  Err_signal <= 1;
                end
              end 
              else begin
                if (({1'b0, trn_td[11+32:2+32]} + tx_TLP_Length[9:0])>11'H400) begin
                  $display ("\n %t:\n !! Tx 4KB straddled !!", $time);
                  $display ("\n Address=%08X  Length=%04X (%04X bytes)\n", trn_td[63:32], tx_TLP_Length, tx_TLP_Length<<2);
                  Err_signal <= 1;
                end
              end
 
            end
          end
 
 
        'H20: begin
            if ( trn_tsrc_rdy_n | trn_tdst_rdy_n) begin
              FSM_TLP_Fmt        <= 'H20;
            end
            else if (tx_TLP_Length==2) begin
              if (trn_trem_n=='H00 && trn_teof_n==0) begin
                FSM_TLP_Fmt        <= 'H10;
              end
              else begin
                $display ("\n %t:\n !! trn_teof_n/trn_trem_n error !!\n", $time);
                Err_signal <= 1;
              end
            end
            else if (tx_TLP_Length==1) begin
              if (trn_trem_n=='H0f && trn_teof_n==0) begin
                FSM_TLP_Fmt        <= 'H10;
              end
              else begin
                $display ("\n %t:\n !! trn_teof_n/trn_trem_n error !!\n", $time);
                Err_signal <= 1;
              end
            end
            else if (tx_TLP_Length==0) begin
              $display ("\n %t:\n !! Tx TLP Length error !!", $time);
              Err_signal <= 1;
            end
            else if (!trn_teof_n) begin
              $display ("\n %t:\n !! trn_teof_n too early !!", $time);
              Err_signal <= 1;
            end
            else begin
              tx_TLP_Length      <= tx_TLP_Length - 2;
              FSM_TLP_Fmt        <= 'H20;
            end
         end
 
        default: begin
           FSM_TLP_Fmt     <= 'H00;
         end
 
      endcase
   end
 
 
 
 
   //************************************************//
   //************************************************//
   //************************************************//
 
   reg  [ 7:00] FSM_Tx_Desc_MRd;
  // Descriptors MRd
   always @(negedge trn_clk )
   if (!trn_reset_n) begin
      FSM_Tx_Desc_MRd        <= 0;
      Desc_tx_MRd_Valid      <= 0;
   end
   else begin
 
      case (FSM_Tx_Desc_MRd)
 
        'H00: begin
            FSM_Tx_Desc_MRd       <= 'H10;
         end
 
        'H10: begin
           case ({ trn_tsrc_rdy_n
                 , trn_tdst_rdy_n
                 , trn_tsof_n
                 , trn_td[15]
                 })
 
             'B0001:
                 if ( (trn_td[31+32:24+32]=='H00 || trn_td[31+32:24+32]=='H20)
                    &&(trn_td[9+32:32]=='H8)) begin
                      Desc_tx_MRd_Leng[10]  <= (trn_td[9+32:32]==0);
                      Desc_tx_MRd_Leng[9:0] <= trn_td[9+32:32];
                      Desc_tx_MRd_TAG       <= trn_td[15:8];
                      FSM_Tx_Desc_MRd <= 'H31;
                 end
                 else begin
                      FSM_Tx_Desc_MRd <= 'H10;
                 end
 
              default: begin
                 FSM_Tx_Desc_MRd <= 'H10;
              end
 
           endcase
         end
 
 
        'H31: begin   // Low 32 bits Address
           if (trn_tsrc_rdy_n|trn_tdst_rdy_n) begin
             FSM_Tx_Desc_MRd   <= 'H31;
           end
           else begin
               Desc_tx_MRd_Addr      <= trn_td[31:00];
               Desc_tx_MRd_Valid     <= 1;
               FSM_Tx_Desc_MRd       <= 'H10;
           end
         end
 
 
        default: begin
           FSM_Tx_Desc_MRd <= 'H00;
         end
 
      endcase
   end
 
 
 
   // DMA MRd out of Tx
   reg [ 7: 0]   FSM_Tx_MRd;
   reg           tx_DMA_MRd_A64b;
   always @(negedge trn_clk )
   if (!trn_reset_n) begin
      FSM_Tx_MRd      <= 0;
      tx_MRd_come     <= 0;
   end
   else begin
 
      case (FSM_Tx_MRd)
 
        'H00: begin
            FSM_Tx_MRd       <= 'H10;
         end
 
        'H10: begin
           case ({ trn_tsrc_rdy_n
                 , trn_tdst_rdy_n
                 , trn_tsof_n
                 , trn_td[15]
                 })
 
             'B0000:
                 case (trn_td[31+32:24+32])
                   'H00: begin   // 3-dw header
                      tx_MRd_Length[9:0] <= trn_td[9+32:32];
                      tx_MRd_Length[10]  <= (trn_td[9+32:32]=='H0)?1:0;
                      tx_MRd_Tag         <= trn_td[15:8];
                      FSM_Tx_MRd         <= 'H30;
                      tx_DMA_MRd_A64b    <= 0;
                    end
 
                   'H20: begin   // 4-dw header
                      tx_MRd_Length[9:0] <= trn_td[9+32:32];
                      tx_MRd_Length[10]  <= (trn_td[9+32:32]=='H0)?1:0;
                      tx_MRd_Tag         <= trn_td[15:8];
                      FSM_Tx_MRd         <= 'H30;
                      tx_DMA_MRd_A64b    <= 1;
                    end
 
                   default: begin
                      FSM_Tx_MRd <= 'H10;   // Idle
                    end
                 endcase
 
              default: begin
                 FSM_Tx_MRd <= 'H10;
              end
 
           endcase
         end
 
 
        'H30: begin
           if (trn_tsrc_rdy_n|trn_tdst_rdy_n) begin
             FSM_Tx_MRd <= 'H30;
           end
           else if( trn_td[1:0]==0) begin
             FSM_Tx_MRd <= 'H10;
             tx_MRd_come <= 'B1;
           end
           else begin
             $display ("\n %t:\n !! Bad TLP Address for Tx MRd !!", $time);
             Err_signal <= 1;
           end
        end
 
        default: begin
           FSM_Tx_MRd <= 'H00;
         end
 
      endcase
   end
 
 
 
   // Msg checking ...
   reg [7: 0] fsm_Tx_Msg;
   reg [3: 0] tx_Msg_Tag_Lo;
   always @(negedge trn_clk )
   if (!trn_reset_n) begin
      fsm_Tx_Msg      <= 0;
      tx_Msg_Tag_Lo   <= 1;
   end
 
   else begin
 
      case (fsm_Tx_Msg)
 
        'H00: begin
            fsm_Tx_Msg    <= 'H10;
         end
 
        'H10: begin
           case ({ trn_tsrc_rdy_n
                 , trn_tdst_rdy_n
                 , trn_tsof_n
                 })
 
             'B000:
                 if (trn_td[31+32:28+32]=='H3) begin
                    fsm_Tx_Msg    <= 'H30;
                    if ( trn_td[11:8] != tx_Msg_Tag_Lo ) begin
                      $display ("\n %t:\n !! Msg Tag bad !!", $time, trn_td[11:8]);
                      Err_signal <= 1;
                    end
                    else if ( trn_td[7:0] == `C_MSG_CODE_INTA ) begin
//                      fsm_Tx_Msg   <= 'H30;
                      Accum_Msg_INTA <= Accum_Msg_INTA + 1;
                    end
                    else if ( trn_td[7:0] == `C_MSG_CODE_INTA_N ) begin
//                      fsm_Tx_Msg   <= 'H30;
                      Accum_Msg_INTA_n <= Accum_Msg_INTA_n + 1;
                    end
                    else begin
                      $display ("\n %t:\n !! Bad Msg code (0x%2x) !!", $time, trn_td[7:0]);
                      Err_signal <= 1;
                    end
                 end
                 else begin
                      fsm_Tx_Msg    <= 'H10;
                 end
 
              default: begin
                 fsm_Tx_Msg    <= 'H10;
              end
 
           endcase
         end
 
 
        'H30: begin
           if (trn_tsrc_rdy_n|trn_tdst_rdy_n) begin
             fsm_Tx_Msg <= 'H30;
           end
           else if (trn_td) begin
             $display ("\n %t:\n !! Msg data bad!!", $time);
             Err_signal <= 1;
           end
           else begin
             fsm_Tx_Msg <= 'H10;
             tx_Msg_Tag_Lo  <= tx_Msg_Tag_Lo + 1;
           end
         end
 
 
        default: begin
           fsm_Tx_Msg  <= 'H00;
         end
 
      endcase
   end
 
 
 
   // ================================================= //
   // =======     Interrupt uneven checking     ======= //
   // ================================================= //
   always @ Accum_Msg_INTA
     if (Accum_Msg_INTA>Accum_Msg_INTA_n+1) begin
        $display("\n\n  INTA overrun at %t\n\n", $time);
        Err_signal <= 1;
     end
 
   // 
   always @ Accum_Msg_INTA_n
     if (Accum_Msg_INTA_n>Accum_Msg_INTA) begin
        $display("\n\n  #INTA overrun at %t\n\n", $time);
        Err_signal <= 1;
     end
 
 
 
 
  // ***************************************** //
  //                   Tasks                   //
  // ***************************************** //
 
  ///////////////////////////////////////////////
  //   Wait for the next positive clock event  //
  ///////////////////////////////////////////////
  task To_the_next_Event;
  begin
    wait (!trn_clk);
    wait (trn_clk);
    # `T_DELAY_AFTER ;
  end
  endtask
 
  ///////////////////////////////////////////////
  //   Wait for the next negative clock event  //
  ///////////////////////////////////////////////
  task To_the_next_Tx_Data;
  begin
    wait (trn_clk);
    wait (!trn_clk);
    # `T_DELAY_AFTER ;
  end
  endtask
 
 
  ///////////////////////////////////////////////
  //   Insert GAP                              //
  ///////////////////////////////////////////////
  task Gap_Insert_Rx;
  begin
    To_the_next_Event;
    trn_rsof_n <= 1;
    trn_reof_n <= 1;
    trn_rsrc_rdy_n <= 1;
    trn_rbar_hit_n <= `C_NO_BAR_HIT;
    trn_rd <= -1;
    trn_rrem_n <= -1;
  end
  endtask
 
 
  ///////////////////////////////////////////////
  //                                           //
  //   Feed TLP to Rx: MRd, MWr, Cpl/D, Msg    //
  //                                           //
  ///////////////////////////////////////////////
  task TLP_Feed_Rx;
    input         Use_Private_Array;   // Public or private
    input [11:0]  IndexA;              // Start point in the Array
    input [ 6:0]  BAR_Hit_N;           // Which BAR is hit
 
//    integer       hdr_Leng;
    reg           TLP_has_Payload;
    reg           TLP_hdr_4DW;
    reg   [10:0]  jr;
    reg   [10:0]  payload_Leng;
 
  begin
 
    // TLP format extraction
    TLP_has_Payload     <= Hdr_Array[0][30] ;
//    hdr_Leng            <= Hdr_Array[0][29] + 3;
    TLP_hdr_4DW         <= Hdr_Array[0][29];
 
    // Header #0
    To_the_next_Event;
    trn_rsof_n          <= 0;
    trn_reof_n          <= 1;
    trn_rsrc_rdy_n      <= 0;
    trn_rbar_hit_n      <= BAR_Hit_N;
    trn_rd              <= {Hdr_Array[0], Hdr_Array[1]};
    trn_rrem_n          <= 0;
 
    payload_Leng        <= {Hdr_Array[0][9:0]?1'b0:1'b1, Hdr_Array[0][9:0]};
 
    // Header words # 1
    for (jr=1; jr<2; jr=jr+1) begin
      To_the_next_Event;
      trn_rsrc_rdy_n  <= trn_rsrc_rdy_n_seed;
      if (trn_rsrc_rdy_n_seed) begin
          trn_rsof_n    <= trn_rsof_n;
          trn_rd        <= trn_rd;
          trn_rrem_n    <= trn_rrem_n;
          trn_reof_n    <= trn_reof_n;
//          #0.1    jr    <= jr-1;
          jr             = jr-1;      // !! not <= !!
        end
      else begin
          trn_rsof_n    <= 1;
          if (TLP_hdr_4DW) begin
            trn_rrem_n    <= 'H00;
            trn_rd        <= {Hdr_Array[2], Hdr_Array[3]};
          end
          else if (TLP_has_Payload) begin
            trn_rrem_n    <= 'H00;
            if (Use_Private_Array)
              trn_rd        <= {Hdr_Array[2],Inv_Endian (Private_Array[IndexA])};
            else
              trn_rd        <= {Hdr_Array[2],Inv_Endian (D_Array[IndexA])};
          end
          else begin
            trn_rrem_n    <= 'H0f;
            trn_rd        <= {Hdr_Array[2], 32'H0};
          end
          if (payload_Leng<='H1 && TLP_hdr_4DW==0) begin
            trn_reof_n    <= 0;
          end
          else if (!TLP_has_Payload) begin
            trn_reof_n    <= 0;
          end
          else begin
            trn_reof_n    <= 1;
          end
        end
    end    // Header done.
 
    // Payload data ...
    if ((TLP_has_Payload && TLP_hdr_4DW) || (TLP_has_Payload && (payload_Leng>'H1) && !TLP_hdr_4DW))
 
       for (jr=(!TLP_hdr_4DW); jr<payload_Leng; jr=jr+2) begin
         To_the_next_Event;
         trn_rsrc_rdy_n <= trn_rsrc_rdy_n_seed;
         if (trn_rsrc_rdy_n_seed) begin
           trn_rd       <= trn_rd;
           trn_rrem_n   <= trn_rrem_n;
           trn_reof_n   <= trn_reof_n;
//           #0.1    jr   <= jr-1;
           jr            = jr-2;      // !! not <= !!
         end
         else begin
           if (jr==payload_Leng-1 || jr==payload_Leng-2) begin
             trn_reof_n   <= 0;
           end
           else begin
             trn_reof_n   <= 1;
           end
 
           if (jr==payload_Leng-1) begin
             trn_rrem_n   <= 'H0f;
             if (Use_Private_Array)
               trn_rd     <= {Inv_Endian(Private_Array[IndexA+jr]), 32'Hffff_ffff};
             else
               trn_rd     <= {Inv_Endian(D_Array[IndexA+jr]), 32'Hffff_ffff};
           end
           else begin
             trn_rrem_n   <= 'H00;
             if (Use_Private_Array)
               trn_rd     <= {Inv_Endian(Private_Array[IndexA+jr]), Inv_Endian(Private_Array[IndexA+jr+1])};
             else
               trn_rd     <= {Inv_Endian(D_Array[IndexA+jr]), Inv_Endian(D_Array[IndexA+jr+1])};
           end
 
 
         end
       end
    // Payload done.
 
  end
  endtask
 
 
    /////////////////////////////////////////////
   //                                         //
  //   Function -  Endian Inversion 64-bit   //
 //                                         //
/////////////////////////////////////////////
   function [31:00] Inv_Endian;
   input [31:00] Data;
   begin
      Inv_Endian = {Data[ 7: 0], Data[15: 8], Data[23:16], Data[31:24]};
   end
   endfunction
 
 
endmodule
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.