-- Instruction ROM 64 word x 32 bit
-- 5 address inputs
-- 32 data outputs 
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.STD_LOGIC_ARITH.all;
use IEEE.STD_LOGIC_UNSIGNED.all;

use WORK.ALU_PKG.all;

entity IROM is
    port ( Add    : in  std_logic_vector (5 downto 0);
	   Dout   : out std_logic_vector (31 downto 0) );
end entity IROM;

architecture COND_DATA_FLOW of IROM is
    type MemVecArr is array (0 to 63) of std_logic_vector (31 downto 0);
    -----------------------------
    -- READ ONLY MEMORY
    -----------------------------
    constant ROM  : MemVecArr  := 
    (0 => OP_ALU & R0  & R0  & R0  & "00000" & FN_ADD, -- NO operation 
     1 => OP_ALU & R0  & R0  & R0  & "00000" & FN_ADD, -- NO operation 
     2 => OP_LW  & R0  & R1  & "0000000110000100",     -- LW  R1, 388(R0)
     3 => OP_LW  & R0  & R2  & "0000000110000000",     -- LW  R2, 384(R0)
     4 => OP_LW  & R0  & R3  & "0000000110001000",     -- LW  R3, 392(R0)
     5 => OP_ALU & R1  & R2  & R5  & "00000" & FN_ADD, -- ADD R5,R1,R2
     6 => OP_ALU & R5  & R3  & R5  & "00000" & FN_SUB, -- SUB R5,R5,R3
     7 => OP_ALU & R2  & R0  & R6  & "00000" & FN_ADD, -- ADD R6,R2,R0
     8 => OP_ALU & R6  & R0  & R7  & "00000" & FN_ADD, -- ADD R7,R6,R0
     9 => OP_ALU & R7  & R3  & R8  & "00000" & FN_ADD, -- ADD R8,R7,R3
    10 => OP_LW  & R7  & R10 & "0000000000000000",     -- LW  R10, 0(R7)
    11 => OP_LW  & R8  & R11 & "0000000000000000",     -- LW  R11, 0(R8)
    12 => OP_ALU & R10 & R11 & R9  & "00000" & FN_SLT, -- SLT R9,R10,R11
    13 => OP_BEQ & R9  & R0  & "0000000000000010",     -- BEQ R9,R0, +2
    14 => OP_SW  & R8  & R10 & "0000000000000000",     -- SW  R10, 0(R8)
    15 => OP_SW  & R7  & R11 & "0000000000000000",     -- SW  R11, 0(R7)
    16 => OP_ALU & R7  & R3  & R7  & "00000" & FN_ADD, -- ADD R7,R7,R3
    17 => OP_BEQ & R7  & R5  & "0000000000000001",     -- BEQ R7,R5, +1
    18 => OP_J   & "00000000000000000000001001",       -- J   9
    19 => OP_ALU & R5  & R3  & R5  & "00000" & FN_SUB, -- SUB R5,R5,R3
    20 => OP_BEQ & R5  & R2  & "0000000000000001",     -- BEQ R5,R2, +1
    21 => OP_J   & "00000000000000000000001000",       -- J   8
    others => OP_ALU & R0 & R0 & R0 & "00000" & FN_ADD); -- NOoperation
begin
    Dout <= ROM ( conv_integer(Add)) after 10 ns;
end architecture COND_DATA_FLOW;
