aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--basys3/basys3.srcs/ppu_consts.vhd20
-rw-r--r--basys3/basys3.srcs/ppu_sprite_bg.vhd50
-rw-r--r--basys3/basys3.srcs/ppu_sprite_fg.vhd93
-rw-r--r--basys3/basys3.srcs/ppu_sprite_transform.vhd16
-rw-r--r--basys3/basys3.srcs/ppu_sprite_transform_tb.vhd32
-rw-r--r--basys3/basys3.xpr15
6 files changed, 106 insertions, 120 deletions
diff --git a/basys3/basys3.srcs/ppu_consts.vhd b/basys3/basys3.srcs/ppu_consts.vhd
index 89b7a7a..722954d 100644
--- a/basys3/basys3.srcs/ppu_consts.vhd
+++ b/basys3/basys3.srcs/ppu_consts.vhd
@@ -2,7 +2,7 @@
package ppu_consts is
constant PPU_RAM_BUS_ADDR_WIDTH : natural := 16; -- RAM bus address width
constant PPU_RAM_BUS_DATA_WIDTH : natural := 16; -- RAM bus data width
- constant PPU_FG_SPRITE_COUNT : natural := 128; -- amount of foreground sprites
+ constant PPU_FG_SPRITE_COUNT : natural := 128; -- foreground sprites
constant PPU_COLOR_OUTPUT_DEPTH : natural := 4; -- VGA output channel depth
constant PPU_PALETTE_COLOR_WIDTH : natural := 3; -- palette index width (within sprite)
constant PPU_PALETTE_INDEX_WIDTH : natural := 3; -- palette index width (palette table)
@@ -17,18 +17,22 @@ package ppu_consts is
constant PPU_PAL_DATA_WIDTH : natural := 12; -- palette memory ram bus data width
constant PPU_AUX_ADDR_WIDTH : natural := 1; -- auxiliary memory ram bus address width
constant PPU_AUX_DATA_WIDTH : natural := 16; -- auxiliary memory ram bus data width
- constant PPU_POS_H_WIDTH : natural := 9; -- amount of bits for horizontal screen offset
- constant PPU_POS_V_WIDTH : natural := 8; -- amount of bits for vertical screen offset
+ constant PPU_POS_H_WIDTH : natural := 9; -- bits for horizontal screen offset
+ constant PPU_POS_V_WIDTH : natural := 8; -- bits for vertical screen offset
constant PPU_SPRITE_WIDTH : natural := 16; -- sprite width (pixels)
constant PPU_SPRITE_HEIGHT : natural := 16; -- sprite height (pixels)
+ constant PPU_SPRITE_PIDX_WIDTH : natural := 8; -- bits needed to identify horizontal and vertical pixel within sprite
constant PPU_SPRITE_POS_H_WIDTH: natural := 4; -- bits needed to identify horizontal pixel within sprite
constant PPU_SPRITE_POS_V_WIDTH: natural := 4; -- bits needed to identify vertical pixel within sprite
constant PPU_SCREEN_WIDTH : natural := 320; -- absolute screen width (pixels)
constant PPU_SCREEN_HEIGHT : natural := 240; -- absolute screen height (pixels)
- constant PPU_BG_CANVAS_TILES_H : natural := 40; -- amount of tiles (horizontally) on background canvas
- constant PPU_BG_CANVAS_TILES_V : natural := 30; -- amount of tiles (vertically) on background canvas
- constant PPU_TILE_INDEX_WIDTH : natural := 10; -- amount of bits needed to index a tile from TMM memory
- constant PPU_PIXELS_PER_TILE_WORD : natural := 5; -- amount of pixels defined in one word in TMM memory
- constant PPU_SPRITE_PIXELS_PER_WORD : natural := 52; -- amount of words needed for a single sprite
+ constant PPU_BG_CANVAS_TILES_H : natural := 40; -- tiles (horizontally) on background canvas
+ constant PPU_BG_CANVAS_TILES_V : natural := 30; -- tiles (vertically) on background canvas
+ constant PPU_BG_CANVAS_TILE_H_WIDTH : natural := 6; -- bits needed to describe horizontal bg tile index (grid coordinates)
+ constant PPU_BG_CANVAS_TILE_V_WIDTH : natural := 5; -- bits needed to describe vertical bg tile index (grid coordinates)
+ constant PPU_TILE_INDEX_WIDTH : natural := 10; -- bits needed to index a tile from TMM memory
+ constant PPU_PIXELS_PER_TILE_WORD : natural := 5; -- pixels defined in one word in TMM memory
+ constant PPU_SPRITE_PIXELS_PER_WORD : natural := 52; -- words needed for a single sprite
+ constant PPU_PIXEL_BIT_WIDTH : natural := 3; -- bits needed to identify pixel in TMM word
end package ppu_consts;
diff --git a/basys3/basys3.srcs/ppu_sprite_bg.vhd b/basys3/basys3.srcs/ppu_sprite_bg.vhd
index d8235f5..243fd93 100644
--- a/basys3/basys3.srcs/ppu_sprite_bg.vhd
+++ b/basys3/basys3.srcs/ppu_sprite_bg.vhd
@@ -31,11 +31,11 @@ end ppu_sprite_bg;
architecture Behavioral of ppu_sprite_bg is
component ppu_sprite_transform port(
- XI : in std_logic_vector(PPU_SPRITE_POS_H_WIDTH-1 downto 0); -- pixel position relative to tile
- YI : in std_logic_vector(PPU_SPRITE_POS_V_WIDTH-1 downto 0); -- pixel position relative to tile
+ XI : in unsigned(PPU_SPRITE_POS_H_WIDTH-1 downto 0); -- pixel position relative to tile
+ YI : in unsigned(PPU_SPRITE_POS_V_WIDTH-1 downto 0); -- pixel position relative to tile
FLIP_H, FLIP_V : in std_logic; -- flip sprite
- XO : out std_logic_vector(PPU_SPRITE_POS_H_WIDTH-1 downto 0); -- new pixel position relative to tile
- YO : out std_logic_vector(PPU_SPRITE_POS_V_WIDTH-1 downto 0)); -- new pixel position relative to tile
+ XO : out unsigned(PPU_SPRITE_POS_H_WIDTH-1 downto 0); -- new pixel position relative to tile
+ YO : out unsigned(PPU_SPRITE_POS_V_WIDTH-1 downto 0)); -- new pixel position relative to tile
end component;
-- BAM and TMM in/out temp + registers
@@ -57,11 +57,9 @@ architecture Behavioral of ppu_sprite_bg is
-- auxiliary signals (temp variables)
signal PIXEL_ABS_X, PIXEL_ABS_Y : integer := 0; -- absolute pixel position (relative to BG canvas instead of viewport)
signal TILE_IDX_X, TILE_IDX_Y : integer := 0; -- background canvas tile grid xy
- signal TILE_PIXEL_IDX_X, TILE_PIXEL_IDX_Y : integer := 0; -- xy position of pixel within tile (local tile coords)
- signal TRANS_TILE_PIDX_X, TRANS_TILE_PIDX_Y : integer := 0; -- transformed xy position of pixel within tile
- signal TRANS_TILE_PIXEL_IDX : integer := 0; -- index of pixel within tile (reading order)
- signal TRANSFORM_XI, TRANSFORM_XO : std_logic_vector(PPU_SPRITE_POS_H_WIDTH-1 downto 0); -- transform inputs/outputs (x axis)
- signal TRANSFORM_YI, TRANSFORM_YO : std_logic_vector(PPU_SPRITE_POS_V_WIDTH-1 downto 0); -- transform inputs/outputs (y axis)
+ signal TILE_PIDX_X, TRANS_TILE_PIDX_X : unsigned(PPU_SPRITE_POS_H_WIDTH-1 downto 0) := (others => '0'); -- x position of pixel within tile (local tile coords)
+ signal TILE_PIDX_Y, TRANS_TILE_PIDX_Y : unsigned(PPU_SPRITE_POS_V_WIDTH-1 downto 0) := (others => '0'); -- y position of pixel within tile (local tile coords)
+ signal TRANS_TILE_PIDX : integer := 0; -- index of pixel within tile (reading order)
signal TILEMAP_WORD_OFFSET : integer := 0; -- word offset from tile start address in TMM
signal PIXEL_BIT_OFFSET : integer := 0; -- pixel index within word of TMM
signal TMM_DATA_PAL_IDX : std_logic_vector(PPU_PALETTE_COLOR_WIDTH-1 downto 0); -- color of palette
@@ -77,32 +75,28 @@ begin
T_CIDX <= BAM_DATA_COL_IDX & TMM_DATA_PAL_IDX;
-- BAM address calculations
- PIXEL_ABS_X <= to_integer(unsigned(X)) + to_integer(unsigned(BG_SHIFT_X));
- PIXEL_ABS_Y <= to_integer(unsigned(Y)) + to_integer(unsigned(BG_SHIFT_Y));
- TILE_IDX_X <= PIXEL_ABS_X / 16;
- TILE_IDX_Y <= PIXEL_ABS_Y / 16;
- TILE_PIXEL_IDX_X <= PIXEL_ABS_X - TILE_IDX_X * 16;
- TILE_PIXEL_IDX_Y <= PIXEL_ABS_Y - TILE_IDX_Y * 16;
+ PIXEL_ABS_X <= to_integer(unsigned(X)) + to_integer(unsigned(BG_SHIFT_X)); -- pixel position relative to background canvas
+ PIXEL_ABS_Y <= to_integer(unsigned(Y)) + to_integer(unsigned(BG_SHIFT_Y)); -- pixel position relative to background canvas
+ TILE_IDX_X <= PIXEL_ABS_X / 16; -- tile grid index
+ TILE_IDX_Y <= PIXEL_ABS_Y / 16; -- tile grid index
+ TILE_PIDX_X <= to_unsigned(PIXEL_ABS_X - TILE_IDX_X * 16, TILE_PIDX_X'length); -- (sprite local) pixel coords
+ TILE_PIDX_Y <= to_unsigned(PIXEL_ABS_Y - TILE_IDX_Y * 16, TILE_PIDX_Y'length); -- (sprite local) pixel coords
T_BAM_ADDR <= std_logic_vector(to_unsigned((TILE_IDX_Y * integer(PPU_BG_CANVAS_TILES_H)) + TILE_IDX_X, PPU_BAM_ADDR_WIDTH));
-- BAM data dependant calculations
- TRANSFORM_XI <= std_logic_vector(to_unsigned(TILE_PIXEL_IDX_X, PPU_SPRITE_POS_H_WIDTH));
- TRANSFORM_YI <= std_logic_vector(to_unsigned(TILE_PIXEL_IDX_Y, PPU_SPRITE_POS_V_WIDTH));
transform: component ppu_sprite_transform port map(
- XI => TRANSFORM_XI,
- YI => TRANSFORM_YI,
+ XI => TILE_PIDX_X,
+ YI => TILE_PIDX_Y,
FLIP_H => BAM_DATA_FLIP_H,
FLIP_V => BAM_DATA_FLIP_V,
- XO => TRANSFORM_XO,
- YO => TRANSFORM_YO);
- TRANS_TILE_PIDX_X <= to_integer(unsigned(TRANSFORM_XO));
- TRANS_TILE_PIDX_Y <= to_integer(unsigned(TRANSFORM_YO));
+ XO => TRANS_TILE_PIDX_X,
+ YO => TRANS_TILE_PIDX_Y);
- TRANS_TILE_PIXEL_IDX <= integer(PPU_SPRITE_WIDTH) * TRANS_TILE_PIDX_Y + TRANS_TILE_PIDX_X;
- TILEMAP_WORD_OFFSET <= TRANS_TILE_PIXEL_IDX / PPU_PIXELS_PER_TILE_WORD;
- PIXEL_BIT_OFFSET <= TRANS_TILE_PIXEL_IDX mod PPU_PIXELS_PER_TILE_WORD;
-
- T_TMM_ADDR <= std_logic_vector(to_unsigned(PPU_SPRITE_PIXELS_PER_WORD * to_integer(unsigned(BAM_DATA_TILE_IDX)) + TILEMAP_WORD_OFFSET, PPU_TMM_ADDR_WIDTH));
+ -- TMM address calculations
+ TRANS_TILE_PIDX <= integer(PPU_SPRITE_WIDTH) * to_integer(TRANS_TILE_PIDX_Y) + to_integer(TRANS_TILE_PIDX_X); -- pixel index of sprite
+ TILEMAP_WORD_OFFSET <= TRANS_TILE_PIDX / PPU_PIXELS_PER_TILE_WORD; -- word offset from starting word of sprite
+ PIXEL_BIT_OFFSET <= TRANS_TILE_PIDX mod PPU_PIXELS_PER_TILE_WORD; -- pixel bit offset
+ T_TMM_ADDR <= std_logic_vector(to_unsigned(PPU_SPRITE_PIXELS_PER_WORD * to_integer(unsigned(BAM_DATA_TILE_IDX)) + TILEMAP_WORD_OFFSET, PPU_TMM_ADDR_WIDTH)); -- TMM address
-- TMM DATA
with PIXEL_BIT_OFFSET select
diff --git a/basys3/basys3.srcs/ppu_sprite_fg.vhd b/basys3/basys3.srcs/ppu_sprite_fg.vhd
index 340104a..c3cb59a 100644
--- a/basys3/basys3.srcs/ppu_sprite_fg.vhd
+++ b/basys3/basys3.srcs/ppu_sprite_fg.vhd
@@ -36,11 +36,11 @@ end ppu_sprite_fg;
architecture Behavioral of ppu_sprite_fg is
component ppu_sprite_transform port(
- XI : in std_logic_vector(PPU_SPRITE_POS_H_WIDTH-1 downto 0); -- pixel position relative to tile
- YI : in std_logic_vector(PPU_SPRITE_POS_V_WIDTH-1 downto 0); -- pixel position relative to tile
+ XI : in unsigned(PPU_SPRITE_POS_H_WIDTH-1 downto 0); -- pixel position relative to tile
+ YI : in unsigned(PPU_SPRITE_POS_V_WIDTH-1 downto 0); -- pixel position relative to tile
FLIP_H, FLIP_V : in std_logic; -- flip sprite
- XO : out std_logic_vector(PPU_SPRITE_POS_H_WIDTH-1 downto 0); -- new pixel position relative to tile
- YO : out std_logic_vector(PPU_SPRITE_POS_V_WIDTH-1 downto 0)); -- new pixel position relative to tile
+ XO : out unsigned(PPU_SPRITE_POS_H_WIDTH-1 downto 0); -- new pixel position relative to tile
+ YO : out unsigned(PPU_SPRITE_POS_V_WIDTH-1 downto 0)); -- new pixel position relative to tile
end component;
component er_ram -- exposed register RAM
generic(
@@ -77,15 +77,13 @@ architecture Behavioral of ppu_sprite_fg is
alias FAM_REG_COL_IDX is INT_FAM(12 downto 10); -- Palette index for tile
alias FAM_REG_TILE_IDX is INT_FAM(9 downto 0); -- Tilemap index
- -- signal PIXEL_ABS_X, PIXEL_ABS_Y : integer := 0; -- absolute pixel position (relative to FG canvas instead of viewport)
- -- signal TILE_IDX_X, TILE_IDX_Y : integer := 0; -- background canvas tile grid xy
- -- signal TILE_PIXEL_IDX_X, TILE_PIXEL_IDX_Y : integer := 0; -- xy position of pixel within tile (local tile coords)
- -- signal TRANS_TILE_PIDX_X, TRANS_TILE_PIDX_Y : integer := 0; -- transformed xy position of pixel within tile
- -- signal TRANS_TILE_PIXEL_IDX : integer := 0; -- index of pixel within tile (reading order)
- -- signal TRANSFORM_XI, TRANSFORM_XO : std_logic_vector(PPU_SPRITE_POS_H_WIDTH-1 downto 0); -- transform inputs/outputs (x axis)
- -- signal TRANSFORM_YI, TRANSFORM_YO : std_logic_vector(PPU_SPRITE_POS_V_WIDTH-1 downto 0); -- transform inputs/outputs (y axis)
- -- signal TILEMAP_WORD_OFFSET : integer := 0; -- word offset from tile start address in TMM
- -- signal PIXEL_BIT_OFFSET : integer := 0; -- pixel index within word of TMM
+ signal SPRITE_ACTIVE : std_logic := '0'; -- is pixel in bounding box of sprite
+ signal PIXEL_ABS_X, PIXEL_ABS_Y : integer := 0; -- absolute pixel position (relative to FG canvas instead of viewport)
+ signal TILE_PIDX_X, TRANS_TILE_PIDX_X : unsigned(PPU_SPRITE_POS_H_WIDTH-1 downto 0) := (others => '0'); -- xy position of pixel within tile (local tile coords)
+ signal TILE_PIDX_Y, TRANS_TILE_PIDX_Y : unsigned(PPU_SPRITE_POS_V_WIDTH-1 downto 0) := (others => '0'); -- xy position of pixel within tile (local tile coords)
+ signal TRANS_TILE_PIXEL_IDX : integer := 0; -- index of pixel within tile (reading order)
+ signal TILEMAP_WORD_OFFSET : integer := 0; -- word offset from tile start address in TMM
+ signal PIXEL_BIT_OFFSET : integer := 0; -- pixel index within word of TMM
signal TMM_DATA_PAL_IDX : std_logic_vector(PPU_PALETTE_COLOR_WIDTH-1 downto 0); -- color of palette
begin
-- output drivers
@@ -104,42 +102,39 @@ begin
DATA => FAM_DATA,
REG => INT_FAM);
- -- -- -- FAM address calculations
- -- -- PIXEL_ABS_X <= to_integer(unsigned(X)) + to_integer(unsigned(FG_SHIFT_X));
- -- -- PIXEL_ABS_Y <= to_integer(unsigned(Y)) + to_integer(unsigned(FG_SHIFT_Y));
- -- -- TILE_IDX_X <= PIXEL_ABS_X / 16;
- -- -- TILE_IDX_Y <= PIXEL_ABS_Y / 16;
- -- -- TILE_PIXEL_IDX_X <= PIXEL_ABS_X - TILE_IDX_X * 16;
- -- -- TILE_PIXEL_IDX_Y <= PIXEL_ABS_Y - TILE_IDX_Y * 16;
- -- -- T_FAM_ADDR <= std_logic_vector(to_unsigned((TILE_IDX_Y * integer(PPU_FG_CANVAS_TILES_H)) + TILE_IDX_X, PPU_FAM_ADDR_WIDTH));
-
- -- -- -- FAM data dependant calculations
- -- -- TRANSFORM_XI <= std_logic_vector(to_unsigned(TILE_PIXEL_IDX_X, PPU_SPRITE_POS_H_WIDTH));
- -- -- TRANSFORM_YI <= std_logic_vector(to_unsigned(TILE_PIXEL_IDX_Y, PPU_SPRITE_POS_V_WIDTH));
- -- -- transform: component ppu_sprite_transform port map(
- -- -- XI => TRANSFORM_XI,
- -- -- YI => TRANSFORM_YI,
- -- -- FLIP_H => FAM_DATA_FLIP_H,
- -- -- FLIP_V => FAM_DATA_FLIP_V,
- -- -- XO => TRANSFORM_XO,
- -- -- YO => TRANSFORM_YO);
- -- -- TRANS_TILE_PIDX_X <= to_integer(unsigned(TRANSFORM_XO));
- -- -- TRANS_TILE_PIDX_Y <= to_integer(unsigned(TRANSFORM_YO));
-
- -- -- TRANS_TILE_PIXEL_IDX <= integer(PPU_SPRITE_WIDTH) * TRANS_TILE_PIDX_Y + TRANS_TILE_PIDX_X;
- -- -- TILEMAP_WORD_OFFSET <= TRANS_TILE_PIXEL_IDX / PPU_PIXELS_PER_TILE_WORD;
- -- -- PIXEL_BIT_OFFSET <= TRANS_TILE_PIXEL_IDX mod PPU_PIXELS_PER_TILE_WORD;
-
- -- -- T_TMM_ADDR <= std_logic_vector(to_unsigned(PPU_SPRITE_PIXELS_PER_WORD * to_integer(unsigned(FAM_DATA_TILE_IDX)) + TILEMAP_WORD_OFFSET, PPU_TMM_ADDR_WIDTH));
-
- -- -- -- TMM DATA
- -- -- with PIXEL_BIT_OFFSET select
- -- -- TMM_DATA_PAL_IDX <= R_TMM_DATA(2 downto 0) when 0,
- -- -- R_TMM_DATA(5 downto 3) when 1,
- -- -- R_TMM_DATA(8 downto 6) when 2,
- -- -- R_TMM_DATA(11 downto 9) when 3,
- -- -- R_TMM_DATA(14 downto 12) when 4,
- -- -- (others => '0') when others;
+ SPRITE_ACTIVE <= ((unsigned(X) + 16) >= unsigned(FAM_REG_POS_H)) and
+ ((unsigned(X) + 16) < (unsigned(FAM_REG_POS_H) + to_unsigned(PPU_SPRITE_WIDTH, PPU_POS_H_WIDTH))) and
+ ((unsigned(Y) + 16) >= unsigned(FAM_REG_POS_V)) and
+ ((unsigned(Y) + 16) < (unsigned(FAM_REG_POS_V) + to_unsigned(PPU_SPRITE_HEIGHT, PPU_POS_V_WIDTH)));
+
+ HIT <= SPRITE_ACTIVE and (nor TMM_DATA_PAL_IDX); -- if pixel in sprite hitbox and TMM_DATA_PAL_IDX > 0
+
+ TILE_PIDX_X <= to_unsigned(unsigned(X) + 16 - to_unsigned(FAM_REG_POS_H, TILE_PIDX_X'length), TILE_PIDX_X'length); -- (sprite local) pixel coords
+ TILE_PIDX_Y <= to_unsigned(unsigned(Y) + 16 - to_unsigned(FAM_REG_POS_V, TILE_PIDX_Y'length), TILE_PIDX_Y'length); -- (sprite local) pixel coords
+
+ -- FAM data dependant calculations
+ transform: component ppu_sprite_transform port map(
+ XI => TILE_PIDX_X,
+ YI => TILE_PIDX_Y,
+ FLIP_H => FAM_REG_FLIP_H,
+ FLIP_V => FAM_REG_FLIP_V,
+ XO => TRANS_TILE_PIDX_X,
+ YO => TRANS_TILE_PIDX_Y);
+
+ -- TMM address calculations (sprite word start, word offset, and pixel offset)
+ TRANS_TILE_PIXEL_IDX <= integer(PPU_SPRITE_WIDTH) * to_integer(TRANS_TILE_PIDX_Y) + to_integer(TRANS_TILE_PIDX_X); -- pixel index of sprite
+ TILEMAP_WORD_OFFSET <= TRANS_TILE_PIXEL_IDX / PPU_PIXELS_PER_TILE_WORD; -- word offset from starting word of sprite
+ PIXEL_BIT_OFFSET <= TRANS_TILE_PIXEL_IDX mod PPU_PIXELS_PER_TILE_WORD; -- pixel bit offset
+ T_TMM_ADDR <= std_logic_vector(to_unsigned(PPU_SPRITE_PIXELS_PER_WORD * to_integer(unsigned(FAM_REG_TILE_IDX)) + TILEMAP_WORD_OFFSET, PPU_TMM_ADDR_WIDTH)); -- TMM address
+
+ -- TMM DATA
+ with PIXEL_BIT_OFFSET select
+ TMM_DATA_PAL_IDX <= R_TMM_DATA(2 downto 0) when 0,
+ R_TMM_DATA(5 downto 3) when 1,
+ R_TMM_DATA(8 downto 6) when 2,
+ R_TMM_DATA(11 downto 9) when 3,
+ R_TMM_DATA(14 downto 12) when 4,
+ (others => '0') when others;
-- state machine (pipeline stage counter) + sync r/w
process(CLK, RESET)
diff --git a/basys3/basys3.srcs/ppu_sprite_transform.vhd b/basys3/basys3.srcs/ppu_sprite_transform.vhd
index fa10b9b..f94616c 100644
--- a/basys3/basys3.srcs/ppu_sprite_transform.vhd
+++ b/basys3/basys3.srcs/ppu_sprite_transform.vhd
@@ -5,19 +5,19 @@ use ieee.numeric_std.all;
use work.ppu_consts.all;
entity ppu_sprite_transform is port( -- flip sprites
- XI : in std_logic_vector(PPU_SPRITE_POS_H_WIDTH-1 downto 0); -- pixel position relative to tile
- YI : in std_logic_vector(PPU_SPRITE_POS_V_WIDTH-1 downto 0); -- pixel position relative to tile
+ XI : in unsigned(PPU_SPRITE_POS_H_WIDTH-1 downto 0); -- pixel position relative to tile
+ YI : in unsigned(PPU_SPRITE_POS_V_WIDTH-1 downto 0); -- pixel position relative to tile
FLIP_H, FLIP_V : in std_logic; -- flip sprite
- XO : out std_logic_vector(PPU_SPRITE_POS_H_WIDTH-1 downto 0); -- new pixel position relative to tile
- YO : out std_logic_vector(PPU_SPRITE_POS_V_WIDTH-1 downto 0)); -- new pixel position relative to tile
+ XO : out unsigned(PPU_SPRITE_POS_H_WIDTH-1 downto 0); -- new pixel position relative to tile
+ YO : out unsigned(PPU_SPRITE_POS_V_WIDTH-1 downto 0)); -- new pixel position relative to tile
end ppu_sprite_transform;
architecture Behavioral of ppu_sprite_transform is
- signal FLIPPED_X : std_logic_vector(PPU_SPRITE_POS_H_WIDTH-1 downto 0);
- signal FLIPPED_Y : std_logic_vector(PPU_SPRITE_POS_V_WIDTH-1 downto 0);
+ signal FLIPPED_X : unsigned(PPU_SPRITE_POS_H_WIDTH-1 downto 0);
+ signal FLIPPED_Y : unsigned(PPU_SPRITE_POS_V_WIDTH-1 downto 0);
begin
- FLIPPED_X <= std_logic_vector(to_unsigned(PPU_SPRITE_WIDTH-1 - to_integer(unsigned(XI)), PPU_SPRITE_POS_H_WIDTH));
- FLIPPED_Y <= std_logic_vector(to_unsigned(PPU_SPRITE_HEIGHT-1 - to_integer(unsigned(YI)), PPU_SPRITE_POS_V_WIDTH));
+ FLIPPED_X <= to_unsigned(PPU_SPRITE_WIDTH-1, PPU_SPRITE_POS_H_WIDTH) - XI;
+ FLIPPED_Y <= to_unsigned(PPU_SPRITE_HEIGHT-1, PPU_SPRITE_POS_V_WIDTH) - YI;
XO <= FLIPPED_X when FLIP_V = '1' else XI;
YO <= FLIPPED_Y when FLIP_H = '1' else YI;
diff --git a/basys3/basys3.srcs/ppu_sprite_transform_tb.vhd b/basys3/basys3.srcs/ppu_sprite_transform_tb.vhd
index cec8c20..516a653 100644
--- a/basys3/basys3.srcs/ppu_sprite_transform_tb.vhd
+++ b/basys3/basys3.srcs/ppu_sprite_transform_tb.vhd
@@ -12,18 +12,18 @@ end ppu_sprite_transform_tb;
architecture behavioral of ppu_sprite_transform_tb is
component ppu_sprite_transform port( -- flip sprites
- XI : in std_logic_vector(PPU_SPRITE_POS_H_WIDTH-1 downto 0); -- pixel position relative to tile
- YI : in std_logic_vector(PPU_SPRITE_POS_V_WIDTH-1 downto 0); -- pixel position relative to tile
+ XI : in unsigned(PPU_SPRITE_POS_H_WIDTH-1 downto 0); -- pixel position relative to tile
+ YI : in unsigned(PPU_SPRITE_POS_V_WIDTH-1 downto 0); -- pixel position relative to tile
FLIP_H, FLIP_V : in std_logic; -- flip sprite
- XO : out std_logic_vector(PPU_SPRITE_POS_H_WIDTH-1 downto 0); -- new pixel position relative to tile
- YO : out std_logic_vector(PPU_SPRITE_POS_V_WIDTH-1 downto 0)); -- new pixel position relative to tile
+ XO : out unsigned(PPU_SPRITE_POS_H_WIDTH-1 downto 0); -- new pixel position relative to tile
+ YO : out unsigned(PPU_SPRITE_POS_V_WIDTH-1 downto 0)); -- new pixel position relative to tile
end component;
- signal XI : std_logic_vector(PPU_SPRITE_POS_H_WIDTH-1 downto 0);
- signal YI : std_logic_vector(PPU_SPRITE_POS_V_WIDTH-1 downto 0);
+ signal XI : unsigned(PPU_SPRITE_POS_H_WIDTH-1 downto 0);
+ signal YI : unsigned(PPU_SPRITE_POS_V_WIDTH-1 downto 0);
signal FLIP_H, FLIP_V : std_logic := '0';
- signal XO : std_logic_vector(PPU_SPRITE_POS_H_WIDTH-1 downto 0);
- signal YO : std_logic_vector(PPU_SPRITE_POS_V_WIDTH-1 downto 0);
+ signal XO : unsigned(PPU_SPRITE_POS_H_WIDTH-1 downto 0);
+ signal YO : unsigned(PPU_SPRITE_POS_V_WIDTH-1 downto 0);
begin
uut : component ppu_sprite_transform
port map(
@@ -36,12 +36,12 @@ begin
tb : process
begin
- XI <= std_logic_vector(to_unsigned(4, PPU_SPRITE_POS_H_WIDTH));
- YI <= std_logic_vector(to_unsigned(6, PPU_SPRITE_POS_V_WIDTH));
+ XI <= to_unsigned(4, PPU_SPRITE_POS_H_WIDTH);
+ YI <= to_unsigned(6, PPU_SPRITE_POS_V_WIDTH);
wait for 5 ns;
- XI <= std_logic_vector(to_unsigned(2, PPU_SPRITE_POS_H_WIDTH));
- YI <= std_logic_vector(to_unsigned(14, PPU_SPRITE_POS_V_WIDTH));
+ XI <= to_unsigned(2, PPU_SPRITE_POS_H_WIDTH);
+ YI <= to_unsigned(14, PPU_SPRITE_POS_V_WIDTH);
wait for 5 ns;
FLIP_H <= '1';
@@ -50,15 +50,15 @@ begin
FLIP_V <= '1';
wait for 5 ns;
- XI <= std_logic_vector(to_unsigned(6, PPU_SPRITE_POS_H_WIDTH));
- YI <= std_logic_vector(to_unsigned(8, PPU_SPRITE_POS_V_WIDTH));
+ XI <= to_unsigned(6, PPU_SPRITE_POS_H_WIDTH);
+ YI <= to_unsigned(8, PPU_SPRITE_POS_V_WIDTH);
wait for 5 ns;
FLIP_H <= '0';
wait for 5 ns;
- XI <= std_logic_vector(to_unsigned(2, PPU_SPRITE_POS_H_WIDTH));
- YI <= std_logic_vector(to_unsigned(14, PPU_SPRITE_POS_V_WIDTH));
+ XI <= to_unsigned(2, PPU_SPRITE_POS_H_WIDTH);
+ YI <= to_unsigned(14, PPU_SPRITE_POS_V_WIDTH);
wait for 5 ns;
wait; -- stop for simulator
diff --git a/basys3/basys3.xpr b/basys3/basys3.xpr
index 7bc2f3c..d828223 100644
--- a/basys3/basys3.xpr
+++ b/basys3/basys3.xpr
@@ -61,7 +61,7 @@
<Option Name="IPStaticSourceDir" Val="$PIPUSERFILESDIR/ipstatic"/>
<Option Name="EnableBDX" Val="FALSE"/>
<Option Name="DSABoardId" Val="basys3"/>
- <Option Name="WTXSimLaunchSim" Val="42"/>
+ <Option Name="WTXSimLaunchSim" Val="55"/>
<Option Name="WTModelSimLaunchSim" Val="0"/>
<Option Name="WTQuestaLaunchSim" Val="0"/>
<Option Name="WTIesLaunchSim" Val="0"/>
@@ -168,7 +168,7 @@
</File>
<Config>
<Option Name="DesignMode" Val="RTL"/>
- <Option Name="TopModule" Val="ppu"/>
+ <Option Name="TopModule" Val="ppu_sprite_bg"/>
<Option Name="dataflowViewerSettings" Val="min_width=16"/>
</Config>
</FileSet>
@@ -247,18 +247,11 @@
<Option Name="PamSignalDriverFile" Val="xil_bypass_driver"/>
<Option Name="PamPseudoTop" Val="pseudo_tb"/>
<Option Name="SrcSet" Val="sources_1"/>
+ <Option Name="NLNetlistMode" Val="funcsim"/>
</Config>
</FileSet>
<FileSet Name="utils_1" Type="Utils" RelSrcDir="$PSRCDIR/utils_1" RelGenDir="$PGENDIR/utils_1">
<Filter Type="Utils"/>
- <File Path="$PSRCDIR/utils_1/imports/synth_1/ppu_sprite_bg.dcp">
- <FileInfo>
- <Attr Name="UsedIn" Val="synthesis"/>
- <Attr Name="UsedIn" Val="implementation"/>
- <Attr Name="UsedInSteps" Val="synth_1"/>
- <Attr Name="AutoDcp" Val="1"/>
- </FileInfo>
- </File>
<Config>
<Option Name="TopAutoSet" Val="TRUE"/>
</Config>
@@ -312,7 +305,7 @@
</Simulator>
</Simulators>
<Runs Version="1" Minor="19">
- <Run Id="synth_1" Type="Ft3:Synth" SrcSet="sources_1" Part="xc7a35tcpg236-1" ConstrsSet="constrs_1" Description="Vivado Synthesis Defaults" AutoIncrementalCheckpoint="true" IncrementalCheckpoint="$PSRCDIR/utils_1/imports/synth_1/ppu_sprite_bg.dcp" WriteIncrSynthDcp="false" State="current" Dir="$PRUNDIR/synth_1" IncludeInArchive="true" IsChild="false" AutoIncrementalDir="$PSRCDIR/utils_1/imports/synth_1" AutoRQSDir="$PSRCDIR/utils_1/imports/synth_1">
+ <Run Id="synth_1" Type="Ft3:Synth" SrcSet="sources_1" Part="xc7a35tcpg236-1" ConstrsSet="constrs_1" Description="Vivado Synthesis Defaults" AutoIncrementalCheckpoint="true" WriteIncrSynthDcp="false" State="current" Dir="$PRUNDIR/synth_1" IncludeInArchive="true" IsChild="false" AutoIncrementalDir="$PSRCDIR/utils_1/imports/synth_1" AutoRQSDir="$PSRCDIR/utils_1/imports/synth_1">
<Strategy Version="1" Minor="2">
<StratHandle Name="Vivado Synthesis Defaults" Flow="Vivado Synthesis 2022"/>
<Step Id="synth_design"/>