LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.NUMERIC_STD.ALL;

library work;
use work.utils_pkg.all;

ENTITY ram_wb IS
	GENERIC 
	(
		NUM_WORDS 	: integer := 64
	);
	Port
	(
		CLK_I		: in  STD_LOGIC;
		RST_I		: in  STD_LOGIC;
		CYC_I		: in  STD_LOGIC;
		STB_I		: in  STD_LOGIC;
		SEL_I		: in  unsigned(3 downto 0);
		WE_I		: in  STD_LOGIC;
		ACK_O		: out STD_LOGIC;
		SRDY_O		: out STD_LOGIC;
		MRDY_I		: in  STD_LOGIC;
		ADDR_I		: in  unsigned(31 downto 0);
		DAT_I		: in  unsigned(31 downto 0);
		DAT_O		: out unsigned(31 downto 0)
	);
END ram_wb;

ARCHITECTURE behavior OF ram_wb IS

	constant addr_width : natural := NextExpBaseTwo(NUM_WORDS);
	signal ram_en : std_logic;
	signal we : unsigned(3 downto 0);
	signal re : std_logic;

begin

	SRDY_O	<= CYC_I;
	
	ram_en	<= CYC_I and STB_I and MRDY_I;
	we 		<= SEL_I and (3 downto 0 => ram_en and WE_I);
	re 		<= ram_en and not WE_I;
	
data_valid_register:
	process(CLK_I)
	begin
		if rising_edge(CLK_I) then
			if RST_I = '1' then
				ACK_O	<= '0';
			else
				ACK_O	<= re;
			end if;
		end if;
	end process;

inst_ram_0 : entity work.dpram_1w1r1c_ra
	GENERIC MAP 
	(
		addr_width => addr_width,
		data_width => 8
	)
	PORT MAP 
	(
		clk		=> CLK_I,
		we_a		=> we(0),
		re_b		=> '1',
		addr_a	=> ADDR_I(addr_width+1 downto 2),
		addr_b	=> ADDR_I(addr_width+1 downto 2),
		din_a		=> DAT_I(7 downto 0),
		dout_b	=> DAT_O(7 downto 0)
	);

inst_ram_1 : entity work.dpram_1w1r1c_ra
	GENERIC MAP 
	(
		addr_width => addr_width,
		data_width => 8
	)
	PORT MAP 
	(
		clk		=> CLK_I,
		we_a		=> we(1),
		re_b		=> '1',
		addr_a	=> ADDR_I(addr_width+1 downto 2),
		addr_b	=> ADDR_I(addr_width+1 downto 2),
		din_a		=> DAT_I(15 downto 8),
		dout_b	=> DAT_O(15 downto 8)
	);

inst_ram_2 : entity work.dpram_1w1r1c_ra
	GENERIC MAP 
	(
		addr_width => addr_width,
		data_width => 8
	)
	PORT MAP 
	(
		clk		=> CLK_I,
		we_a		=> we(2),
		re_b		=> '1',
		addr_a	=> ADDR_I(addr_width+1 downto 2),
		addr_b	=> ADDR_I(addr_width+1 downto 2),
		din_a		=> DAT_I(23 downto 16),
		dout_b	=> DAT_O(23 downto 16)
	);

inst_ram_3 : entity work.dpram_1w1r1c_ra
	GENERIC MAP 
	(
		addr_width => addr_width,
		data_width => 8
	)
	PORT MAP 
	(
		clk		=> CLK_I,
		we_a		=> we(3),
		re_b		=> '1',
		addr_a	=> ADDR_I(addr_width+1 downto 2),
		addr_b	=> ADDR_I(addr_width+1 downto 2),
		din_a		=> DAT_I(31 downto 24),
		dout_b	=> DAT_O(31 downto 24)
	);


end behavior;
