Adds configurable pipeline stage module

Introduces a VHDL entity for a configurable pipeline stage with generic parameters for data widths, reset behavior, and register balancing. Implements AXI-like handshake interfaces for input and output data management. Includes support for up to four data channels with optional pipeline registers.

Facilitates modular and reusable design for pipeline processing.
This commit is contained in:
2025-04-16 17:25:17 +00:00
parent aae0a66fec
commit 87b9bf20bf

161
src/PipelineStage.vhd Normal file
View File

@@ -0,0 +1,161 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.math_real.all;
entity PipelineStage is
generic (
--@ Number of pipeline stages (FFs in the pipeline including I/O FFs)
G_PipelineStages : integer := 3;
--@ Data width
G_D0_Width : integer := 1;
--@ Data width
G_D1_Width : integer := 0;
--@ Data width
G_D2_Width : integer := 0;
--@ Data width
G_D3_Width : integer := 0;
--@ Reset active at this level
G_ResetActiveAt : std_logic := '1';
--@ Register balancing attribute
--@ - `no` : **Disable** register balancing,
--@ - `yes`: **Enable** register balancing in both directions,
--@ - `forward`: **Enable** register balancing
--@ and moves a set of FFs at the inputs of a LUT to a single FF at its output,
--@ - `backward`: **Enable** register balancing
--@ and moves a single FF at the output of a LUT to a set of FFs at its inputs.
G_RegisterBalancing : string := "yes"
);
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';
--@ Pipeline enable for additional stages; (**Synchronous**, **Active high**)
O_PipelineEnable : out std_logic := '0';
--@ @virtualbus AXI-Data-In @dir In Input interface with AXI-like handshake
--@ 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 0
I_Data_0 : in std_logic_vector(G_D0_Width - 1 downto 0) := (others => '-');
--@ Data input 1
I_Data_1 : in std_logic_vector(G_D1_Width - 1 downto 0) := (others => '-');
--@ Data input 2
I_Data_2 : in std_logic_vector(G_D2_Width - 1 downto 0) := (others => '-');
--@ Data input 3
I_Data_3 : in std_logic_vector(G_D3_Width - 1 downto 0) := (others => '-');
--@ @end
--@ @virtualbus AXI-Data-Out @dir Out Output interface with AXI-like handshake
--@ 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 0
O_Data_0 : out std_logic_vector(G_D0_Width - 1 downto 0) := (others => '-');
--@ Data output 1
O_Data_1 : out std_logic_vector(G_D1_Width - 1 downto 0) := (others => '-');
--@ Data output 2
O_Data_2 : out std_logic_vector(G_D2_Width - 1 downto 0) := (others => '-');
--@ Data output 3
O_Data_3 : out std_logic_vector(G_D3_Width - 1 downto 0) := (others => '-')
--@ @end
);
end entity PipelineStage;
architecture Rtl of PipelineStage is
signal S_PipelineEnable : std_logic := '0';
begin
--@ Forwarding the pipeline enable signal to the output port.
--@ This signal is used to control the pipeline enable signal
--@ of additional external stages.
O_PipelineEnable <= S_PipelineEnable;
--@ Pipeline controller
I_PipelineCtrl : entity work.PipelineController
generic map(
G_PipelineStages => G_PipelineStages,
G_ResetActiveAt => G_ResetActiveAt
)
port map(
I_CLK => I_CLK,
I_CE => I_CE,
I_RST => I_RST,
O_Enable => S_PipelineEnable,
I_Valid => I_Valid,
O_Ready => O_Ready,
O_Valid => O_Valid,
I_Ready => I_Ready
);
GEN_PipelineRegister_D0 : if G_D0_Width > 0 generate
--@ Pipeline register Data 0
I_PielineRegister_D0 : entity work.PipelineRegister
generic map(
G_PipelineStages => G_PipelineStages,
G_Width => G_D0_Width,
G_RegisterBalancing => G_RegisterBalancing
)
port map(
I_CLK => I_CLK,
I_Enable => S_PipelineEnable,
I_Data => I_Data_0,
O_Data => O_Data_0
);
end generate;
GEN_PipelineRegister_D1 : if G_D1_Width > 0 generate
--@ Pipeline register Data 1
I_PielineRegister_D1 : entity work.PipelineRegister
generic map(
G_PipelineStages => G_PipelineStages,
G_Width => G_D1_Width,
G_RegisterBalancing => G_RegisterBalancing
)
port map(
I_CLK => I_CLK,
I_Enable => S_PipelineEnable,
I_Data => I_Data_1,
O_Data => O_Data_1
);
end generate;
GEN_PipelineRegister_D2 : if G_D2_Width > 0 generate
--@ Pipeline register Data 2
I_PielineRegister_D2 : entity work.PipelineRegister
generic map(
G_PipelineStages => G_PipelineStages,
G_Width => G_D2_Width,
G_RegisterBalancing => G_RegisterBalancing
)
port map(
I_CLK => I_CLK,
I_Enable => S_PipelineEnable,
I_Data => I_Data_2,
O_Data => O_Data_2
);
end generate;
GEN_PipelineRegister_D3 : if G_D3_Width > 0 generate
--@ Pipeline register Data 3
I_PielineRegister_D3 : entity work.PipelineRegister
generic map(
G_PipelineStages => G_PipelineStages,
G_Width => G_D3_Width,
G_RegisterBalancing => G_RegisterBalancing
)
port map(
I_CLK => I_CLK,
I_Enable => S_PipelineEnable,
I_Data => I_Data_3,
O_Data => O_Data_3
);
end generate;
end architecture;