207 lines
5.9 KiB
VHDL
207 lines
5.9 KiB
VHDL
library ieee;
|
|
use ieee.std_logic_1164.all;
|
|
use ieee.numeric_std.all;
|
|
library work;
|
|
use work.parameter_pkg.all;
|
|
use work.types_pkg.all;
|
|
use work.constants_pkg.all;
|
|
|
|
entity memory_management is port (
|
|
clk, rst : in std_logic;
|
|
stall_flags : in std_logic_vector(PIPELINE_DEPTH-1 downto 0);
|
|
memory_stall : out std_logic;
|
|
data_rom_enable: in std_logic;
|
|
pmem_ctrl_in : in mem_ctrl_type_in;
|
|
pmem_ctrl_out : out mem_ctrl_type_out;
|
|
xmem_ctrl_in : in mem_ctrl_type_in;
|
|
xmem_ctrl_out : out mem_ctrl_type_out;
|
|
ymem_ctrl_in : in mem_ctrl_type_in;
|
|
ymem_ctrl_out : out mem_ctrl_type_out
|
|
);
|
|
end memory_management;
|
|
|
|
|
|
architecture rtl of memory_management is
|
|
|
|
|
|
component mem_control is
|
|
generic(
|
|
mem_type : memory_type
|
|
);
|
|
port(
|
|
clk, rst : in std_logic;
|
|
rd_addr : in unsigned(BW_ADDRESS-1 downto 0);
|
|
rd_en : in std_logic;
|
|
data_out : out std_logic_vector(23 downto 0);
|
|
data_out_valid : out std_logic;
|
|
wr_addr : in unsigned(BW_ADDRESS-1 downto 0);
|
|
wr_en : in std_logic;
|
|
wr_accomplished : out std_logic;
|
|
data_in : in std_logic_vector(23 downto 0)
|
|
);
|
|
end component mem_control;
|
|
|
|
signal pmem_data_out : std_logic_vector(23 downto 0);
|
|
signal pmem_data_out_valid : std_logic;
|
|
|
|
signal pmem_rd_addr : unsigned(BW_ADDRESS-1 downto 0);
|
|
signal pmem_rd_en : std_logic;
|
|
|
|
signal xmem_rd_en : std_logic;
|
|
signal xmem_data_out : std_logic_vector(23 downto 0);
|
|
signal xmem_data_out_valid : std_logic;
|
|
signal xmem_rd_polling : std_logic;
|
|
|
|
signal ymem_rd_en : std_logic;
|
|
signal ymem_data_out : std_logic_vector(23 downto 0);
|
|
signal ymem_data_out_valid : std_logic;
|
|
signal ymem_rd_polling : std_logic;
|
|
|
|
signal pmem_stall_buffer : std_logic_vector(23 downto 0);
|
|
signal pmem_stall_buffer_valid : std_logic;
|
|
signal xmem_stall_buffer : std_logic_vector(23 downto 0);
|
|
signal ymem_stall_buffer : std_logic_vector(23 downto 0);
|
|
|
|
signal stall_flags_d : std_logic_vector(PIPELINE_DEPTH-1 downto 0);
|
|
|
|
begin
|
|
|
|
-- here it is necessary to store the output of the pmem/xmem/ymem when the pipeline enters a stall
|
|
-- when the pipeline wakes up, this temporal result is inserted into the pipeline
|
|
stall_buffer: process(clk) is
|
|
begin
|
|
if rising_edge(clk) then
|
|
if rst = '1' then
|
|
pmem_stall_buffer <= (others => '0');
|
|
pmem_stall_buffer_valid <= '0';
|
|
xmem_stall_buffer <= (others => '0');
|
|
ymem_stall_buffer <= (others => '0');
|
|
stall_flags_d <= (others => '0');
|
|
else
|
|
stall_flags_d <= stall_flags;
|
|
if stall_flags(ST_FETCH2) = '1' and stall_flags_d(ST_FETCH2) = '0' then
|
|
if pmem_data_out_valid = '1' then
|
|
pmem_stall_buffer <= pmem_data_out;
|
|
pmem_stall_buffer_valid <= '1';
|
|
end if;
|
|
end if;
|
|
if stall_flags(ST_FETCH2) = '0' and stall_flags_d(ST_FETCH2) = '1' then
|
|
pmem_stall_buffer_valid <= '0';
|
|
end if;
|
|
|
|
|
|
end if;
|
|
end if;
|
|
end process stall_buffer;
|
|
|
|
memory_stall <= '1' when ( xmem_rd_en = '1' or (xmem_rd_polling = '1' and xmem_data_out_valid = '0') ) or
|
|
( ymem_rd_en = '1' or (ymem_rd_polling = '1' and ymem_data_out_valid = '0') ) else
|
|
'0';
|
|
|
|
-------------------------------
|
|
-- PMEM CONTROLLER
|
|
-------------------------------
|
|
inst_pmem_ctrl : mem_control
|
|
generic map(
|
|
mem_type => P_MEM
|
|
)
|
|
port map(
|
|
clk => clk,
|
|
rst => rst,
|
|
rd_addr => pmem_ctrl_in.rd_addr,
|
|
rd_en => pmem_ctrl_in.rd_en,
|
|
data_out => pmem_data_out,
|
|
data_out_valid => pmem_data_out_valid,
|
|
wr_addr => pmem_ctrl_in.wr_addr,
|
|
wr_en => pmem_ctrl_in.wr_en,
|
|
data_in => pmem_ctrl_in.data_in
|
|
);
|
|
|
|
-- In case we wake up from a stall use the buffered value
|
|
pmem_ctrl_out.data_out <= pmem_stall_buffer when stall_flags(ST_FETCH2) = '0' and
|
|
stall_flags_d(ST_FETCH2) = '1' and
|
|
pmem_stall_buffer_valid = '1' else
|
|
pmem_data_out;
|
|
|
|
pmem_ctrl_out.data_out_valid <= pmem_stall_buffer_valid when stall_flags(ST_FETCH2) = '0' and
|
|
stall_flags_d(ST_FETCH2) = '1' else
|
|
'0' when stall_flags(ST_FETCH2) = '1' else
|
|
pmem_data_out_valid;
|
|
|
|
-------------------------------
|
|
-- XMEM CONTROLLER
|
|
-------------------------------
|
|
inst_xmem_ctrl : mem_control
|
|
generic map(
|
|
mem_type => X_MEM
|
|
)
|
|
port map(
|
|
clk => clk,
|
|
rst => rst,
|
|
rd_addr => xmem_ctrl_in.rd_addr,
|
|
rd_en => xmem_rd_en,
|
|
data_out => xmem_data_out,
|
|
data_out_valid => xmem_data_out_valid,
|
|
wr_addr => xmem_ctrl_in.wr_addr,
|
|
wr_en => xmem_ctrl_in.wr_en,
|
|
data_in => xmem_ctrl_in.data_in
|
|
);
|
|
|
|
xmem_rd_en <= '1' when xmem_rd_polling = '0' and xmem_ctrl_in.rd_en = '1' else '0';
|
|
|
|
xmem_ctrl_out.data_out <= xmem_data_out;
|
|
xmem_ctrl_out.data_out_valid <= xmem_data_out_valid;
|
|
|
|
-------------------------------
|
|
-- YMEM CONTROLLER
|
|
-------------------------------
|
|
inst_ymem_ctrl : mem_control
|
|
generic map(
|
|
mem_type => Y_MEM
|
|
)
|
|
port map(
|
|
clk => clk,
|
|
rst => rst,
|
|
rd_addr => ymem_ctrl_in.rd_addr,
|
|
rd_en => ymem_rd_en,
|
|
data_out => ymem_data_out,
|
|
data_out_valid => ymem_data_out_valid,
|
|
wr_addr => ymem_ctrl_in.wr_addr,
|
|
wr_en => ymem_ctrl_in.wr_en,
|
|
data_in => ymem_ctrl_in.data_in
|
|
);
|
|
|
|
ymem_rd_en <= '1' when ymem_rd_polling = '0' and ymem_ctrl_in.rd_en = '1' else '0';
|
|
|
|
ymem_ctrl_out.data_out <= ymem_data_out;
|
|
ymem_ctrl_out.data_out_valid <= ymem_data_out_valid;
|
|
|
|
mem_stall_control: process(clk) is
|
|
begin
|
|
if rising_edge(clk) then
|
|
if rst = '1' then
|
|
xmem_rd_polling <= '0';
|
|
ymem_rd_polling <= '0';
|
|
else
|
|
if xmem_rd_en = '1' then
|
|
xmem_rd_polling <= '1';
|
|
end if;
|
|
|
|
if xmem_data_out_valid = '1' then
|
|
xmem_rd_polling <= '0';
|
|
end if;
|
|
|
|
if ymem_rd_en = '1' then
|
|
ymem_rd_polling <= '1';
|
|
end if;
|
|
|
|
if ymem_data_out_valid = '1' then
|
|
ymem_rd_polling <= '0';
|
|
end if;
|
|
|
|
end if;
|
|
end if;
|
|
end process;
|
|
end architecture;
|
|
|