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:
345
libs/PriorityEncoders.vhd
Normal file
345
libs/PriorityEncoders.vhd
Normal file
@@ -0,0 +1,345 @@
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
|
||||
--@ Priority Encoder (2 to 1 bits)
|
||||
--@ This is a combinatorial priority encoder that encodes the highest priority
|
||||
--@ bit in the input vector to a 1-bit output code.
|
||||
entity PriorityEncoder_2 is
|
||||
port (
|
||||
--@ Input vector to be encoded.
|
||||
--@ The least significant bit has the highest priority.
|
||||
I_Select : in std_logic_vector(1 downto 0) := (others => '0');
|
||||
--@ Output code.
|
||||
--@ The output code is the index of the highest priority bit in the input vector.
|
||||
O_Code : out std_logic_vector(0 downto 0) := (others => '0')
|
||||
);
|
||||
end entity PriorityEncoder_2;
|
||||
|
||||
architecture Combinatoric of PriorityEncoder_2 is
|
||||
--@ Internal signal to hold the encoded output.
|
||||
signal C_Code : std_logic_vector(0 downto 0);
|
||||
|
||||
--@ Attribute to force the synthesis tool (XST, old Parser) to treat this as a combinatorial signal.
|
||||
attribute PRIORITY_EXTRACT : string;
|
||||
attribute PRIORITY_EXTRACT of C_Code : signal is "force";
|
||||
begin
|
||||
C_Code <= "0" when I_Select(1) = '1' else
|
||||
"1" when I_Select(0) = '1' else
|
||||
"-";
|
||||
|
||||
O_Code <= C_Code;
|
||||
end architecture;
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
|
||||
--@ Priority Encoder (4 to 2 bits)
|
||||
--@ This is a combinatorial priority encoder that encodes the highest priority
|
||||
--@ bit in the input vector to a 2-bit output code.
|
||||
entity PriorityEncoder_4 is
|
||||
port (
|
||||
--@ Input vector to be encoded.
|
||||
--@ The least significant bit has the highest priority.
|
||||
I_Select : in std_logic_vector(3 downto 0) := (others => '0');
|
||||
--@ Output code.
|
||||
--@ The output code is the index of the highest priority bit in the input vector.
|
||||
O_Code : out std_logic_vector(1 downto 0) := (others => '0')
|
||||
);
|
||||
end entity PriorityEncoder_4;
|
||||
|
||||
architecture Combinatoric of PriorityEncoder_4 is
|
||||
--@ Internal signal to hold the encoded output.
|
||||
signal C_Code : std_logic_vector(1 downto 0);
|
||||
|
||||
--@ Attribute to force the synthesis tool (XST, old Parser) to treat this as a combinatorial signal.
|
||||
attribute PRIORITY_EXTRACT : string;
|
||||
attribute PRIORITY_EXTRACT of C_Code : signal is "force";
|
||||
begin
|
||||
C_Code <= "00" when I_Select(3) = '1' else
|
||||
"01" when I_Select(2) = '1' else
|
||||
"10" when I_Select(1) = '1' else
|
||||
"11" when I_Select(0) = '1' else
|
||||
"--";
|
||||
|
||||
O_Code <= C_Code;
|
||||
end architecture;
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
|
||||
--@ Priority Encoder (8 to 3 bits)
|
||||
--@ This is a combinatorial priority encoder that encodes the highest priority
|
||||
--@ bit in the input vector to a 3-bit output code.
|
||||
entity PriorityEncoder_8 is
|
||||
port (
|
||||
--@ Input vector to be encoded.
|
||||
--@ The least significant bit has the highest priority.
|
||||
I_Select : in std_logic_vector(7 downto 0) := (others => '0');
|
||||
--@ Output code.
|
||||
--@ The output code is the index of the highest priority bit in the input vector.
|
||||
O_Code : out std_logic_vector(2 downto 0) := (others => '0')
|
||||
);
|
||||
end entity PriorityEncoder_8;
|
||||
|
||||
architecture Combinatoric of PriorityEncoder_8 is
|
||||
--@ Internal signal to hold the encoded output.
|
||||
signal C_Code : std_logic_vector(2 downto 0);
|
||||
|
||||
--@ Attribute to force the synthesis tool (XST, old Parser) to treat this as a combinatorial signal.
|
||||
attribute PRIORITY_EXTRACT : string;
|
||||
attribute PRIORITY_EXTRACT of C_Code : signal is "force";
|
||||
begin
|
||||
C_Code <= "000" when I_Select(7) = '1' else
|
||||
"001" when I_Select(6) = '1' else
|
||||
"010" when I_Select(5) = '1' else
|
||||
"011" when I_Select(4) = '1' else
|
||||
"100" when I_Select(3) = '1' else
|
||||
"101" when I_Select(2) = '1' else
|
||||
"110" when I_Select(1) = '1' else
|
||||
"111" when I_Select(0) = '1' else
|
||||
"---";
|
||||
|
||||
O_Code <= C_Code;
|
||||
end architecture;
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
|
||||
--@ Priority Encoder (16 to 4 bits)
|
||||
--@ This is a combinatorial priority encoder that encodes the highest priority
|
||||
--@ bit in the input vector to a 4-bit output code.
|
||||
entity PriorityEncoder_16 is
|
||||
port (
|
||||
--@ Input vector to be encoded.
|
||||
--@ The least significant bit has the highest priority.
|
||||
I_Select : in std_logic_vector(15 downto 0) := (others => '0');
|
||||
--@ Output code.
|
||||
--@ The output code is the index of the highest priority bit in the input vector.
|
||||
O_Code : out std_logic_vector(3 downto 0) := (others => '0')
|
||||
);
|
||||
end entity PriorityEncoder_16;
|
||||
|
||||
architecture Combinatoric of PriorityEncoder_16 is
|
||||
--@ Internal signal to hold the encoded output.
|
||||
signal C_Code : std_logic_vector(3 downto 0);
|
||||
|
||||
--@ Attribute to force the synthesis tool (XST, old Parser) to treat this as a combinatorial signal.
|
||||
attribute PRIORITY_EXTRACT : string;
|
||||
attribute PRIORITY_EXTRACT of C_Code : signal is "force";
|
||||
begin
|
||||
C_Code <= "0000" when I_Select(15) = '1' else
|
||||
"0001" when I_Select(14) = '1' else
|
||||
"0010" when I_Select(13) = '1' else
|
||||
"0011" when I_Select(12) = '1' else
|
||||
"0100" when I_Select(11) = '1' else
|
||||
"0101" when I_Select(10) = '1' else
|
||||
"0110" when I_Select(9) = '1' else
|
||||
"0111" when I_Select(8) = '1' else
|
||||
"1000" when I_Select(7) = '1' else
|
||||
"1001" when I_Select(6) = '1' else
|
||||
"1010" when I_Select(5) = '1' else
|
||||
"1011" when I_Select(4) = '1' else
|
||||
"1100" when I_Select(3) = '1' else
|
||||
"1101" when I_Select(2) = '1' else
|
||||
"1110" when I_Select(1) = '1' else
|
||||
"1111" when I_Select(0) = '1' else
|
||||
"----";
|
||||
|
||||
O_Code <= C_Code;
|
||||
end architecture;
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
|
||||
--@ Priority Encoder (32 to 5 bits)
|
||||
--@ This is a combinatorial priority encoder that encodes the highest priority
|
||||
--@ bit in the input vector to a 5-bit output code.
|
||||
entity PriorityEncoder_32 is
|
||||
port (
|
||||
--@ Input vector to be encoded.
|
||||
--@ The least significant bit has the highest priority.
|
||||
I_Select : in std_logic_vector(31 downto 0) := (others => '0');
|
||||
--@ Output code.
|
||||
--@ The output code is the index of the highest priority bit in the input vector.
|
||||
O_Code : out std_logic_vector(4 downto 0) := (others => '0')
|
||||
);
|
||||
end entity PriorityEncoder_32;
|
||||
|
||||
architecture Combinatoric of PriorityEncoder_32 is
|
||||
--@ Internal signal to hold the encoded output.
|
||||
signal C_Code : std_logic_vector(4 downto 0);
|
||||
|
||||
--@ Attribute to force the synthesis tool (XST, old Parser) to treat this as a combinatorial signal.
|
||||
attribute PRIORITY_EXTRACT : string;
|
||||
attribute PRIORITY_EXTRACT of C_Code : signal is "force";
|
||||
|
||||
begin
|
||||
C_Code <= "00000" when I_Select(31) = '1' else
|
||||
"00001" when I_Select(30) = '1' else
|
||||
"00010" when I_Select(29) = '1' else
|
||||
"00011" when I_Select(28) = '1' else
|
||||
"00100" when I_Select(27) = '1' else
|
||||
"00101" when I_Select(26) = '1' else
|
||||
"00110" when I_Select(25) = '1' else
|
||||
"00111" when I_Select(24) = '1' else
|
||||
"01000" when I_Select(23) = '1' else
|
||||
"01001" when I_Select(22) = '1' else
|
||||
"01010" when I_Select(21) = '1' else
|
||||
"01011" when I_Select(20) = '1' else
|
||||
"01100" when I_Select(19) = '1' else
|
||||
"01101" when I_Select(18) = '1' else
|
||||
"01110" when I_Select(17) = '1' else
|
||||
"01111" when I_Select(16) = '1' else
|
||||
"10000" when I_Select(15) = '1' else
|
||||
"10001" when I_Select(14) = '1' else
|
||||
"10010" when I_Select(13) = '1' else
|
||||
"10011" when I_Select(12) = '1' else
|
||||
"10100" when I_Select(11) = '1' else
|
||||
"10101" when I_Select(10) = '1' else
|
||||
"10110" when I_Select(9) = '1' else
|
||||
"10111" when I_Select(8) = '1' else
|
||||
"11000" when I_Select(7) = '1' else
|
||||
"11001" when I_Select(6) = '1' else
|
||||
"11010" when I_Select(5) = '1' else
|
||||
"11011" when I_Select(4) = '1' else
|
||||
"11100" when I_Select(3) = '1' else
|
||||
"11101" when I_Select(2) = '1' else
|
||||
"11110" when I_Select(1) = '1' else
|
||||
"11111" when I_Select(0) = '1' else
|
||||
"-----";
|
||||
|
||||
O_Code <= C_Code;
|
||||
end architecture;
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
|
||||
--@ Priority Encoder (64 to 6 bits)
|
||||
--@ This is a combinatorial priority encoder that encodes the highest priority
|
||||
--@ bit in the input vector to a 6-bit output code.
|
||||
entity PriorityEncoder_64 is
|
||||
port (
|
||||
--@ Input vector to be encoded.
|
||||
--@ The least significant bit has the highest priority.
|
||||
I_Select : in std_logic_vector(63 downto 0) := (others => '0');
|
||||
--@ Output code.
|
||||
--@ The output code is the index of the highest priority bit in the input vector.
|
||||
O_Code : out std_logic_vector(5 downto 0) := (others => '0')
|
||||
);
|
||||
end entity PriorityEncoder_64;
|
||||
|
||||
architecture Combinatoric of PriorityEncoder_64 is
|
||||
--@ Internal signal to hold the encoded output.
|
||||
signal C_Code : std_logic_vector(5 downto 0);
|
||||
|
||||
--@ Attribute to force the synthesis tool (XST, old Parser) to treat this as a combinatorial signal.
|
||||
attribute PRIORITY_EXTRACT : string;
|
||||
attribute PRIORITY_EXTRACT of C_Code : signal is "force";
|
||||
|
||||
begin
|
||||
C_Code <= "000000" when I_Select(63) = '1' else
|
||||
"000001" when I_Select(62) = '1' else
|
||||
"000010" when I_Select(61) = '1' else
|
||||
"000011" when I_Select(60) = '1' else
|
||||
"000100" when I_Select(59) = '1' else
|
||||
"000101" when I_Select(58) = '1' else
|
||||
"000110" when I_Select(57) = '1' else
|
||||
"000111" when I_Select(56) = '1' else
|
||||
"001000" when I_Select(55) = '1' else
|
||||
"001001" when I_Select(54) = '1' else
|
||||
"001010" when I_Select(53) = '1' else
|
||||
"001011" when I_Select(52) = '1' else
|
||||
"001100" when I_Select(51) = '1' else
|
||||
"001101" when I_Select(50) = '1' else
|
||||
"001110" when I_Select(49) = '1' else
|
||||
"001111" when I_Select(48) = '1' else
|
||||
"010000" when I_Select(47) = '1' else
|
||||
"010001" when I_Select(46) = '1' else
|
||||
"010010" when I_Select(45) = '1' else
|
||||
"010011" when I_Select(44) = '1' else
|
||||
"010100" when I_Select(43) = '1' else
|
||||
"010101" when I_Select(42) = '1' else
|
||||
"010110" when I_Select(41) = '1' else
|
||||
"010111" when I_Select(40) = '1' else
|
||||
"011000" when I_Select(39) = '1' else
|
||||
"011001" when I_Select(38) = '1' else
|
||||
"011010" when I_Select(37) = '1' else
|
||||
"011011" when I_Select(36) = '1' else
|
||||
"011100" when I_Select(35) = '1' else
|
||||
"011101" when I_Select(34) = '1' else
|
||||
"011110" when I_Select(33) = '1' else
|
||||
"011111" when I_Select(32) = '1' else
|
||||
"100000" when I_Select(31) = '1' else
|
||||
"100001" when I_Select(30) = '1' else
|
||||
"100010" when I_Select(29) = '1' else
|
||||
"100011" when I_Select(28) = '1' else
|
||||
"100100" when I_Select(27) = '1' else
|
||||
"100101" when I_Select(26) = '1' else
|
||||
"100110" when I_Select(25) = '1' else
|
||||
"100111" when I_Select(24) = '1' else
|
||||
"101000" when I_Select(23) = '1' else
|
||||
"101001" when I_Select(22) = '1' else
|
||||
"101010" when I_Select(21) = '1' else
|
||||
"101011" when I_Select(20) = '1' else
|
||||
"101100" when I_Select(19) = '1' else
|
||||
"101101" when I_Select(18) = '1' else
|
||||
"101110" when I_Select(17) = '1' else
|
||||
"101111" when I_Select(16) = '1' else
|
||||
"110000" when I_Select(15) = '1' else
|
||||
"110001" when I_Select(14) = '1' else
|
||||
"110010" when I_Select(13) = '1' else
|
||||
"110011" when I_Select(12) = '1' else
|
||||
"110100" when I_Select(11) = '1' else
|
||||
"110101" when I_Select(10) = '1' else
|
||||
"110110" when I_Select(9) = '1' else
|
||||
"110111" when I_Select(8) = '1' else
|
||||
"111000" when I_Select(7) = '1' else
|
||||
"111001" when I_Select(6) = '1' else
|
||||
"111010" when I_Select(5) = '1' else
|
||||
"111011" when I_Select(4) = '1' else
|
||||
"111100" when I_Select(3) = '1' else
|
||||
"111101" when I_Select(2) = '1' else
|
||||
"111110" when I_Select(1) = '1' else
|
||||
"111111" when I_Select(0) = '1' else
|
||||
"------";
|
||||
|
||||
O_Code <= C_Code;
|
||||
end architecture;
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
use ieee.math_real.all;
|
||||
|
||||
--@ Priority Encoder (Generic)
|
||||
--@ This is a combinatorial priority encoder that encodes the highest priority
|
||||
--@ bit in the input vector to a 6-bit output code.
|
||||
entity PriorityEncoder_G is
|
||||
generic (
|
||||
--@ Code width with minimum 2 bits and maximum 6 bits.
|
||||
G_CodeWidth : integer := 6
|
||||
);
|
||||
port (
|
||||
--@ Input vector to be encoded.
|
||||
--@ The least significant bit has the highest priority.
|
||||
I_Select : in std_logic_vector(2 ** G_CodeWidth - 1 downto 0);
|
||||
--@ Output code.
|
||||
--@ The output code is the index of the highest priority bit in the input vector.
|
||||
O_Code : out std_logic_vector(G_CodeWidth - 1 downto 0)
|
||||
);
|
||||
end entity PriorityEncoder_G;
|
||||
|
||||
architecture Combinatoric of PriorityEncoder_G is
|
||||
signal C_Select : std_logic_vector(63 downto 0) := (others => '-');
|
||||
signal C_Code : std_logic_vector(5 downto 0) := (others => '-');
|
||||
begin
|
||||
|
||||
entity_inst : entity work.PriorityEncoder_64
|
||||
port map(
|
||||
I_Select => C_Select,
|
||||
O_Code => C_Code
|
||||
);
|
||||
|
||||
C_Select(G_CodeWidth * 2 - 1 downto 0) <= I_Select;
|
||||
O_Code <= C_Code(G_CodeWidth - 1 downto 0);
|
||||
end architecture;
|
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