diff options
Diffstat (limited to 'basys3/basys3.srcs')
-rw-r--r-- | basys3/basys3.srcs/ppu_pceg.vhd | 34 | ||||
-rw-r--r-- | basys3/basys3.srcs/ppu_pceg_consts.vhd | 1 | ||||
-rw-r--r-- | basys3/basys3.srcs/ppu_sprite_bg.vhd | 29 | ||||
-rw-r--r-- | basys3/basys3.srcs/ppu_sprite_bg_tb.vhd | 6 | ||||
-rw-r--r-- | basys3/basys3.srcs/ppu_sprite_fg.vhd | 40 |
5 files changed, 61 insertions, 49 deletions
diff --git a/basys3/basys3.srcs/ppu_pceg.vhd b/basys3/basys3.srcs/ppu_pceg.vhd index f87c60d..a491244 100644 --- a/basys3/basys3.srcs/ppu_pceg.vhd +++ b/basys3/basys3.srcs/ppu_pceg.vhd @@ -25,9 +25,16 @@ begin SPRITE_FG <= PL_FG_IDLE; DISPCTL_BWEN <= '0'; elsif falling_edge(CLK) then + -- increment clock counter + CLK_IDX := CLK_IDX + 1; + if CLK_IDX = PPU_PCEG_TOTAL_STAGES then + CLK_IDX := 0; + end if; + + CLK_IDX_T <= CLK_IDX; + case CLK_IDX is when 0 => - DISPCTL_BWEN <= '0'; SPRITE_BG <= PL_BG_IDLE; SPRITE_FG <= PL_FG_IDLE; SPRITE_FG_HIT <= PL_HIT_INACCURATE; @@ -38,27 +45,26 @@ begin SPRITE_BG <= PL_BG_BAM_DATA; SPRITE_FG <= PL_FG_TMM_DATA; when 3 => - SPRITE_BG <= PL_BG_TMM_ADDR; + SPRITE_BG <= PL_BG_IDLE; SPRITE_FG <= PL_FG_IDLE; SPRITE_FG_HIT <= PL_HIT_ACCURATE; - when 4 => + when 4 => null; + when 5 => null; + when 6 => + SPRITE_BG <= PL_BG_TMM_ADDR; + when 7 => SPRITE_BG <= PL_BG_TMM_DATA; - when 5 => + when 8 => SPRITE_BG <= PL_BG_IDLE; - when 6 => + when 9 => null; + when 10 => null; + when 11 => DISPCTL_BWEN <= '1'; - when 7 => + when 12 => null; + when 13 => DISPCTL_BWEN <= '0'; when others => null; end case; - - -- increment clock counter - CLK_IDX := CLK_IDX + 1; - if CLK_IDX = PPU_PCEG_TOTAL_STAGES then - CLK_IDX := 0; - end if; - - CLK_IDX_T <= CLK_IDX; end if; end process; end Behavioral; diff --git a/basys3/basys3.srcs/ppu_pceg_consts.vhd b/basys3/basys3.srcs/ppu_pceg_consts.vhd index 3a9775a..395c386 100644 --- a/basys3/basys3.srcs/ppu_pceg_consts.vhd +++ b/basys3/basys3.srcs/ppu_pceg_consts.vhd @@ -1,6 +1,5 @@ library ieee; use ieee.std_logic_1164.all; -use work.ppu_consts.all; package ppu_pceg_consts is constant PPU_PCEG_TOTAL_STAGES : natural := 16; diff --git a/basys3/basys3.srcs/ppu_sprite_bg.vhd b/basys3/basys3.srcs/ppu_sprite_bg.vhd index 9b6643e..a0c4ba8 100644 --- a/basys3/basys3.srcs/ppu_sprite_bg.vhd +++ b/basys3/basys3.srcs/ppu_sprite_bg.vhd @@ -110,28 +110,33 @@ begin begin if RESET = '1' then -- reset internal pipeline registers - R_BAM_ADDR <= (others => '0'); R_BAM_DATA <= (others => '0'); - R_TMM_ADDR <= (others => '0'); R_TMM_DATA <= (others => '0'); elsif falling_edge(CLK) then - BAM_ADDR_EN <= true when PL_STAGE = PL_BG_BAM_ADDR else false; - TMM_ADDR_EN <= true when PL_STAGE = PL_BG_TMM_ADDR else false; - -- R_BAM_ADDR <= T_BAM_ADDR; - -- R_BAM_DATA <= T_BAM_DATA; - -- R_TMM_ADDR <= T_TMM_ADDR; - -- R_TMM_DATA <= T_TMM_DATA; case PL_STAGE is - when PL_BG_BAM_ADDR => - R_BAM_ADDR <= T_BAM_ADDR; when PL_BG_BAM_DATA => R_BAM_DATA <= T_BAM_DATA; - when PL_BG_TMM_ADDR => - R_TMM_ADDR <= T_TMM_ADDR; when PL_BG_TMM_DATA => R_TMM_DATA <= T_TMM_DATA; when others => null; end case; end if; end process; + + process(CLK, RESET) + begin + if RESET = '1' then + BAM_ADDR_EN <= false; + + R_BAM_ADDR <= (others => '0'); + R_TMM_ADDR <= (others => '0'); + TMM_ADDR_EN <= false; + elsif rising_edge(CLK) then + BAM_ADDR_EN <= true when PL_STAGE = PL_BG_BAM_ADDR else false; + TMM_ADDR_EN <= true when PL_STAGE = PL_BG_TMM_ADDR else false; + + R_BAM_ADDR <= T_BAM_ADDR; + R_TMM_ADDR <= T_TMM_ADDR; + end if; + end process; end Behavioral; diff --git a/basys3/basys3.srcs/ppu_sprite_bg_tb.vhd b/basys3/basys3.srcs/ppu_sprite_bg_tb.vhd index 65da15c..5074103 100644 --- a/basys3/basys3.srcs/ppu_sprite_bg_tb.vhd +++ b/basys3/basys3.srcs/ppu_sprite_bg_tb.vhd @@ -6,6 +6,7 @@ use ieee.std_logic_1164.all; use ieee.numeric_std.all; use unisim.vcomponents.all; use work.ppu_consts.all; +use work.ppu_pceg_consts.all; entity ppu_sprite_bg_tb is end ppu_sprite_bg_tb; @@ -13,8 +14,9 @@ end ppu_sprite_bg_tb; architecture Behavioral of ppu_sprite_bg_tb is component ppu_sprite_bg port( -- inputs - CLK : in std_logic; -- pipeline clock + CLK : in std_logic; -- system clock RESET : in std_logic; -- reset clock counter + PL_STAGE : in ppu_sprite_bg_pl_state; -- pipeline stage OE : in std_logic; -- output enable (of CIDX) X : in std_logic_vector(PPU_POS_H_WIDTH-1 downto 0); -- current screen pixel x Y : in std_logic_vector(PPU_POS_V_WIDTH-1 downto 0); -- current screen pixel y @@ -44,10 +46,12 @@ architecture Behavioral of ppu_sprite_bg_tb is signal TMM_ADDR : std_logic_vector(PPU_TMM_ADDR_WIDTH-1 downto 0); signal TMM_DATA : std_logic_vector(PPU_TMM_DATA_WIDTH-1 downto 0) := (others => '0'); signal CIDX : std_logic_vector(PPU_PALETTE_CIDX_WIDTH-1 downto 0); -- output color + signal PL_STAGE : ppu_sprite_bg_pl_state; begin uut : ppu_sprite_bg port map( CLK => CLK, RESET => RESET, + PL_STAGE => PL_BG_IDLE, OE => OE, X => X, Y => Y, diff --git a/basys3/basys3.srcs/ppu_sprite_fg.vhd b/basys3/basys3.srcs/ppu_sprite_fg.vhd index 9aabd88..94fecaa 100644 --- a/basys3/basys3.srcs/ppu_sprite_fg.vhd +++ b/basys3/basys3.srcs/ppu_sprite_fg.vhd @@ -82,10 +82,8 @@ architecture Behavioral of ppu_sprite_fg is signal TILEMAP_WORD : unsigned(PPU_TMM_ADDR_WIDTH-1 downto 0) := (others => '0'); signal TILEMAP_WORD_OFFSET : integer := 0; -- word offset from tile start address in TMM signal TMM_DATA_COL_IDX : std_logic_vector(PPU_PALETTE_COLOR_WIDTH-1 downto 0); -- color of palette - - signal PL_STAGE_NOW : ppu_sprite_fg_pl_state; - signal PL_HIT_NOW : ppu_sprite_fg_hit_pl_state; + signal TMM_ADDR_EN : boolean := false; begin -- FAM memory FAM : component er_ram @@ -137,10 +135,10 @@ begin inaccurate_occlusion_shims: if IDX >= PPU_ACCURATE_FG_SPRITE_COUNT generate -- state machine for synchronizing pipeline stages begin - HIT <= (SPRITE_ACTIVE) when PL_HIT_NOW = PL_HIT_INACCURATE else - (SPRITE_ACTIVE and (or TMM_DATA_COL_IDX)) when PL_HIT_NOW = PL_HIT_ACCURATE else '0'; + HIT <= (SPRITE_ACTIVE) when PL_HIT = PL_HIT_INACCURATE else + (SPRITE_ACTIVE and (or TMM_DATA_COL_IDX)) when PL_HIT = PL_HIT_ACCURATE else '0'; -- only fetch if OE is high, and during the second pipeline stage - TMM_ADDR <= R_TMM_ADDR when OE = '1' and PL_STAGE_NOW = PL_FG_TMM_ADDR else (others => 'Z'); + TMM_ADDR <= R_TMM_ADDR when OE = '1' and TMM_ADDR_EN else (others => 'Z'); T_TMM_ADDR <= std_logic_vector(TILEMAP_WORD + to_unsigned(TILEMAP_WORD_OFFSET, PPU_TMM_ADDR_WIDTH)); -- TMM address -- TMM DATA @@ -152,28 +150,15 @@ begin R_TMM_DATA(14 downto 12) when 4, (others => '0') when others; - -- rising edge clock process (buffer pipeline stage) - process(CLK, RESET) - begin - if rising_edge(CLK) then - PL_HIT_NOW <= PL_HIT; - PL_STAGE_NOW <= PL_STAGE; - end if; - end process; - - -- falling edge clock process (read buffered pipeline stage) + -- rising edge process (read/write) process(CLK, RESET) begin if RESET = '1' then - -- reset internal pipeline registers - R_TMM_ADDR <= (others => '0'); R_TMM_DATA <= (others => '0'); elsif OE = '0' then null; -- don't read/write if current sprite is not the top sprite elsif falling_edge(CLK) then - case PL_STAGE_NOW is - when PL_FG_TMM_ADDR => - R_TMM_ADDR <= T_TMM_ADDR; + case PL_STAGE is when PL_FG_TMM_DATA => R_TMM_DATA <= T_TMM_DATA; when others => null; @@ -181,6 +166,19 @@ begin end if; end process; end generate; + -- falling edge process (TMM ADDR master control) + process(CLK, RESET) + begin + if RESET = '1' then + TMM_ADDR_EN <= false; + + R_TMM_ADDR <= (others => '0'); + elsif rising_edge(CLK) then + TMM_ADDR_EN <= true when PL_STAGE = PL_FG_TMM_ADDR else false; + + R_TMM_ADDR <= T_TMM_ADDR; + end if; + end process; accurate_occlusion_logic: if IDX < PPU_ACCURATE_FG_SPRITE_COUNT generate -- TMM cache lines |