library IEEE;
use IEEE.STD_LOGIC_1164.all, IEEE.NUMERIC_STD.all;

entity TEST_RSRAID is
end entity TEST_RSRAID;

architecture TESTBENCH of TEST_RSRAID is
    component GFMATMULT 
	port ( GET   : in  std_logic;
	       IN1   : in  unsigned(3 downto 0);
	       IN2   : in  unsigned(3 downto 0);
	       IN3   : in  unsigned(3 downto 0);
	       ADD   : in  unsigned(3 downto 0);
	       ELE   : in  unsigned(3 downto 0);
	       WE    : in  std_logic;
	       CLK   : in  std_logic;
	       RESET : in  std_logic;
	       DONE  : out std_logic;
	       OUT1  : out unsigned(3 downto 0);
	       OUT2  : out unsigned(3 downto 0);
	       OUT3  : out unsigned(3 downto 0) );
    end component;
    -- I/O signals
    signal     GET      :  std_logic := '0';
    signal     D1IN     :  unsigned(3 downto 0);
    signal     D2IN     :  unsigned(3 downto 0);
    signal     D3IN     :  unsigned(3 downto 0);
    signal     ADD      :  unsigned(3 downto 0);
    signal     ELE      :  unsigned(3 downto 0);
    signal     EWE,DWE  :  std_logic := '0';
    signal     CLK      :  std_logic := '0';
    signal     RESET    :  std_logic := '1';
    signal     DONE     :  std_logic;
    signal     D1OUT    :  unsigned(3 downto 0);
    signal     D2OUT    :  unsigned(3 downto 0);
    signal     D3OUT    :  unsigned(3 downto 0);
    -- other signals     
    signal     EDONE    :  std_logic;
    signal     C1       :  unsigned(3 downto 0);
    signal     C2       :  unsigned(3 downto 0);
    signal     C3       :  unsigned(3 downto 0);
begin
    -- clock generation
    CLK <= not CLK after 10 ns;

    ENCODER: GFMATMULT port map 
    (GET,D1IN,D2IN,D3IN,ADD,ELE,EWE,CLK,RESET,EDONE,C1,C2,C3);

    DECODER: GFMATMULT port map 
    (EDONE,D1IN,C1,C2,ADD,ELE,DWE,CLK,RESET,DONE,D1OUT,D2OUT,D3OUT);

    process 
    begin
        RESET_LOOP: for N in 0 to 3 loop
	wait until falling_edge(CLK);
        end loop RESET_LOOP;
	    RESET <= '0';

	-- WRITE ENCODER ELE --   
	wait until falling_edge(CLK);
	    EWE <= '1';
	    ADD <= TO_UNSIGNED(0,4);
	    ELE <= TO_UNSIGNED(1,4);
	wait until falling_edge(CLK);
	    ADD <= TO_UNSIGNED(1,4);
	    ELE <= TO_UNSIGNED(1,4);
	wait until falling_edge(CLK);
	    ADD <= TO_UNSIGNED(2,4);
	    ELE <= TO_UNSIGNED(1,4);
	wait until falling_edge(CLK);
	    ADD <= TO_UNSIGNED(3,4);
	    ELE <= TO_UNSIGNED(1,4);
	wait until falling_edge(CLK);
	    ADD <= TO_UNSIGNED(4,4);
	    ELE <= TO_UNSIGNED(2,4);
	wait until falling_edge(CLK);
	    ADD <= TO_UNSIGNED(5,4);
	    ELE <= TO_UNSIGNED(3,4);
	wait until falling_edge(CLK);
	    ADD <= TO_UNSIGNED(6,4);
	    ELE <= TO_UNSIGNED(1,4);
	wait until falling_edge(CLK);
	    ADD <= TO_UNSIGNED(7,4);
	    ELE <= TO_UNSIGNED(4,4);
	wait until falling_edge(CLK);
	    ADD <= TO_UNSIGNED(8,4);
	    ELE <= TO_UNSIGNED(5,4);
	wait until falling_edge(CLK);
	    EWE <='0';

	-- WRITE DECODER ELE --   
	wait until falling_edge(CLK);
	    DWE <= '1';
	    ADD <= TO_UNSIGNED(0,4);
	    ELE <= TO_UNSIGNED(1,4);
	wait until falling_edge(CLK);
	    ADD <= TO_UNSIGNED(1,4);
	    ELE <= TO_UNSIGNED(0,4);
	wait until falling_edge(CLK);
	    ADD <= TO_UNSIGNED(2,4);
	    ELE <= TO_UNSIGNED(0,4);
	wait until falling_edge(CLK);
	    ADD <= TO_UNSIGNED(3,4);
	    ELE <= TO_UNSIGNED(2,4);
	wait until falling_edge(CLK);
	    ADD <= TO_UNSIGNED(4,4);
	    ELE <= TO_UNSIGNED(3,4);
	wait until falling_edge(CLK);
	    ADD <= TO_UNSIGNED(5,4);
	    ELE <= TO_UNSIGNED(1,4);
	wait until falling_edge(CLK);
	    ADD <= TO_UNSIGNED(6,4);
	    ELE <= TO_UNSIGNED(3,4);
	wait until falling_edge(CLK);
	    ADD <= TO_UNSIGNED(7,4);
	    ELE <= TO_UNSIGNED(2,4);
	wait until falling_edge(CLK);
	    ADD <= TO_UNSIGNED(8,4);
	    ELE <= TO_UNSIGNED(1,4);
	wait until falling_edge(CLK);
	    DWE <='0';

	-- MAT CALCULATION --
	wait until falling_edge(CLK);
	    GET <= '1';
	    D1IN <= TO_UNSIGNED(3,4);
	    D2IN <= TO_UNSIGNED(13,4);
	    D3IN <= TO_UNSIGNED(9,4);
	wait until falling_edge(CLK);
	    GET <='0';
	for N in 0 to 32 loop
	wait until falling_edge(CLK);
	end loop;

	-- MAT CALCULATION --
	wait until falling_edge(CLK);
	    GET <= '1';
	    D1IN <= TO_UNSIGNED(0,4);
	    D2IN <= TO_UNSIGNED(0,4);
	    D3IN <= TO_UNSIGNED(0,4);
	wait until falling_edge(CLK);
	    GET <='0';
	for N in 0 to 32 loop
	wait until falling_edge(CLK);
	end loop;
	
	-- MAT CALCULATION --
	wait until falling_edge(CLK);
	    GET <= '1';
	    D1IN <= TO_UNSIGNED(15,4);
	    D2IN <= TO_UNSIGNED(15,4);
	    D3IN <= TO_UNSIGNED(15,4);
	wait until falling_edge(CLK);
	    GET <='0';
	for N in 0 to 32 loop
	wait until falling_edge(CLK);
	end loop;

	-- MAT CALCULATION --
	wait until falling_edge(CLK);
	    GET <= '1';
	    D1IN <= TO_UNSIGNED(0,4);
	    D2IN <= TO_UNSIGNED(15,4);
	    D3IN <= TO_UNSIGNED(14,4);
	wait until falling_edge(CLK);
	    GET <='0';
	for N in 0 to 32 loop
	wait until falling_edge(CLK);
	end loop;
	
	


	wait;
    end process;
end architecture TESTBENCH;

configuration CFG_RSRAID of TEST_RSRAID is
    for TESTBENCH 
    end for;
end configuration CFG_RSRAID;
