Adds modules for sprite operations, including opcode decoding, register handling, and vertical pipeline calculations. Replaces legacy scheduler with a more modular and efficient design. Updates constraints for clock timing. Enhances sprite rendering pipeline with improved modularity and scalability.
233 lines
10 KiB
VHDL
233 lines
10 KiB
VHDL
library ieee;
|
|
use ieee.std_logic_1164.all;
|
|
use ieee.numeric_std.all;
|
|
use ieee.math_real.all;
|
|
|
|
entity SpriteChannel is
|
|
generic (
|
|
--@ Data width of the operation data.
|
|
G_OPCodeData_Width : integer := 10;
|
|
--@ 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 Y position (Line) register
|
|
G_Y_Width : integer := 10;
|
|
--@ The height of the sprite in pixels
|
|
G_Sprite_Height : integer := 16;
|
|
--@ The width of the sprite in pixels
|
|
G_Sprite_Width : integer := 16
|
|
);
|
|
port (
|
|
--@ Clock signal; **Rising edge** triggered
|
|
I_CLK : in std_logic;
|
|
--@ Clock Enable signal
|
|
I_CE : in std_logic;
|
|
--@ Synchronous reset signal
|
|
I_RST : in std_logic;
|
|
|
|
--@ @virtualbus Operation-Write @dir in Operation Write Interface
|
|
--@ Indicates if the `OPCode` and `OPData` are valid. (**Active high**)
|
|
I_OP_Valid : in std_logic := '0';
|
|
--@ Indicates if the decoder is ready to accept data. (**Active high**)
|
|
O_OP_Ready : out std_logic := '0';
|
|
--@ Operation code for the sprite channel
|
|
I_OP_Code : in std_logic_vector(3 downto 0) := (others => '0');
|
|
--@ Data to be used with the operation code.
|
|
I_OP_Data : in std_logic_vector(G_OPCodeData_Width - 1 downto 0) := (others => '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(7 downto 0)
|
|
--@ @end
|
|
|
|
);
|
|
end entity;
|
|
|
|
architecture RTL of SpriteChannel 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 : std_logic_vector(G_X_Width - 1 downto 0) := (others => '0');
|
|
signal R_Y : std_logic_vector(G_Y_Width - 1 downto 0) := (others => '0');
|
|
signal R_IsVisible : std_logic := '0';
|
|
|
|
signal OI_P0_Address_Valid : std_logic := '0';
|
|
signal IO_P0_Address_Ready : std_logic := '0';
|
|
signal OI_P0_Address : std_logic_vector(G_Index_Width + G_Offset_Width - 1 downto 0) := (others => '0');
|
|
|
|
signal IO_P0_Data_Valid : std_logic := '0';
|
|
signal OI_P0_Data_Ready : std_logic := '0';
|
|
signal IO_P0_Data : std_logic_vector(7 downto 0) := (others => '0');
|
|
|
|
signal OI_Register_Index_WE : std_logic := '0';
|
|
signal OI_Register_Index : std_logic_vector(G_Index_Width - 1 downto 0) := (others => '0');
|
|
signal OI_Register_Offset_WE : std_logic := '0';
|
|
signal OI_Register_Offset : std_logic_vector(G_Offset_Width - 1 downto 0) := (others => '0');
|
|
signal OI_Register_X_We : std_logic := '0';
|
|
signal OI_Register_X : std_logic_vector(G_X_Width - 1 downto 0) := (others => '0');
|
|
signal OI_Register_Y_WE : std_logic := '0';
|
|
signal OI_Register_Y : std_logic_vector(G_Y_Width - 1 downto 0) := (others => '0');
|
|
signal OI_IsVisible_WE : std_logic := '0';
|
|
signal OI_IsVisible : std_logic := '0';
|
|
|
|
signal I_YHitCheck_Ready : std_logic := '0';
|
|
signal I_YHitCheck_Valid : std_logic := '0';
|
|
signal I_YHitCheck_IsVisible : std_logic := '0';
|
|
signal I_YHitCheck_Offset : std_logic_vector(G_Offset_Width - 1 downto 0) := (others => '0');
|
|
signal O_YHitCheck_Valid : std_logic := '0';
|
|
signal O_YHitCheck_YToCheck : std_logic_vector(G_Y_Width - 1 downto 0) := (others => '0');
|
|
signal O_YHitCheck_Ready : std_logic := '0';
|
|
|
|
signal OI_CalcPipeline_Valid : std_logic := '0';
|
|
signal IO_CalcPipeline_Ready : std_logic := '0';
|
|
signal OI_CalcPipeline_X_Request : std_logic_vector(G_X_Width - 1 downto 0) := (others => '0');
|
|
begin
|
|
i_RegisterFile : entity work.RegisterFile
|
|
generic map(
|
|
G_Index_Width => G_Index_Width,
|
|
G_Offset_Width => G_Offset_Width,
|
|
G_X_Width => G_X_Width,
|
|
G_Y_Width => G_Y_Width
|
|
)
|
|
port map(
|
|
I_CLK => I_CLK,
|
|
I_CE => I_CE,
|
|
I_RST => I_RST,
|
|
I_Index_WE => OI_Register_Index_WE,
|
|
I_Index => OI_Register_Index,
|
|
I_Offset_WE => OI_Register_Offset_WE,
|
|
I_Offset => OI_Register_Offset,
|
|
I_X_We => OI_Register_X_We,
|
|
I_X => OI_Register_X,
|
|
I_Y_WE => OI_Register_Y_WE,
|
|
I_Y => OI_Register_Y,
|
|
I_IsVisible_WE => OI_IsVisible_WE,
|
|
I_IsVisible => OI_IsVisible,
|
|
O_Index => R_Index,
|
|
O_Offset => R_Offset,
|
|
O_X => R_X,
|
|
O_Y => R_Y,
|
|
O_IsVisible => R_IsVisible
|
|
);
|
|
|
|
i_OPDecoder : entity work.OPDecoder
|
|
generic map(
|
|
G_OPCodeData_Width => G_OPCodeData_Width,
|
|
G_Index_Width => G_Index_Width,
|
|
G_Offset_Width => G_Offset_Width,
|
|
G_X_Width => G_X_Width,
|
|
G_Y_Width => G_Y_Width
|
|
)
|
|
port map(
|
|
I_CLK => I_CLK,
|
|
I_CE => I_CE,
|
|
I_RST => I_RST,
|
|
I_OP_Valid => I_OP_Valid,
|
|
O_OP_Ready => O_OP_Ready,
|
|
I_OP_Code => I_OP_Code,
|
|
I_OP_Data => I_OP_Data,
|
|
O_Register_Index_WE => OI_Register_Index_WE,
|
|
O_Register_Index => OI_Register_Index,
|
|
O_Register_Offset_WE => OI_Register_Offset_WE,
|
|
O_Register_Offset => OI_Register_Offset,
|
|
O_Register_X_We => OI_Register_X_We,
|
|
O_Register_X => OI_Register_X,
|
|
O_Register_Y_WE => OI_Register_Y_WE,
|
|
O_Register_Y => OI_Register_Y,
|
|
O_IsVisible_WE => OI_IsVisible_WE,
|
|
O_IsVisible => OI_IsVisible,
|
|
|
|
I_IsVisible => R_IsVisible,
|
|
|
|
I_YHitCheck_Ready => I_YHitCheck_Ready,
|
|
O_YHitCheck_Valid => O_YHitCheck_Valid,
|
|
O_YHitCheck_YToCheck => O_YHitCheck_YToCheck,
|
|
O_YHitCheck_Ready => O_YHitCheck_Ready,
|
|
I_YHitCheck_Valid => I_YHitCheck_Valid,
|
|
I_YHitCheck_IsVisible => I_YHitCheck_IsVisible,
|
|
I_YHitCheck_Offset => I_YHitCheck_Offset,
|
|
|
|
O_HSpritePipeline_Valid => OI_CalcPipeline_Valid,
|
|
I_HSpritePipeline_Ready => IO_CalcPipeline_Ready,
|
|
O_HSpritePipeline_X_Request => OI_CalcPipeline_X_Request
|
|
);
|
|
|
|
i_YHitCheck : entity work.VerticalSpritePipeline
|
|
generic map(
|
|
G_Y_Width => G_Y_Width,
|
|
G_Sprite_Height => G_Sprite_Height,
|
|
G_Offset_Width => G_Offset_Width,
|
|
G_PipelineStages => 2
|
|
)
|
|
port map(
|
|
I_CLK => I_CLK,
|
|
I_CE => I_CE,
|
|
O_Ready => I_YHitCheck_Ready,
|
|
I_Valid => O_YHitCheck_Valid,
|
|
I_YToCheck => O_YHitCheck_YToCheck,
|
|
I_Y => R_Y,
|
|
I_Ready => O_YHitCheck_Ready,
|
|
O_Valid => I_YHitCheck_Valid,
|
|
O_IsVisible => I_YHitCheck_IsVisible,
|
|
O_Offset => I_YHitCheck_Offset
|
|
);
|
|
|
|
i_Rom : entity work.Rom
|
|
generic map(
|
|
G_Address_Width => 13,
|
|
G_Data_Width => 8,
|
|
G_P0_BufferStages => 1,
|
|
G_P0_ID_Width => 0,
|
|
G_P1_BufferStages => 0,
|
|
G_P1_ID_Width => 0,
|
|
G_RomType => "Block"
|
|
)
|
|
port map(
|
|
I_CLK => I_CLK,
|
|
I_CE => I_CE,
|
|
I_P0_Address_Valid => OI_P0_Address_Valid,
|
|
O_P0_Address_Ready => IO_P0_Address_Ready,
|
|
I_P0_Address => OI_P0_Address,
|
|
O_P0_Data_Valid => IO_P0_Data_Valid,
|
|
I_P0_Data_Ready => OI_P0_Data_Ready,
|
|
O_P0_Data => IO_P0_Data
|
|
);
|
|
|
|
i_CalcPipeline : entity work.HorizontalSpritePipeline
|
|
generic map(
|
|
G_Index_Width => G_Index_Width,
|
|
G_Offset_Width => G_Offset_Width,
|
|
G_X_Width => G_X_Width,
|
|
G_Rom_Width => 8,
|
|
G_Pixel_Width => 8
|
|
)
|
|
port map(
|
|
I_CLK => I_CLK,
|
|
I_CE => I_CE,
|
|
I_RST => I_RST,
|
|
I_OP_Valid => OI_CalcPipeline_Valid,
|
|
O_OP_Ready => IO_CalcPipeline_Ready,
|
|
I_OP_X_Request => OI_CalcPipeline_X_Request,
|
|
I_OP_Index => R_Index,
|
|
I_OP_Offset => R_Offset,
|
|
I_OP_X_Sprite => R_X,
|
|
O_Rom_Valid => OI_P0_Address_Valid,
|
|
I_Rom_Ready => IO_P0_Address_Ready,
|
|
O_Rom_Address => OI_P0_Address,
|
|
I_Rom_Valid => IO_P0_Data_Valid,
|
|
O_Rom_Ready => OI_P0_Data_Ready,
|
|
I_Rom_Data => IO_P0_Data,
|
|
O_Pixel_Valid => O_Pixel_Valid,
|
|
I_Pixel_Ready => I_Pixel_Ready,
|
|
O_Pixel_Data => O_Pixel_Data
|
|
);
|
|
|
|
end architecture RTL;
|