// --------------------------------------------------------------------
// >>>>>>>>>>>>>>>>>>>>>>>>> COPYRIGHT NOTICE <<<<<<<<<<<<<<<<<<<<<<<<<
// --------------------------------------------------------------------
// Copyright (c) 2005 by Lattice Semiconductor Corporation
// --------------------------------------------------------------------
//
// Permission:
//
//   Lattice Semiconductor grants permission to use this code for use
//   in synthesis for any Lattice programmable logic product.  Other
//   use of this code, including the selling or duplication of any
//   portion is strictly prohibited.
//
// 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 Semiconductor provides no warranty
//   regarding the use or functionality of this code.
//
// --------------------------------------------------------------------
//
//                     Lattice Semiconductor Corporation
//                     5555 NE Moore Court
//                     Hillsboro, OR 97214
//                     U.S.A
//
//                     TEL: 1-800-Lattice (USA and Canada)
//                          408-826-6000 (other locations)
//
//                     web: http://www.latticesemi.com/
//                     email: techsupport@latticesemi.com
//
// --------------------------------------------------------------------
//
//  Project:           DDR memory test
//  File:              ddr_top.v
//  Title:             ddr_top
//  Description:       This is the top level module of DDR memory test
//                     design running at 200MHz DDR400 on LatticeEC
//                     Advanced Evaluation Board.
//
// --------------------------------------------------------------------
//
// Revision History :
// --------------------------------------------------------------------
// $Log: ddr_top.v,v $
// Revision 1.2  2005-05-09 16:07:43-07  jhsin
// Fixed two major bugs related to the generations of data_mask and datacheck signals.
//
// Revision 1.1  2005-02-02 17:02:26-08  jhsin
// Changed debug port definition to bring test_data out.
//
// Revision 1.0  2005-02-01 16:42:00-08  jhsin
// Initial revision
//
//
// --------------------------------------------------------------------

`timescale 100ps / 10ps

module ddr_top
  (
   //-------INPUTS
   clk_in,           // 33MHz System clock
   rst_n,            // Generic I/F Active low system reset

   vref1A,
   vref2A,
   vref1B,
   vref2B,

   //-------OUTPUTS
   ledout,           // Generic I/F LED output Bus
   debug_port_a,     // Debug Output Port A
   debug_port_b,     // Debug Output Port B
   debug_port_c,     // Debug Output Port C

   // Bi-directional databus to external memory
   ddr_data,         // DDR SDRAM I/F Data bus output
   ddr_dqs,          // DDR SDRAM I/F Data strobe output

   // Output to External memory
   // SDRAM Address, controls and clock
   ddr_clk,          // DDR SDRAM clock
   ddr_clk_n,        // DDR SDRAM Inverted clock
   ddr_cke0,         // DDR SDRAM I/F Clock enable
   ddr_cke1,         // DDR SDRAM I/F Clock enable
   ddr_ras_n,        // DDR SDRAM I/F Row address strobe
   ddr_cas_n,        // DDR SDRAM I/F Column address strobe
   ddr_we_n,         // DDR SDRAM I/F Write enable
   ddr_cs_n,         // DDR SDRAM I/F Chip select
   ddr_cs_n1,        // DDR SDRAM I/F Chip select
   ddr_dm,           // DDR SDRAM I/F Data mask lines
   ddr_ba,           // DDR SDRAM I/F Bank bus
   ddr_addr          // DDR SDRAM I/F Address bus
);

// ====================================================================
// Define all inputs / outputs
// ====================================================================
//--------Inputs
input                      clk_in;       // System clock
input                      rst_n;        // Generic I/F Active low system reset

input                      vref1A;
input                      vref2A;
input                      vref1B;
input                      vref2B;

//-------OUTPUTS
output [7:0]               ledout;       // Generic I/F LED Output Bus
output [15:0]              debug_port_a; // Debug Output Port A
output [15:0]              debug_port_b; // Debug Output Port B
output [19:0]              debug_port_c; // Debug Output Port C

inout [`DATA_WIDTH-1:0]    ddr_data;     // DDR SDRAM I/F Data bus output
inout [`DATA_WIDTH/8-1:0]  ddr_dqs;      // DDR SDRAM I/F Data strobe output

output                     ddr_clk;      // DDR SDRAM clock
output                     ddr_clk_n;    // DDR SDRAM Inverted clock
output                     ddr_cke0;     // DDR SDRAM I/F Clock enable
output                     ddr_cke1;     // DDR SDRAM I/F Clock enable
output                     ddr_ras_n;    // DDR SDRAM I/F Row address strobe
output                     ddr_cas_n;    // DDR SDRAM I/F Column address strobe
output                     ddr_we_n;     // DDR SDRAM I/F Write enable
output [`CS_WIDTH-1:0]     ddr_cs_n;
output                     ddr_cs_n1;
output [`DATA_WIDTH/8-1:0] ddr_dm;       // DDR SDRAM I/F Data mask lines
output [1:0]               ddr_ba;       // DDR SDRAM I/F Bank bus
output [12:0]              ddr_addr;     // DDR SDRAM I/F Address bus

// ====================================================================
// Internal signals
// ====================================================================

//---- Wires
wire                       pll_clk;
wire [3:0]                 number_of_tests_passed;
wire [3:0]                 number_of_tests_failed;

wire [3:0]                 cmd;             // Generic I/F Command for controller
                                            // 0001  READ
                                            // 0010  WRITE
                                            // 0011  READA
                                            // 0100  WRITREA
                                            // 0101  PDOWN
                                            // 0110  LOAD_MR
                                            // 0111  SELF_REF

wire [`ADDR_WIDTH-1:0]     addr;            // Generic I/F Address bus
wire                       cmd_valid;
wire                       init_start;
wire [4:0]                 burst_count;
wire [`DSIZE-1:0]          write_data;      // Generic I/F Data input bus
wire [`USER_DM-1:0]        data_mask;       // Generic I/F Data mask select inputs
wire                       cmd_rdy;         // Generic I/F Busy signal
wire                       init_done;
wire                       data_rdy;        // Generic I/F indicates controller has
                                            // accepted a data from Datain bus
