Add first version.

This commit is contained in:
2024-03-24 01:31:49 +01:00
parent 9ef431c636
commit e03dc4e0c8
14 changed files with 638 additions and 69 deletions

View File

@@ -0,0 +1,83 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.math_real.all;
entity PipelineController is
generic (
--@ Number of pipeline stages
G_PipelineStages : integer := 3;
--@ Reset active at:
G_ResetActiveAt : std_logic := '1'
);
port (
--@ Clock signal; **Rising edge** triggered
I_CLK : in std_logic;
--@ Reset signal; Active at `G_ResetActiveAt`
I_RST : in std_logic;
--@ Chip enable; Active high
I_CE : in std_logic;
--@ Pipeline enable; Active high when pipeline can accept data and `I_CE` is high. <br>
--@ **Note:** Connect to `I_Enable` of the registers to be controlled by this controller.
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.
I_Valid : in std_logic;
--@ Ready flag; indicates that the connected registers is ready to accept data.
O_Ready : out std_logic;
--@ @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;
--@ Ready flag; indicates that the external component is ready to accept data.
I_Ready : in std_logic
--@ @end
);
end entity PipelineController;
architecture RTL of PipelineController is
--@ Pipeline ready signal for each stage of the pipeline to indicate that the data in pipeline is valid
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; <br>
--@ mapped to `O_Enable` and `O_Ready` ports.
signal C_Ready : std_logic := '1';
begin
O_Valid <= R_Valid(R_Valid'high);
O_Enable <= C_Ready and I_CE;
O_Ready <= C_Ready and I_CE;
--@ Produce the `C_Ready` signal for the pipeline controller,
--@ controlling the data flow in the pipeline.
P_Flags : 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
-- No data available in the last stage of the pipeline.
C_Ready <= '1';
end if;
end process;
--@ Shift the pipeline stages with `R_Valid` signal as placeholder to control the 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
R_Valid <= R_Valid(R_Valid'high - 1 downto R_Valid'low) & I_Valid;
end if;
end if;
end if;
end process;
end architecture RTL;

60
src/PipelineRegister.vhd Normal file
View File

@@ -0,0 +1,60 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.math_real.all;
entity PipelineRegister is
generic (
--@ Number of pipeline stages
G_PipelineStages : integer := 3;
--@ Data width
G_Width : integer := 32;
--@ Register balancing attribute<br>
--@ - "no" : **Disable** register balancing, <br>
--@ - "yes": **Enable** register balancing in both directions, <br>
--@ - "forward": **Enable** and moves a set of FFs at the inputs of a LUT to a single FF at its output, <br>
--@ - "backward": **Enable** 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 signal; **Rising edge** triggered
I_CLK : in std_logic;
--@ Enable input from **Pipeline Controller**
I_Enable : in std_logic;
--@ Data input
I_Data : in std_logic_vector(G_Width - 1 downto 0);
--@ Data output
O_Data : out std_logic_vector(G_Width - 1 downto 0) := (others => '0')
);
end entity PipelineRegister;
architecture RTL of PipelineRegister is
attribute register_balancing : string;
--@ 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'));
--@ Pipeline register balancing attribute from generic
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
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
R_Data(i) <= I_Data;
else
R_Data(i) <= R_Data(i - 1);
end if;
end loop;
end if;
end if;
end process;
O_Data <= R_Data(G_PipelineStages - 1);
end architecture RTL;

3
src/Pipeline_pb.ucf Normal file
View File

@@ -0,0 +1,3 @@
NET I_CLK LOC = B8;
NET I_CLK TNM_NET = CLOCK;
TIMESPEC TS_CLOCK = PERIOD CLOCK 240 MHz HIGH 50 %;

118
src/Pipeline_pb.vhd Normal file
View File

@@ -0,0 +1,118 @@
--@ Performance Benchmarking Environment
--@ This file is a wrapper for the module which is to be tested
--@ and capsulates the module with flip-flops to create a synchronous
--@ interface for the module. This is necessary to test the synthesis
--@ results of the module.
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.math_real.all;
entity Pipeline_pb is
generic (
--@ Number of pipeline stages
G_PipelineStages : integer := 3;
--@ Data width
G_Width : integer := 32;
--@ Register balancing attribute<br>
--@ - "no" : No register balancing <br>
--@ - "yes": Register balancing in both directions <br>
--@ - "forward": Moves a set of FFs at the inputs of a LUT to a single FF at its output. <br>
--@ - "backward": Moves a single FF at the output of a LUT to a set of FFs at its inputs.
G_RegisterBalancing : string := "yes"
);
port (
I_CLK : in std_logic;
I_RST : in std_logic;
I_CE : in std_logic;
I_Data : in std_logic_vector(G_Width - 1 downto 0);
I_Valid : in std_logic;
O_Ready : out std_logic;
O_Data : out std_logic_vector(G_Width - 1 downto 0);
O_Valid : out std_logic;
I_Ready : in std_logic
);
end entity Pipeline_pb;
architecture RTL of Pipeline_pb is
-- Keep attribute: Prevents the synthesis tool from removing the entity if is "true".
attribute keep : string;
-- IOB attribute: Attaches the FF to the IOB if is "true".
attribute IOB : string;
-- General Interace
signal R_RST : std_logic;
signal R_CE : std_logic;
-- Attribute
attribute keep of R_RST, R_CE : signal is "true";
attribute IOB of R_RST, R_CE : signal is "false";
-- Input Interface
signal R_DataIn : std_logic_vector(G_Width - 1 downto 0);
signal R_ValidIn : std_logic;
signal R_ReadyOut : std_logic;
-- Attribute
attribute keep of R_DataIn, R_ValidIn, R_ReadyOut : signal is "true";
attribute IOB of R_DataIn, R_ValidIn, R_ReadyOut : signal is "false";
-- Output Interface
signal R_DataOut : std_logic_vector(G_Width - 1 downto 0);
signal R_ValidOut : std_logic;
signal R_ReadyIn : std_logic;
-- Attribute
attribute keep of R_DataOut, R_ValidOut, R_ReadyIn : signal is "true";
attribute IOB of R_DataOut, R_ValidOut, R_ReadyIn : signal is "false";
signal C_PipelineEnable : std_logic;
begin
BenchmarkEnvironmentFFs : process (I_CLK)
begin
if rising_edge(I_CLK) then
-- General Interace
R_RST <= I_RST;
R_CE <= I_CE;
-- Input Interface
R_DataIn <= I_Data;
R_ValidIn <= I_Valid;
O_Ready <= R_ReadyOut;
-- Output Interface
O_Data <= R_DataOut;
O_Valid <= R_ValidOut;
R_ReadyIn <= I_Ready;
end if;
end process;
PipelineController : entity work.PipelineController
generic map(
G_PipelineStages => G_PipelineStages,
G_ResetActiveAt => '1'
)
port map(
I_CLK => I_CLK,
I_RST => R_RST,
I_CE => R_CE,
O_Enable => C_PipelineEnable,
I_Valid => R_ValidIn,
O_Ready => R_ReadyOut,
O_Valid => R_ValidOut,
I_Ready => R_ReadyIn
);
PipelineRegister : entity work.PipelineRegister
generic map(
G_PipelineStages => G_PipelineStages,
G_Width => G_Width,
G_RegisterBalancing => G_RegisterBalancing
)
port map(
I_CLK => I_CLK,
I_Enable => C_PipelineEnable,
I_Data => R_DataIn,
O_Data => R_DataOut
);
end architecture RTL;