feat(rob): add reorder buffer entity with slot management

- Introduces a VHDL implementation for a reorder buffer (ROB)
- Adds generic parameters for slot depth, ID width, and data width
- Implements synchronous reset, clock enable, and data flow logic
- Improves modularity with pipeline stage instantiation
This commit is contained in:
2025-07-07 13:14:53 +00:00
parent d953462d1f
commit dce101dfdf

110
src/ROB.vhd Normal file
View File

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