diff options
Diffstat (limited to 'basys3')
| -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 | ||||
| -rw-r--r-- | basys3/basys3.xpr | 27 | 
4 files changed, 157 insertions, 41 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; diff --git a/basys3/basys3.xpr b/basys3/basys3.xpr index a8821cb..a08109b 100644 --- a/basys3/basys3.xpr +++ b/basys3/basys3.xpr @@ -59,7 +59,7 @@      <Option Name="IPStaticSourceDir" Val="$PIPUSERFILESDIR/ipstatic"/>      <Option Name="EnableBDX" Val="FALSE"/>      <Option Name="DSABoardId" Val="basys3"/> -    <Option Name="WTXSimLaunchSim" Val="0"/> +    <Option Name="WTXSimLaunchSim" Val="2"/>      <Option Name="WTModelSimLaunchSim" Val="0"/>      <Option Name="WTQuestaLaunchSim" Val="0"/>      <Option Name="WTIesLaunchSim" Val="0"/> @@ -90,6 +90,12 @@    <FileSets Version="1" Minor="31">      <FileSet Name="sources_1" Type="DesignSrcs" RelSrcDir="$PSRCDIR/sources_1" RelGenDir="$PGENDIR/sources_1">        <Filter Type="Srcs"/> +      <File Path="$PSRCDIR/ppu_pceg.vhdl"> +        <FileInfo> +          <Attr Name="UsedIn" Val="synthesis"/> +          <Attr Name="UsedIn" Val="simulation"/> +        </FileInfo> +      </File>        <File Path="$PSRCDIR/ppu.vhd">          <FileInfo>            <Attr Name="UsedIn" Val="synthesis"/> @@ -99,7 +105,7 @@        <Config>          <Option Name="DesignMode" Val="RTL"/>          <Option Name="TopModule" Val="ppu"/> -        <Option Name="TopAutoSet" Val="TRUE"/> +        <Option Name="dataflowViewerSettings" Val="min_width=16"/>        </Config>      </FileSet>      <FileSet Name="constrs_1" Type="Constrs" RelSrcDir="$PSRCDIR/constrs_1" RelGenDir="$PGENDIR/constrs_1"> @@ -110,11 +116,16 @@      </FileSet>      <FileSet Name="sim_1" Type="SimulationSrcs" RelSrcDir="$PSRCDIR/sim_1" RelGenDir="$PGENDIR/sim_1">        <Filter Type="Srcs"/> +      <File Path="$PSRCDIR/ppu_pceg_tb.vhdl"> +        <FileInfo> +          <Attr Name="UsedIn" Val="synthesis"/> +          <Attr Name="UsedIn" Val="simulation"/> +        </FileInfo> +      </File>        <Config>          <Option Name="DesignMode" Val="RTL"/> -        <Option Name="TopModule" Val="ppu"/> +        <Option Name="TopModule" Val="ppu_pceg_tb"/>          <Option Name="TopLib" Val="xil_defaultlib"/> -        <Option Name="TopAutoSet" Val="TRUE"/>          <Option Name="TransportPathDelay" Val="0"/>          <Option Name="TransportIntDelay" Val="0"/>          <Option Name="SelectedSimModel" Val="rtl"/> @@ -201,9 +212,7 @@      </Run>      <Run Id="ppu_tmm_synth_1" Type="Ft3:Synth" SrcSet="ppu_tmm" Part="xc7a35tcpg236-1" ConstrsSet="ppu_tmm" Description="Vivado Synthesis Defaults" AutoIncrementalCheckpoint="false" WriteIncrSynthDcp="false" Dir="$PRUNDIR/ppu_tmm_synth_1" IncludeInArchive="true" IsChild="false" AutoIncrementalDir="$PSRCDIR/utils_1/imports/ppu_tmm_synth_1" AutoRQSDir="$PSRCDIR/utils_1/imports/ppu_tmm_synth_1">        <Strategy Version="1" Minor="2"> -        <StratHandle Name="Vivado Synthesis Defaults" Flow="Vivado Synthesis 2022"> -          <Desc>Vivado Synthesis Defaults</Desc> -        </StratHandle> +        <StratHandle Name="Vivado Synthesis Defaults" Flow="Vivado Synthesis 2022"/>          <Step Id="synth_design"/>        </Strategy>        <GeneratedRun Dir="$PRUNDIR" File="gen_run.xml"/> @@ -247,9 +256,7 @@      </Run>      <Run Id="ppu_tmm_impl_1" Type="Ft2:EntireDesign" Part="xc7a35tcpg236-1" ConstrsSet="ppu_tmm" Description="Default settings for Implementation." AutoIncrementalCheckpoint="false" WriteIncrSynthDcp="false" SynthRun="ppu_tmm_synth_1" IncludeInArchive="false" IsChild="false" GenFullBitstream="true" AutoIncrementalDir="$PSRCDIR/utils_1/imports/ppu_tmm_impl_1" AutoRQSDir="$PSRCDIR/utils_1/imports/ppu_tmm_impl_1">        <Strategy Version="1" Minor="2"> -        <StratHandle Name="Vivado Implementation Defaults" Flow="Vivado Implementation 2022"> -          <Desc>Default settings for Implementation.</Desc> -        </StratHandle> +        <StratHandle Name="Vivado Implementation Defaults" Flow="Vivado Implementation 2022"/>          <Step Id="init_design"/>          <Step Id="opt_design"/>          <Step Id="power_opt_design"/> |