diff options
author | lonkaars <loek@pipeframe.xyz> | 2023-02-18 15:09:01 +0100 |
---|---|---|
committer | lonkaars <loek@pipeframe.xyz> | 2023-02-18 15:09:01 +0100 |
commit | db386aab71014ffb37fb24e02c4b8a9194a0b4f9 (patch) | |
tree | bf645a27420451f9053055730eb8cd2f82518494 /basys3/basys3.srcs | |
parent | 94e6cdf0b1594363c9ec3ac5cd364d3c2e9218fc (diff) |
ppu pceg done + ppu top.vhdl done
Diffstat (limited to 'basys3/basys3.srcs')
-rw-r--r-- | basys3/basys3.srcs/ppu.vhd | 78 | ||||
-rw-r--r-- | basys3/basys3.srcs/ppu_pceg.vhdl | 46 | ||||
-rw-r--r-- | basys3/basys3.srcs/ppu_pceg_tb.vhdl | 47 |
3 files changed, 140 insertions, 31 deletions
diff --git a/basys3/basys3.srcs/ppu.vhd b/basys3/basys3.srcs/ppu.vhd index 59e64c3..efe2125 100644 --- a/basys3/basys3.srcs/ppu.vhd +++ b/basys3/basys3.srcs/ppu.vhd @@ -2,17 +2,16 @@ library ieee; use ieee.std_logic_1164.all; --use ieee.numeric_std.all; -entity ppu is - port( - CLK100: in std_logic; -- system clock - RESET: in std_logic; -- global (async) system reset - EN: in std_logic; -- PPU VRAM enable (enable ADDR and DATA tri-state drivers) - WEN: in std_logic; -- PPU VRAM write enable - ADDR: in std_logic_vector(15 downto 0); -- PPU VRAM ADDR - DATA: in std_logic_vector(15 downto 0); - R,G,B: out std_logic_vector(3 downto 0); - NVSYNC, NHSYNC: out std_logic; -- native VGA out - TVSYNC, TVBLANK, THSYNC, THBLANK: out std_logic); -- tiny VGA out +entity ppu is port( + CLK100: in std_logic; -- system clock + RESET: in std_logic; -- global (async) system reset + EN: in std_logic; -- PPU VRAM enable (enable ADDR and DATA tri-state drivers) + WEN: in std_logic; -- PPU VRAM write enable + ADDR: in std_logic_vector(15 downto 0); -- PPU VRAM ADDR + DATA: in std_logic_vector(15 downto 0); + R,G,B: out std_logic_vector(3 downto 0); + NVSYNC, NHSYNC: out std_logic; -- native VGA out + TVSYNC, TVBLANK, THSYNC, THBLANK: out std_logic); -- tiny VGA out end ppu; architecture Behavioral of ppu is @@ -21,7 +20,6 @@ architecture Behavioral of ppu is constant PPU_PALETTE_IDX_WIDTH: natural := 3; -- palette index width (within sprite) constant PPU_PALETTE_WIDTH: natural := 3; -- palette index width (palette table) constant PPU_PALETTE_CIDX_WIDTH: natural := PPU_PALETTE_IDX_WIDTH + PPU_PALETTE_WIDTH; -- global palette index width - constant PPU_PIPELINE_STAGE_COUNT: natural := 5; -- amount of pipeline clock edges to generate constant PPU_TMM_ADDR_WIDTH: natural := 16; constant PPU_TMM_DATA_WIDTH: natural := 16; constant PPU_BAM_ADDR_WIDTH: natural := 11; @@ -37,8 +35,10 @@ architecture Behavioral of ppu is component ppu_pceg port( -- pipeline clock edge generator CLK: in std_logic; -- system clock - R: in std_logic; -- async reset - S: out std_logic_vector(PPU_PIPELINE_STAGE_COUNT-1 downto 0)); -- pipeline stages + RESET: in std_logic; -- async reset + SPRITE: out std_logic; -- sprite info fetch + sprite pixel fetch + COMP_PAL: out std_logic; -- compositor + palette lookup + DONE: out std_logic); -- last pipeline stage done end component; component ppu_addr_dec port( -- pipeline clock edge generator WEN: in std_logic; -- EXT write enable @@ -95,6 +95,7 @@ architecture Behavioral of ppu is component ppu_sprite_bg port( -- background sprite -- inputs CLK: in std_logic; -- system clock + RESET: in std_logic; -- reset clock counter 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 @@ -115,7 +116,7 @@ architecture Behavioral of ppu is component ppu_sprite_fg port( -- foreground sprite -- inputs CLK: in std_logic; -- system clock - RESET: in std_logic; -- reset internal memory + RESET: in std_logic; -- reset internal memory and clock counters 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 @@ -157,7 +158,6 @@ architecture Behavioral of ppu is X: out std_logic_vector(PPU_POS_H_WIDTH-1 downto 0); -- current screen pixel x Y: out std_logic_vector(PPU_POS_V_WIDTH-1 downto 0); -- current screen pixel y - PREADY: out std_logic; -- current pixel ready (pixel color is stable) VSYNC, VBLANK, HSYNC, HBLANK: out std_logic); -- VGA sync outputs @@ -177,7 +177,7 @@ architecture Behavioral of ppu is -- signals signal SYSCLK, SYSRST: std_logic; -- system clock and reset - signal PL_S: std_logic_vector(PPU_PIPELINE_STAGE_COUNT-1 downto 0); -- pipeline stages + signal PL_SPRITE, PL_COMP_PAL, PL_DONE: std_logic; -- pipeline stages signal TMM_WEN, BAM_WEN, FAM_WEN, PAL_WEN, AUX_WEN: std_logic; signal TMM_AI, TMM_AO: std_logic_vector(PPU_TMM_ADDR_WIDTH-1 downto 0); signal BAM_AI, BAM_AO: std_logic_vector(PPU_BAM_ADDR_WIDTH-1 downto 0); @@ -194,8 +194,8 @@ architecture Behavioral of ppu is signal FG_EN, FG_HIT: std_logic_vector(PPU_FG_SPRITE_COUNT-1 downto 0); signal X: std_logic_vector(PPU_POS_H_WIDTH-1 downto 0); -- current screen pixel x signal Y: std_logic_vector(PPU_POS_V_WIDTH-1 downto 0); -- current screen pixel y - signal TR,TG,TB: std_logic_vector(PPU_COLOR_OUTPUT_DEPTH-1 downto 0); -- tiny RGB out (to be buffered) - signal PREADY: std_logic; -- current pixel color stable + signal UR,UG,UB: std_logic_vector(PPU_COLOR_OUTPUT_DEPTH-1 downto 0); -- unstable RGB (to be buffered) + signal SR,SG,SB: std_logic_vector(PPU_COLOR_OUTPUT_DEPTH-1 downto 0); -- stable RGB (buffered until PL_COMP_PAL) signal BG_SHIFT_X: std_logic_vector(PPU_POS_H_WIDTH-1 downto 0); signal BG_SHIFT_Y: std_logic_vector(PPU_POS_V_WIDTH-1 downto 0); signal FG_FETCH: std_logic; @@ -205,8 +205,10 @@ begin pipeline_clock_edge_generator: component ppu_pceg port map( CLK => SYSCLK, - R => SYSRST, - S => PL_S); + RESET => SYSRST, + SPRITE => PL_SPRITE, + COMP_PAL => PL_COMP_PAL, + DONE => PL_DONE); address_decoder: component ppu_addr_dec port map( EN => EN, @@ -256,7 +258,8 @@ begin FG_FETCH => FG_FETCH); background_sprite: component ppu_sprite_bg port map( - CLK => SYSCLK, + CLK => PL_SPRITE, + RESET => SYSRST, OE => BG_EN, X => X, Y => Y, @@ -270,7 +273,7 @@ begin foreground_sprites: for FG_IDX in 0 to PPU_FG_SPRITE_COUNT-1 generate foreground_sprite: component ppu_sprite_fg port map( - CLK => SYSCLK, + CLK => PL_SPRITE, RESET => SYSRST, OE => FG_EN(FG_IDX), X => X, @@ -297,16 +300,29 @@ begin PAL_WEN => PAL_WEN, PAL_ADDR => PAL_AO, PAL_DATA => DATA(PPU_PAL_DATA_WIDTH-1 downto 0), - R => TR, - G => TG, - B => TB); + R => UR, + G => UG, + B => UB); + + -- palette lookup output buffer (pipeline stage 5) + process(PL_COMP_PAL, SYSRST) + begin + if SYSRST = '1' then + SR <= x"0"; + SG <= x"0"; + SB <= x"0"; + elsif rising_edge(PL_COMP_PAL) then + SR <= UR; + SG <= UG; + SB <= UB; + end if; + end process; tiny_vga_signal_generator: component ppu_vga_tiny port map( -- tiny vga signal generator CLK => SYSCLK, RESET => SYSRST, X => X, Y => Y, - PREADY => PREADY, VSYNC => TVSYNC, VBLANK => TVBLANK, HSYNC => THSYNC, @@ -317,10 +333,10 @@ begin RESET => SYSRST, X => X, Y => Y, - PREADY => PREADY, - RI => TR, - GI => TG, - BI => TB, + PREADY => PL_DONE, + RI => SR, + GI => SG, + BI => SB, RO => R, GO => G, BO => B, diff --git a/basys3/basys3.srcs/ppu_pceg.vhdl b/basys3/basys3.srcs/ppu_pceg.vhdl new file mode 100644 index 0000000..a5b86ae --- /dev/null +++ b/basys3/basys3.srcs/ppu_pceg.vhdl @@ -0,0 +1,46 @@ +library ieee; +use ieee.std_logic_1164.all; +--use ieee.numeric_std.all; + +entity ppu_pceg is port( + CLK: in std_logic; -- system clock + RESET: in std_logic; -- async reset + SPRITE: out std_logic; -- sprite info fetch + sprite pixel fetch + COMP_PAL: out std_logic; -- compositor + palette lookup + DONE: out std_logic); -- last pipeline stage done +end ppu_pceg; + +architecture Behavioral of ppu_pceg is + constant PPU_PL_TOTAL_STAGES: natural := 14; + + type states is (PL_SPRITE, PL_COMP_PAL, PL_DONE); + signal state: states := PL_SPRITE; +begin + -- output drivers + SPRITE <= CLK when state = PL_SPRITE else '0'; + COMP_PAL <= CLK when state = PL_COMP_PAL else '0'; + DONE <= '1' when state = PL_DONE else '0'; + + process(CLK, RESET) + variable CLK_IDX: natural range 0 to PPU_PL_TOTAL_STAGES+1 := 0; + begin + if RESET = '1' then + state <= PL_SPRITE; + elsif rising_edge(CLK) then + -- clock counter ranges + if CLK_IDX < 4 then + state <= PL_SPRITE; + elsif CLK_IDX < 5 then + state <= PL_COMP_PAL; + else + state <= PL_DONE; + end if; + + -- increment clock counter + CLK_IDX := CLK_IDX + 1; + if CLK_IDX = PPU_PL_TOTAL_STAGES then + CLK_IDX := 0; + end if; + end if; + end process; +end Behavioral; diff --git a/basys3/basys3.srcs/ppu_pceg_tb.vhdl b/basys3/basys3.srcs/ppu_pceg_tb.vhdl new file mode 100644 index 0000000..137d4b4 --- /dev/null +++ b/basys3/basys3.srcs/ppu_pceg_tb.vhdl @@ -0,0 +1,47 @@ +library ieee; +library unisim; + +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +use unisim.vcomponents.all; + +entity ppu_pceg_tb is +end ppu_pceg_tb; + +architecture behavioral of ppu_pceg_tb is + component ppu_pceg port( + CLK: in std_logic; -- system clock + RESET: in std_logic; -- async reset + SPRITE: out std_logic; -- sprite info fetch + sprite pixel fetch + COMP_PAL: out std_logic; -- compositor + palette lookup + DONE: out std_logic); -- last pipeline stage done + end component; + signal CLK: std_logic := '0'; + signal RESET: std_logic := '0'; + signal SPRITE: std_logic; + signal COMP_PAL: std_logic; + signal DONE: std_logic; + +begin + uut: ppu_pceg port map( + CLK => CLK, + RESET => RESET, + SPRITE => SPRITE, + COMP_PAL => COMP_PAL, + DONE => DONE); + + tb: process + begin + for i in 0 to 32 loop + if i > 20 then + RESET <= '1'; + end if; + + wait for 5 ns; + CLK <= '1'; + wait for 5 ns; + CLK <= '0'; + end loop; + wait; -- stop for simulator + end process; +end; |