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:
110
src/ROB.vhd
Normal file
110
src/ROB.vhd
Normal 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;
|
Reference in New Issue
Block a user