library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; use ieee.math_real.all; entity ROB is generic ( G_SlotDepth : integer := 1; G_IDWidth : integer := 3; G_DataWidth : integer := 10 ); port ( --@ Clock; (**Rising edge** triggered) I_CLK : in std_logic := '0'; --@ Clock Enable; (**Synchronous**, **Active high**) I_CE : in std_logic := '1'; --@ Reset; (**Synchronous**, **Active high**) I_RST : in std_logic := '0'; --@ AXI like valid; (**Synchronous**, **Active high**) I_Valid : in std_logic := '0'; --@ AXI like ready; (**Synchronous**, **Active high**) O_Ready : out std_logic := '0'; --@ Data input I_Data : in std_logic_vector(G_DataWidth - 1 downto 0) := (others => '-'); I_ID : in std_logic_vector(G_IDWidth - 1 downto 0) := (others => '0'); --@ AXI like valid; (**Synchronous**, **Active high**) O_Valid : out std_logic := '0'; --@ AXI like ready; (**Synchronous**, **Active high**) I_Ready : in std_logic := '0'; --@ Data output O_Data : out std_logic_vector(G_DataWidth - 1 downto 0) := (others => '-'); O_ReadPointer : out std_logic_vector(G_IDWidth - 1 downto 0) := (others => '0') ); end entity ROB; architecture RTL of ROB is constant K_IDDepth : integer := 2**G_IDWidth; signal R_ReadPointer : std_logic_vector(G_IDWidth - 1 downto 0) := (others => '0'); signal C_ReadPointerEnable : std_logic := '0'; type T_Data is array (0 to K_IDDepth -1) of std_logic_vector(G_DataWidth-1 downto 0); type T_Flag is array (0 to K_IDDepth -1) of std_logic; signal R_O_Data : T_Data := (others => (others => '0')); signal C_O_Valid : T_Flag := (others => '0'); signal C_I_Ready : T_Flag := (others => '0'); signal C_I_Valid : T_Flag := (others => '0'); signal C_O_Ready : T_Flag := (others => '0'); begin P_ReadPointer : process (I_CLK) begin if rising_edge(I_CLK) then if I_RST = '1' then R_ReadPointer <= (others => '0'); elsif I_CE = '1' then if C_ReadPointerEnable = '1' then R_ReadPointer <= std_logic_vector(unsigned(R_ReadPointer) + 1); end if; end if; end if; end process; O_ReadPointer <= R_ReadPointer; C_ReadPointerEnable <= I_Ready and C_O_Valid(to_integer(unsigned(R_ReadPointer))); O_Data <= R_O_Data(to_integer(unsigned(R_ReadPointer))); O_Valid <= C_O_Valid(to_integer(unsigned(R_ReadPointer))); P_OutputReadyMux : process (R_ReadPointer, I_Ready) begin C_I_Ready <= (others => '0'); C_I_Ready(to_integer(unsigned(R_ReadPointer))) <= I_Ready; end process; GEN_SlotRegister : for i in 0 to K_IDDepth -1 generate begin INST_SlotRegister : entity work.PipelineStage generic map( G_PipelineStages => G_SlotDepth, G_D0_Width => G_DataWidth ) port map( I_CLK => I_CLK, I_CE => I_CE, I_RST => I_RST, I_Valid => C_I_Valid(i), O_Ready => C_O_Ready(i), I_Data_0 => I_Data, O_Valid => C_O_Valid(i), I_Ready => C_I_Ready(i), O_Data_0 => R_O_Data(i) ); end generate; O_Ready <= C_O_Ready(to_integer(unsigned(I_ID))); P_InputValidMux : process (I_ID, I_Valid) begin C_I_Valid <= (others => '0'); C_I_Valid(to_integer(unsigned(I_ID))) <= I_Valid; end process; end architecture;