Adds priority encoders and pipeline-based modules
Implements various priority encoder components with combinatorial logic for encoding input vectors to output codes of varying widths. Introduces pipeline-based modules for handling calculation, ROM data fetching, and scheduling operations with AXI-like handshaking interfaces. Facilitates modular and reusable design for priority encoding and data processing tasks.
This commit is contained in:
207
src/CalcPipeline.vhd
Normal file
207
src/CalcPipeline.vhd
Normal file
@@ -0,0 +1,207 @@
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
use ieee.math_real.all;
|
||||
|
||||
entity CalcPipeline is
|
||||
generic (
|
||||
--@ Width of the sprite index (Base address) register
|
||||
G_Index_Width : integer := 5;
|
||||
--@ Width of the sprite offset (Line address) register
|
||||
G_Offset_Width : integer := 8;
|
||||
--@ Width of the X position (Row) register
|
||||
G_X_Width : integer := 10;
|
||||
--@ Width of the pixel data from rom
|
||||
G_Rom_Width : integer := 8;
|
||||
--@ Width of the pixel data output
|
||||
G_Pixel_Width : integer := 8
|
||||
);
|
||||
port (
|
||||
--@ Clock; (**Rising edge** triggered)
|
||||
I_CLK : in std_logic;
|
||||
--@ Clock Enable; (**Synchronous**, **Active high**)
|
||||
I_CE : in std_logic;
|
||||
--@ Reset; (**Synchronous**, **Active high**)
|
||||
I_RST : in std_logic;
|
||||
|
||||
--@ @virtualbus Start-OP @dir In Start calculation bus
|
||||
--@ AXI like valid; (**Synchronous**, **Active high**)
|
||||
I_OP_Valid : in std_logic;
|
||||
--@ AXI like ready; (**Synchronous**, **Active high**)
|
||||
O_OP_Ready : out std_logic;
|
||||
--@ Index address
|
||||
I_OP_Index : in std_logic_vector(G_Index_Width - 1 downto 0);
|
||||
--@ Offset address
|
||||
I_OP_Offset : in std_logic_vector(G_Offset_Width - 1 downto 0);
|
||||
--@ X position of the request
|
||||
I_OP_X_Request : in std_logic_vector(G_X_Width - 1 downto 0);
|
||||
--@ X position of the sprite
|
||||
I_OP_X_Sprite : in std_logic_vector(G_X_Width - 1 downto 0);
|
||||
--@ @end
|
||||
|
||||
--@ @virtualbus Rom-Address @dir Out Request rom data bus
|
||||
--@ AXI like valid; (**Synchronous**, **Active high**)
|
||||
O_Rom_Valid : out std_logic;
|
||||
--@ AXI like ready; (**Synchronous**, **Active high**)
|
||||
I_Rom_Ready : in std_logic;
|
||||
--@ Rom address
|
||||
O_Rom_Address : out std_logic_vector(G_Index_Width + G_Offset_Width - 1 downto 0);
|
||||
--@ @end
|
||||
|
||||
--@ @virtualbus Rom-Data @dir In Rom data bus
|
||||
--@ AXI like valid; (**Synchronous**, **Active high**)
|
||||
I_Rom_Valid : in std_logic;
|
||||
--@ AXI like ready; (**Synchronous**, **Active high**)
|
||||
O_Rom_Ready : out std_logic;
|
||||
--@ Rom data
|
||||
I_Rom_Data : in std_logic_vector(G_Rom_Width - 1 downto 0);
|
||||
--@ @end
|
||||
|
||||
--@ @virtualbus Pixel-Data @dir Out Pixel data output bus
|
||||
--@ AXI like valid; (**Synchronous**, **Active high**)
|
||||
O_Pixel_Valid : out std_logic;
|
||||
--@ AXI like ready; (**Synchronous**, **Active high**)
|
||||
I_Pixel_Ready : in std_logic;
|
||||
--@ Pixel data
|
||||
O_Pixel_Data : out std_logic_vector(G_Pixel_Width - 1 downto 0)
|
||||
--@ @end
|
||||
);
|
||||
end entity CalcPipeline;
|
||||
|
||||
architecture RTL of CalcPipeline is
|
||||
signal R_Index : std_logic_vector(G_Index_Width - 1 downto 0) := (others => '0');
|
||||
signal R_Offset : std_logic_vector(G_Offset_Width - 1 downto 0) := (others => '0');
|
||||
signal R_X_Request : std_logic_vector(G_X_Width - 1 downto 0) := (others => '0');
|
||||
signal R_X_Sprite : std_logic_vector(G_X_Width - 1 downto 0) := (others => '0');
|
||||
|
||||
signal C_Address : std_logic_vector(G_Index_Width + G_Offset_Width - 1 downto 0) := (others => '0');
|
||||
signal R_Address : std_logic_vector(G_Index_Width + G_Offset_Width - 1 downto 0) := (others => '0');
|
||||
|
||||
signal I_I_Calculating_Ready : std_logic := '0';
|
||||
signal O_I_Calculating_Valid : std_logic := '0';
|
||||
|
||||
signal I_O_Calculating_Ready : std_logic := '0';
|
||||
signal O_O_Calculating_Valid : std_logic := '0';
|
||||
|
||||
signal C_X_Visible : std_logic := '0';
|
||||
signal R_X_Visible : std_logic := '0';
|
||||
|
||||
signal I_RomRequest_Valid : std_logic := '0';
|
||||
signal O_RomRequest_Ready : std_logic := '0';
|
||||
begin
|
||||
|
||||
INST_I_Calculating : entity work.PipelineStage
|
||||
generic map(
|
||||
G_PipelineStages => 1,
|
||||
G_D0_Width => G_Index_Width,
|
||||
G_D1_Width => G_Offset_Width,
|
||||
G_D2_Width => G_X_Width,
|
||||
G_D3_Width => G_X_Width
|
||||
)
|
||||
port map(
|
||||
I_CLK => I_CLK,
|
||||
I_CE => I_CE,
|
||||
I_RST => I_RST,
|
||||
I_Valid => I_OP_Valid,
|
||||
O_Ready => O_OP_Ready,
|
||||
I_Data_0 => I_OP_Index,
|
||||
I_Data_1 => I_OP_Offset,
|
||||
I_Data_2 => I_OP_X_Request,
|
||||
I_Data_3 => I_OP_X_Sprite,
|
||||
O_Valid => O_I_Calculating_Valid,
|
||||
I_Ready => I_I_Calculating_Ready,
|
||||
O_Data_0 => R_Index,
|
||||
O_Data_1 => R_Offset,
|
||||
O_Data_2 => R_X_Request,
|
||||
O_Data_3 => R_X_Sprite
|
||||
);
|
||||
|
||||
process (R_Offset, R_Index, R_X_Request, R_X_Sprite)
|
||||
variable V_Offset : unsigned(G_Offset_Width - 1 downto 0);
|
||||
variable V_X_Request : unsigned(G_X_Width - 1 downto 0);
|
||||
variable V_X_Sprite : unsigned(G_X_Width - 1 downto 0);
|
||||
variable V_RelativeOffset : unsigned(G_X_Width - 1 downto 0);
|
||||
variable V_CalculateOffset : unsigned(G_Offset_Width - 1 downto 0);
|
||||
begin
|
||||
V_Offset := unsigned(R_Offset);
|
||||
V_X_Request := unsigned(R_X_Request);
|
||||
V_X_Sprite := unsigned(R_X_Sprite);
|
||||
|
||||
V_RelativeOffset := V_X_Request - V_X_Sprite;
|
||||
V_CalculateOffset := V_Offset + V_RelativeOffset(G_Offset_Width - 1 downto 0);
|
||||
|
||||
if V_CalculateOffset > 15 then
|
||||
C_X_Visible <= '0';
|
||||
else
|
||||
C_X_Visible <= '1';
|
||||
end if;
|
||||
|
||||
C_Address <= R_Index & std_logic_vector(V_CalculateOffset);
|
||||
end process;
|
||||
|
||||
INST_O_Calculating : entity work.PipelineStage
|
||||
generic map(
|
||||
G_PipelineStages => 1,
|
||||
G_D0_Width => G_Index_Width + G_Offset_Width,
|
||||
G_D1_Width => 1
|
||||
)
|
||||
port map(
|
||||
I_CLK => I_CLK,
|
||||
I_CE => I_CE,
|
||||
I_RST => I_RST,
|
||||
I_Valid => O_I_Calculating_Valid,
|
||||
O_Ready => I_I_Calculating_Ready,
|
||||
I_Data_0 => C_Address,
|
||||
I_Data_1(0) => C_X_Visible,
|
||||
O_Valid => O_O_Calculating_Valid,
|
||||
I_Ready => I_O_Calculating_Ready,
|
||||
O_Data_0 => R_Address,
|
||||
O_Data_1(0) => R_X_Visible
|
||||
);
|
||||
|
||||
process (R_X_Visible, O_O_Calculating_Valid, O_RomRequest_Ready)
|
||||
begin
|
||||
if R_X_Visible = '0' then
|
||||
I_RomRequest_Valid <= '0';
|
||||
I_O_Calculating_Ready <= '1';
|
||||
else
|
||||
I_RomRequest_Valid <= O_O_Calculating_Valid;
|
||||
I_O_Calculating_Ready <= O_RomRequest_Ready;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
INST_RomRequest : entity work.PipelineStage
|
||||
generic map(
|
||||
G_PipelineStages => 1,
|
||||
G_D0_Width => G_Index_Width + G_Offset_Width
|
||||
)
|
||||
port map(
|
||||
I_CLK => I_CLK,
|
||||
I_CE => I_CE,
|
||||
I_RST => I_RST,
|
||||
I_Valid => I_RomRequest_Valid,
|
||||
O_Ready => O_RomRequest_Ready,
|
||||
I_Data_0 => R_Address,
|
||||
O_Valid => O_Rom_Valid,
|
||||
I_Ready => I_Rom_Ready,
|
||||
O_Data_0 => O_Rom_Address
|
||||
);
|
||||
|
||||
I_ForwardPixelData : entity work.PipelineStage
|
||||
generic map(
|
||||
G_PipelineStages => 1,
|
||||
G_D0_Width => G_Pixel_Width
|
||||
)
|
||||
port map(
|
||||
I_CLK => I_CLK,
|
||||
I_CE => I_CE,
|
||||
I_RST => I_RST,
|
||||
I_Valid => I_Rom_Valid,
|
||||
O_Ready => O_Rom_Ready,
|
||||
I_Data_0 => I_Rom_Data,
|
||||
O_Valid => O_Pixel_Valid,
|
||||
I_Ready => I_Pixel_Ready,
|
||||
O_Data_0 => O_Pixel_Data
|
||||
);
|
||||
|
||||
end architecture;
|
305
src/Rom.vhd
Normal file
305
src/Rom.vhd
Normal file
@@ -0,0 +1,305 @@
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
use ieee.math_real.all;
|
||||
use work.SpriteRom.all;
|
||||
|
||||
entity Rom is
|
||||
generic (
|
||||
--@ ROM Address Width
|
||||
G_Address_Width : integer := 13;
|
||||
--@ ROM Data Width
|
||||
G_Data_Width : integer := 8;
|
||||
--@ Port-0 In/Out Buffer Stages
|
||||
G_P0_BufferStages : integer := 1;
|
||||
--@ Port-0 Identifier Width
|
||||
G_P0_ID_Width : integer := 4;
|
||||
--@ Port-1 In/Out Buffer Stages
|
||||
G_P1_BufferStages : integer := 1;
|
||||
--@ Port-1 Identifier Width
|
||||
G_P1_ID_Width : integer := 4;
|
||||
--@ Implementation of the ROM: "Block" or "Distributed"
|
||||
G_RomType : string := "Block"
|
||||
);
|
||||
port (
|
||||
--@ Clock signal; (**Rising edge** triggered)
|
||||
I_CLK : in std_logic := '0';
|
||||
--@ Clock enable signal (**Active high**)
|
||||
I_CE : in std_logic := '1';
|
||||
|
||||
--@ @virtualbus Address-Port-0 @dir in Address Port 0
|
||||
I_P0_Address_Valid : in std_logic := '0';
|
||||
O_P0_Address_Ready : out std_logic := '0';
|
||||
I_P0_Address : in std_logic_vector(G_Address_Width - 1 downto 0) := (others => '0');
|
||||
I_P0_ID : in std_logic_vector(G_P0_ID_Width - 1 downto 0) := (others => '0');
|
||||
--@ @end
|
||||
|
||||
--@ @virtualbus Address-Port-0 @dir in Address Port 0
|
||||
I_P1_Address_Valid : in std_logic := '0';
|
||||
O_P1_Address_Ready : out std_logic := '0';
|
||||
I_P1_Address : in std_logic_vector(G_Address_Width - 1 downto 0) := (others => '0');
|
||||
I_P1_ID : in std_logic_vector(G_P1_ID_Width - 1 downto 0) := (others => '0');
|
||||
--@ @end
|
||||
|
||||
--@ @virtualbus Data-Port-0 @dir out Data Port 0
|
||||
O_P0_Data_Valid : out std_logic := '0';
|
||||
I_P0_Data_Ready : in std_logic := '0';
|
||||
O_P0_Data : out std_logic_vector(G_Data_Width - 1 downto 0) := (others => '0');
|
||||
O_P0_ID : out std_logic_vector(G_P0_ID_Width - 1 downto 0) := (others => '0');
|
||||
--@ @end
|
||||
|
||||
--@ @virtualbus Data-Port-1 @dir out Data Port 1
|
||||
O_P1_Data_Valid : out std_logic := '0';
|
||||
I_P1_Data_Ready : in std_logic := '0';
|
||||
O_P1_Data : out std_logic_vector(G_Data_Width - 1 downto 0) := (others => '0');
|
||||
O_P1_ID : out std_logic_vector(G_P1_ID_Width - 1 downto 0) := (others => '0')
|
||||
--@ @end
|
||||
);
|
||||
end entity Rom;
|
||||
|
||||
architecture Rtl of Rom is
|
||||
signal Rom : T_Rom := K_SPRITE_ROM;
|
||||
attribute ROM_STYLE : string;
|
||||
attribute ROM_STYLE of Rom : signal is G_RomType;
|
||||
|
||||
signal S_P0_InBufferEnable : std_logic := '0';
|
||||
signal S_P0_OutBufferEnable : std_logic := '0';
|
||||
|
||||
signal S_P0_Address_Valid : std_logic := '0';
|
||||
signal R_P0_Address : std_logic_vector(G_Address_Width - 1 downto 0) := (others => '0');
|
||||
signal R_P0_Address_ID : std_logic_vector(G_P0_ID_Width - 1 downto 0) := (others => '0');
|
||||
signal R_P0_Data_Valid : std_logic := '0';
|
||||
signal C_P0_Address_Ready : std_logic := '0';
|
||||
signal S_P0_Data_Ready : std_logic := '0';
|
||||
signal R_P0_Data : std_logic_vector(G_Data_Width - 1 downto 0) := (others => '0');
|
||||
signal R_P0_Data_ID : std_logic_vector(G_P0_ID_Width - 1 downto 0) := (others => '0');
|
||||
|
||||
signal S_P1_InBufferEnable : std_logic := '0';
|
||||
signal S_P1_OutBufferEnable : std_logic := '0';
|
||||
|
||||
signal S_P1_Address_Valid : std_logic := '0';
|
||||
signal R_P1_Address : std_logic_vector(G_Address_Width - 1 downto 0) := (others => '0');
|
||||
signal R_P1_Address_ID : std_logic_vector(G_P1_ID_Width - 1 downto 0) := (others => '0');
|
||||
signal R_P1_Data_Valid : std_logic := '0';
|
||||
signal C_P1_Address_Ready : std_logic := '0';
|
||||
signal S_P1_Data_Ready : std_logic := '0';
|
||||
signal R_P1_Data : std_logic_vector(G_Data_Width - 1 downto 0) := (others => '0');
|
||||
signal R_P1_Data_ID : std_logic_vector(G_P1_ID_Width - 1 downto 0) := (others => '0');
|
||||
begin
|
||||
|
||||
I_P0_InBufferCtrl : entity work.PipelineController
|
||||
generic map(
|
||||
G_PipelineStages => G_P0_BufferStages
|
||||
)
|
||||
port map(
|
||||
I_CLK => I_CLK,
|
||||
I_CE => I_CE,
|
||||
O_Enable => S_P0_InBufferEnable,
|
||||
I_Valid => I_P0_Address_Valid,
|
||||
O_Ready => O_P0_Address_Ready,
|
||||
O_Valid => S_P0_Address_Valid,
|
||||
I_Ready => C_P0_Address_Ready
|
||||
);
|
||||
|
||||
I_P0_InBuffer_Data : entity work.PipelineRegister
|
||||
generic map(
|
||||
G_PipelineStages => G_P0_BufferStages,
|
||||
G_Width => G_Address_Width,
|
||||
G_RegisterBalancing => "forward"
|
||||
)
|
||||
port map(
|
||||
I_CLK => I_CLK,
|
||||
I_Enable => S_P0_InBufferEnable,
|
||||
I_Data => I_P0_Address,
|
||||
O_Data => R_P0_Address
|
||||
);
|
||||
|
||||
I_P0_InBuffer_ID : entity work.PipelineRegister
|
||||
generic map(
|
||||
G_PipelineStages => G_P0_BufferStages,
|
||||
G_Width => G_P0_ID_Width,
|
||||
G_RegisterBalancing => "forward"
|
||||
)
|
||||
port map(
|
||||
I_CLK => I_CLK,
|
||||
I_Enable => S_P0_InBufferEnable,
|
||||
I_Data => I_P0_ID,
|
||||
O_Data => R_P0_Address_ID
|
||||
);
|
||||
|
||||
C_P0_Address_Ready <= not R_P0_Data_Valid;
|
||||
|
||||
P_P0_Flags : process (I_CLK)
|
||||
begin
|
||||
if rising_edge(I_CLK) then
|
||||
if I_CE = '1' then
|
||||
if S_P0_Address_Valid = '1' and C_P0_Address_Ready = '1' then
|
||||
R_P0_Data_Valid <= '1';
|
||||
R_P0_Data_ID <= R_P0_Address_ID;
|
||||
end if;
|
||||
|
||||
if S_P0_Data_Ready = '1' and R_P0_Data_Valid = '1' then
|
||||
R_P0_Data_Valid <= '0';
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
P_P0_Read : process (I_CLK)
|
||||
begin
|
||||
if rising_edge(I_CLK) then
|
||||
if I_CE = '1' then
|
||||
R_P0_Data <= Rom(to_integer(unsigned(R_P0_Address)));
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
I_P0_OutBufferCtrl : entity work.PipelineController
|
||||
generic map(
|
||||
G_PipelineStages => G_P0_BufferStages
|
||||
)
|
||||
port map(
|
||||
I_CLK => I_CLK,
|
||||
I_CE => I_CE,
|
||||
O_Enable => S_P0_OutBufferEnable,
|
||||
I_Valid => R_P0_Data_Valid,
|
||||
O_Ready => S_P0_Data_Ready,
|
||||
O_Valid => O_P0_Data_Valid,
|
||||
I_Ready => I_P0_Data_Ready
|
||||
);
|
||||
|
||||
I_P0_OutBuffer_Data : entity work.PipelineRegister
|
||||
generic map(
|
||||
G_PipelineStages => G_P0_BufferStages,
|
||||
G_Width => G_Data_Width,
|
||||
G_RegisterBalancing => "backward"
|
||||
)
|
||||
port map(
|
||||
I_CLK => I_CLK,
|
||||
I_Enable => S_P0_OutBufferEnable,
|
||||
I_Data => R_P0_Data,
|
||||
O_Data => O_P0_Data
|
||||
);
|
||||
|
||||
I_P0_OutBuffer_ID : entity work.PipelineRegister
|
||||
generic map(
|
||||
G_PipelineStages => G_P0_BufferStages,
|
||||
G_Width => G_P0_ID_Width,
|
||||
G_RegisterBalancing => "backward"
|
||||
)
|
||||
port map(
|
||||
I_CLK => I_CLK,
|
||||
I_Enable => S_P0_OutBufferEnable,
|
||||
I_Data => R_P0_Data_ID,
|
||||
O_Data => O_P0_ID
|
||||
);
|
||||
|
||||
-----------------------
|
||||
|
||||
I_P1_InBufferCtrl : entity work.PipelineController
|
||||
generic map(
|
||||
G_PipelineStages => G_P1_BufferStages
|
||||
)
|
||||
port map(
|
||||
I_CLK => I_CLK,
|
||||
I_CE => I_CE,
|
||||
O_Enable => S_P1_InBufferEnable,
|
||||
I_Valid => I_P1_Address_Valid,
|
||||
O_Ready => O_P1_Address_Ready,
|
||||
O_Valid => S_P1_Address_Valid,
|
||||
I_Ready => C_P1_Address_Ready
|
||||
);
|
||||
|
||||
I_P1_InBuffer_Data : entity work.PipelineRegister
|
||||
generic map(
|
||||
G_PipelineStages => G_P1_BufferStages,
|
||||
G_Width => G_Address_Width,
|
||||
G_RegisterBalancing => "forward"
|
||||
)
|
||||
port map(
|
||||
I_CLK => I_CLK,
|
||||
I_Enable => S_P1_InBufferEnable,
|
||||
I_Data => I_P1_Address,
|
||||
O_Data => R_P1_Address
|
||||
);
|
||||
|
||||
I_P1_InBuffer_ID : entity work.PipelineRegister
|
||||
generic map(
|
||||
G_PipelineStages => G_P1_BufferStages,
|
||||
G_Width => G_P1_ID_Width,
|
||||
G_RegisterBalancing => "forward"
|
||||
)
|
||||
port map(
|
||||
I_CLK => I_CLK,
|
||||
I_Enable => S_P1_InBufferEnable,
|
||||
I_Data => I_P1_ID,
|
||||
O_Data => R_P1_Address_ID
|
||||
);
|
||||
|
||||
C_P1_Address_Ready <= not R_P1_Data_Valid;
|
||||
|
||||
P_P1_Flags : process (I_CLK)
|
||||
begin
|
||||
if rising_edge(I_CLK) then
|
||||
if I_CE = '1' then
|
||||
if S_P1_Address_Valid = '1' and C_P1_Address_Ready = '1' then
|
||||
R_P1_Data_Valid <= '1';
|
||||
R_P1_Data_ID <= R_P1_Address_ID;
|
||||
end if;
|
||||
|
||||
if S_P1_Data_Ready = '1' and R_P1_Data_Valid = '1' then
|
||||
R_P1_Data_Valid <= '0';
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
P_P1_Read : process (I_CLK)
|
||||
begin
|
||||
if rising_edge(I_CLK) then
|
||||
if I_CE = '1' then
|
||||
R_P1_Data <= Rom(to_integer(unsigned(R_P1_Address)));
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
I_P1_OutBufferCtrl : entity work.PipelineController
|
||||
generic map(
|
||||
G_PipelineStages => G_P1_BufferStages
|
||||
)
|
||||
port map(
|
||||
I_CLK => I_CLK,
|
||||
I_CE => I_CE,
|
||||
O_Enable => S_P1_OutBufferEnable,
|
||||
I_Valid => R_P1_Data_Valid,
|
||||
O_Ready => S_P1_Data_Ready,
|
||||
O_Valid => O_P1_Data_Valid,
|
||||
I_Ready => I_P1_Data_Ready
|
||||
);
|
||||
|
||||
I_P1_OutBuffer : entity work.PipelineRegister
|
||||
generic map(
|
||||
G_PipelineStages => G_P1_BufferStages,
|
||||
G_Width => G_Data_Width,
|
||||
G_RegisterBalancing => "backward"
|
||||
)
|
||||
port map(
|
||||
I_CLK => I_CLK,
|
||||
I_Enable => S_P1_OutBufferEnable,
|
||||
I_Data => R_P1_Data,
|
||||
O_Data => O_P1_Data
|
||||
);
|
||||
|
||||
I_P1_OutBuffer_ID : entity work.PipelineRegister
|
||||
generic map(
|
||||
G_PipelineStages => G_P1_BufferStages,
|
||||
G_Width => G_P1_ID_Width,
|
||||
G_RegisterBalancing => "backward"
|
||||
)
|
||||
port map(
|
||||
I_CLK => I_CLK,
|
||||
I_Enable => S_P1_OutBufferEnable,
|
||||
I_Data => R_P1_Data_ID,
|
||||
O_Data => O_P1_ID
|
||||
);
|
||||
end architecture;
|
144
src/Scheduler.vhd
Normal file
144
src/Scheduler.vhd
Normal file
@@ -0,0 +1,144 @@
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
use ieee.math_real.all;
|
||||
|
||||
entity AXI_Handshaking_Scheduler_4 is
|
||||
generic (
|
||||
G_DataWidth : integer := 32
|
||||
);
|
||||
port (
|
||||
--@ Clock signal; (**Rising edge** triggered)
|
||||
I_CLK : in std_logic;
|
||||
--@ Clock enable signal (**Active high**)
|
||||
I_CE : in std_logic;
|
||||
--@ Synchronous reset signal (**Active high**)
|
||||
I_RST : in std_logic;
|
||||
|
||||
--@ @virtualbus P0 @dir in P0 interface
|
||||
I_P0_Valid : in std_logic := '0';
|
||||
O_P0_Ready : out std_logic := '0';
|
||||
I_P0_Data : in std_logic_vector(G_DataWidth - 1 downto 0) := (others => '0');
|
||||
--@ @end
|
||||
--@ @virtualbus P1 @dir in P1 interface
|
||||
I_P1_Valid : in std_logic := '0';
|
||||
O_P1_Ready : out std_logic := '0';
|
||||
I_P1_Data : in std_logic_vector(G_DataWidth - 1 downto 0) := (others => '0');
|
||||
--@ @end
|
||||
--@ @virtualbus P2 @dir in P2 interface
|
||||
I_P2_Valid : in std_logic := '0';
|
||||
O_P2_Ready : out std_logic := '0';
|
||||
I_P2_Data : in std_logic_vector(G_DataWidth - 1 downto 0) := (others => '0');
|
||||
--@ @end
|
||||
--@ @virtualbus P3 @dir in P3 interface
|
||||
I_P3_Valid : in std_logic := '0';
|
||||
O_P3_Ready : out std_logic := '0';
|
||||
I_P3_Data : in std_logic_vector(G_DataWidth - 1 downto 0) := (others => '0');
|
||||
--@ @end
|
||||
|
||||
--@ @virtualbus Out @dir out Output interface
|
||||
O_Out_Valid : out std_logic := '0';
|
||||
I_Out_Ready : in std_logic := '0';
|
||||
O_Out_Data : out std_logic_vector(G_DataWidth - 1 downto 0) := (others => '0');
|
||||
O_Out_Address : out std_logic_vector(1 downto 0) := (others => '0')
|
||||
--@ @end
|
||||
|
||||
);
|
||||
end entity AXI_Handshaking_Scheduler_4;
|
||||
|
||||
architecture Rtl of AXI_Handshaking_Scheduler_4 is
|
||||
signal R_Counter : unsigned(1 downto 0) := (others => '0');
|
||||
|
||||
signal C_Select : std_logic_vector(3 downto 0) := (others => '0');
|
||||
signal C_Code : std_logic_vector(1 downto 0) := (others => '0');
|
||||
signal C_CodeReverse : std_logic_vector(1 downto 0) := (others => '0');
|
||||
begin
|
||||
|
||||
i_PriorityEncoder_4 : entity work.PriorityEncoder_4
|
||||
port map(
|
||||
I_Select => C_Select,
|
||||
O_Code => C_Code
|
||||
);
|
||||
|
||||
P_SelectMux : process (R_Counter, I_P0_Valid, I_P1_Valid, I_P2_Valid, I_P3_Valid)
|
||||
begin
|
||||
if R_Counter = "00" then
|
||||
C_Select <= I_P0_Valid & I_P1_Valid & I_P2_Valid & I_P3_Valid;
|
||||
elsif R_Counter = "01" then
|
||||
C_Select <= I_P1_Valid & I_P2_Valid & I_P3_Valid & I_P0_Valid;
|
||||
elsif R_Counter = "10" then
|
||||
C_Select <= I_P2_Valid & I_P3_Valid & I_P0_Valid & I_P1_Valid;
|
||||
elsif R_Counter = "11" then
|
||||
C_Select <= I_P3_Valid & I_P0_Valid & I_P1_Valid & I_P2_Valid;
|
||||
else
|
||||
C_Select <= (others => '-');
|
||||
end if;
|
||||
end process;
|
||||
|
||||
P_CodeReverse : process (C_Code, R_Counter)
|
||||
begin
|
||||
C_CodeReverse <= std_logic_vector(unsigned(C_Code) + R_Counter);
|
||||
end process;
|
||||
|
||||
P_OutMux : process (
|
||||
C_CodeReverse, I_P0_Data, I_P1_Data, I_P2_Data, I_P3_Data,
|
||||
I_P0_Valid, I_P1_Valid, I_P2_Valid, I_P3_Valid,
|
||||
I_Out_Ready)
|
||||
begin
|
||||
O_Out_Valid <= '0';
|
||||
O_P0_Ready <= '0';
|
||||
O_P1_Ready <= '0';
|
||||
O_P2_Ready <= '0';
|
||||
O_P3_Ready <= '0';
|
||||
O_Out_Data <= (others => '0');
|
||||
O_Out_Address <= C_CodeReverse;
|
||||
|
||||
case C_CodeReverse is
|
||||
when "00" =>
|
||||
O_Out_Valid <= I_P0_Valid;
|
||||
O_P0_Ready <= I_Out_Ready;
|
||||
O_Out_Data <= I_P0_Data;
|
||||
when "01" =>
|
||||
O_Out_Valid <= I_P1_Valid;
|
||||
O_P1_Ready <= I_Out_Ready;
|
||||
O_Out_Data <= I_P1_Data;
|
||||
when "10" =>
|
||||
O_Out_Valid <= I_P2_Valid;
|
||||
O_P2_Ready <= I_Out_Ready;
|
||||
O_Out_Data <= I_P2_Data;
|
||||
when "11" =>
|
||||
O_Out_Valid <= I_P3_Valid;
|
||||
O_P3_Ready <= I_Out_Ready;
|
||||
O_Out_Data <= I_P3_Data;
|
||||
when others =>
|
||||
null;
|
||||
end case;
|
||||
end process;
|
||||
|
||||
P_Counter : process (I_CLK)
|
||||
begin
|
||||
if rising_edge(I_CLK) then
|
||||
if I_CE = '1' then
|
||||
if I_RST = '1' then
|
||||
R_Counter <= (others => '0');
|
||||
else
|
||||
if I_Out_Ready = '1' then
|
||||
|
||||
case C_CodeReverse is
|
||||
when "00" =>
|
||||
R_Counter <= "01";
|
||||
when "01" =>
|
||||
R_Counter <= "10";
|
||||
when "10" =>
|
||||
R_Counter <= "11";
|
||||
when "11" =>
|
||||
R_Counter <= "00";
|
||||
when others =>
|
||||
R_Counter <= "00";
|
||||
end case;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process P_Counter;
|
||||
end architecture;
|
Reference in New Issue
Block a user