// =============================================================================
// >>>>>>>>>>>>>>>>>>>>>>>>> COPYRIGHT NOTICE <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// -----------------------------------------------------------------------------
//   Copyright (c) 2022 by Lattice Semiconductor Corporation
//   ALL RIGHTS RESERVED
// -----------------------------------------------------------------------------
//
//   Permission:
//
//      Lattice SG Pte. Ltd. grants permission to use this code
//      pursuant to the terms of the Lattice Reference Design License Agreement.
//
//
//   Disclaimer:
//
//      This VHDL or Verilog source code is intended as a design reference
//      which illustrates how these types of functions can be implemented.
//      It is the user's responsibility to verify their design for
//      consistency and functionality through the use of formal
//      verification methods.  Lattice provides no warranty
//      regarding the use or functionality of this code.
//
// -----------------------------------------------------------------------------
//
//                  Lattice SG Pte. Ltd.
//                  101 Thomson Road, United Square #07-02
//                  Singapore 307591
//
//
//                  TEL: 1-800-Lattice (USA and Canada)
//                       +65-6631-2000 (Singapore)
//                       +1-503-268-8001 (other locations)
//
//                  web: http://www.latticesemi.com/
//                  email: techsupport@latticesemi.com
//
// -----------------------------------------------------------------------------
//
// =============================================================================
//                         FILE DETAILS
// Project               :
// File                  : eval_top.v
// Title                 :
// Dependencies          :
// Description           : Evaluation top level design for MC_Avant
// =============================================================================
//                        REVISION HISTORY
// Version               : 1.0.0.
// Author(s)             :
// Mod. Date             : 
// Changes Made          : Initial release.
// =============================================================================
`define LPDDR4


`include "kitcar.v"
`include "pll_aclk_pclk.v"
`include "apb2init.sv"
`include "traffic_gen/ctrl_fifo.v"
`include "traffic_gen/lscc_lfsr.v"
`include "traffic_gen/lscc_axi4_m_csr.sv"
`include "traffic_gen/lscc_axi4_m_rd.sv"
`include "traffic_gen/lscc_axi4_m_wr.sv"
`include "traffic_gen/lscc_axi4_perf_calc.sv"
`include "traffic_gen/lscc_axi4_traffic_gen.sv"
`include "traffic_gen/ahbl0.v" 
`include "traffic_gen/ahbl2apb0.v"
`include "traffic_gen/apb0.v"
`include "traffic_gen/cpu0.v"
`include "traffic_gen/gpio0.v"
`include "traffic_gen/lscc_osc.v"
`include "traffic_gen/memc_apb.v"
`include "traffic_gen/osc0.v"
`include "traffic_gen/lscc_ram_dp_true.v"
`include "traffic_gen/sysmem0.v"
`include "traffic_gen/sysmem0_sim.v"
`include "traffic_gen/uart0.v"
`include "traffic_gen/mc_axi4_traffic_gen.v"
`include "axi_bridge/lscc_ram_dp.v"
`include "axi_bridge/lpddr4_mc_dpram.v"
`include "axi_bridge/lpddr4_mc_sch_ebr.v"
`include "axi_bridge/lpddr4_mc_double_sync.sv"
`include "axi_bridge/lpddr4_mc_toggle_sync.sv"
`include "axi_bridge/lpddr4_mc_sync_fifo.v"
`include "axi_bridge/lpddr4_mc_reorder_buffer.sv"
`include "axi_bridge/lpddr4_mc_axi_slv_wr.sv"
`include "axi_bridge/lpddr4_mc_axi_slv_rd.sv"
`include "axi_bridge/lpddr4_mc_axi_iface_top.sv"

// For debugging the DQS/DQ/DMI on the board
// Look for dbg_rddata_en_o, dbg_wddata_en_o in ports.xml
//`define DQSDQ_DEBUG_EN  

