-------------------------------------------------------------------------
-- Project: JCPU, a portable 8-bit RISC CPU written in VHDL
-- This file: testbench for embedded cpu with rom
--
-- Copyright (C) 2007 J. Ahrensfeld
--
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- This program 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 General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
--
-- 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;

ENTITY tb_j1 IS
END tb_j1;

ARCHITECTURE behavior OF tb_j1 IS 

	constant CLK_PERIOD : time := 10 ns;
	
	-- Inputs
	signal sys_clk_i	: std_logic := '0';
	signal sys_rst_i	: std_logic := '1';
	signal io_din		: unsigned(15 downto 0) := (others => '0');
	signal inst_din		: unsigned(15 downto 0) := (others => '0');
	signal data_din		: unsigned(15 downto 0) := (others => '0');

	-- Outputs
	signal io_rd		: std_logic;
	signal io_wr		: std_logic;
	signal io_addr		: unsigned(15 downto 0);
	signal io_dout		: unsigned(15 downto 0);
	signal data_dout	: unsigned(15 downto 0);
	signal inst_addr	: unsigned(12 downto 0);
	signal data_addr	: unsigned(12 downto 0);
	signal data_we		: std_logic;
	signal data_en		: std_logic;

	type rom_t is array (integer range <>) of unsigned(15 downto 0);

	signal rom : rom_t(0 to 15) := 
	(
		X"8123",	-- 0000
		X"0002",	-- 0001
		X"0005",	-- 0002
		X"8456",	-- 0003
		X"4008",	-- 0004
		X"0003",	-- 0005
		X"0000",	-- 0006
		X"0000",	-- 0007
		X"8456",	-- 0008
		X"8451",	-- 0009
		X"7000",	-- 000A
		X"0000",	-- 000B
		X"0000",	-- 000C
		X"0000",	-- 000D
		X"0000",	-- 000E
		X"0000"		-- 000F
	);

BEGIN

	-- Instruction rom
process(sys_clk_i)
begin
	if rising_edge(sys_clk_i) then
		inst_din	<= rom(to_integer(inst_addr(3 downto 0)));
	end if;
end process;

uut: entity work.j1
	PORT MAP
	(
		sys_clk_i		=> sys_clk_i,
		sys_rst_i		=> sys_rst_i,
		io_din			=> io_din,
		io_rd			=> io_rd,
		io_wr			=> io_wr,
		io_addr			=> io_addr,
		inst_din		=> inst_din,
		inst_addr		=> inst_addr,
		data_addr		=> data_addr,
		data_we			=> data_we,
		data_en			=> data_en,
		data_din		=> data_din,
		data_dout		=> data_dout
	);

inst_ram: entity work.ram_2c_2r_2w
	GENERIC MAP
	(
		addr_width	=> 13,
		data_width	=> 16
	)
	PORT MAP(
		clka		=> sys_clk_i,
		clkb		=> sys_clk_i,
		en_a		=> '1',
		en_b		=> data_en,
		we_a		=> '0',
		we_b		=> data_we,
		addr_a		=> (others => '0'), --inst_addr
		addr_b		=> data_addr,
		din_a		=> (others => '0'),
		din_b		=> data_dout,
		dout_a		=> open, -- inst_din
		dout_b		=> data_din
	);

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

STIMULUS: process

	begin

		wait for 3*CLK_PERIOD;
		sys_rst_i <= '0';
		wait for 2*CLK_PERIOD;
	
	
		wait for 1000*CLK_PERIOD;

		assert false report "Test finished" severity error;
		wait; 
	
	end process;

end behavior;
