-------------------------------------------------------------------------
-- Project: JCPU, a portable 8-bit RISC CPU written in VHDL
-- This file: testbench for system test using Xilinx ML-402

-- Copyright (C) 2007 J. Ahrensfeld

-- This library is free software; you can redistribute it and/or
-- modify it under the terms of the GNU Lesser General Public
-- License as published by the Free Software Foundation; either
-- version 2.1 of the License, or (at your option) any later version.

-- This library is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-- Lesser General Public License for more details.

-- You should have received a copy of the GNU Lesser General Public
-- License along with this library; if not, write to the Free Software
-- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

-- For questions and ideas, please contact the author at jens@jayfield.org

-----------------------------------------------------------------------

LIBRARY ieee;
use IEEE.STD_LOGIC_1164.ALL;
USE ieee.numeric_std.ALL;
use std.textio.all; --  Imports the standard textio package.

library work;
use work.cpu_pkg.all;
use work.ddr_sdr_conf_pkg.all;
use work.systest_cfg.all;

ENTITY tb_systest IS
END tb_systest;

ARCHITECTURE behavior OF tb_systest IS 

	constant CLK_PERIOD : time := 10 ns;
	signal sys_rst_n_in : std_logic := '0';
	signal sys_clk_in : std_logic := '1';
	signal dip  : unsigned(7 downto 0) := (others => '0');
	signal btn  : unsigned(4 downto 0) := (others => '0');
	signal led : unsigned(8 downto 0);
	signal sys_rx : std_logic := '0';
	signal sys_tx : std_logic;
	
	signal sys_lcd_d			: unsigned(3 downto 0);
	signal sys_lcd_e			: std_logic;
	signal sys_lcd_rs			: std_logic;
	signal sys_lcd_rw			: std_logic;

	signal refresh        : boolean:= true;

	signal sys_sdr_clk_p		: std_logic;    -- ddr_sdram_clock
	signal sys_sdr_clk_n		: std_logic;    -- /ddr_sdram_clock
	signal sys_sdr_cke_q		: std_logic;    -- clock enable
	signal sys_sdr_cs_qn		: std_logic;    -- /chip select
	signal sys_sdr_ras_qn		: std_logic;    -- /ras
	signal sys_sdr_cas_qn		: std_logic;    -- /cas
	signal sys_sdr_we_qn		: std_logic;    -- /write enable
	signal sys_sdr_dm_q			: unsigned(DDR_DM_WIDTH-1 downto 0);     -- data mask bits, set to "00"
	signal sys_sdr_dqs_q		: unsigned(DDR_DQS_WIDTH-1 downto 0);    -- data strobe, only for write
	signal sys_sdr_ba_q			: unsigned(DDR_BANK_WIDTH-1 downto 0);   -- bank select
	signal sys_sdr_a_q			: unsigned(DDR_ADDR_WIDTH-1 downto 0);   -- address bus 
	signal sys_sdr_data			: unsigned(DDR_DATA_WIDTH-1 downto 0); -- bidir data bus

	signal sys_error			: unsigned(1 downto 0); -- indicates DCM Errors
	signal sys_sdr_clk_fb		: std_logic;
	
BEGIN

uut: entity work.systest
--	GENERIC MAP
--	(
--		ddr_phaseshift => 90,
--		ddr_frequency_hz => 100E6
--	)
	PORT MAP
	(
		sys_rst_n_in => sys_rst_n_in,
		sys_clk_in => sys_clk_in,
		sys_btn => btn,
		sys_dip => dip,
		sys_led => led,
		sys_rx => sys_rx,
		sys_tx => sys_tx,
		sys_lcd_d => sys_lcd_d,
		sys_lcd_e => sys_lcd_e,
		sys_lcd_rs => sys_lcd_rs,
		sys_lcd_rw => sys_lcd_rw,

		sys_sdr_clk_p => sys_sdr_clk_p,
		sys_sdr_clk_n => sys_sdr_clk_n,
		sys_sdr_cke_q => sys_sdr_cke_q,
		sys_sdr_clk_fb => sys_sdr_clk_fb,
		sys_sdr_cs_qn => sys_sdr_cs_qn,
		sys_sdr_ras_qn => sys_sdr_ras_qn,
		sys_sdr_cas_qn => sys_sdr_cas_qn,
		sys_sdr_we_qn => sys_sdr_we_qn,
		sys_sdr_dm_q => sys_sdr_dm_q,
		sys_sdr_dqs_q => sys_sdr_dqs_q,
		sys_sdr_ba_q => sys_sdr_ba_q,
		sys_sdr_a_q => sys_sdr_a_q,
		sys_sdr_data => sys_sdr_data,
		sys_error => sys_error
	);

   -- MICRON DDR SDRAM Simulation Model
   i_mt46v16m16_0 : entity work.mt46v16m16 
      port map (
         dq    => std_logic_vector(sys_sdr_data(15 downto 0)),
         dqs   => std_logic_vector(sys_sdr_dqs_q(1 downto 0)),
         addr  => std_logic_vector(sys_sdr_a_q),
         ba    => std_logic_vector(sys_sdr_ba_q),
         clk   => sys_sdr_clk_p,
         clk_n => sys_sdr_clk_n,
         cke   => sys_sdr_cke_q,
         cs_n  => sys_sdr_cs_qn,
         ras_n => sys_sdr_ras_qn,
         cas_n => sys_sdr_cas_qn,
         we_n  => sys_sdr_we_qn,
         dm    => std_logic_vector(sys_sdr_dm_q(1 downto 0))
         );

   -- MICRON DDR SDRAM Simulation Model
   i_mt46v16m16_1 : entity work.mt46v16m16 
      port map (
         dq    => std_logic_vector(sys_sdr_data(31 downto 16)),
         dqs   => std_logic_vector(sys_sdr_dqs_q(3 downto 2)),
         addr  => std_logic_vector(sys_sdr_a_q),
         ba    => std_logic_vector(sys_sdr_ba_q),
         clk   => sys_sdr_clk_p,
         clk_n => sys_sdr_clk_n,
         cke   => sys_sdr_cke_q,
         cs_n  => sys_sdr_cs_qn,
         ras_n => sys_sdr_ras_qn,
         cas_n => sys_sdr_cas_qn,
         we_n  => sys_sdr_we_qn,
         dm    => std_logic_vector(sys_sdr_dm_q(3 downto 2))
         );

	sys_sdr_clk_fb   <= sys_sdr_clk_p after 2300 ps;
	refresh <= true when falling_edge(sys_sdr_ras_qn) and falling_edge(sys_sdr_cas_qn) and sys_sdr_we_qn='1' else false;

CLK_GEN: process
	begin
		wait for CLK_PERIOD/2;
		sys_clk_in <= not sys_clk_in;
	end process;

STIMULUS: process

	begin

		wait for 3*CLK_PERIOD;
		sys_rst_n_in <= '1';
		wait for 2*CLK_PERIOD;
	
	
		wait; 
	
	end process;
	
END;
