Add first version.
This commit is contained in:
83
src/PipelineController.vhd
Normal file
83
src/PipelineController.vhd
Normal 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
60
src/PipelineRegister.vhd
Normal 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
3
src/Pipeline_pb.ucf
Normal 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
118
src/Pipeline_pb.vhd
Normal 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;
|
Reference in New Issue
Block a user