module eval_top #(
  // SIM=0 for implementation to FPGA device
  // SIM=1 for skipping training for faster simulation
  parameter SIM = 0  // set to 1 for maverick regression
)(
    // inputs
	clk_ext       ,     // 27M ext clock 
//    clk_i         ,
    rstn_i        ,     // from SW1 pushbutton
    pll_refclk_i  ,     // 100MHz
    uart_rxd_i    ,
    // output
    init_done_o   ,
    uart_txd_o    ,
    LED           ,     // to LEDs (LED0-9)
    fs            ,  
    cmos_xclr     ,
    mipi_clk      ,
    out_clk0      ,
    gnd_clk       ,
    out_clk1      ,
    sim_o         ,     // SIM paramter value to tb_top
`ifdef DQSDQ_DEBUG_EN
    dbg_rddata_en_out,
    dbg_wddata_en_out,
`endif
//    ddr_ck_t_o    , 
//    ddr_ck_c_o    , 
    ddr_ck_o      ,
    ddr_cke_o     ,
    ddr_cs_o      ,
    ddr_ca_o      ,
    ddr_odt_ca_o  ,
    ddr_reset_n_o , 
    ddr_dq_io     ,
    ddr_dqs_io    , 
    ddr_dmi_io    
);

`include "dut_params.v"
localparam BI_WR_DATA_FIFO_DEPTH  = 8;
localparam GEN_OUT_WIDTH          = 4;

//-----------------------------------------------------------------------------
//                                                                          --
//                      PORT DEFINITION
//                                                                          --
//----------------------------------------------------------------------------
input   wire                   clk_ext             ;     // 27M ext clock 
//input   wire                   clk_i               ;
input   wire                   rstn_i              ;     // from SW1 pushbutton
input   wire                   pll_refclk_i        ;     //100MHz since fs=3'b001 // from 125MHz Clk
input   wire                   uart_rxd_i          ;
//input   wire                 perf_tst_en_i       ;
                                                                                      
// outputs
output  wire                   uart_txd_o          ;
output  wire                   init_done_o         ;
inout         [11:0]            LED    /* synthesis syn_force_pads=1 */;     // to LEDs (LED0-9) /
output                         sim_o               ;
output  wire  [2:0]            fs                  ;  
output  wire                   cmos_xclr           ;
output  wire                   mipi_clk            ;
output  wire                   out_clk0            ;
output  wire                   gnd_clk             ;
output  wire                   out_clk1            ;
`ifdef DQSDQ_DEBUG_EN
output  logic                  dbg_rddata_en_out   ;
output  logic                  dbg_wddata_en_out   ;
`endif
//output       [0:0]             ddr_ck_t_o          ; 
//output       [0:0]             ddr_ck_c_o          ; 
output       [0:0]             ddr_ck_o            ; 
output       [0:0]             ddr_cke_o           ;
output       [0:0]             ddr_cs_o            ;
output       [5:0]             ddr_ca_o            ;
output                         ddr_odt_ca_o        ;
output                         ddr_reset_n_o       ; 
inout        [BUS_WIDTH -1 :0] ddr_dq_io           ;
inout        [DQS_WIDTH -1:0]  ddr_dqs_io          ; 
inout        [DQS_WIDTH -1:0]  ddr_dmi_io          ;

//------------------------------
// INTERNAL SIGNAL DECLARATIONS: 
//------------------------------
// parameters (constants)

// wires (assigns)
wire          pll_out   ;

wire    [7:0] LED_array ;  
wire    [7:0] LED_array2; 
wire    [9:0] led_o     ;
wire                       aclk_i        ;
wire                       pll_rst_n_i   ;
wire                       rst_n_i       ;
wire                       pclk_i        ;
wire                       preset_n_i    ;
wire                       pll_lock_o    ; 
wire                       sclk_o        ; 
wire                       irq_o         ; 
wire                       init_start_i  ;
wire  [ 7:0]               trn_opr_i     ;
//wire                       init_done_o   ;
wire                       trn_err_o     ;

wire                       apb_penable_i ; 
wire                       apb_psel_i    ; 
wire                       apb_pwrite_i  ; 
wire  [APB_ADDR_WIDTH-1:0] apb_paddr_i   ; 
wire  [APB_DATA_WIDTH-1:0] apb_pwdata_i  ; 
logic                      apb_pready_o  ; 
wire                       apb_pslverr_o ; 
logic [APB_DATA_WIDTH-1:0] apb_prdata_o  ; 

reg                        prst_n        ;
reg                        prst_n_r0     ;
reg                        prst_n_r1     ;

reg                        areset_n      ;
reg                        areset_n_r0   ;
reg                        areset_n_r1   ;

reg                        sreset_n      ;
reg                        sreset_n_r0   ;
reg                        sreset_n_r1   ;



logic                         clk_w      ;
logic                         areset_n_i ;
// Added syn_keep for easier debugging in post-Synthesis netlist
logic                         axi_arvalid_i  /* synthesis syn_keep=1 */; 
logic [AXI_ID_WIDTH-1 : 0]    axi_arid_i     /* synthesis syn_keep=1 */;
logic [AXI_LEN_WIDTH-1 : 0]   axi_arlen_i    /* synthesis syn_keep=1 */;
logic [1:0]                   axi_arburst_i  /* synthesis syn_keep=1 */;
logic [AXI_ADDR_WIDTH -1 : 0] axi_araddr_i   /* synthesis syn_keep=1 */;
logic                         axi_arready_o  /* synthesis syn_keep=1 */;
logic [AXI_QOS_WIDTH - 1:0]   axi_arqos_i    /* synthesis syn_keep=1 */;
logic [2:0]                   axi_arsize_i   /* synthesis syn_keep=1 */;
logic [1:0]                   axi_rresp_o    /* synthesis syn_keep=1 */;
logic [AXI_ID_WIDTH - 1: 0]   axi_rid_o      /* synthesis syn_keep=1 */;
logic [AXI_DATA_WIDTH - 1: 0] axi_rdata_o    /* synthesis syn_keep=1 */;
logic                         axi_rvalid_o   /* synthesis syn_keep=1 */;
logic                         axi_rlast_o    /* synthesis syn_keep=1 */;
logic                         axi_rready_i   /* synthesis syn_keep=1 */;
logic                         axi_bready_i   /* synthesis syn_keep=1 */; 
logic                         axi_bvalid_o   /* synthesis syn_keep=1 */;
logic [1:0]                   axi_bresp_o    /* synthesis syn_keep=1 */; 
logic [AXI_ID_WIDTH-1 : 0]    axi_bid_o      /* synthesis syn_keep=1 */;
logic                         axi_awvalid_i  /* synthesis syn_keep=1 */;
logic [AXI_ID_WIDTH-1 : 0]    axi_awid_i     /* synthesis syn_keep=1 */;
logic [AXI_LEN_WIDTH - 1: 0]  axi_awlen_i    /* synthesis syn_keep=1 */;
logic  [1:0]                  axi_awburst_i  /* synthesis syn_keep=1 */;
logic  [2:0]                  axi_awsize_i   /* synthesis syn_keep=1 */;
logic [AXI_ADDR_WIDTH -1 : 0] axi_awaddr_i   /* synthesis syn_keep=1 */;
logic                         axi_awready_o  /* synthesis syn_keep=1 */;
logic [AXI_QOS_WIDTH - 1:0]   axi_awqos_i    /* synthesis syn_keep=1 */;
logic                         axi_wvalid_i   /* synthesis syn_keep=1 */;
logic                         axi_wready_o   /* synthesis syn_keep=1 */;
logic [AXI_DATA_WIDTH - 1: 0] axi_wdata_i    /* synthesis syn_keep=1 */;
logic [AXI_DATA_WIDTH/8 -1:0] axi_wstrb_i    /* synthesis syn_keep=1 */;
logic                         axi_wlast_i    /* synthesis syn_keep=1 */;

logic                              wr_req_ready_o   ;
logic                              wr_req_valid_i   ;
logic [AXI_ID_WIDTH-1:0]           wr_req_id_i      ;
logic [ORDER_ID_WIDTH-1:0]         wr_req_order_id_i;
logic [AXI_ADDR_WIDTH-1:0]         wr_req_addr_i    ;
logic [AXI_LEN_WIDTH-1:0]          wr_req_len_i     ;
logic [2:0]                        wr_req_size_i    ;
logic                              wr_ready_o       ;
logic                              wr_valid_i       ;
logic [BI_RD_DATA_Q_WIDTH-1:0]     wr_data_i        ;
logic [(BI_RD_DATA_Q_WIDTH/8)-1:0] wr_byte_en_i     ;
logic                              wr_data_last_i   ;
logic                              rd_req_ready_o   ;
logic                              rd_req_valid_i   ; 
logic [AXI_ID_WIDTH-1:0]           rd_req_id_i      ;
logic [ORDER_ID_WIDTH-1:0]         rd_req_order_id_i;
logic [AXI_ADDR_WIDTH-1:0]         rd_req_addr_i    ;
logic [AXI_LEN_WIDTH-1:0]          rd_req_len_i     ;
logic [2:0]                        rd_req_size_i    ;
logic                              rd_rsp_ready_i   ;
logic                              rd_rsp_valid_o   ;
logic [AXI_ID_WIDTH-1:0]           rd_rsp_id_o      ;
logic [ORDER_ID_WIDTH-1:0]         rd_rsp_order_id_o;
logic [BI_RD_DATA_Q_WIDTH -1 :0]   rd_rsp_data_o    ;
logic [AXI_LEN_WIDTH-1:0]          rd_rsp_len_o     ;
logic [3-1:0]                      rd_rsp_size_o    ;
logic [7:0]                        rd_rsp_buff_addr_o;

logic                         arst_w;
logic                         osc_clk_90;

logic [GEN_OUT_WIDTH-1:0] a_test_num_w;
logic                     a_rd_error_occur_w;
logic                     a_rd_error_occur_r;
logic                     s_rd_error_occur_r1/* synthesis syn_preserve=1 CDC_Register=2 */;
logic                     s_rd_error_occur_r2;
logic [GEN_OUT_WIDTH-1:0] rvl_a_test_num_r;
logic [GEN_OUT_WIDTH-1:0] a_test_num_r     /* synthesis syn_preserve=1 */;
logic [GEN_OUT_WIDTH-1:0] a2s_test_num_r1  /* synthesis syn_preserve=1 CDC_Register=2 */;
logic [GEN_OUT_WIDTH-1:0] a2s_test_num_r2 ;
logic [GEN_OUT_WIDTH-1:0] rvl_s_test_num_r;
logic                     rvl_s_rd_error_occur_r;
`ifdef DQSDQ_DEBUG_EN
logic                     dbg_rddata_en_o;
logic                     dbg_wddata_en_o;
`endif
//-------------------------------------//
//-- assign (non-process) operations --//
//-------------------------------------//
assign mipi_clk    = clk_ext  ;
//assign out_clk0    = in_clk1;
assign out_clk1    = pclk_i   ;  
assign fs[2:0]     = 3'b001   ;  // Select 100MHz for pll_refclk_i
assign cmos_xclr   = rstn_i   ;
assign gnd_clk     = 1'b0     ;

assign pll_rst_n_i = rstn_i   ; 
assign rst_n_i     = rstn_i   ; 
assign preset_n_i  = prst_n   ; 
assign sim_o       = SIM[0]   ; // tell tb_top if SIM parameter is set

generate
  if (DATA_CLK_EN) begin : ASYNC_AXI
    logic aclk_pll_lock;
    assign clk_w   = aclk_i;

    assign arst_w  = rstn_i & aclk_pll_lock;

    pll_aclk_pclk u_aclk_pclk (
        .clki_i (osc_clk_90   ), 
        .rstn_i (rstn_i       ), 
        .clkop_o(aclk_i        ), 
        .clkos_o(pclk_i       ), 
        .lock_o (aclk_pll_lock));
  end
  else begin : SYNC_AXI
    assign clk_w   = sclk_o;  
    assign arst_w  = rstn_i;
    assign pclk_i  = osc_clk_90;
  end
endgenerate

assign areset_n_i   = areset_n;

always @(posedge pclk_i or negedge rstn_i) begin
   if (!rstn_i) begin
       prst_n    <= 1'b0;
       prst_n_r0 <= 1'b0;
       prst_n_r1 <= 1'b0;
   end
   else begin
       prst_n_r0 <= 1'b1;
       prst_n_r1 <= prst_n_r0;
       prst_n    <= prst_n_r1;
   end
end

always @(posedge clk_w or negedge arst_w) begin
   if (!arst_w) begin
       areset_n    <= 1'b0;
       areset_n_r0 <= 1'b0;
       areset_n_r1 <= 1'b0;
   end
   else begin

       areset_n_r0 <= 1'b1        ;
       areset_n_r1 <= areset_n_r0 ;
       areset_n    <= areset_n_r1 ;
   end
end

always @(posedge sclk_o or negedge rstn_i) begin
   if (!rstn_i) begin
       sreset_n    <= 1'b0;
       sreset_n_r0 <= 1'b0;
       sreset_n_r1 <= 1'b0;
   end
   else begin

       sreset_n_r0 <= 1'b1        ;
       sreset_n_r1 <= sreset_n_r0 ;
       sreset_n    <= sreset_n_r1 ;
   end
end

//--------------------------------------------------------------------
//--  module instances
//--------------------------------------------------------------------
osc0 osc_int_inst (
    .hf_out_en_i  (1'b1      ), 
    .hf_clk_out_o (osc_clk_90));

// for checking that the AXI clock is running
kitcar #(
    .clk_freq   (112000000))
kitcar_inst (
    .clk        (clk_w    ),
    .rstn       (areset_n_i),
    .LED_array  (LED_array)
);

// for checking that the pclk_i clock is running
kitcar #(
    .clk_freq   (90000000  ))
kitcar_inst2 (
    .clk        (pclk_i    ),
    .rstn       (preset_n_i),
    .LED_array  (LED_array2)
);


logic [2:0]  gen_in_w;
logic        perf_tst_en;
logic        s2p_r1_trn_done;
logic        s2p_r2_trn_done;
logic [11:0] apb_paddr_o; 

assign perf_tst_en = SIM ? 1'b0 : 1'b1;
assign gen_in_w    = {perf_tst_en,s2p_r2_trn_done, irq_o};
assign apb_paddr_i = apb_paddr_o[APB_ADDR_WIDTH-1:0];

always @(posedge pclk_i or negedge preset_n_i) begin
   if (!preset_n_i) begin
       s2p_r1_trn_done <= 1'b0;
       s2p_r2_trn_done <= 1'b0;
   end
   else begin
       s2p_r1_trn_done <= init_done_o;
       s2p_r2_trn_done <= s2p_r1_trn_done;
   end
end

mc_axi4_traffic_gen #(
    .SIM           (SIM           ),
    .GEN_IN_WIDTH  (3             ),
    .DATA_CLK_EN   (DATA_CLK_EN   ),
    .DDR_CMD_FREQ  (DDR_CMD_FREQ  ),
    .AXI_ADDR_WIDTH(AXI_ADDR_WIDTH),
    .AXI_DATA_WIDTH(AXI_DATA_WIDTH),
    .AXI_ID_WIDTH  (AXI_ID_WIDTH  ),
    .AXI_LEN_WIDTH (AXI_LEN_WIDTH )
) u_tragen (
    .aclk_i       (clk_w        ),
    .areset_n_i   (areset_n_i    ),
    .pclk_i       (pclk_i       ),
    .preset_n_i   (preset_n_i   ),
    .sclk_i       (sclk_o   ),
    .rstn_i       (sreset_n  ),
    .rxd_i        (uart_rxd_i   ), 
    .txd_o        (uart_txd_o   ), 
    .led_o        (led_o        ),
	.p_rd_error_occur_o(        ),
	.a_rd_timeout_o(            ),
	.a_wr_timeout_o(            ),
    .a_test_num_o  (a_test_num_w),
    .a_rd_error_occur_o(a_rd_error_occur_w),
    
    .gen_in_i     (gen_in_w     ),
    .apb_psel_o   (apb_psel_i   ),   
    .apb_paddr_o  (apb_paddr_o  ), 
    .apb_penable_o(apb_penable_i), 
    .apb_pwrite_o (apb_pwrite_i ),
    .apb_pwdata_o (apb_pwdata_i ), 
    .apb_pready_i (apb_pready_o ), 
    .apb_prdata_i (apb_prdata_o ), 
    .apb_pslverr_i(apb_pslverr_o),

    .axi_awready_i(axi_awready_o),
    .axi_awvalid_o(axi_awvalid_i),
    .axi_awid_o   (axi_awid_i   ),
    .axi_awaddr_o (axi_awaddr_i ),
    .axi_awlen_o  (axi_awlen_i  ),
    .axi_awburst_o(axi_awburst_i),
    .axi_awqos_o  (axi_awqos_i  ), 
    .axi_awsize_o (axi_awsize_i ),

    .axi_wvalid_o (axi_wvalid_i ), 
    .axi_wready_i (axi_wready_o ),
    .axi_wdata_o  (axi_wdata_i  ), 
    .axi_wstrb_o  (axi_wstrb_i  ), 
    .axi_wlast_o  (axi_wlast_i  ),
    
    .axi_bready_o (axi_bready_i ), 
    .axi_bvalid_i (axi_bvalid_o ),  
    .axi_bresp_i  (axi_bresp_o  ),  
    .axi_bid_i    (axi_bid_o    ),
    
    .axi_arready_i(axi_arready_o),  
    .axi_arvalid_o(axi_arvalid_i),  
    .axi_arid_o   (axi_arid_i   ),  
    .axi_arlen_o  (axi_arlen_i  ),  
    .axi_arburst_o(axi_arburst_i),  
    .axi_araddr_o (axi_araddr_i ),  
    .axi_arqos_o  (axi_arqos_i  ),  
    .axi_arsize_o (axi_arsize_i ),  

    .axi_rready_o (axi_rready_i ),
    .axi_rvalid_i (axi_rvalid_o ),
    .axi_rdata_i  (axi_rdata_o  ),
    .axi_rresp_i  (axi_rresp_o  ),
    .axi_rid_i    (axi_rid_o    ),
    .axi_rlast_i  (axi_rlast_o  )
 );
 
generate
  if(AXI == 0) begin : BRIDGE
    lpddr4_mc_axi_iface_top #(
      .DDR_WIDTH               (DDR_WIDTH),
      .SCH_NUM_RD_SUPPORT      (SCH_NUM_RD_SUPPORTED),
      .SCH_NUM_WR_SUPPORT      (SCH_NUM_WR_SUPPORTED),
      .INT_ID_WIDTH            (ORDER_ID_WIDTH      ),
      .AXI_ADDR_WIDTH          (AXI_ADDR_WIDTH),
      .AXI_ID_WIDTH            (AXI_ID_WIDTH),
      .AXI_DATA_WIDTH          (AXI_DATA_WIDTH),
      .AXI_CTRL_WIDTH          (AXI_CTRL_WIDTH),
      .AXI_LEN_WIDTH           (AXI_LEN_WIDTH),
      .AXI_STRB_WIDTH          (AXI_STRB_WIDTH),
      .AXI_QOS_WIDTH           (AXI_QOS_WIDTH),
      .BI_RD_DATA_Q_WIDTH      (BI_RD_DATA_Q_WIDTH),
      .BI_RD_DATA_Q_DEPTH      (BI_RD_DATA_Q_DEPTH),
      .DATA_CLK_EN             (DATA_CLK_EN),
      .BI_WR_DATA_FIFO_DEPTH(BI_WR_DATA_FIFO_DEPTH)
    )
    u_axi_if
    (
      .clk_i             (sclk_o        ), // Native I/F is only Sync, No CDC
      .sclk_i            (sclk_o        ),
      .rst_n_i           (areset_n      ), // Sync to sclk_o when DATA_CLK_EN=0
      .srst_n_i          (areset_n      ), // Sync to sclk_o when DATA_CLK_EN=0
       //AXI4 INTERFACE
      .axi_arvalid_i     (axi_arvalid_i ), 
      .axi_arid_i        (axi_arid_i    ),
      .axi_arlen_i       (axi_arlen_i   ),
      .axi_arburst_i     (axi_arburst_i ),
      .axi_araddr_i      (axi_araddr_i  ),
      .axi_arready_o     (axi_arready_o ),
      .axi_arqos_i       (axi_arqos_i   ),
      .axi_arsize_i      (axi_arsize_i  ),
      .axi_rresp_o       (axi_rresp_o   ),
      .axi_rdata_o       (axi_rdata_o   ),
      .axi_rid_o         (axi_rid_o     ),
      .axi_rvalid_o      (axi_rvalid_o  ),
      .axi_rlast_o       (axi_rlast_o   ),
      .axi_rready_i      (axi_rready_i  ),
      .axi_awvalid_i     (axi_awvalid_i ),
      .axi_awlen_i       (axi_awlen_i   ),
      .axi_awburst_i     (axi_awburst_i ),
      .axi_awaddr_i      (axi_awaddr_i  ),
      .axi_awready_o     (axi_awready_o ),
      .axi_awqos_i       (axi_awqos_i   ),
      .axi_awsize_i      (axi_awsize_i  ), 
      .axi_awid_i        (axi_awid_i    ),
      .axi_wvalid_i      (axi_wvalid_i  ),
      .axi_wready_o      (axi_wready_o  ),
      .axi_wdata_i       (axi_wdata_i   ),
      .axi_wstrb_i       (axi_wstrb_i   ),      
      .axi_wlast_i       (axi_wlast_i   ), 
      .axi_bready_i      (axi_bready_i  ),
      .axi_bvalid_o      (axi_bvalid_o  ),
      .axi_bresp_o       (axi_bresp_o   ),
      .axi_bid_o         (axi_bid_o     ),
    
      //NATIVE INTERFACE 
      .wr_req_txn_id_o   ({wr_req_id_i,wr_req_order_id_i}),
      .wr_req_addr_o     (wr_req_addr_i ),
      .wr_req_len_o      (wr_req_len_i  ),
      .wr_req_size_o     (wr_req_size_i ),
      .wr_req_valid_o    (wr_req_valid_i),
      .wr_req_ready_i    (wr_req_ready_o),
      .wr_data_o         (wr_data_i     ),
      .wr_byte_en_o      (wr_byte_en_i  ),
      .wr_last_o         (wr_data_last_i),
      .wr_valid_o        (wr_valid_i    ),
      .wr_ready_i        (wr_ready_o    ),
      .rd_req_valid_o    (rd_req_valid_i),
      .rd_req_addr_o     (rd_req_addr_i ),
      .rd_req_len_o      (rd_req_len_i  ),
      .rd_req_size_o     (rd_req_size_i ),
      .rd_req_arid_o     ({rd_req_id_i,rd_req_order_id_i}),
      .rd_req_ready_i    (rd_req_ready_o),
      .rd_rsp_rid_i      ({rd_rsp_id_o,rd_rsp_order_id_o}),
      .rd_rsp_data_i     (rd_rsp_data_o      ),
      .rd_rsp_len_i      (rd_rsp_len_o       ),
      .rd_rsp_size_i     (rd_rsp_size_o      ),
      .rd_rsp_addr_i     (rd_rsp_buff_addr_o ),
      .rd_rsp_valid_i    (rd_rsp_valid_o     ),
      .rd_rsp_ready_o    (rd_rsp_ready_i     )
    );
  end

  if (APB_INTF_EN == 0) begin : INIT_EN
    apb2init #(
      .DDR_TYPE      (DDR_TYPE      ),
      .GEAR_RATIO    (GEAR_RATIO    ),
      .PWR_DOWN_EN   (PWR_DOWN_EN   ),
      .DBI_ENABLE    (DBI_ENABLE    ),
      .ECC_ENABLE    (ECC_ENABLE    ),
      .DDR_WIDTH     (DDR_WIDTH     ),
      .RANK_WIDTH    (RANK_WIDTH    ), 
      .APB_DATA_WIDTH(APB_DATA_WIDTH),
      .SIM           (SIM           )
    )
    u_apb2init (
      .pclk_i        (pclk_i          ),
      .preset_n_i    (preset_n_i      ),
      .sclk_i        (sclk_o          ),
      .p_trn_done_i  (s2p_r2_trn_done ),
      .s_init_start_o(init_start_i    ),
      .apb_penable_i (apb_penable_i   ), 
      .apb_psel_i    (apb_psel_i      ), 
      .apb_pwrite_i  (apb_pwrite_i    ), 
      .apb_paddr_i   (apb_paddr_i[9:0]), 
      .apb_pwdata_i  (apb_pwdata_i    ), 
      .apb_pready_o  (apb_pready_o    ), 
      .apb_prdata_o  (apb_prdata_o    ),
      .apb_pslverr_o (apb_pslverr_o   )
    );
    assign trn_opr_i = SIM ? 8'h00 : 8'h1F;
  end // if (APB_INTF_EN == 0)
endgenerate

`include "dut_inst.v"

