aboutsummaryrefslogtreecommitdiff
path: root/basys3
diff options
context:
space:
mode:
Diffstat (limited to 'basys3')
-rw-r--r--basys3/basys3.srcs/ppu.vhd183
1 files changed, 116 insertions, 67 deletions
diff --git a/basys3/basys3.srcs/ppu.vhd b/basys3/basys3.srcs/ppu.vhd
index 2f16956..be4c404 100644
--- a/basys3/basys3.srcs/ppu.vhd
+++ b/basys3/basys3.srcs/ppu.vhd
@@ -16,11 +16,24 @@ entity ppu is
end ppu;
architecture Behavioral of ppu is
- constant PPU_FG_SPRITE_COUNT: natural := 128;
- constant PPU_PALETTE_IDX_SIZE: natural := 3;
- constant PPU_PALETTE_SIZE: natural := 3;
- constant PPU_PALETTE_CIDX_SIZE: natural := PPU_PALETTE_IDX_SIZE + PPU_PALETTE_SIZE;
- constant PPU_PIPELINE_STAGE_COUNT: natural := 5;
+ constant PPU_FG_SPRITE_COUNT: natural := 1; -- amount of foreground sprites
+ constant PPU_COLOR_OUTPUT_DEPTH: natural := 4; -- VGA output channel depth
+ 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;
+ constant PPU_BAM_DATA_WIDTH: natural := 15;
+ constant PPU_FAM_ADDR_WIDTH: natural := 8;
+ constant PPU_FAM_DATA_WIDTH: natural := 16;
+ constant PPU_PAL_ADDR_WIDTH: natural := 6;
+ constant PPU_PAL_DATA_WIDTH: natural := 12;
+ constant PPU_AUX_ADDR_WIDTH: natural := 2;
+ constant PPU_AUX_DATA_WIDTH: natural := 16;
+ 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
component ppu_pceg port( -- pipeline clock edge generator
CLK: in std_logic; -- system clock
@@ -28,76 +41,89 @@ architecture Behavioral of ppu is
S: out std_logic_vector(PPU_PIPELINE_STAGE_COUNT-1 downto 0)); -- pipeline stages
end component;
component ppu_addr_dec port( -- pipeline clock edge generator
- EN: in std_logic; -- ADDR enable (tri-state driver)
- WEN: in std_logic; -- write enable
- ADDR: in std_logic_vector(15 downto 0); -- address in
-
- ADDR_DRV: out std_logic_vector(15 downto 0); -- address out driver
+ WEN: in std_logic; -- EXT write enable
TMM_WEN,
BAM_WEN,
FAM_WEN,
PAL_WEN,
- AUX_WEN: out std_logic);
+ AUX_WEN: out std_logic; -- write enable MUX
+ TMM_DI: out std_logic_vector(PPU_TMM_DATA_WIDTH-1 downto 0); -- TMM write DATA MUX
+ BAM_DI: out std_logic_vector(PPU_BAM_DATA_WIDTH-1 downto 0); -- BAM write DATA MUX
+ FAM_DI: out std_logic_vector(PPU_FAM_DATA_WIDTH-1 downto 0); -- FAM write DATA MUX
+ PAL_DI: out std_logic_vector(PPU_PAL_DATA_WIDTH-1 downto 0); -- PAL write DATA MUX
+ AUX_DI: out std_logic_vector(PPU_AUX_DATA_WIDTH-1 downto 0); -- AUX write DATA MUX
+ EN: in std_logic; -- EXT *ADDR enable (switch *AO to ADDR instead of *AI)
+ ADDR: in std_logic_vector(15 downto 0); -- address in
+ TMM_AI: in std_logic_vector(PPU_TMM_ADDR_WIDTH-1 downto 0);
+ BAM_AI: in std_logic_vector(PPU_BAM_ADDR_WIDTH-1 downto 0);
+ FAM_AI: in std_logic_vector(PPU_FAM_ADDR_WIDTH-1 downto 0);
+ PAL_AI: in std_logic_vector(PPU_PAL_ADDR_WIDTH-1 downto 0);
+ AUX_AI: in std_logic_vector(PPU_AUX_ADDR_WIDTH-1 downto 0);
+ TMM_AO: out std_logic_vector(PPU_TMM_ADDR_WIDTH-1 downto 0);
+ BAM_AO: out std_logic_vector(PPU_BAM_ADDR_WIDTH-1 downto 0);
+ FAM_AO: out std_logic_vector(PPU_FAM_ADDR_WIDTH-1 downto 0);
+ PAL_AO: out std_logic_vector(PPU_PAL_ADDR_WIDTH-1 downto 0);
+ AUX_AO: out std_logic_vector(PPU_AUX_ADDR_WIDTH-1 downto 0));
end component;
component ppu_bam port( -- BAM block memory
clka: in std_logic;
rsta: in std_logic;
wea: in std_logic_vector(0 downto 0);
- addra: in std_logic_vector(10 downto 0);
- dina: in std_logic_vector(14 downto 0);
- douta: out std_logic_vector(14 downto 0);
+ addra: in std_logic_vector(PPU_BAM_ADDR_WIDTH-1 downto 0);
+ dina: in std_logic_vector(PPU_BAM_DATA_WIDTH-1 downto 0);
+ douta: out std_logic_vector(PPU_BAM_DATA_WIDTH-1 downto 0);
rsta_busy: out std_logic);
end component;
component ppu_tmm port( -- TMM block memory
clka: in std_logic;
rsta: in std_logic;
wea: in std_logic_vector(0 downto 0);
- addra: in std_logic_vector(15 downto 0);
- dina: in std_logic_vector(15 downto 0);
- douta: out std_logic_vector(15 downto 0);
+ addra: in std_logic_vector(PPU_TMM_ADDR_WIDTH-1 downto 0);
+ dina: in std_logic_vector(PPU_TMM_DATA_WIDTH-1 downto 0);
+ douta: out std_logic_vector(PPU_TMM_DATA_WIDTH-1 downto 0);
rsta_busy: out std_logic);
end component;
component ppu_sprite_bg port( -- background sprite
-- inputs
CLK: in std_logic; -- system clock
OE: in std_logic; -- output enable (of CIDX)
- X: in std_logic_vector(8 downto 0); -- current screen pixel x
- Y: in std_logic_vector(7 downto 0); -- current screen pixel y
+ 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
-- internal memory block (AUX)
AUX_WEN: in std_logic; -- VRAM AUX write enable
- AUX_ADDR: in std_logic_vector(1 downto 0); -- VRAM AUX address
- AUX_DATA: in std_logic_vector(15 downto 0); -- VRAM AUX data
+ AUX_ADDR: in std_logic_vector(PPU_AUX_ADDR_WIDTH-1 downto 0); -- VRAM AUX address
+ AUX_DATA: in std_logic_vector(PPU_AUX_DATA_WIDTH-1 downto 0); -- VRAM AUX data
-- used memory blocks
- BAM_ADDR: out std_logic_vector(10 downto 0);
- BAM_DATA: in std_logic_vector(15 downto 0);
- TMM_ADDR: out std_logic_vector(15 downto 0);
- TMM_DATA: in std_logic_vector(15 downto 0);
+ BAM_ADDR: out std_logic_vector(PPU_BAM_ADDR_WIDTH-1 downto 0);
+ BAM_DATA: in std_logic_vector(PPU_BAM_DATA_WIDTH-1 downto 0);
+ TMM_ADDR: out std_logic_vector(PPU_TMM_ADDR_WIDTH-1 downto 0);
+ TMM_DATA: in std_logic_vector(PPU_TMM_DATA_WIDTH-1 downto 0);
-- outputs
- CIDX: out std_logic_vector(PPU_PALETTE_CIDX_SIZE-1 downto 0)); -- output color
+ CIDX: out std_logic_vector(PPU_PALETTE_CIDX_WIDTH-1 downto 0)); -- output color
end component;
component ppu_sprite_fg port( -- foreground sprite
-- inputs
CLK: in std_logic; -- system clock
OE: in std_logic; -- output enable (of CIDX)
- X: in std_logic_vector(8 downto 0); -- current screen pixel x
- Y: in std_logic_vector(7 downto 0); -- current screen pixel y
+ 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
FETCH: in std_logic; -- fetch sprite data from TMM (TODO: generic map, set foreground sprite component index)
-- internal memory block (FAM)
FAM_WEN: in std_logic; -- VRAM FAM write enable
- FAM_ADDR: in std_logic_vector(1 downto 0); -- VRAM fam address
- FAM_DATA: in std_logic_vector(15 downto 0); -- VRAM fam data
+ FAM_ADDR: in std_logic_vector(PPU_FAM_ADDR_WIDTH-1 downto 0); -- VRAM fam address
+ FAM_DATA: in std_logic_vector(PPU_FAM_DATA_WIDTH-1 downto 0); -- VRAM fam data
-- used memory blocks
- TMM_ADDR: out std_logic_vector(15 downto 0);
- TMM_DATA: in std_logic_vector(15 downto 0);
+ TMM_ADDR: out std_logic_vector(PPU_TMM_ADDR_WIDTH-1 downto 0);
+ TMM_DATA: in std_logic_vector(PPU_TMM_DATA_WIDTH-1 downto 0);
-- outputs
- CIDX: out std_logic_vector(PPU_PALETTE_CIDX_SIZE-1 downto 0); -- output color
+ CIDX: out std_logic_vector(PPU_PALETTE_CIDX_WIDTH-1 downto 0); -- output color
HIT: out std_logic); -- current pixel is not transparent
end component;
component ppu_comp port( -- compositor
@@ -107,13 +133,13 @@ architecture Behavioral of ppu is
end component;
component ppu_plut port( -- palette lookup table
CLK: in std_logic; -- system clock
- CIDX: in std_logic_vector(PPU_PALETTE_CIDX_SIZE-1 downto 0); -- color in
+ CIDX: in std_logic_vector(PPU_PALETTE_CIDX_WIDTH-1 downto 0); -- color in
RESET: in std_logic;
-- internal memory block (AUX)
PAL_WEN: in std_logic; -- VRAM PAL write enable
- PAL_ADDR: in std_logic_vector(5 downto 0); -- VRAM PAL address
- PAL_DATA: in std_logic_vector(11 downto 0); -- VRAM PAL data
+ PAL_ADDR: in std_logic_vector(PPU_PAL_ADDR_WIDTH-1 downto 0); -- VRAM PAL address
+ PAL_DATA: in std_logic_vector(PPU_PAL_DATA_WIDTH-1 downto 0); -- VRAM PAL data
R,G,B: out std_logic_vector(3 downto 0)); -- VGA color out
end component;
@@ -121,8 +147,8 @@ architecture Behavioral of ppu is
CLK: in std_logic; -- system clock
RESET: in std_logic;
- X: out std_logic_vector(8 downto 0); -- current screen pixel x
- Y: out std_logic_vector(7 downto 0); -- current screen pixel y
+ 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,
@@ -132,12 +158,12 @@ architecture Behavioral of ppu is
CLK: in std_logic; -- system clock
RESET: in std_logic;
- X: in std_logic_vector(8 downto 0); -- current screen pixel x
- Y: in std_logic_vector(7 downto 0); -- current screen pixel y
+ 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
PREADY: in std_logic; -- current pixel ready (pixel color is stable)
- RI,GI,BI: in std_logic_vector(3 downto 0); -- VGA color in
+ RI,GI,BI: in std_logic_vector(PPU_COLOR_OUTPUT_DEPTH-1 downto 0); -- VGA color in
- RO,GO,BO: out std_logic_vector(3 downto 0); -- VGA color out
+ RO,GO,BO: out std_logic_vector(PPU_COLOR_OUTPUT_DEPTH-1 downto 0); -- VGA color out
VSYNC, HSYNC: out std_logic); -- VGA sync outputs
end component;
@@ -145,13 +171,22 @@ architecture Behavioral of ppu is
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 TMM_WEN, BAM_WEN, FAM_WEN, PAL_WEN, AUX_WEN: std_logic;
- signal ADDR_BUS: std_logic_vector(15 downto 0);
- signal CIDX: std_logic_vector(PPU_PALETTE_CIDX_SIZE-1 downto 0);
+ 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);
+ signal FAM_AI, FAM_AO: std_logic_vector(PPU_FAM_ADDR_WIDTH-1 downto 0);
+ signal PAL_AI, PAL_AO: std_logic_vector(PPU_PAL_ADDR_WIDTH-1 downto 0);
+ signal AUX_AI, AUX_AO: std_logic_vector(PPU_AUX_ADDR_WIDTH-1 downto 0);
+ signal TMM_DI, TMM_DO: std_logic_vector(PPU_TMM_DATA_WIDTH-1 downto 0);
+ signal BAM_DI, BAM_DO: std_logic_vector(PPU_BAM_DATA_WIDTH-1 downto 0);
+ signal FAM_DI, FAM_DO: std_logic_vector(PPU_FAM_DATA_WIDTH-1 downto 0);
+ signal PAL_DI, PAL_DO: std_logic_vector(PPU_PAL_DATA_WIDTH-1 downto 0);
+ signal AUX_DI, AUX_DO: std_logic_vector(PPU_AUX_DATA_WIDTH-1 downto 0);
+ signal CIDX: std_logic_vector(PPU_PALETTE_CIDX_WIDTH-1 downto 0);
signal BG_EN: std_logic;
signal FG_EN, FG_HIT: std_logic_vector(PPU_FG_SPRITE_COUNT-1 downto 0);
- signal X: std_logic_vector(8 downto 0); -- current screen pixel x
- signal Y: std_logic_vector(7 downto 0); -- current screen pixel y
- signal TR,TG,TB: std_logic_vector(3 downto 0); -- tiny RGB out (to be buffered)
+ 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
begin
SYSCLK <= CLK100;
@@ -166,7 +201,21 @@ begin
EN => EN,
WEN => WEN,
ADDR => ADDR,
- ADDR_DRV => ADDR_BUS,
+ TMM_DI => TMM_DI,
+ BAM_DI => BAM_DI,
+ FAM_DI => FAM_DI,
+ PAL_DI => PAL_DI,
+ AUX_DI => AUX_DI,
+ TMM_AI => TMM_AI,
+ BAM_AI => BAM_AI,
+ FAM_AI => FAM_AI,
+ PAL_AI => PAL_AI,
+ AUX_AI => AUX_AI,
+ TMM_AO => TMM_AO,
+ BAM_AO => BAM_AO,
+ FAM_AO => FAM_AO,
+ PAL_AO => PAL_AO,
+ AUX_AO => AUX_AO,
TMM_WEN => TMM_WEN,
BAM_WEN => BAM_WEN,
FAM_WEN => FAM_WEN,
@@ -177,17 +226,17 @@ begin
clka => SYSCLK,
rsta => SYSRST,
wea => (others => BAM_WEN),
- addra => ADDR_BUS(10 downto 0),
- dina => DATA(14 downto 0),
- douta => open,
+ addra => BAM_AO,
+ dina => BAM_DI,
+ douta => BAM_DO,
rsta_busy => open);
tilemap_memory: component ppu_tmm port map(
clka => SYSCLK,
rsta => SYSRST,
wea => (others => TMM_WEN),
- addra => ADDR_BUS(15 downto 0),
- dina => DATA(15 downto 0),
- douta => open,
+ addra => TMM_AO,
+ dina => TMM_DI,
+ douta => TMM_DO,
rsta_busy => open);
background_sprite: component ppu_sprite_bg port map(
@@ -196,12 +245,12 @@ begin
X => X,
Y => Y,
AUX_WEN => AUX_WEN,
- AUX_ADDR => ADDR_BUS(1 downto 0),
- AUX_DATA => DATA(15 downto 0),
- BAM_ADDR => open,
- BAM_DATA => (others => '0'),
- TMM_ADDR => open,
- TMM_DATA => (others => '0'),
+ AUX_ADDR => AUX_AO,
+ AUX_DATA => AUX_DI,
+ BAM_ADDR => BAM_AI,
+ BAM_DATA => BAM_DO,
+ TMM_ADDR => TMM_AI,
+ TMM_DATA => TMM_DO,
CIDX => CIDX);
foreground_sprites: for FG_IDX in 0 to PPU_FG_SPRITE_COUNT-1 generate
@@ -212,10 +261,10 @@ begin
Y => Y,
FETCH => '0',
FAM_WEN => FAM_WEN,
- FAM_ADDR => (others => '0'),
- FAM_DATA => (others => '0'),
- TMM_ADDR => open,
- TMM_DATA => (others => '0'),
+ FAM_ADDR => FAM_AO,
+ FAM_DATA => FAM_DI,
+ TMM_ADDR => TMM_AI,
+ TMM_DATA => TMM_DO,
CIDX => CIDX,
HIT => FG_HIT(FG_IDX));
end generate;
@@ -229,9 +278,9 @@ begin
CLK => SYSCLK,
CIDX => CIDX,
RESET => SYSRST,
- PAL_WEN => '0',
- PAL_ADDR => (others => '0'),
- PAL_DATA => (others => '0'),
+ PAL_WEN => PAL_WEN,
+ PAL_ADDR => PAL_AO,
+ PAL_DATA => PAL_DI,
R => TR,
G => TG,
B => TB);