-- See the file "LICENSE" for the full license governing this code. --
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.numeric_std.ALL;

use work.wishbone.all;
use work.config.all;
use work.lt16soc_memories.all;
use work.lt16soc_peripherals.all;

ENTITY project_2top_tb IS
END ENTITY;

ARCHITECTURE sim OF project_2top_tb IS

	constant CLK_PERIOD : time := 10 ns;

	signal clk 	: std_logic := '0';
	signal rst	: std_logic;

	signal led0	: std_logic_vector(7 downto 0);
    signal led1	: std_logic_vector(7 downto 0);
    signal btn0 : std_logic_vector(4 downto 0) := (others => '0');
    signal btn1 : std_logic_vector(4 downto 0) := (others => '0');
    signal sw : std_logic_vector(15 downto 0) := (others => '0');
    signal anodes0 : std_logic_vector(7 downto 0);
    signal cathodes0 : std_logic_vector(7 downto 0);
    signal anodes1 : std_logic_vector(7 downto 0);
    signal cathodes1 : std_logic_vector(7 downto 0);
    signal rst_n : std_logic;
    
	constant peer_num_inst : integer := 2;
	signal rx_vector : std_logic_vector(peer_num_inst - 1 downto 0);
	signal tx_vector : std_logic_vector(peer_num_inst - 1 downto 0);
	
	signal de : std_logic_vector(1 downto 0);
	signal re_n : std_logic_vector(1 downto 0);

	COMPONENT lt16soc_top IS
		generic(
			programfilename : string := "../../programs/project_sim.ram"
		);
		port(
			clk		: in  std_logic;
			rst		: in std_logic;
			led		: out std_logic_vector(7 downto 0);
			btn : in std_logic_vector(4 downto 0);
	        sw : in std_logic_vector(15 downto 0);
            anodes : out std_logic_vector(7 downto 0);
            cathodes : out std_logic_vector(7 downto 0);
            pmod_rxd : in std_logic;
            pmod_txd : out std_logic;
            pmod_de : out std_logic;
            pmod_re_n : out std_logic
		);
	END COMPONENT;
	
    component phys_can_sim 
		generic(
			peer_num : integer );
		port(
			rst : in std_logic;
			rx_vector : out std_logic_vector(peer_num - 1 downto 0);
			tx_vector : in std_logic_vector(peer_num - 1 downto 0) );
	end component phys_can_sim;

BEGIN

	soc0: lt16soc_top
    port map(
		clk=>clk,
		rst=>rst,
		led=>led0,
		btn=>btn0,
		sw=>sw,
        anodes=>anodes0,
        cathodes=>cathodes0,
        pmod_rxd => rx_vector(0),
        pmod_txd => tx_vector(0),
        pmod_de => de(0),
        pmod_re_n => re_n(0)
	);

    soc1: lt16soc_top
    port map(
		clk=>clk,
		rst=>rst,
		led=>led1,
		btn=>btn1,
		sw=>sw,
        anodes=>anodes1,
        cathodes=>cathodes1,
        pmod_rxd => rx_vector(1),
        pmod_txd => tx_vector(1),
        pmod_de => de(1),
        pmod_re_n => re_n(1)
	);
        
    can_interconnect : phys_can_sim
    generic map(
        peer_num => peer_num_inst
    )
    port map(
        rst => rst_n,
        rx_vector => rx_vector,
        tx_vector => tx_vector
    );

	clk_gen: process
	begin
		clk	<= not clk;
		wait for CLK_PERIOD/2;
	end process clk_gen;

	stimuli: process
	begin
		rst	<= '0';
		sw <= x"000F";
		
		wait for CLK_PERIOD;
		rst	<= '1';
		
		wait for 3us;
		-- btn0 <= "00100"; -- freq
		btn0 <= "00001"; -- add
		-- btn0 <= "00010"; -- clear
		
		wait for 50us;
		sw <= x"000A";
		btn0 <= "00000";
		btn1 <= "00001"; -- add		
		
		--wait for 50us;
		--btn0 <= "00100"; -- freq
		
        wait for 50us;
        sw <= x"1550";
        btn0 <= "00000";
		btn1 <= "00100"; -- freq
		
		wait for 500us;
		btn0 <= "00010"; -- clear
		
        wait for 50us;
		sw <= x"000C";
		btn0 <= "00000";
		btn1 <= "00001"; -- add	
		
        wait for 50us;
		btn1 <= "00010"; -- clear
				
		wait for 100us;
		assert false report "Simulation terminated!" severity failure;
	end process stimuli;
	
	rst_n <= not rst;

END ARCHITECTURE;
