rtps-fpga/src/mem_ctrl.vhd
Greek 52bd4053d1 Add mem_ctrl Level 0 Test 1
mem_ctrl fixed and testbench implemented
2021-02-17 14:01:49 +01:00

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;