library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

use work.mem_pkg.all;
use work.cache_pkg.all;

entity mgmt_st_1w is
	generic (
		SETS_LD  : natural := SETS_LD
	);
	port (
		clk     : in std_logic;
		res_n   : in std_logic;

		index   : in c_index_type;
		we      : in std_logic;
		we_repl	: in std_logic;

		mgmt_info_in  : in c_mgmt_info;
		mgmt_info_out : out c_mgmt_info
	);
end entity;

architecture impl of mgmt_st_1w is
	-- (word) address consists of |index bits|
	constant CACHE_MGMT_ADDRESS_BITS : integer := SETS_LD;

	-- array types
	type mgmt_storage_type is array (0 to (2**CACHE_MGMT_ADDRESS_BITS) - 1) of c_mgmt_info;
	constant INITIAL_MGMT : mgmt_storage_type := (others => (
		valid => '0',
		dirty => '0',
		replace => '0',
		tag => (others => '0')
	));
	signal mgmt, mgmt_next : mgmt_storage_type := INITIAL_MGMT;
begin
	-- concurrent
	mgmt_info_out <= mgmt(to_integer(unsigned(index))); -- when we = '0' else mgmt_info_in;

	-- synchronous
	sync : process(clk, res_n)
	begin
		if res_n = '0' then
			mgmt <= INITIAL_MGMT;
		elsif rising_edge(clk) then
			mgmt <= mgmt_next;
		end if;
	end process;

	async : process(all)
	begin
		mgmt_next <= mgmt;
		if we = '1' then
			mgmt_next(to_integer(unsigned(index))) <= mgmt_info_in;
		end if;
	end process;
end architecture;
