///////////////////////////////////////////////////////////////////////////////////////////////////
// Company: <Name>
//
// File: testbench.v
// File history:
//      <Revision number>: <Date>: <Comments>
//      <Revision number>: <Date>: <Comments>
//      <Revision number>: <Date>: <Comments>
//
// Description: 
//
// <Description here>
//
// Targeted device: <Family::IGLOO2> <Die::M2GL010T> <Package::484 FBGA>
// Author: <Name>
//
/////////////////////////////////////////////////////////////////////////////////////////////////// 

`timescale 1ps /1fs

`include "dram.v"

module testbench;

parameter SYSCLK_PERIOD = 12048;    // 83MHz
parameter BRCLK_PERIOD  = 8680500;  // 115200Hz

reg SYSCLK;
reg BRCLK;
reg NSYSRESET;

wire MDDR_CAS_N;
wire MDDR_CKE;
wire MDDR_CLK;
wire MDDR_CLK_N;
wire MDDR_CS_N;
wire MDDR_ODT;
wire MDDR_RAS_N;
wire MDDR_RESET_N;
wire MDDR_WE_N;	
wire [15:0] MDDR_ADDR;
wire [2:0]  MDDR_BA;
wire [1:0]  MDDR_DM_RDQS;
wire [1:0]  MDDR_DQS;
wire [1:0]  MDDR_DQS_N;
wire [15:0] MDDR_DQ;
wire TX;

wire MDDR_DQS_TMATCH_0_IN;
wire MDDR_DQS_TMATCH_0_OUT;

wire [2:0] COMMAND;

wire [3:0]  fsm;
reg fsm_en;

assign MDDR_DQS_TMATCH_0_IN = MDDR_DQS_TMATCH_0_OUT;
assign COMMAND = {MDDR_RAS_N,MDDR_CAS_N,MDDR_WE_N};

assign fsm = testbench.MDDR_TA_top_0.COM_Interface_0.Control_Logic_0.fsm;

initial
begin
    SYSCLK    = 1'b0;
    BRCLK     = 1'b0;
    NSYSRESET = 1'b0;

    @(posedge testbench.MDDR_TA_top_0.AXI_IF_0.CLK);
    repeat(2000)
      begin
         #(BRCLK_PERIOD / 2.0) BRCLK <= !BRCLK;
      end

end


initial
begin
    $display ("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
    $display ("Loading LSRAM from lsram.mem file");
    $display ("");
    $readmemh("lsram_512x64.mem",testbench.MDDR_TA_top_0.AXI_IF_0.Rdata_mem);
    $display (" Completed Loading LSRAM"); 
    $display ("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");

    @(posedge testbench.MDDR_TA_top_0.AXI_IF_0.RESETn);
    force testbench.MDDR_TA_top_0.COM_Interface_0.COREUART_0.DATA_OUT   = 8'b1100011;   /* Handshaking Commmand 'c'  */

    @(posedge testbench.MDDR_TA_top_0.COM_Interface_0.Control_Logic_0.RX_RDY);
    repeat(5) @(posedge BRCLK);
    force testbench.MDDR_TA_top_0.COM_Interface_0.COREUART_0.DATA_OUT   = 8'b01001001;  /* 2KB Write */

	@(posedge fsm_en);
    repeat(40) @(posedge BRCLK);
    force testbench.MDDR_TA_top_0.COM_Interface_0.COREUART_0.DATA_OUT   = 8'b1100011;  /* Handshaking Commmand 'c'  */

    @(posedge testbench.MDDR_TA_top_0.COM_Interface_0.Control_Logic_0.RX_RDY);
    repeat(5) @(posedge BRCLK);
    force testbench.MDDR_TA_top_0.COM_Interface_0.COREUART_0.DATA_OUT   = 8'b01001010; /* 2KB Read */

end

always @(posedge testbench.MDDR_TA_top_0.AXI_IF_0.CLK)
begin
 if(fsm == 4'b1001) 
   begin
     fsm_en  <= 1'b1;
   end
 else
   begin
     fsm_en  <= 1'b0;
   end
end

/* DEVRST_N Signal gneration */

initial
begin
    #(SYSCLK_PERIOD * 10 )
        NSYSRESET = 1'b1;
end

/* 83MHz Clock Driver */

always @(SYSCLK)
    #(SYSCLK_PERIOD / 2.0) SYSCLK <= !SYSCLK;


/* Instantiate Unit Under Test:  MDDR_TA_top */

MDDR_TA_top MDDR_TA_top_0 (
    // Inputs
    .MDDR_DQS_TMATCH_0_IN(MDDR_DQS_TMATCH_0_IN),
    .DEVRST_N(NSYSRESET),
    .RX({1{1'b0}}),

    // Outputs
    .MDDR_DQS_TMATCH_0_OUT(MDDR_DQS_TMATCH_0_OUT),
    .MDDR_CAS_N(MDDR_CAS_N),
    .MDDR_CLK(MDDR_CLK),
    .MDDR_CLK_N(MDDR_CLK_N),
    .MDDR_CKE(MDDR_CKE),
    .MDDR_CS_N(MDDR_CS_N),
    .MDDR_ODT( ),
    .MDDR_RAS_N(MDDR_RAS_N),
    .MDDR_RESET_N(MDDR_RESET_N),
    .MDDR_WE_N(MDDR_WE_N),
    .MDDR_ADDR(MDDR_ADDR[15:0]),
    .MDDR_BA(MDDR_BA),
    .TX(TX),

    // Inouts
    .MDDR_DM_RDQS(MDDR_DM_RDQS ),
    .MDDR_DQ(MDDR_DQ ),
    .MDDR_DQS(MDDR_DQS )

);

/* Instantiate and connect LPDDR Memory Model */

  dram dram_0 (
  .CLK(MDDR_CLK),
  .CLK_N(MDDR_CLK_N),
  .CKE(MDDR_CKE),
  .CS_N(MDDR_CS_N),
  .RAS_N(MDDR_RAS_N ),
  .CAS_N(MDDR_CAS_N),
  .WE_N(MDDR_WE_N),
  .DM(MDDR_DM_RDQS[1:0]),
  .BA(MDDR_BA[1:0]),
  .ADDR(MDDR_ADDR[13:0]),
  .DQ(MDDR_DQ[15:0]),
  .DQS(MDDR_DQS[1:0])
  );

endmodule

