- 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
111 lines
3.9 KiB
VHDL
111 lines
3.9 KiB
VHDL
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;
|