diff --git a/.gitignore b/.gitignore
index fd6e778..acabbfd 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,3 @@
-build/working
\ No newline at end of file
+build/working
+.locale/
+vhdl_ls.toml
diff --git a/src/PipelineController.vhd b/src/PipelineController.vhd
index 23c880e..3d2ade3 100644
--- a/src/PipelineController.vhd
+++ b/src/PipelineController.vhd
@@ -48,7 +48,6 @@
--@ - 0.0.1 (2024-03-24) Initial version
--@ - 0.0.2 (2024-04-13) Enhanced the validity update logic to correctly handle configurations with a single pipeline stage
----------------------------------------------------------------------------------
-
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
@@ -57,31 +56,34 @@ use ieee.math_real.all;
entity PipelineController is
generic (
--@ Number of pipeline stages (FFs in the pipeline including I/O FFs)
- G_PipelineStages : integer := 3;
+ G_PipelineStages : integer := 3;
--@ Reset active at this level
- G_ResetActiveAt : std_logic := '1'
+ G_ResetActiveAt : std_logic := '1'
);
port (
--@ Clock signal; **Rising edge** triggered
- I_CLK : in std_logic;
+ I_CLK : in std_logic := '0';
--@ Reset signal; Active at `G_ResetActiveAt`
- I_RST : in std_logic;
+ I_RST : in std_logic := '0';
--@ Chip enable; Active high
- I_CE : in std_logic;
+ I_CE : in std_logic := '1';
+
--@ Pipeline enable; Active high when pipeline can accept data and `I_CE` is high.
--@ **Note:** Connect `CE` of the registers to be controlled by this controller to `O_Enable`.
- O_Enable : out std_logic;
+ O_Enable : out std_logic := '0';
+
--@ @virtualbus Input-AXI-Handshake @dir in Input AXI like Handshake
--@ Valid data flag; indicates that the data on `I_Data` of the connected registers is valid.
- I_Valid : in std_logic;
+ I_Valid : in std_logic := '0';
--@ Ready flag; indicates that the connected registers is ready to accept data.
- O_Ready : out std_logic;
+ O_Ready : out std_logic := '0';
--@ @end
+
--@ @virtualbus Output-AXI-Handshake @dir out Output AXI like Handshake
--@ Valid data flag; indicates that the data on `O_Data` of the connected registers is valid.
- O_Valid : out std_logic;
+ O_Valid : out std_logic := '0';
--@ Ready flag; indicates that the external component is ready to accept data.
- I_Ready : in std_logic
+ I_Ready : in std_logic := '0'
--@ @end
);
end entity PipelineController;
@@ -91,59 +93,75 @@ architecture RTL of PipelineController is
signal R_Valid : std_logic_vector(G_PipelineStages - 1 downto 0) := (others => '0');
--@ Ready signal for the pipeline controller to indicate that the pipeline can accept data;
--@ mapped to `O_Enable` and `O_Ready` ports.
- signal C_Ready : std_logic := '1';
+ signal C_Ready : std_logic := '1';
begin
- --@ Produce the `O_Valid`, `O_Enable`, and `O_Ready` signals for the pipeline controller.
- --@ - `O_Enable`, and `O_Ready` are **and** combined from the `C_Ready` and `I_CE` signals.
- --@ - `O_Valid` is the last bit of the `R_Valid` signal
- --@ and represents the validity of the data in the last stage of the pipeline.
- P_ExternalFlags : process (R_Valid, C_Ready, I_CE)
- begin
- O_Valid <= R_Valid(R_Valid'high);
+ GEN_ForwardExternalFlags : if G_PipelineStages = 0 generate
+ --@ If no pipeline stages are defined, the flags are directly connected to the input and output ports.
+ P_ExternalFlags : process (I_CE, I_Valid, I_Ready)
+ begin
+ O_Valid <= I_Valid;
+ O_Enable <= I_Ready and I_CE;
+ O_Ready <= I_Ready and I_CE;
+ end process;
+ end generate;
- O_Enable <= C_Ready and I_CE;
- O_Ready <= C_Ready and I_CE;
- end process;
+ GEN_ExternalFlags : if G_PipelineStages > 0 generate
+ --@ Produce the `O_Valid`, `O_Enable`, and `O_Ready` signals for the pipeline controller.
+ --@ - `O_Enable`, and `O_Ready` are **and** combined from the `C_Ready` and `I_CE` signals.
+ --@ - `O_Valid` is the last bit of the `R_Valid` signal
+ --@ and represents the validity of the data in the last stage of the pipeline.
+ P_ExternalFlags : process (R_Valid, C_Ready, I_CE)
+ begin
+ O_Valid <= R_Valid(R_Valid'high);
- --@ Produce the `C_Ready` signal for the pipeline controller,
- --@ controlling the data flow in the pipeline.
- --@ `C_Ready` is asserted when the data is available in the last stage of the pipeline
- --@ **and** the external component is ready to accept data
- --@ **or** when no data is available in the last stage of the pipeline.
- P_InternalFlags : process (R_Valid, I_Ready)
- begin
- if R_Valid(R_Valid'high) = '1' then
- -- Data is available in the last stage of the pipeline.
- if I_Ready = '1' then
- -- O_Data is accepted from the external component.
- C_Ready <= '1';
+ O_Enable <= C_Ready and I_CE;
+ O_Ready <= C_Ready and I_CE;
+ end process;
+ end generate;
+
+ GEN_InternalFlags : if G_PipelineStages > 0 generate
+ --@ Produce the `C_Ready` signal for the pipeline controller,
+ --@ controlling the data flow in the pipeline.
+ --@ `C_Ready` is asserted when the data is available in the last stage of the pipeline
+ --@ **and** the external component is ready to accept data
+ --@ **or** when no data is available in the last stage of the pipeline.
+ P_InternalFlags : process (R_Valid, I_Ready)
+ begin
+ if R_Valid(R_Valid'high) = '1' then
+ -- Data is available in the last stage of the pipeline.
+ if I_Ready = '1' then
+ -- O_Data is accepted from the external component.
+ C_Ready <= '1';
+ else
+ -- O_Data is not accepted from the external component.
+ C_Ready <= '0';
+ end if;
else
- -- O_Data is not accepted from the external component.
- C_Ready <= '0';
+ -- No data available in the last stage of the pipeline.
+ C_Ready <= '1';
end if;
- else
- -- No data available in the last stage of the pipeline.
- C_Ready <= '1';
- end if;
- end process;
+ end process;
+ end generate;
- --@ Shift the pipeline stages with `R_Valid` signal as placeholder to control
- --@ the validity of the data in the individual pipeline stages.
- P_ValidPipeline : process (I_CLK)
- begin
- if rising_edge(I_CLK) then
- if I_RST = G_ResetActiveAt then
- R_Valid <= (others => '0');
- elsif I_CE = '1' then
- if C_Ready = '1' then
- if G_PipelineStages = 1 then
- R_Valid(0) <= I_Valid;
- else
- R_Valid <= R_Valid(R_Valid'high - 1 downto R_Valid'low) & I_Valid;
+ GEN_ValidPipe : if G_PipelineStages > 0 generate
+ --@ Shift the pipeline stages with `R_Valid` signal as placeholder to control
+ --@ the validity of the data in the individual pipeline stages.
+ P_ValidPipeline : process (I_CLK)
+ begin
+ if rising_edge(I_CLK) then
+ if I_RST = G_ResetActiveAt then
+ R_Valid <= (others => '0');
+ elsif I_CE = '1' then
+ if C_Ready = '1' then
+ if G_PipelineStages = 1 then
+ R_Valid(0) <= I_Valid;
+ else
+ R_Valid <= R_Valid(R_Valid'high - 1 downto R_Valid'low) & I_Valid;
+ end if;
end if;
end if;
end if;
- end if;
- end process;
-end architecture RTL;
\ No newline at end of file
+ end process;
+ end generate;
+end architecture RTL;
diff --git a/src/PipelineRegister.vhd b/src/PipelineRegister.vhd
index d2d5403..b09c352 100644
--- a/src/PipelineRegister.vhd
+++ b/src/PipelineRegister.vhd
@@ -39,9 +39,9 @@ use ieee.math_real.all;
entity PipelineRegister is
generic (
--@ Number of pipeline stages (Correspondent to the number of registers in the pipeline)
- G_PipelineStages : integer := 3;
+ G_PipelineStages : integer := 3;
--@ Data width
- G_Width : integer := 32;
+ G_Width : integer := 32;
--@ Register balancing attribute
--@ - `no` : **Disable** register balancing,
--@ - `yes`: **Enable** register balancing in both directions,
@@ -49,17 +49,17 @@ entity PipelineRegister is
--@ 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"
+ G_RegisterBalancing : string := "yes"
);
port (
- --@ Clock signal; **Rising edge** triggered
- I_CLK : in std_logic;
+ --@ Clock; (**Rising edge** triggered)
+ I_CLK : in std_logic := '0';
--@ Enable input from **Pipeline Controller**
- I_Enable : in std_logic;
+ I_Enable : in std_logic := '0';
--@ Data input
- I_Data : in std_logic_vector(G_Width - 1 downto 0);
+ I_Data : in std_logic_vector(G_Width - 1 downto 0) := (others => '0');
--@ Data output
- O_Data : out std_logic_vector(G_Width - 1 downto 0) := (others => '0')
+ O_Data : out std_logic_vector(G_Width - 1 downto 0) := (others => '0')
);
end entity PipelineRegister;
@@ -69,35 +69,50 @@ architecture RTL of PipelineRegister is
--@ Pipeline register data type; organized as an array (Stages) of std_logic_vector (Data).
type T_Data is array(0 to G_PipelineStages - 1) of std_logic_vector(G_Width - 1 downto 0);
--@ Pipeline register data signal; `G_PipelineStages` stages of `G_Width` bits.
- signal R_Data : T_Data := (others => (others => '0'));
+ signal R_Data : T_Data := (others => (others => '0'));
--@ Pipeline register balancing attribute from generic
attribute register_balancing of R_Data : signal is G_RegisterBalancing;
begin
- --@ Pipeline register and connection of the data from the input port to the first stage of the pipeline register.
- --@ **I_Data -> R_Data(0) -> R_Data(1) -> ... -> R_Data(G_PipelineStages - 1)** -> O_Data
- P_PipelineRegister : process (I_CLK)
- begin
- if rising_edge(I_CLK) then
- if I_Enable = '1' then
- for i in 0 to G_PipelineStages - 1 loop
- if i = 0 then
- --@ Input data from the input port to the first stage of the pipeline register
- R_Data(i) <= I_Data;
- else
- --@ Data from the previous stage of the pipeline register to the current stage
- R_Data(i) <= R_Data(i - 1);
- end if;
- end loop;
+ --@ Generate the pipeline registers if `G_PipelineStages` is greater than 0.
+ GEN_PipelineRegister : if G_PipelineStages > 0 generate
+ --@ Pipeline register and connection of the data from the input port to the first stage of the pipeline register.
+ --@ **I_Data -> R_Data(0) -> R_Data(1) -> ... -> R_Data(G_PipelineStages - 1)** -> O_Data
+ P_PipelineRegister : process (I_CLK)
+ begin
+ if rising_edge(I_CLK) then
+ if I_Enable = '1' then
+ for i in 0 to G_PipelineStages - 1 loop
+ if i = 0 then
+ --@ Input data from the input port to the first stage of the pipeline register
+ R_Data(i) <= I_Data;
+ else
+ --@ Data from the previous stage of the pipeline register to the current stage
+ R_Data(i) <= R_Data(i - 1);
+ end if;
+ end loop;
+ end if;
end if;
- end if;
- end process;
+ end process;
+ end generate;
- --@ Connect (combinatoric) data from the last stage of the pipeline register to the output port.
- --@ I_Data -> R_Data(0) -> R_Data(1) -> ... -> **R_Data(G_PipelineStages - 1) -> O_Data**
- P_ForwardData : process (R_Data)
- begin
- O_Data <= R_Data(G_PipelineStages - 1);
- end process;
+ --@ Generate the connection last register to the output port if `G_PipelineStages` is greater than 0.
+ GEN_ForwardRegister : if G_PipelineStages > 0 generate
+ --@ Connect (combinatoric) data from the last stage of the pipeline register to the output port.
+ --@ I_Data -> R_Data(0) -> R_Data(1) -> ... -> **R_Data(G_PipelineStages - 1) -> O_Data**
+ P_ForwardData : process (R_Data)
+ begin
+ O_Data <= R_Data(G_PipelineStages - 1);
+ end process;
+ end generate;
-end architecture RTL;
\ No newline at end of file
+ --@ Generate the connection of the input port to the output port if `G_PipelineStages` is 0.
+ GEN_ForwardData : if G_PipelineStages = 0 generate
+ --@ If `G_PipelineStages` is 0, the data from the input port is directly connected to the output port.
+ P_ForwardData : process (I_Data)
+ begin
+ O_Data <= I_Data;
+ end process;
+ end generate;
+
+end architecture RTL;