-------------------------------------------------------------------------
-- 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.

ENTITY tb_rom_wb IS
END tb_rom_wb;

ARCHITECTURE behavior OF tb_rom_wb IS 

	constant CLK_PERIOD : time := 10 ns;
	signal CLK_O	: std_logic := '1';
	signal RST_O	: std_logic := '1';
	signal CYC_O	: std_logic := '0';
	signal STB_O	: std_logic := '0';
	signal ACK_I	: std_logic;
	signal MRDY_O	: std_logic := '1';
	signal SRDY_I	: std_logic;
	signal ADDR_O	: unsigned(31 downto 0) := (others => '-');
	signal DAT_I	: unsigned(31 downto 0);

	signal dout_rst			: std_logic := '0';
	signal dout_reg			: unsigned(31 downto 0);
	signal dout_cnt			: natural range 0 to 255;

BEGIN

inst_rom_wb : entity work.rom_wb
	PORT MAP
	(
		RST_I		=> RST_O,
		CLK_I		=> CLK_O,
		CYC_I		=> CYC_O,
		STB_I		=> STB_O,
		WE_I		=> '0',
		ACK_O		=> ACK_I,
		SRDY_O		=> SRDY_I,
		MRDY_I		=> MRDY_O,
		ADDR_I		=> ADDR_O,
		DAT_O		=> DAT_I
	);

read_register:
	process(CLK_O)
	begin
		if rising_edge(CLK_O) then
			if dout_rst = '1' then
				dout_cnt <= 0;
			elsif ACK_I = '1' then
				dout_reg	<= DAT_I;
				dout_cnt 	<= dout_cnt + 1;
			end if;
		end if;
	end process;

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

