---------------------------------------------------------------------- -- Leaf project -- developed by: Daniel Santos -- module: register file -- 2026 ---------------------------------------------------------------------- library IEEE; use IEEE.std_logic_1164.all; use IEEE.numeric_std.all; use work.leaf_pkg.all; entity reg_file is generic ( SIZE : natural := 32 ); port ( clk_i : in std_logic; we_i : in std_logic; wr_sel_i : in std_logic_vector(1 downto 0); wr_addr_i : in std_logic_vector(4 downto 0); wr_data0_i : in std_logic_vector(XLEN-1 downto 0); wr_data1_i : in std_logic_vector(XLEN-1 downto 0); wr_data2_i : in std_logic_vector(XLEN-1 downto 0); wr_data3_i : in std_logic_vector(XLEN-1 downto 0); rd_addr0_i : in std_logic_vector(4 downto 0); rd_addr1_i : in std_logic_vector(4 downto 0); rd_data0_o : out std_logic_vector(XLEN-1 downto 0); rd_data1_o : out std_logic_vector(XLEN-1 downto 0) ); end entity reg_file; architecture reg_file_arch of reg_file is constant EMBEDDED : boolean := SIZE = 16; type regs_array is array(0 to SIZE-1) of std_logic_vector(XLEN-1 downto 0); signal regs: regs_array; signal wr_data: std_logic_vector(XLEN-1 downto 0); constant X0_ADDR: std_logic_vector(4 downto 0) := b"00000"; constant X0_DATA: std_logic_vector(XLEN-1 downto 0) := (others => '0'); function to_uint(value: std_logic_vector) return integer is begin return to_integer(unsigned(value)); end function; begin wr_data_mux: process(wr_sel_i, wr_data0_i, wr_data1_i, wr_data2_i, wr_data3_i) begin case wr_sel_i is when b"00" => wr_data <= wr_data0_i; when b"01" => wr_data <= wr_data1_i; when b"10" => wr_data <= wr_data2_i; when b"11" => wr_data <= wr_data3_i; when others => wr_data <= (others => '-'); end case; end process wr_data_mux; large_reg_file: if (EMBEDDED = false) generate write_reg: process(clk_i) begin if rising_edge(clk_i) then regs(0) <= X0_DATA; if we_i = '1' then if wr_addr_i /= X0_ADDR then regs(to_uint(wr_addr_i)) <= wr_data; end if; end if; end if; end process write_reg; rd_data0_o <= regs(to_uint(rd_addr0_i)); rd_data1_o <= regs(to_uint(rd_addr1_i)); end generate large_reg_file; small_reg_file: if (EMBEDDED = true) generate write_reg: process(clk_i) begin if rising_edge(clk_i) then regs(0) <= X0_DATA; if we_i = '1' then if wr_addr_i /= X0_ADDR then regs(to_uint(wr_addr_i(3 downto 0))) <= wr_data; end if; end if; end if; end process write_reg; rd_data0_o <= regs(to_uint(rd_addr0_i(3 downto 0))); rd_data1_o <= regs(to_uint(rd_addr1_i(3 downto 0))); end generate small_reg_file; end architecture reg_file_arch;