diff --git a/src/ROB.vhd b/src/ROB.vhd new file mode 100644 index 0000000..3df3ff9 --- /dev/null +++ b/src/ROB.vhd @@ -0,0 +1,110 @@ +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;