diff --git a/docs/PipelineController.md b/docs/PipelineController.md
index 1b91e1d..73ce3cb 100644
--- a/docs/PipelineController.md
+++ b/docs/PipelineController.md
@@ -4,23 +4,73 @@
## Diagram

+## Description
+
+- Name: **Pipeline Controller**
+- Version: 0.0.1
+- Author: _Maximilian Passarello ([Blog](mpassarello.de))_
+- License: [MIT](LICENSE)
+
+The Pipeline Controller provides an easy way to construct a pipeline
+with AXI-Like handshaking at the input and output of the pipeline.
+
+### Core functions
+
+- **Data flow control**: Data flow control is implemented via handshaking at the input and output ports.
+- **Validity control**: The controller keeps the validity of the data in the individual pipeline stages under control.
+- **Adjustability**: The pipeline controller can be customized via the generics.
+
+### Generics
+
+Use the generic `G_PipelineStages` to set how deep the pipeline is.
+This depth contains all the registers associated with the pipeline.
+For example, for an _I_FF ⇨ Combinatorics ⇨ O_FF_ construction, the generic must be set to **2**.
+
+The active level of the reset input can also be set.
+
+### Clock Enable
+
+The `I_CE` port is active high and, when deactivated,
+effectively switches on the acceptance or output of data via handshaking in addition to the pipeline.
+
+### Reset
+
+A reset is explicitly **not** necessary on the pipeline registers.
+The validity of the data is kept under control via the pipeline controller
+and only this requires a dedicated reset if necessary.
+
+### Pipeline control
+
+You must connect the `O_Enable` port to the CE input of the corresponding pipeline registers.
+This is used to activate or deactivate the pipeline in full or via CE deactivated state.
+
+### AXI like Handshaking
+
+- **Input**: The `O_Ready` (active high) port is used to signal to the data-supplying component that data should be accepted.
+If it switches on `I_Valid` (active high), this in turn signals that data is ready to be accepted at its output.
+If both ports are active at the same time, the transfer is executed.
+- **Output**: The process runs analogously at the pipeline output.
+
+## History
+- 0.0.1 (2024-03-24) Initial version
+
## Generics
-| Generic name | Type | Value | Description |
-| ---------------- | --------- | ----- | ------------------------- |
-| G_PipelineStages | integer | 3 | Number of pipeline stages |
-| G_ResetActiveAt | std_logic | '1' | Reset active at: |
+| Generic name | Type | Value | Description |
+| ---------------- | --------- | ----- | ----------------------------------------------------------------- |
+| G_PipelineStages | integer | 3 | Number of pipeline stages (FFs in the pipeline including I/O FFs) |
+| G_ResetActiveAt | std_logic | '1' | Reset active at this level |
## Ports
-| Port name | Direction | Type | Description |
-| -------------------- | --------- | ----------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
-| I_CLK | in | std_logic | Clock signal; **Rising edge** triggered |
-| I_RST | in | std_logic | Reset signal; Active at `G_ResetActiveAt` |
-| I_CE | in | std_logic | Chip enable; Active high |
-| O_Enable | out | std_logic | Pipeline enable; Active high when pipeline can accept data and `I_CE` is high.
**Note:** Connect to `I_Enable` of the registers to be controlled by this controller. |
-| Input-AXI-Handshake | in | Virtual bus | Input AXI like Handshake |
-| Output-AXI-Handshake | out | Virtual bus | Output AXI like Handshake |
+| Port name | Direction | Type | Description |
+| -------------------- | --------- | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| I_CLK | in | std_logic | Clock signal; **Rising edge** triggered |
+| I_RST | in | std_logic | Reset signal; Active at `G_ResetActiveAt` |
+| I_CE | in | std_logic | Chip enable; Active high |
+| O_Enable | out | std_logic | 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`. |
+| Input-AXI-Handshake | in | Virtual bus | Input AXI like Handshake |
+| Output-AXI-Handshake | out | Virtual bus | Output AXI like Handshake |
### Virtual Buses
@@ -45,9 +95,12 @@
| C_Ready | std_logic | Ready signal for the pipeline controller to indicate that the pipeline can accept data;
mapped to `O_Enable` and `O_Ready` ports. |
## Processes
-- P_Flags: ( R_Valid, I_Ready )
+- P_ExternalFlags: ( R_Valid, C_Ready, I_CE )
- **Description**
- Produce the `C_Ready` signal for the pipeline controller, controlling the data flow in the pipeline.
+ 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_InternalFlags: ( R_Valid, I_Ready )
+ - **Description**
+ 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_ValidPipeline: ( I_CLK )
- **Description**
- Shift the pipeline stages with `R_Valid` signal as placeholder to control the pipeline stages.
+ Shift the pipeline stages with `R_Valid` signal as placeholder to control the validity of the data in the individual pipeline stages.
diff --git a/docs/PipelineRegister.md b/docs/PipelineRegister.md
index ab6f625..8fe020b 100644
--- a/docs/PipelineRegister.md
+++ b/docs/PipelineRegister.md
@@ -4,13 +4,47 @@
## Diagram

+## Description
+
+- Name: **Pipeline Register**
+- Version: 0.0.1
+- Author: _Maximilian Passarello ([Blog](mpassarello.de))_
+- License: [MIT](LICENSE)
+
+The pipeline register provides a simple way to pipeline combinatorial logic using the **register rebalancing** of the synthesis.
+
+### Core functions
+
+- **Register rebalancing**: The generic `G_RegisterBalancing` can be used
+to precisely configure how register rebalancing works.
+- **Number of registers**: The pipeline register instantiates a number of FFs corresponding
+to the generic `G_PipelineStages`.
+- **Data width**: The data width of the registers
+and the input/output vectors (std_logic_vector) is configured via the generic `G_Width`.
+
+### Register rebalancing
+
+The generic `G_RegisterBalancing` can be used to set the **Register Rebalancing** of the Xilinx ISE.
+The possible variants are
+- `no`: Deactivates the rebalancing register.
+- `yes`: Activates the rebalancing register in both directions (forwards and backwards).
+- `forward`: Activates the rebalancing register in the forward direction.
+This causes the synthesis to shift and reduce a **multiple** of FFs at the inputs of a LUT
+to a **single** FF forward at the output of a LUT.
+- `backward`: Activates the rebalancing register in the backward direction.
+This causes the synthesis to shift and duplicate a **single** FF at the output of a LUT
+backwards to a **multiple** of FFs at the input of a LUT.
+
+## History
+- 0.0.1 (2024-03-24) Initial version
+
## Generics
-| Generic name | Type | Value | Description |
-| ------------------- | ------- | ----- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
-| G_PipelineStages | integer | 3 | Number of pipeline stages |
-| G_Width | integer | 32 | Data width |
-| G_RegisterBalancing | string | "yes" | Register balancing attribute
- "no" : **Disable** register balancing,
- "yes": **Enable** register balancing in both directions,
- "forward": **Enable** and moves a set of FFs at the inputs of a LUT to a single FF at its output,
- "backward": **Enable** and moves a single FF at the output of a LUT to a set of FFs at its inputs. |
+| Generic name | Type | Value | Description |
+| ------------------- | ------- | ----- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
+| G_PipelineStages | integer | 3 | Number of pipeline stages (Correspondent to the number of registers in the pipeline) |
+| G_Width | integer | 32 | Data width |
+| G_RegisterBalancing | string | "yes" | 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. |
## Ports
@@ -36,4 +70,7 @@
## Processes
- P_PipelineRegister: ( I_CLK )
- **Description**
- Pipeline register I_Data -> R_Data(0) -> R_Data(1) -> ... -> R_Data(G_PipelineStages - 1) -> O_Data
+ 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_ForwardData: ( R_Data )
+ - **Description**
+ 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**
diff --git a/src/PipelineController.vhd b/src/PipelineController.vhd
index f262543..6efc2d7 100644
--- a/src/PipelineController.vhd
+++ b/src/PipelineController.vhd
@@ -1,3 +1,53 @@
+----------------------------------------------------------------------------------
+--@ - Name: **Pipeline Controller**
+--@ - Version: 0.0.1
+--@ - Author: _Maximilian Passarello ([Blog](mpassarello.de))_
+--@ - License: [MIT](LICENSE)
+--@
+--@ The Pipeline Controller provides an easy way to construct a pipeline
+--@ with AXI-Like handshaking at the input and output of the pipeline.
+--@
+--@ ### Core functions
+--@
+--@ - **Data flow control**: Data flow control is implemented via handshaking at the input and output ports.
+--@ - **Validity control**: The controller keeps the validity of the data in the individual pipeline stages under control.
+--@ - **Adjustability**: The pipeline controller can be customized via the generics.
+--@
+--@ ### Generics
+--@
+--@ Use the generic `G_PipelineStages` to set how deep the pipeline is.
+--@ This depth contains all the registers associated with the pipeline.
+--@ For example, for an _I_FF ⇨ Combinatorics ⇨ O_FF_ construction, the generic must be set to **2**.
+--@
+--@ The active level of the reset input can also be set.
+--@
+--@ ### Clock Enable
+--@
+--@ The `I_CE` port is active high and, when deactivated,
+--@ effectively switches on the acceptance or output of data via handshaking in addition to the pipeline.
+--@
+--@ ### Reset
+--@
+--@ A reset is explicitly **not** necessary on the pipeline registers.
+--@ The validity of the data is kept under control via the pipeline controller
+--@ and only this requires a dedicated reset if necessary.
+--@
+--@ ### Pipeline control
+--@
+--@ You must connect the `O_Enable` port to the CE input of the corresponding pipeline registers.
+--@ This is used to activate or deactivate the pipeline in full or via CE deactivated state.
+--@
+--@ ### AXI like Handshaking
+--@
+--@ - **Input**: The `O_Ready` (active high) port is used to signal to the data-supplying component that data should be accepted.
+--@ If it switches on `I_Valid` (active high), this in turn signals that data is ready to be accepted at its output.
+--@ If both ports are active at the same time, the transfer is executed.
+--@ - **Output**: The process runs analogously at the pipeline output.
+--@
+--@ ## History
+--@ - 0.0.1 (2024-03-24) Initial version
+----------------------------------------------------------------------------------
+
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
@@ -5,9 +55,9 @@ use ieee.math_real.all;
entity PipelineController is
generic (
- --@ Number of pipeline stages
+ --@ Number of pipeline stages (FFs in the pipeline including I/O FFs)
G_PipelineStages : integer := 3;
- --@ Reset active at:
+ --@ Reset active at this level
G_ResetActiveAt : std_logic := '1'
);
port (
@@ -18,7 +68,7 @@ entity PipelineController is
--@ Chip enable; Active high
I_CE : in std_logic;
--@ Pipeline enable; Active high when pipeline can accept data and `I_CE` is high.
- --@ **Note:** Connect to `I_Enable` of the registers to be controlled by this controller.
+ --@ **Note:** Connect `CE` of the registers to be controlled by this controller to `O_Enable`.
O_Enable : out std_logic;
--@ @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.
@@ -43,14 +93,24 @@ architecture RTL of PipelineController is
signal C_Ready : std_logic := '1';
begin
- O_Valid <= R_Valid(R_Valid'high);
+ --@ 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);
- O_Enable <= C_Ready and I_CE;
- O_Ready <= C_Ready and I_CE;
+ O_Enable <= C_Ready and I_CE;
+ O_Ready <= C_Ready and I_CE;
+ end process;
--@ Produce the `C_Ready` signal for the pipeline controller,
- --@ controlling the data flow in the pipeline.
- P_Flags : process (R_Valid, I_Ready)
+ --@ 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.
@@ -67,7 +127,8 @@ begin
end if;
end process;
- --@ Shift the pipeline stages with `R_Valid` signal as placeholder to control the pipeline stages.
+ --@ 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
diff --git a/src/PipelineRegister.vhd b/src/PipelineRegister.vhd
index 49ad026..d2d5403 100644
--- a/src/PipelineRegister.vhd
+++ b/src/PipelineRegister.vhd
@@ -1,3 +1,36 @@
+----------------------------------------------------------------------------------
+--@ - Name: **Pipeline Register**
+--@ - Version: 0.0.1
+--@ - Author: _Maximilian Passarello ([Blog](mpassarello.de))_
+--@ - License: [MIT](LICENSE)
+--@
+--@ The pipeline register provides a simple way to pipeline combinatorial logic using the **register rebalancing** of the synthesis.
+--@
+--@ ### Core functions
+--@
+--@ - **Register rebalancing**: The generic `G_RegisterBalancing` can be used
+--@ to precisely configure how register rebalancing works.
+--@ - **Number of registers**: The pipeline register instantiates a number of FFs corresponding
+--@ to the generic `G_PipelineStages`.
+--@ - **Data width**: The data width of the registers
+--@ and the input/output vectors (std_logic_vector) is configured via the generic `G_Width`.
+--@
+--@ ### Register rebalancing
+--@
+--@ The generic `G_RegisterBalancing` can be used to set the **Register Rebalancing** of the Xilinx ISE.
+--@ The possible variants are
+--@ - `no`: Deactivates the rebalancing register.
+--@ - `yes`: Activates the rebalancing register in both directions (forwards and backwards).
+--@ - `forward`: Activates the rebalancing register in the forward direction.
+--@ This causes the synthesis to shift and reduce a **multiple** of FFs at the inputs of a LUT
+--@ to a **single** FF forward at the output of a LUT.
+--@ - `backward`: Activates the rebalancing register in the backward direction.
+--@ This causes the synthesis to shift and duplicate a **single** FF at the output of a LUT
+--@ backwards to a **multiple** of FFs at the input of a LUT.
+--@
+--@ ## History
+--@ - 0.0.1 (2024-03-24) Initial version
+----------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
@@ -5,15 +38,17 @@ use ieee.math_real.all;
entity PipelineRegister is
generic (
- --@ Number of pipeline stages
+ --@ Number of pipeline stages (Correspondent to the number of registers in the pipeline)
G_PipelineStages : integer := 3;
--@ Data width
G_Width : integer := 32;
--@ Register balancing attribute
- --@ - "no" : **Disable** register balancing,
- --@ - "yes": **Enable** register balancing in both directions,
- --@ - "forward": **Enable** and moves a set of FFs at the inputs of a LUT to a single FF at its output,
- --@ - "backward": **Enable** and moves a single FF at the output of a LUT to a set of FFs at its inputs.
+ --@ - `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 (
@@ -39,15 +74,18 @@ architecture RTL of PipelineRegister is
attribute register_balancing of R_Data : signal is G_RegisterBalancing;
begin
- --@ Pipeline register I_Data -> R_Data(0) -> R_Data(1) -> ... -> R_Data(G_PipelineStages - 1) -> O_Data
+ --@ 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;
@@ -55,6 +93,11 @@ begin
end if;
end process;
- O_Data <= R_Data(G_PipelineStages - 1);
+ --@ 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 architecture RTL;
\ No newline at end of file
diff --git a/tests/Pipeline_tb.vhd b/tests/Pipeline_tb.vhd
index 50f35ca..7587962 100644
--- a/tests/Pipeline_tb.vhd
+++ b/tests/Pipeline_tb.vhd
@@ -1,21 +1,29 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
+use ieee.math_real.all;
entity Pipeline_tb is
-- The testbench does not require any ports
end entity Pipeline_tb;
architecture behavior of Pipeline_tb is
+ shared variable seed1 : integer := 483;
+ shared variable seed2 : integer := 847;
+ impure function rand_int(min_val, max_val : integer) return integer is
+ variable r : real;
+ begin
+ uniform(seed1, seed2, r);
+ return integer(
+ round(r * real(max_val - min_val + 1) + real(min_val) - 0.5));
+ end function;
+
-- Clock signal period
constant period : time := 20 ns;
-- Adjustable wait times
- constant write_delay : natural := 0; -- Wait time between write operations in clock cycles
- constant read_delay : natural := 0; -- Wait time between read operations in clock cycles
-
- -- Adjustable number of data values to be written
- constant writes : natural := 100;
+ constant write_delay : natural := 10; -- Maximal wait time between write operations in clock cycles
+ constant read_delay : natural := 10; -- Maximal wait time between read operations in clock cycles
-- Setting constants for the FIFO to be tested
constant K_Width : integer := 32; -- Data width of the FIFO
@@ -25,22 +33,18 @@ architecture behavior of Pipeline_tb is
-- Testbench signals
signal CLK : std_logic := '0';
signal RST : std_logic := '1';
+ signal CE : std_logic := '1';
- signal I_WriteCE : std_logic := '0';
- signal I_Data : std_logic_vector(K_Width - 1 downto 0) := (others => 'U');
- signal I_Valid : std_logic := '0';
- signal O_Ready : std_logic;
+ signal I_Data : std_logic_vector(K_Width - 1 downto 0) := (others => 'U');
+ signal I_Valid : std_logic := '0';
+ signal O_Ready : std_logic;
- signal I_ReadCE : std_logic := '0';
- signal O_Data : std_logic_vector(K_Width - 1 downto 0);
- signal O_Valid : std_logic;
- signal I_Ready : std_logic := '0';
-
- signal CE : std_logic := '1';
+ signal O_Data : std_logic_vector(K_Width - 1 downto 0) := (others => 'U');
+ signal O_Valid : std_logic;
+ signal I_Ready : std_logic := '0';
signal PipelineEnable : std_logic;
begin
- CE <= I_WriteCE or I_ReadCE;
uut0 : entity work.PipelineController
generic map(
@@ -72,61 +76,79 @@ begin
);
-- Clock process
- clocking : process
+ Clocking : process
begin
while true loop
CLK <= '0';
- wait for period / 2;
+ wait for (period / 2);
CLK <= '1';
- wait for period / 2;
+ wait for (period / 2);
end loop;
end process;
- -- Write process adapted for the falling edge of the clock signal
- write_process : process
- begin
- wait for 100 ns; -- Initial wait time for reset and FIFO initialization
- RST <= '0';
- wait for period; -- Wait an additional clock cycle after reset
- I_WriteCE <= '1';
- wait until falling_edge(CLK);
- for i in 0 to writes loop -- Writing loop for data values
- if O_Ready = '0' then
- wait on O_Ready until O_Ready = '1';
- wait until falling_edge(CLK);
- end if;
+ -- Clock enable process
+ -- This process is used to enable the clock signal for a certain amount of time
+ -- and only for the Pipeline Controller to check if the dataflow is working correctly.
+ -- ClockEnable : process
+ -- begin
+ -- while true loop
+ -- CE <= '1';
+ -- wait for 1000 ns;
+ -- CE <= '0';
+ -- wait for 500 ns;
+ -- end loop;
+ -- end process;
- I_Data <= std_logic_vector(to_unsigned(i, K_Width)); -- Data to be written
- I_Valid <= '1';
- wait until falling_edge(CLK);
- I_Valid <= '0'; -- Reset 'valid' after writing
- for j in 1 to write_delay loop
- wait until falling_edge(CLK); -- Wait based on the set wait time
- end loop;
- end loop;
- I_WriteCE <= '0'; -- Deactivate write signal after writing
- wait;
- end process;
+ -- 100 ns Reset
+ RST <= '1', '0' after 100 ns;
- -- Read process adapted for the falling edge of the clock signal
- read_process : process
+ -- Write process
+ Write : process (CLK)
+ variable delay : integer := 0;
+ variable i : integer := 1;
begin
- wait for 110 ns; -- Delay to start writing
- I_ReadCE <= '1';
- while true loop
- if O_Valid = '1' and I_Ready = '0' then
- I_Ready <= '1'; -- Signal readiness to read
- wait until falling_edge(CLK);
- if read_delay /= 0 then
- I_Ready <= '0'; -- Reset the signal after reading
- end if;
- for j in 1 to read_delay loop
- wait until falling_edge(CLK); -- Wait based on the set wait time
- end loop;
+ if rising_edge(CLK) then
+ if RST = '1' then
+ I_Valid <= '0';
+ delay := write_delay;
+ i := 1;
+ I_Data <= (others => 'U');
else
- wait until falling_edge(CLK); -- Synchronize with the clock when not ready to read
+ if O_Ready = '1' and delay = 0 then
+ I_Data <= std_logic_vector(to_unsigned(i, K_Width)); -- Data to be written
+ I_Valid <= '1';
+ i := i + 1;
+ delay := rand_int(1, write_delay);
+ elsif O_Ready = '1' and I_Valid = '1' then
+ I_Valid <= '0';
+ end if;
+ if delay /= 0 then
+ delay := delay - 1;
+ end if;
end if;
- end loop;
+ end if;
+ end process;
+
+ -- Read process
+ Read : process (CLK)
+ variable delay : integer := 0;
+ begin
+ if rising_edge(CLK) then
+ if RST = '1' then
+ I_Ready <= '0';
+ delay := read_delay;
+ else
+ if O_Valid = '1' and delay = 0 then
+ I_Ready <= '1'; -- Signal readiness to read
+ delay := rand_int(1, read_delay);
+ elsif O_Valid = '1' and I_Ready = '1' then
+ I_Ready <= '0';
+ end if;
+ if delay /= 0 then
+ delay := delay - 1;
+ end if;
+ end if;
+ end if;
end process;
end architecture behavior;
diff --git a/tests/Pipeline_tb.wcfg b/tests/Pipeline_tb.wcfg
index 99c7119..327c10b 100644
--- a/tests/Pipeline_tb.wcfg
+++ b/tests/Pipeline_tb.wcfg
@@ -13,7 +13,7 @@
-
+
clk
clk
@@ -22,6 +22,10 @@
rst
rst
+
+ ce
+ ce
+
i_data[31:0]
i_data[31:0]
@@ -47,6 +51,8 @@
i_ready
i_ready
+ true
+ #00ff00
Pipeline
@@ -54,6 +60,10 @@
128 128 255
230 230 230
+
+ pipelineenable
+ pipelineenable
+
Controller
label
@@ -69,10 +79,27 @@
o_ready
o_ready
-
- r_valid[2:0]
- r_valid[2:0]
- BINARYRADIX
+
+ r_valid[0:2]
+ label
+
+ [0]
+ r_valid[0]
+ true
+ #ff00ff
+
+
+ [1]
+ r_valid[1]
+ true
+ #ff00ff
+
+
+ [2]
+ r_valid[2]
+ true
+ #ff00ff
+
o_valid
@@ -113,16 +140,22 @@
[0]
r_data[0]
UNSIGNEDDECRADIX
+ true
+ #ff00ff
[1]
r_data[1]
UNSIGNEDDECRADIX
+ true
+ #ff00ff
[2]
r_data[2]
UNSIGNEDDECRADIX
+ true
+ #ff00ff