111 lines
3.9 KiB
VHDL
111 lines
3.9 KiB
VHDL
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 (
|
|
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) := (others => '0');
|
|
signal fifo_empty : std_logic := '0';
|
|
signal fifo_cnt : natural range 0 to MAX_BURST_LENGTH := 0;
|
|
signal delay_cnt : natural range 0 to READ_LATENCY := 0;
|
|
signal ready_in_sig, valid_out_sig : std_logic := '0';
|
|
|
|
begin
|
|
|
|
--*****COMPONENT INSTANTIATION*****
|
|
ram_inst : entity work.single_port_ram(arch)
|
|
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 : entity work.FWFT_FIFO(arch)
|
|
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; |