--
--  File: regfile.vhd
--  created by Design Wizard: 12/12/01 02:43:47
--

--{{ Section below this comment is automatically maintained
--   and may be overwritten
--{entity {regfile} architecture {regfile_bh}}

library IEEE;
use IEEE.std_logic_1164.all;				 
use ieee.numeric_std.all;

entity regfile is	  
	generic (Tac : Time := 1 ns;
           tag : string := "";
           origin_x, origin_y : real := 0.0);
	port (
		rd_a_L1: in STD_LOGIC_VECTOR (4 downto 0);
		rd_a_L2: in STD_LOGIC_VECTOR (4 downto 0);
		rd_a_R1: in STD_LOGIC_VECTOR (4 downto 0);
		rd_a_R2: in STD_LOGIC_VECTOR (4 downto 0);
		rd_q_L1: out STD_LOGIC_VECTOR (63 downto 0);
		rd_q_L2: out STD_LOGIC_VECTOR (63 downto 0);
		rd_q_R1: out STD_LOGIC_VECTOR (63 downto 0);
		rd_q_R2: out STD_LOGIC_VECTOR (63 downto 0);
		wr_a_R: in STD_LOGIC_VECTOR (4 downto 0);
		wr_a_L: in STD_LOGIC_VECTOR (4 downto 0);
		wr_a_M: in STD_LOGIC_VECTOR (4 downto 0);	
		wr_d_R: in STD_LOGIC_VECTOR (63 downto 0);
		wr_d_L: in STD_LOGIC_VECTOR (63 downto 0);
		wr_d_M: in STD_LOGIC_VECTOR (63 downto 0);
		we_R: in STD_LOGIC;
		we_L: in STD_LOGIC;
		we_M: in STD_LOGIC
	);
end regfile;

--}} End of automatically maintained section

architecture regfile_bh of regfile is						  
type register_array is array (integer range 1 to 31) of std_logic_vector(63 downto 0);
signal regf : 	register_array;
begin
  -- <<enter your statements here>>	 
    reg: process (rd_a_L1, rd_a_L2, rd_a_R1, rd_a_R2, wr_a_L, wr_a_R, wr_d_L, wr_d_R, wr_a_M, wr_d_M, we_R, we_L, we_M)

    constant all_zeros : std_logic_vector(63 downto 0) := x"0000000000000000";

    -- type register_array is array (integer range 1 to 31) of std_logic_vector(63 downto 0);
    variable register_file : register_array := (x"0000000000000000",x"0000000000000020",
                                                x"0100010001000100",x"0000000000000000",
                                                x"0000000000000101",x"0000000000000110",
                                                x"0000000000000111",x"0000000000001000",
                                                x"3333333333333333",x"4444444444444444",
                                                x"0000000000000020",x"4444444444444444",
                                                x"3333333333333333",x"4444444444444444",
                                                x"3333333333333333",x"4444444444444444",
                                                x"3333333333333333",x"4444444444444444",
                                                x"3333333333333333",x"4444444444444444",
                                                x"3333333333333333",x"4444444444444444",
                                                x"3333333333333333",x"4444444444444444",
                                                x"3333333333333333",x"4444444444444444",
                                                x"3333333333333333",x"4444444444444444",
                                                x"3333333333333333",x"4444444444444444",
                                                x"3333333333333333");
    variable reg_index_R, reg_index_L, reg_index_M, reg_index_R1, reg_index_R2, reg_index_L1, reg_index_L2 : integer;

  begin
    -- do write first if enabled
	-- Left way write first	because it executes earlier than the right way.
    if we_L = '1' then
      reg_index_L := to_integer(unsigned(wr_a_L));
      if reg_index_L /= 0 then
      	register_file(reg_index_L) := wr_d_L;
      end if;
    end if;
	
    -- Right way write
    if we_R = '1' then
      reg_index_R := to_integer(unsigned(wr_a_R));
      if reg_index_R /= 0 then
      	register_file(reg_index_R) := wr_d_R;
      end if;
    end if;
    
    -- Data from DATA CACHE write
    if we_M = '1' then
      reg_index_M := to_integer(unsigned(wr_a_M));
      if reg_index_M /= 0 then
      	register_file(reg_index_M) := wr_d_M;
      end if;
    end if;

    --
    -- Right-way read port 1
    --
    reg_index_R1 := to_integer(unsigned(rd_a_R1));
    if reg_index_R1 /= 0 then
      rd_q_R1 <= register_file(reg_index_R1) after Tac;
    else
      rd_q_R1 <= all_zeros after Tac;
    end if;
    --
    -- Right-way read port 2
    --
    reg_index_R2 := to_integer(unsigned(rd_a_R2));
    if reg_index_R2 /= 0 then
      rd_q_R2 <= register_file(reg_index_R2) after Tac;
    else
      rd_q_R2 <= all_zeros after Tac;
    end if;

   -- Left-way read port 1
    --
    reg_index_L1 := to_integer(unsigned(rd_a_L1));
    if reg_index_L1 /= 0 then
      rd_q_L1 <= register_file(reg_index_L1) after Tac;
    else
      rd_q_L1 <= all_zeros after Tac;
    end if;
    --
    -- Left-way read port 2
    --
    reg_index_L2 := to_integer(unsigned(rd_a_L2));
    if reg_index_L2 /= 0 then
      rd_q_L2 <= register_file(reg_index_L2) after Tac;
    else
      rd_q_L2 <= all_zeros after Tac;
    end if;
	
	regf <=	register_file;
  end process reg;

end regfile_bh;
