library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity mem_ctrl is generic ( ADDR_WIDTH : natural; DATA_WIDTH : natural; MEMORY_DEPTH : natural; MAX_BURST_LENGTH : natural ); port ( -- SYSTEM clk : in std_logic; reset : in std_logic; addr : in std_logic_vector(ADDR_WIDTH-1 downto 0); read : in std_logic; ready_in : out std_logic; valid_in : in std_logic; data_in : in std_logic_vector(DATA_WIDTH-1 downto 0); ready_out : in std_logic; valid_out : out std_logic; data_out : out std_logic_vector(DATA_WIDTH-1 downto 0) ); end entity; architecture arch of mem_ctrl is -- *CONSTANT DECLARATION* constant READ_LATENCY : natural := 1; -- *TYPE DECLARATION* -- *SIGNAL DECLARATION* signal mem_read_data : std_logic_vector(DATA_WIDTH-1 downto 0); signal delay_line : std_logic_vector(READ_LATENCY-1 downto 0); signal fifo_empty : std_logic; signal fifo_cnt : natural range 0 to MAX_BURST_LENGTH; signal delay_cnt : natural range 0 to READ_LATENCY; signal ready_in_sig, valid_out_sig : std_logic; begin --*****COMPONENT INSTANTIATION***** ram_inst : configuration work.single_port_ram_cfg generic map ( ADDR_WIDTH => ADDR_WIDTH, DATA_WIDTH => DATA_WIDTH, MEMORY_DEPTH => MEMORY_DEPTH ) port map ( clk => clk, addr => addr, wen => ready_in_sig and valid_in and (not read), ren => ready_in_sig and valid_in and read, wr_data => data_in, rd_data => mem_read_data ); ready_in_sig <= '0' when (fifo_cnt - delay_cnt = 0) else '1'; ready_in <= ready_in_sig; valid_out_sig <= not fifo_empty; valid_out <= valid_out_sig; delay_line_prc : process(clk) begin if rising_edge(clk) then if (reset = '1') then delay_line <= (others => '0'); delay_cnt <= 0; else -- Shift Right if (READ_LATENCY > 1) then delay_line(READ_LATENCY-2 downto 0) <= delay_line(READ_LATENCY-1 downto 1); delay_line(READ_LATENCY-1) <= ready_in_sig and valid_in and read; if ((ready_in_sig and valid_in and read) = '1' and delay_line(1) = '0') then delay_cnt <= delay_cnt + 1; elsif ((ready_in_sig and valid_in and read) = '0' and delay_line(1) = '1') then delay_cnt <= delay_cnt - 1; end if; else delay_line(0) <= ready_in_sig and valid_in and read; if ((ready_in_sig and valid_in and read) = '1' and delay_line(0) = '0') then delay_cnt <= delay_cnt + 1; elsif ((ready_in_sig and valid_in and read) = '0' and delay_line(0) = '1') then delay_cnt <= delay_cnt - 1; end if; end if; end if; end if; end process; burst_fifo_inst : configuration work.FWFT_FIFO_cfg generic map ( FIFO_DEPTH => MAX_BURST_LENGTH, DATA_WIDTH => DATA_WIDTH ) port map ( clk => clk, reset => reset, data_in => mem_read_data, write => delay_line(0), read => ready_out and valid_out_sig, data_out => data_out, empty => fifo_empty, full => open, free => fifo_cnt ); end architecture;