//-------------------------------------//
//-------- output assignments  --------//
//-------------------------------------//

assign LED[11:0]     = {~LED_array2[0],~LED_array[0], led_o[9:0]};
assign ddr_odt_ca_o = 1'b0;  // unused because we use implicit ODT

`ifdef DQSDQ_DEBUG_EN
always @(posedge sclk_o or negedge sreset_n) begin
   if (!sreset_n) begin
    dbg_rddata_en_out <= 1'b0;
    dbg_wddata_en_out <= 1'b0;
  end
  else begin
    dbg_rddata_en_out <= dbg_rddata_en_o;
    dbg_wddata_en_out <= dbg_wddata_en_o;
  end
end // always_ff
`endif

//--------------------------------------------//
//-------- for debugging with Reveal  --------//
//--------------------------------------------//

always @(posedge clk_w or negedge areset_n) begin
   if (!areset_n) begin
       rvl_a_test_num_r   <= {GEN_OUT_WIDTH{1'b0}};
       a_test_num_r       <= {GEN_OUT_WIDTH{1'b0}};
       a_rd_error_occur_r <= 1'b0;
   end
   else begin
       rvl_a_test_num_r   <= a_test_num_w;
       a_test_num_r       <= a_test_num_w;
       a_rd_error_occur_r <= a_rd_error_occur_w;
   end
end

always @(posedge sclk_o or negedge sreset_n) begin
   if (!sreset_n) begin
       s_rd_error_occur_r1    <= 1'b0;
       s_rd_error_occur_r2    <= 1'b0;
       rvl_s_rd_error_occur_r <= 1'b0;
       a2s_test_num_r1        <= {GEN_OUT_WIDTH{1'b0}};
       a2s_test_num_r2        <= {GEN_OUT_WIDTH{1'b0}};
       rvl_s_test_num_r       <= {GEN_OUT_WIDTH{1'b0}};
   end
   else begin
       s_rd_error_occur_r1    <= a_rd_error_occur_r;
       s_rd_error_occur_r2    <= s_rd_error_occur_r1;
       rvl_s_rd_error_occur_r <= s_rd_error_occur_r2;
       a2s_test_num_r1        <= a_test_num_r;
       a2s_test_num_r2        <= a2s_test_num_r1;
       rvl_s_test_num_r       <= a2s_test_num_r2;
   end
end




endmodule