STIMULUS: process

	begin

		wait for 3*CLK_PERIOD;
		RST_O <= '0';

		-- 8-word burst cycle
		wait for 3*CLK_PERIOD;
		dout_rst	<= '1';
		wait until rising_edge(CLK_O);
		dout_rst	<= '0';
		CYC_O	<= '1';
		STB_O	<= '1';
		ADDR_O	<= X"0000_0180";
		wait until rising_edge(CLK_O) and SRDY_I = '1';
		ADDR_O	<= ADDR_O + 4;
		wait until rising_edge(CLK_O) and SRDY_I = '1';
		ADDR_O	<= ADDR_O + 4;
		wait until rising_edge(CLK_O) and SRDY_I = '1';
		ADDR_O	<= ADDR_O + 4;
		wait until rising_edge(CLK_O) and SRDY_I = '1';
		ADDR_O	<= ADDR_O + 4;
		wait until rising_edge(CLK_O) and SRDY_I = '1';
		ADDR_O	<= ADDR_O + 4;
		wait until rising_edge(CLK_O) and SRDY_I = '1';
		ADDR_O	<= ADDR_O + 4;
		wait until rising_edge(CLK_O) and SRDY_I = '1';
		ADDR_O	<= ADDR_O + 4;
		wait until rising_edge(CLK_O) and SRDY_I = '1';
		ADDR_O	<= ADDR_O + 4;
		wait until rising_edge(CLK_O) and SRDY_I = '1';
		ADDR_O	<= ADDR_O + 4;
		wait until rising_edge(CLK_O) and SRDY_I = '1';
		ADDR_O	<= ADDR_O + 4;
		wait until rising_edge(CLK_O) and SRDY_I = '1';
		ADDR_O	<= ADDR_O + 4;
		wait until rising_edge(CLK_O) and SRDY_I = '1';
		ADDR_O	<= ADDR_O + 4;
		wait until rising_edge(CLK_O) and SRDY_I = '1';
		ADDR_O	<= ADDR_O + 4;
		wait until rising_edge(CLK_O) and SRDY_I = '1';
		ADDR_O	<= ADDR_O + 4;
		wait until rising_edge(CLK_O) and SRDY_I = '1';
		ADDR_O	<= ADDR_O + 4;
		wait until rising_edge(CLK_O) and SRDY_I = '1';
		ADDR_O	<= ADDR_O + 4;
		wait until rising_edge(CLK_O) and SRDY_I = '1';
		ADDR_O	<= ADDR_O + 4;
		wait until rising_edge(CLK_O) and SRDY_I = '1';
		ADDR_O	<= ADDR_O + 4;
		wait until rising_edge(CLK_O) and SRDY_I = '1';
		ADDR_O	<= ADDR_O + 4;
		wait until rising_edge(CLK_O) and SRDY_I = '1';
		ADDR_O	<= ADDR_O + 4;
		wait until rising_edge(CLK_O) and SRDY_I = '1';
		ADDR_O	<= ADDR_O + 4;
		wait until rising_edge(CLK_O) and SRDY_I = '1';
		ADDR_O	<= ADDR_O + 4;
		wait until rising_edge(CLK_O) and SRDY_I = '1';
		ADDR_O	<= ADDR_O + 4;
		wait until rising_edge(CLK_O) and SRDY_I = '1';
		ADDR_O	<= ADDR_O + 4;
		wait until rising_edge(CLK_O) and SRDY_I = '1';
		ADDR_O	<= ADDR_O + 4;
		wait until rising_edge(CLK_O) and SRDY_I = '1';
		ADDR_O	<= ADDR_O + 4;
		wait until rising_edge(CLK_O) and SRDY_I = '1';
		ADDR_O	<= ADDR_O + 4;
		wait until rising_edge(CLK_O) and SRDY_I = '1';
		ADDR_O	<= ADDR_O + 4;
		wait until rising_edge(CLK_O) and SRDY_I = '1';
		STB_O	<= '0';
		MRDY_O	<= '0';
		wait until rising_edge(CLK_O) and SRDY_I = '1';
		STB_O	<= '1';
		MRDY_O	<= '1';
		ADDR_O	<= ADDR_O + 4;
		wait until rising_edge(CLK_O) and SRDY_I = '1';
		ADDR_O	<= ADDR_O + 4;
		wait until rising_edge(CLK_O) and SRDY_I = '1';
		ADDR_O	<= ADDR_O + 4;
		wait until rising_edge(CLK_O) and SRDY_I = '1';
		ADDR_O	<= ADDR_O + 4;
		wait until rising_edge(CLK_O) and SRDY_I = '1';
		ADDR_O	<= ADDR_O + 4;
		wait until rising_edge(CLK_O) and SRDY_I = '1';
		ADDR_O	<= ADDR_O + 4;
		wait until rising_edge(CLK_O) and SRDY_I = '1';
		ADDR_O	<= ADDR_O + 4;
		wait until rising_edge(CLK_O) and SRDY_I = '1';
		ADDR_O	<= ADDR_O + 4;
		wait until rising_edge(CLK_O) and SRDY_I = '1';
		ADDR_O	<= ADDR_O + 4;
		wait until rising_edge(CLK_O) and SRDY_I = '1';
		ADDR_O	<= ADDR_O + 4;
		wait until rising_edge(CLK_O) and SRDY_I = '1';
		ADDR_O	<= ADDR_O + 4;
		wait until rising_edge(CLK_O) and SRDY_I = '1';
		ADDR_O	<= ADDR_O + 4;
		wait until rising_edge(CLK_O) and SRDY_I = '1';
		ADDR_O	<= ADDR_O + 4;
		wait until rising_edge(CLK_O) and SRDY_I = '1';
		ADDR_O	<= ADDR_O + 4;
		wait until rising_edge(CLK_O) and SRDY_I = '1';
		ADDR_O	<= ADDR_O + 4;
		wait until rising_edge(CLK_O) and SRDY_I = '1';
		ADDR_O	<= ADDR_O + 4;
		wait until rising_edge(CLK_O) and SRDY_I = '1';
		ADDR_O	<= ADDR_O + 4;
		wait until rising_edge(CLK_O) and SRDY_I = '1';
		ADDR_O	<= ADDR_O + 4;
		wait until rising_edge(CLK_O) and SRDY_I = '1';
		ADDR_O	<= ADDR_O + 4;
		wait until rising_edge(CLK_O) and SRDY_I = '1';
		ADDR_O	<= ADDR_O + 4;
		wait until rising_edge(CLK_O) and SRDY_I = '1';
		ADDR_O	<= ADDR_O + 4;
		wait until rising_edge(CLK_O) and SRDY_I = '1';
		ADDR_O	<= ADDR_O + 4;
		wait until rising_edge(CLK_O) and SRDY_I = '1';
		ADDR_O	<= ADDR_O + 4;
		wait until rising_edge(CLK_O) and SRDY_I = '1';
		ADDR_O	<= ADDR_O + 4;
		wait until rising_edge(CLK_O) and SRDY_I = '1';
		ADDR_O	<= ADDR_O + 4;
		wait until rising_edge(CLK_O) and SRDY_I = '1';
		ADDR_O	<= ADDR_O + 4;
		wait until rising_edge(CLK_O) and SRDY_I = '1';
		STB_O	<= '0';
		
		wait until rising_edge(CLK_O) and dout_cnt = 54;
		CYC_O	<= '0';

		wait; 
	
	end process;
	
END;