wire [`DSIZE-1:0]          read_data;       // Generic I/F Data output bus
wire                       read_data_valid; // Generic I/F indicates Dataout bus has
                                            // a valid data

wire                       fsm2;
wire [1:0]                 datacheck;
wire [15:0]                latched_data;
wire [7:0]                 test_data;

// ====================================================================
// Instantiate the sub blocks of the top level
// ====================================================================

//
// Wait at least 200 us (Osc Freq = 33.33MHz, 24'hffffff = 16777215, 16777215x30ns = 503316450ns = 503.3ms)
//
reg [23:0] wait_200us_count;
reg        waited_200us;

always @(posedge clk_in or negedge rst_n)
begin
   if (~rst_n) begin
      wait_200us_count <= 24'h000000;
      waited_200us <= 1'b0;
   end
   else begin
      wait_200us_count <= wait_200us_count + 1;
      if (wait_200us_count == 24'hffffff) waited_200us <= 1'b1;
   end
end

// ====================================================================
// DDR SDRAM Controller (DDRCT-GEN-E2-N1)
// ====================================================================
ddr_sdram_mem_top U1_ddr_sdram_mem_top (

   // Clock and reset
   .clk_in(clk_in),
   .pll_clk(pll_clk),
   .rst_n(rst_n),

   // Inputs signals from the User Interface
   .cmd(cmd),
   .addr(addr),
   .cmd_valid(cmd_valid),
   .burst_count(5'b00001),
   .init_start(init_start),
   .write_data(write_data),
   .data_mask(data_mask),

   // These signals are brought out only during testing.  So that the core
   // can be verified with different settings.  In real designs,
   // these signals will be driven by a  constant value within the module.

   // User Interface Output signals
   .cmd_rdy(cmd_rdy),
   .init_done(init_done),
   .data_rdy(data_rdy),
   .read_data(read_data),
   .read_data_valid(read_data_valid),

   // Bi-directional databus to external memory
   .em_ddr_data(ddr_data),
   .em_ddr_dqs(ddr_dqs),

   // Output to External memory
   // SDRAM Address, controls and clock
   .em_ddr_clk(ddr_clk),
   .em_ddr_clk_n(ddr_clk_n),
   .em_ddr_clk1(),
   .em_ddr_clk1_n(),
   .em_ddr_cke0(ddr_cke0),
   .em_ddr_cke1(ddr_cke1),
   .em_ddr_ras_n(ddr_ras_n),
   .em_ddr_cas_n(ddr_cas_n),
   .em_ddr_we_n(ddr_we_n),
   .em_ddr_cs_n(ddr_cs_n),
   .em_ddr_cs_n1(ddr_cs_n1),

   .burst_term(1'b0),

   .em_ddr_dm(ddr_dm),
   .em_ddr_ba(ddr_ba),
   .em_ddr_addr(ddr_addr[11:0])
);

assign ddr_addr[12] = 1'b0;

ddr_test U2_ddr_test (

   //-------INPUTS
   .waited_200us(waited_200us),
   .init_done(init_done),
   .pll_clk(pll_clk),
   .rst_n(rst_n),
   .cmd_rdy(cmd_rdy),
   .data_rdy(data_rdy),
   .read_data_valid(read_data_valid),
   .read_data(read_data),

   //-------OUTPUTS
   .init_start(init_start),
   .test_data(test_data),
   .fsm2(fsm2),
   .datacheck(datacheck),
   .latched_data(latched_data),
   .number_of_tests_passed(number_of_tests_passed),
   .number_of_tests_failed(number_of_tests_failed),
   .cmd(cmd),
   .cmd_valid(cmd_valid),
   .data_mask(data_mask),
   .addr(addr),
   .write_data(write_data)
);

assign ledout = { number_of_tests_passed, number_of_tests_failed };

assign debug_port_a = { cmd_rdy,
                        data_rdy,
                        read_data_valid,
                        cmd,
                        addr[17:16],
                        fsm2,
                        init_start,
                        init_done,
                        vref1A,vref1B,vref2A,vref2B };

assign debug_port_b = { addr[15:0] };

assign debug_port_c = { cmd_valid,
                        1'b0,
                        datacheck,
                        latched_data[15:8],
                        test_data };

endmodule
