///////////////////////////////////////////////////////////////////////////////
//-------------------------------------------------------------------------
//
// 2022 Microchip Technology Inc. and its subsidiaries
//  All rights reserved.
//                                                                 
//  ANY USE OR REDISTRIBUTION IN PART OR IN WHOLE MUST BE HANDLED IN
//  ACCORDANCE WITH THE MICROCHIP LICENSE AGREEMENT AND MUST BE APPROVED
//  IN ADVANCE IN WRITING.
//
//-------------------------------------------------------------------------
// Title        : RTG4 DDR Testbench
// Author       : <Application Team>
// Description  : A testbench which connects DDR model to the design,
//                and simulates communication coming from the UART module
// Hierarchy    :
//               testbench            <-- This module
//                |     |
//               top   ddr3
//
// Targeted device: <Family::RTG4> <Die::RT4G150> <Package::1657 CG>
//
//-------------------------------------------------------------------------

`timescale 1ps /1fs

`include "ddr3.v"

module testbench;

reg CTRLR_READY;
reg [255:0]RDATA;
reg [8:0]RADDR;
reg NSYSRESET;
reg [1:0]data_pattern;

// Declare DDR3 Memory Model Connection Wires
wire DDR_CAS_N;
wire DDR_CKE;
wire DDR_CS_N;
wire DDR_ODT;
wire DDR_RAS_N;
wire DDR_RESET_N;
wire DDR_WE_N;

wire [15:0] DDR_ADDR;
wire [2:0] DDR_BA;
wire [3:0] DDR_DM_RDQS;
wire [3:0] DDR_DQS;
wire [3:0] DDR_DQS_N;
wire [31:0] DDR_DQ;

wire ddr_rd_wrt_err;

/* DEVRST_N Signal gneration */
parameter SYSCLK_PERIOD = 5ns ;

initial
begin
        NSYSRESET = 1'b0;
        data_pattern = 2'b0; // incremental data pattern
        RADDR = 9'b0;
        #(SYSCLK_PERIOD * 100 )
        NSYSRESET = 1'b1;
end

//////////////////////////////////////////////////////////////////////
// Instantiate Unit Under Test:  DDR_AXI
//////////////////////////////////////////////////////////////////////

top top_0(
    // Inputs
    .data_pattern(data_pattern),
    .resetn(NSYSRESET),
    .R_ADDR(RADDR),
    // Outputs
    .A(DDR_ADDR),
    .BA(DDR_BA),
    .CAS_N(DDR_CAS_N),
    .CK0(DDR_CK0),
    .CK0_N(DDR_CK0_N),
    .CKE(DDR_CKE),
    .CS_N(DDR_CS_N),
    .CTRLR_READY(CTRLR_READY),
    .DM(DDR_DM_RDQS),
    .ODT(DDR_ODT),
    .RAS_N(DDR_RAS_N),
    .RESET_N(DDR_RESET_N),
    .SHIELD0(),
    .SHIELD1(),
    .SHIELD2(),
    .SHIELD3(),
    .WE_N(DDR_WE_N),
    .ddr_rd_wrt_err(ddr_rd_wrt_err),
    .R_DATA(RDATA),
    // Inouts
    .DQ(DDR_DQ),
    .DQS(DDR_DQS),
    .DQS_N(DDR_DQS_N)
);

//////////////////////////////////////////////////////////////////////
// Instantiate DDR3 SDRAM ddr3.v module
//////////////////////////////////////////////////////////////////////
// Instantiate and connect DDR3 Memory Model
micron_ddr3 mem_ddr3_16_I0 (
	.rst_n(DDR_RESET_N),
	.ck(DDR_CK0),
	.ck_n(DDR_CK0_N),	
	.cke(DDR_CKE),
	.cs_n(DDR_CS_N),
	.ras_n(DDR_RAS_N ),
	.cas_n(DDR_CAS_N),
	.we_n(DDR_WE_N),
	.addr(DDR_ADDR),
	.ba(DDR_BA),
	.dm_tdqs(DDR_DM_RDQS[1:0]),
	.dq(DDR_DQ[15:0]),	
	.dqs(DDR_DQS[1:0]),
	.dqs_n(DDR_DQS_N[1:0]),
	.odt(DDR_ODT),
	.tdqs_n()
);

micron_ddr3 mem_ddr3_16_I1 (
	.rst_n(DDR_RESET_N),
	.ck(DDR_CK0),
	.ck_n(DDR_CK0_N),	
	.cke(DDR_CKE),
	.cs_n(DDR_CS_N),
	.ras_n(DDR_RAS_N ),
	.cas_n(DDR_CAS_N),
	.we_n(DDR_WE_N),
	.addr(DDR_ADDR),
	.ba(DDR_BA),
	.dm_tdqs(DDR_DM_RDQS[3:2]),
	.dq(DDR_DQ[31:16]),	
	.dqs(DDR_DQS[3:2]),
	.dqs_n(DDR_DQS_N[3:2]),
	.odt(DDR_ODT),
	.tdqs_n()
);

always @(posedge DDR_CK0) begin
 if(NSYSRESET == 1'b0) begin
$display (" design is in Reset");
 end
 else begin
     if(!ddr_rd_wrt_err && top_0.control_logic.l_r_valid_int && top_0.control_logic.last_r_burst) begin
        $display ("/******************************************************/");
        $display ("DDR Memory Write & Read test completed succesfully");
     $stop;
     end
end
end


endmodule

