Add Dual Port Memory Controller
This commit is contained in:
parent
46ca2228b6
commit
622ebf6083
123
src/dp_mem_ctrl.vhd
Normal file
123
src/dp_mem_ctrl.vhd
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
-- altera vhdl_input_version vhdl_2008
|
||||||
|
-- XXX: QSYS Fix (https://www.intel.com/content/www/us/en/support/programmable/articles/000079458.html)
|
||||||
|
|
||||||
|
library ieee;
|
||||||
|
use ieee.std_logic_1164.all;
|
||||||
|
use ieee.numeric_std.all;
|
||||||
|
|
||||||
|
entity dp_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;
|
||||||
|
-- READ PORT
|
||||||
|
raddr : in std_logic_vector(ADDR_WIDTH-1 downto 0);
|
||||||
|
rvalid_in : in std_logic;
|
||||||
|
rready_in : out std_logic;
|
||||||
|
rvalid_out : out std_logic;
|
||||||
|
rready_out : in std_logic;
|
||||||
|
rdata_out : out std_logic_vector(DATA_WIDTH-1 downto 0);
|
||||||
|
-- WRITE PORT
|
||||||
|
waddr : in std_logic_vector(ADDR_WIDTH-1 downto 0);
|
||||||
|
wvalid_in : in std_logic;
|
||||||
|
wready_in : out std_logic;
|
||||||
|
wdata_in : in std_logic_vector(DATA_WIDTH-1 downto 0)
|
||||||
|
);
|
||||||
|
end entity;
|
||||||
|
|
||||||
|
architecture arch of dp_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 rready_in_sig, wready_in_sig, rvalid_out_sig : std_logic;
|
||||||
|
|
||||||
|
begin
|
||||||
|
|
||||||
|
--*****COMPONENT INSTANTIATION*****
|
||||||
|
ram_inst : configuration work.dual_port_ram_cfg
|
||||||
|
generic map (
|
||||||
|
ADDR_WIDTH => ADDR_WIDTH,
|
||||||
|
DATA_WIDTH => DATA_WIDTH,
|
||||||
|
MEMORY_DEPTH => MEMORY_DEPTH
|
||||||
|
)
|
||||||
|
port map (
|
||||||
|
clk => clk,
|
||||||
|
raddr => raddr,
|
||||||
|
waddr => waddr,
|
||||||
|
wen => wready_in_sig and wvalid_in,
|
||||||
|
ren => rready_in_sig and rvalid_in,
|
||||||
|
wr_data => wdata_in,
|
||||||
|
rd_data => mem_read_data
|
||||||
|
);
|
||||||
|
|
||||||
|
wready_in_sig <= '1'; -- We are always ready to receive writes
|
||||||
|
wready_in <= wready_in_sig;
|
||||||
|
|
||||||
|
rready_in_sig <= '0' when (fifo_cnt - delay_cnt = 0) else '1';
|
||||||
|
rready_in <= rready_in_sig;
|
||||||
|
|
||||||
|
rvalid_out_sig <= not fifo_empty;
|
||||||
|
rvalid_out <= rvalid_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) <= rready_in_sig and rvalid_in;
|
||||||
|
|
||||||
|
if ((rready_in_sig and rvalid_in) = '1' and delay_line(1) = '0') then
|
||||||
|
delay_cnt <= delay_cnt + 1;
|
||||||
|
elsif ((rready_in_sig and rvalid_in) = '0' and delay_line(1) = '1') then
|
||||||
|
delay_cnt <= delay_cnt - 1;
|
||||||
|
end if;
|
||||||
|
else -- READ_LATENCY = 1
|
||||||
|
delay_line(0) <= rready_in_sig and rvalid_in;
|
||||||
|
|
||||||
|
if ((rready_in_sig and rvalid_in) = '1' and delay_line(0) = '0') then
|
||||||
|
delay_cnt <= delay_cnt + 1;
|
||||||
|
elsif ((rready_in_sig and rvalid_in) = '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 => rready_out and rvalid_out_sig,
|
||||||
|
data_out => rdata_out,
|
||||||
|
empty => fifo_empty,
|
||||||
|
full => open,
|
||||||
|
free => fifo_cnt
|
||||||
|
);
|
||||||
|
end architecture;
|
||||||
Loading…
Reference in New Issue
Block a user