-- --------------------------------------------------------------------
-- >>>>>>>>>>>>>>>>>>>>>>>>> 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.vhd,v $
-- Revision 1.0  2005-05-09 16:21:47-07  jhsin
-- Initial revision
--
--
-- --------------------------------------------------------------------

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;

library work;
  use work.ddrct_gen_e2_1_001_params.all;

entity ddr_top is
   port (
      -- INPUTS
      clk_in : in  std_logic; -- 33MHz System clock
      rst_n  : in  std_logic; -- Generic I/F Active low system reset
   
      vref1A : in  std_logic;
      vref2A : in  std_logic;
      vref1B : in  std_logic;
      vref2B : in  std_logic;
   
      -- OUTPUTS
      ledout       : out std_logic_vector(7 downto 0);  -- Generic I/F LED output Bus
      debug_port_a : out std_logic_vector(15 downto 0); -- Debug Output Port A
      debug_port_b : out std_logic_vector(15 downto 0); -- Debug Output Port B
      debug_port_c : out std_logic_vector(19 downto 0); -- Debug Output Port C
   
      -- Bi-directional databus to external memory
      ddr_data : inout std_logic_vector(DATA_WIDTH-1 downto 0); -- DDR SDRAM I/F Data bus output
      ddr_dqs  : inout std_logic_vector(DATA_WIDTH/8-1 downto 0); -- DDR SDRAM I/F Data strobe output
   
      -- Output to External memory
      -- SDRAM Address, controls and clock
      ddr_clk   : out std_logic; -- DDR SDRAM clock
      ddr_clk_n : out std_logic; -- DDR SDRAM Inverted clock
      ddr_cke0  : out std_logic; -- DDR SDRAM I/F Clock enable
      ddr_cke1  : out std_logic; -- DDR SDRAM I/F Clock enable
      ddr_ras_n : out std_logic; -- DDR SDRAM I/F Row address strobe
      ddr_cas_n : out std_logic; -- DDR SDRAM I/F Column address strobe
      ddr_we_n  : out std_logic; -- DDR SDRAM I/F Write enable
      ddr_cs_n  : out std_logic_vector(CS_WIDTH-1 downto 0);  -- DDR SDRAM I/F Chip select
      ddr_cs_n1 : out std_logic;                              -- DDR SDRAM I/F Chip select
      ddr_dm    : out std_logic_vector(DATA_WIDTH/8-1 downto 0);  -- DDR SDRAM I/F Data mask lines
      ddr_ba    : out std_logic_vector(1 downto 0);  -- DDR SDRAM I/F Bank bus
      ddr_addr  : out std_logic_vector(12 downto 0) -- DDR SDRAM I/F Address bus
   );
end ddr_top;

architecture ddr_top_a of ddr_top is

component ddr_sdram_mem_top is
   port(
      -- Clock and Reset
      clk_in          : in std_logic;
      pll_clk         : out std_logic;
      rst_n           : in std_logic;

      -- Input Signals from the user interface
      cmd             : in std_logic_vector(3 downto 0);
      addr            : in std_logic_vector(ADDR_WIDTH-1 downto 0);
      cmd_valid       : in std_logic;
      init_start      : in std_logic;
      burst_count     : in std_logic_vector(4 downto 0);
      write_data      : in std_logic_vector(DSIZE-1 downto 0);
      data_mask       : in std_logic_vector(USER_DM-1 downto 0);

      -- User Interface Output Signals
      cmd_rdy         : out std_logic;
      init_done       : out std_logic;
      data_rdy        : out std_logic;
      read_data       : out std_logic_vector(DSIZE-1 downto 0);
      read_data_valid : out std_logic;

      -- Databus and related signals to external memory
      em_ddr_data     : inout std_logic_vector(DATA_WIDTH-1 downto 0);
      em_ddr_dqs      : inout std_logic_vector(DATA_WIDTH/8-1 downto 0);
      em_ddr_dm       : out std_logic_vector(DATA_WIDTH/8-1 downto 0);

      -- Output to External Memory
      -- SDRAM Address, controls and clock

      em_ddr_clk      : out std_logic;
      em_ddr_clk_n    : out std_logic;
      em_ddr_clk1     : out std_logic;
      em_ddr_clk1_n   : out std_logic;
      em_ddr_cke0     : out std_logic;
      em_ddr_cke1     : out std_logic;
      em_ddr_ras_n    : out std_logic;
      em_ddr_cas_n    : out std_logic;
      em_ddr_we_n     : out std_logic;
      em_ddr_cs_n     : out std_logic_vector(CS_WIDTH-1 downto 0);
      em_ddr_cs_n1    : out std_logic;

      burst_term      : in std_logic;
      em_ddr_addr     : out std_logic_vector(ROW_WIDTH-1 downto 0);
      em_ddr_ba       : out std_logic_vector(1 downto 0)
   );
