First full HDL version

This commit is contained in:
torlus
2014-03-03 21:04:21 +00:00
parent f378ec7051
commit efc98f83bc
367 changed files with 85885 additions and 0 deletions

View 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;