First full HDL version
This commit is contained in:
206
FPGA_quartus_GE/DSP/src/memory_management.vhd
Normal file
206
FPGA_quartus_GE/DSP/src/memory_management.vhd
Normal file
@@ -0,0 +1,206 @@
|
||||
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;
|
||||
|
||||
Reference in New Issue
Block a user