end component ddr_sdram_mem_top;

component ddr_test is
   port (
      -- INPUTS
      waited_200us             : in  std_logic;   
      init_done                : in  std_logic;
      pll_clk                  : in  std_logic;
      rst_n                    : in  std_logic;
      cmd_rdy                  : in  std_logic;
      data_rdy                 : in  std_logic;
      read_data_valid          : in  std_logic;
      read_data                : in  std_logic_vector(DSIZE-1 downto 0);
                           
      -- OUTPUTS           
      init_start               : inout std_logic;
      test_data                : inout std_logic_vector(7 downto 0);
      fsm2_out                 : out std_logic;
      datacheck                : inout std_logic_vector(1 downto 0);
      latched_data             : out std_logic_vector(15 downto 0);
      number_of_tests_passed   : inout std_logic_vector(3 downto 0);
      number_of_tests_failed   : inout std_logic_vector(3 downto 0);
      cmd                      : out std_logic_vector(3 downto 0);
      cmd_valid                : inout std_logic;
      data_mask                : out std_logic_vector(USER_DM-1 downto 0);
      addr                     : out std_logic_vector(ADDR_WIDTH-1 downto 0);
      write_data               : out std_logic_vector(DSIZE-1 downto 0)
   );
end component ddr_test;

signal pll_clk : std_logic;
signal number_of_tests_passed : std_logic_vector(3 downto 0);
signal number_of_tests_failed : std_logic_vector(3 downto 0);

signal cmd : std_logic_vector(3 downto 0); -- Generic I/F Command for controller
                                           -- 0001  READ
                                           -- 0010  WRITE
                                           -- 0011  READA
                                           -- 0100  WRITREA
                                           -- 0101  PDOWN
                                           -- 0110  LOAD_MR
                                           -- 0111  SELF_REF

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

signal fsm2            : std_logic;
signal datacheck       : std_logic_vector(1 downto 0);
signal latched_data    : std_logic_vector(15 downto 0);
signal test_data       : std_logic_vector(7 downto 0);

signal wait_200us_count : std_logic_vector(23 downto 0);
signal waited_200us     : std_logic;

begin

   --
   -- Wait at least 200 us (Osc Freq = 33.33MHz, 24'hffffff = 16777215, 16777215x30ns = 503316450ns = 503.3ms)
   --
   wait_Proc : process (clk_in, rst_n)
   begin
      if (rst_n='0') then
         wait_200us_count <= (others => '0');
         waited_200us <= '0';
      elsif rising_edge(clk_in) then
         wait_200us_count <= wait_200us_count + 1;
         if (wait_200us_count=X"FFFFFF") then
            waited_200us <= '1';
         end if;
      end if;
   end process wait_Proc;

   -- ====================================================================
   -- DDR SDRAM Controller (DDRCT-GEN-E2-N1)
   -- ====================================================================
   U1_ddr_sdram_mem_top : ddr_sdram_mem_top
   port map (
      -- 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 => "00001",
      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   => open,
      em_ddr_clk1_n => open,
      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    => '0',
   
      em_ddr_dm     => ddr_dm,
      em_ddr_ba     => ddr_ba,
      em_ddr_addr   => ddr_addr(11 downto 0)
   );

   ddr_addr(12) <= '0';

   U2_ddr_test : ddr_test
   port map (
      -- 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_out               => 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
   );

   ledout <= number_of_tests_passed & number_of_tests_failed;

   debug_port_a <= cmd_rdy &
                   data_rdy &
                   read_data_valid &
                   cmd &
                   addr(17 downto 16) &
                   fsm2 &
                   init_start &
                   init_done &
                   vref1A & vref1B & vref2A & vref2B;

   debug_port_b <= addr(15 downto 0);

   debug_port_c <= cmd_valid &
                   '0' &
                   datacheck &
                   latched_data(15 downto 8) &
                   test_data;

end ddr_top_a; 
