diff options
-rw-r--r-- | basys3/basys3.srcs/PPU_COMP_TB.vhd | 73 | ||||
-rw-r--r-- | basys3/basys3.srcs/ppu_comp.vhd | 67 | ||||
-rw-r--r-- | basys3/basys3.srcs/ppu_plut.vhd | 99 | ||||
-rw-r--r-- | basys3/basys3.srcs/ppu_vga_native.vhd | 125 | ||||
-rw-r--r-- | basys3/basys3.srcs/ppu_vga_native_tb.vhd | 116 | ||||
-rw-r--r-- | basys3/basys3.srcs/ppu_vga_tiny.vhd | 102 |
6 files changed, 582 insertions, 0 deletions
diff --git a/basys3/basys3.srcs/PPU_COMP_TB.vhd b/basys3/basys3.srcs/PPU_COMP_TB.vhd new file mode 100644 index 0000000..3733dab --- /dev/null +++ b/basys3/basys3.srcs/PPU_COMP_TB.vhd @@ -0,0 +1,73 @@ +---------------------------------------------------------------------------------- +-- Company: +-- Engineer: +-- +-- Create Date: 23.02.2023 12:23:00 +-- Design Name: +-- Module Name: PPU_COMP_TB - Behavioral +-- Project Name: +-- Target Devices: +-- Tool Versions: +-- Description: +-- +-- Dependencies: +-- +-- Revision: +-- Revision 0.01 - File Created +-- Additional Comments: +-- +---------------------------------------------------------------------------------- + + +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; + +-- Uncomment the following library declaration if using +-- arithmetic functions with Signed or Unsigned values +--use IEEE.NUMERIC_STD.ALL; + +-- Uncomment the following library declaration if instantiating +-- any Xilinx leaf cells in this code. +library UNISIM; +use work.ppu_consts.all; +use UNISIM.VComponents.all; + +entity PPU_COMP_TB is + +end PPU_COMP_TB; + +architecture Behavioral of PPU_COMP_TB is +COMPONENT ppu_comp + port ( + FG_HIT: in std_logic_vector(PPU_FG_SPRITE_COUNT-1 downto 0); + BG_EN: out std_logic; + FG_EN: out std_logic_vector(PPU_FG_SPRITE_COUNT-1 downto 0)); +end component; + +signal FG_HIT: std_logic_vector(PPU_FG_SPRITE_COUNT-1 downto 0) := (others => '0'); +signal BG_EN: std_logic := '0'; +signal FG_EN: std_logic_vector(PPU_FG_SPRITE_COUNT-1 downto 0) := (others => '0'); +begin +UUT : ppu_comp port map ( +FG_HIT => FG_HIT, +BG_EN => BG_EN, +FG_EN => FG_EN +); + TB : PROCESS + BEGIN + FG_HIT <= (OTHERS => '0'); + wait for 1 ps; + FG_HIT(6) <= '1'; + FG_HIT(5) <= '1'; + FG_HIT(100) <= '1'; + wait for 1 ps; + + FG_HIT(0) <= '1'; + wait for 1 ps; + FG_HIT <= (OTHERS => '0'); + wait for 1 ps; + + + wait; + END PROCESS; +end Behavioral; diff --git a/basys3/basys3.srcs/ppu_comp.vhd b/basys3/basys3.srcs/ppu_comp.vhd new file mode 100644 index 0000000..1ea315e --- /dev/null +++ b/basys3/basys3.srcs/ppu_comp.vhd @@ -0,0 +1,67 @@ +---------------------------------------------------------------------------------- +-- Company: +-- Engineer: +-- +-- Create Date: 23.02.2023 10:31:25 +-- Design Name: +-- Module Name: ppu_comp - Behavioral +-- Project Name: +-- Target Devices: +-- Tool Versions: +-- Description: +-- +-- Dependencies: +-- +-- Revision: +-- Revision 0.01 - File Created +-- Additional Comments: +-- +---------------------------------------------------------------------------------- + + +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use work.ppu_consts.all; +-- Uncomment the following library declaration if using +-- arithmetic functions with Signed or Unsigned values +--use IEEE.NUMERIC_STD.ALL; + +-- Uncomment the following library declaration if instantiating +-- any Xilinx leaf cells in this code. +--library UNISIM; +--use UNISIM.VComponents.all; + +entity ppu_comp is + Port ( + FG_HIT: in std_logic_vector(PPU_FG_SPRITE_COUNT-1 downto 0); + BG_EN: out std_logic; + FG_EN: out std_logic_vector(PPU_FG_SPRITE_COUNT-1 downto 0)); + +end ppu_comp; + +architecture Behavioral of ppu_comp is +signal FG_HIT_Empty : std_logic_vector(PPU_FG_SPRITE_COUNT-1 downto 0) := (others => '0'); +begin + process (FG_HIT) + variable HIT : BOOLEAN := FALSE; + begin + -- check if fg_hit is not empty + if FG_HIT /= FG_HIT_Empty then + BG_EN <= '0'; + FOR I IN 0 TO PPU_FG_SPRITE_COUNT-1 LOOP + -- if fg_hit is the first one then enable it + IF(FG_HIT(I) = '1' AND HIT = FALSE) THEN + FG_EN(I) <= '1'; + HIT := TRUE; + ELSE + -- make rest low + FG_EN(I) <= '0'; + END IF; + END LOOP; + HIT := FALSE; + else + BG_EN <= '1'; + FG_EN <= (others => '0'); + end if; + end process; +end Behavioral; diff --git a/basys3/basys3.srcs/ppu_plut.vhd b/basys3/basys3.srcs/ppu_plut.vhd new file mode 100644 index 0000000..d03da1f --- /dev/null +++ b/basys3/basys3.srcs/ppu_plut.vhd @@ -0,0 +1,99 @@ +---------------------------------------------------------------------------------- +-- Company: +-- Engineer: +-- +-- Create Date: 23.02.2023 11:03:27 +-- Design Name: +-- Module Name: ppu_plut - Behavioral +-- Project Name: +-- Target Devices: +-- Tool Versions: +-- Description: +-- +-- Dependencies: +-- +-- Revision: +-- Revision 0.01 - File Created +-- Additional Comments: +-- +---------------------------------------------------------------------------------- + + +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use work.ppu_consts.all; +-- Uncomment the following library declaration if using +-- arithmetic functions with Signed or Unsigned values +use IEEE.NUMERIC_STD.ALL; +use ieee.std_logic_unsigned.all; +-- Uncomment the following library declaration if instantiating +-- any Xilinx leaf cells in this code. +--library UNISIM; +--use UNISIM.VComponents.all; + +entity ppu_plut is + Port ( + CLK: in std_logic; -- system clock + 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(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(PPU_COLOR_OUTPUT_DEPTH-1 downto 0)); -- VGA color out +end ppu_plut; + +architecture Behavioral of ppu_plut is + component er_ram + generic( + ADDR_W : natural := PPU_PAL_ADDR_WIDTH; -- ADDR line width + DATA_W : natural := PPU_PAL_DATA_WIDTH; -- DATA line width + ADDR_LOW : natural := 16#0000#; -- starting address + ADDR_RANGE : natural := 16#0040#); -- amount of valid addresses after ADDR_LOW + port( + CLK : in std_logic; -- clock + RST : in std_logic; -- async memory clear + WEN : in std_logic; -- write enable + ADDR : in std_logic_vector(ADDR_W-1 downto 0); + DATA : in std_logic_vector(DATA_W-1 downto 0); + REG : out std_logic_vector((ADDR_RANGE*DATA_W)-1 downto 0)); -- exposed register output + end component; + + SIGNAL PLUT : std_logic_vector((64 * PPU_PAL_DATA_WIDTH)-1 downto 0) := (others => '0'); + SIGNAL CHECK_ZERO_CIDX : std_logic_vector(PPU_PALETTE_CIDX_WIDTH-1 downto 0) := (others => '0');-- color in +begin + RAM : component er_ram port map( + CLK => CLK, + RST => RESET, + WEN => PAL_WEN, + ADDR => PAL_ADDR, + DATA => PAL_DATA, + REG => PLUT); + + + process(CLK,RESET) + VARIABLE COLOR : std_logic_vector(PPU_PAL_DATA_WIDTH-1 downto 0) := (others => '0');-- COLORS RGB IN + VARIABLE CIDX_INT : INTEGER := 0; + begin + IF(RESET = '1') THEN + PLUT <= (others => '0'); + ELSE + IF rising_edge (CLK) THEN + IF (CIDX /= CHECK_ZERO_CIDX) THEN + CIDX_INT := TO_INTEGER(UNSIGNED(CIDX)); + COLOR := PLUT((12 * CIDX_INT) + 11 DOWNTO (12*CIDX_INT)); + R <= COLOR(11 DOWNTO 8); + G <= COLOR(7 DOWNTO 4); + B <= COLOR(3 DOWNTO 0); + ELSE + R <= X"0"; + G <= X"0"; + B <= X"0"; + END IF; + END IF; + END IF; + end process; + +end Behavioral; diff --git a/basys3/basys3.srcs/ppu_vga_native.vhd b/basys3/basys3.srcs/ppu_vga_native.vhd new file mode 100644 index 0000000..f5d9809 --- /dev/null +++ b/basys3/basys3.srcs/ppu_vga_native.vhd @@ -0,0 +1,125 @@ +---------------------------------------------------------------------------------- +-- Company: +-- Engineer: +-- +-- Create Date: 22.02.2023 13:20:47 +-- Design Name: +-- Module Name: ppu_vga_native - Behavioral +-- Project Name: +-- Target Devices: +-- Tool Versions: +-- Description: +-- +-- Dependencies: +-- +-- Revision: +-- Revision 0.01 - File Created +-- Additional Comments: +-- +---------------------------------------------------------------------------------- + + +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use work.ppu_consts.all; + +use IEEE.NUMERIC_STD.ALL; +use IEEE.STD_LOGIC_UNSIGNED.ALL; + +-- Uncomment the following library declaration if instantiating +-- any Xilinx leaf cells in this code. +--library UNISIM; +--use UNISIM.VComponents.all; + +entity ppu_vga_native is + Port ( CLK: in std_logic; -- system clock + RESET: in std_logic; + + 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(PPU_COLOR_OUTPUT_DEPTH-1 downto 0); -- VGA color in + + 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 ppu_vga_native; + +architecture Behavioral of ppu_vga_native is + type line_buffer is array(319 downto 0) of std_logic_vector(11 downto 0); + signal ram_x0 : line_buffer; -- buffer 0 + signal ram_x1: line_buffer; -- buffer 1 + signal hcount: STD_LOGIC_VECTOR(9 downto 0):= (others => '0'); + signal vcount: STD_LOGIC_VECTOR(9 downto 0):= (others => '0'); + signal clkCounter: STD_LOGIC_VECTOR(1 downto 0):= (others => '0'); + signal rgb_out : STD_LOGIC_VECTOR(11 downto 0):= (others => '0'); -- output colors + signal px : integer; -- conversion for hcount + signal py :integer; -- conversion for vcount + signal bufferFilledOnbuffer0 : integer; + signal bufferFilledOnbuffer1 :integer; +begin + process (clk, x, y) + variable v_x : integer ; -- integer to hold vector X + begin + if rising_edge(clk) then + clkCounter <= clkCounter + 1; + if(clkCounter = "11")then + v_x := TO_INTEGER(unsigned(x) - 72); + if(v_x >= 0 and v_x < 320 and PREADY = '1') then + if(y(0) = '0') then + ram_x0(v_x) <= RI & GI & BI; + if v_x = 319 then + bufferFilledOnbuffer0 <= TO_INTEGER(unsigned(y) - 14); + end if; + else + ram_x1(v_x) <= RI & GI & BI; + if v_x = 319 then + bufferFilledOnbuffer1 <= TO_INTEGER(unsigned(y) - 14); + end if; + end if; + end if; + -- T display(display data) + if (hcount >= 144) and (hcount < 784) and (vcount >= 31) and (vcount < 511) then + px <= TO_INTEGER(unsigned(hcount) - 144); + py <= TO_INTEGER(unsigned(vcount) - 31); + if(bufferFilledonBuffer0 = (py/2)) then + rgb_out <= ram_x0(px/2); + elsif(bufferFilledonbuffer1 = (py/2)) then + rgb_out <= ram_x1(px/2); + + else + rgb_out <= (others => '0'); + + end if; + end if; + -- pulse width + hsync <= '1'; + if hcount < 97 then + hsync <= '0'; + end if; + + vsync <= '1'; + if vcount < 3 then + vsync <= '0'; + end if; + + -- sync pulse time + hcount <= hcount + 1; + + if hcount = 800 then + vcount <= vcount + 1; + hcount <= (others => '0'); + end if; + + if vcount = 521 then + vcount <= (others => '0'); + end if; + end if; + + -- output colors + RO <= rgb_out(11 downto 8); + GO <= rgb_out(7 downto 4); + BO <= rgb_out(3 downto 0); + end if; + end process; + +end Behavioral; diff --git a/basys3/basys3.srcs/ppu_vga_native_tb.vhd b/basys3/basys3.srcs/ppu_vga_native_tb.vhd new file mode 100644 index 0000000..3a225d8 --- /dev/null +++ b/basys3/basys3.srcs/ppu_vga_native_tb.vhd @@ -0,0 +1,116 @@ +---------------------------------------------------------------------------------- +-- Company: +-- Engineer: +-- +-- Create Date: 22.02.2023 13:28:57 +-- Design Name: +-- Module Name: ppu_vga_native_tb - Behavioral +-- Project Name: +-- Target Devices: +-- Tool Versions: +-- Description: +-- +-- Dependencies: +-- +-- Revision: +-- Revision 0.01 - File Created +-- Additional Comments: +-- +---------------------------------------------------------------------------------- + + +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use work.ppu_consts.all; + +use IEEE.NUMERIC_STD.ALL; +use IEEE.STD_LOGIC_UNSIGNED.ALL; + + +-- Uncomment the following library declaration if instantiating +-- any Xilinx leaf cells in this code. +library UNISIM; +use UNISIM.VComponents.all; + +entity ppu_vga_native_tb is +end ppu_vga_native_tb; + +architecture Behavioral of ppu_vga_native_tb is +component ppu_vga_native + Port ( CLK: in std_logic; -- system clock + RESET: in std_logic; + + 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(PPU_COLOR_OUTPUT_DEPTH-1 downto 0); -- VGA color in + + 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; +signal clk : std_logic := '0'; +signal rst : std_logic := '0'; +signal Pready : std_logic := '0'; + +signal X : std_logic_vector(PPU_POS_H_WIDTH-1 downto 0) := (others => '0'); + +signal Xas : integer := 72; +signal Yas : integer := 14; +signal counter : std_logic_vector(1 downto 0) := (others => '0'); +signal Y : std_logic_vector(PPU_POS_V_WIDTH-1 downto 0) := (others => '0'); +signal RI,GI,BI: std_logic_vector(PPU_COLOR_OUTPUT_DEPTH-1 downto 0) := (others => '0'); -- VGA color in +signal RO,GO,BO: std_logic_vector(PPU_COLOR_OUTPUT_DEPTH-1 downto 0) := (others => '0'); -- VGA color out +signal VSYNC, HSYNC: std_logic := '0'; +begin + +UUT : ppu_vga_native port map( + clk => clk, + reset => rst, + x => x, + y => y, + pready => pready, + ri => ri, + gi => gi, + bi => bi, + ro => ro, + go => go, + bo => bo, + vsync => vsync, + hsync => hsync +); + + tb : process + begin + clk <= '1'; + wait for 1 ps; + clk <= '0'; + wait for 1 ps; + end process; + + + process(clk) + begin + if rising_edge(clk) then + counter <= counter + 1; + end if; + + if(counter = "11") then + pready <= '1'; + ri <= x"d"; + gi <= x"a"; + bi <= x"d"; + x <= std_logic_vector(to_unsigned(Xas, x'length)); + if (Xas = 391) then + Xas <= 72; + y <= std_logic_vector(to_unsigned(Yas, y'length)); + if (Yas = 255) then + Yas <= 14; + else + Yas <= Yas + 1; + end if; + else + Xas <= Xas + 1; + end if; + end if; + end process; +end Behavioral; diff --git a/basys3/basys3.srcs/ppu_vga_tiny.vhd b/basys3/basys3.srcs/ppu_vga_tiny.vhd new file mode 100644 index 0000000..7b1703e --- /dev/null +++ b/basys3/basys3.srcs/ppu_vga_tiny.vhd @@ -0,0 +1,102 @@ +---------------------------------------------------------------------------------- +-- Company: +-- Engineer: +-- +-- Create Date: 22.02.2023 13:13:03 +-- Design Name: +-- Module Name: ppu_vga_tiny - Behavioral +-- Project Name: +-- Target Devices: +-- Tool Versions: +-- Description: +-- +-- Dependencies: +-- +-- Revision: +-- Revision 0.01 - File Created +-- Additional Comments: +-- +---------------------------------------------------------------------------------- + + +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use work.ppu_consts.all; + +use IEEE.NUMERIC_STD.ALL; +use IEEE.STD_LOGIC_UNSIGNED.ALL; +-- Uncomment the following library declaration if instantiating +-- any Xilinx leaf cells in this code. +--library UNISIM; +--use UNISIM.VComponents.all; + +entity ppu_vga_tiny is + Port ( + CLK: in std_logic; -- system clock + RESET: in std_logic; + + 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 + + VSYNC, VBLANK, + HSYNC, HBLANK: out std_logic); -- VGA sync outputs + +end ppu_vga_tiny; + +architecture Behavioral of ppu_vga_tiny is + signal hcount: STD_LOGIC_VECTOR(PPU_POS_H_WIDTH-1 downto 0):= (others => '0'); + signal vcount: STD_LOGIC_VECTOR(PPU_POS_V_WIDTH-1 downto 0):= (others => '0'); + signal CLKcounter: STD_LOGIC_VECTOR(4 downto 0):= (others => '0'); + +begin +process (CLK) +begin + if rising_edge(CLK) then + CLKcounter <= CLKcounter + 1; + if(CLKcounter > 15) then + -- x,y data uit + X <= hcount; + Y <= vcount; + + --pulse width + if hcount < 32 or hcount >= 320-80 then + hsync <= '0'; + else + hsync <= '1'; + end if; + + if vcount < 8 or vcount >= 240-15 then + vsync <= '0'; + else + vsync <= '1'; + end if; + + -- Hblank and Vblank outputs + if hcount >= 320-80 then + hblank <= '1'; + else + hblank <= '0'; + end if; + + if vcount >= 240-15 then + vblank <= '1'; + else + vblank <= '0'; + end if; + + -- sync pulse time + hcount <= hcount + 1; + + if hcount = 400 then + vcount <= vcount + 1; + hcount <= (others => '0'); + end if; + + if vcount = 255 then + vcount <= (others => '0'); + end if; + end if; + end if; +end process; + +end Behavioral; |