aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--basys3/basys3.srcs/apu_lut_reader.vhd69
-rw-r--r--basys3/basys3.srcs/apu_lut_reader_tb.vhd48
-rw-r--r--basys3/basys3.srcs/apu_note_to_frequency.vhd42
-rw-r--r--basys3/basys3.srcs/ppu_comp.vhd67
-rw-r--r--basys3/basys3.srcs/ppu_comp_tb.vhd44
-rw-r--r--basys3/basys3.srcs/ppu_plut.vhd99
-rw-r--r--basys3/basys3.srcs/ppu_vga_native.vhd125
-rw-r--r--basys3/basys3.srcs/ppu_vga_native_tb.vhd116
-rw-r--r--basys3/basys3.srcs/ppu_vga_tiny.vhd103
-rw-r--r--basys3/basys3.xpr31
-rw-r--r--test/sdl2/.gitignore2
-rw-r--r--test/sdl2/main.c48
-rw-r--r--test/sdl2/makefile18
-rw-r--r--test/sdl2/readme.md6
14 files changed, 799 insertions, 19 deletions
diff --git a/basys3/basys3.srcs/apu_lut_reader.vhd b/basys3/basys3.srcs/apu_lut_reader.vhd
new file mode 100644
index 0000000..2f92eca
--- /dev/null
+++ b/basys3/basys3.srcs/apu_lut_reader.vhd
@@ -0,0 +1,69 @@
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+entity apu_lut_reader is
+ port (
+ clk : in std_logic;
+ rst : in std_logic;
+ freq : in std_logic_vector(11 downto 0);
+ wave : in std_logic_vector(1 downto 0);
+ value : out std_logic_vector(7 downto 0)
+ );
+end entity;
+
+architecture behavioral of apu_lut_reader is
+
+ constant AMPLITUDE : natural := 0;
+ constant SAMPLE_SIZE : natural := 256;
+
+ signal idx : unsigned := (others => '0');
+ signal buf : unsigned := (others => '0');
+
+begin
+
+ process (clk)
+ begin
+ if rst = '1' then
+ idx <= x"00";
+ buf <= x"00";
+ value <= x"00";
+ elsif rising_edge(clk) then
+ -- main code here
+
+ if wave = "00" then -- Sawtooth
+ value <= std_logic_vector( idx );
+ elsif wave = "01" then -- Square
+ if idx < (SAMPLE_SIZE/2) then
+ value <= x"00"; --std_logic_vector( SAMPLE_SIZE-AMPLITUDE ); -- TODO: make so that this work with a changable amplitude (for square wave)
+ else
+ value <= x"FF";
+ end if;
+ elsif wave = "10" then -- Triangle
+ if idx < (SAMPLE_SIZE/2) then
+ value <= std_logic_vector( idx*2 );
+ else
+ value <= std_logic_vector( (SAMPLE_SIZE-idx)*2 );
+ end if;
+ else-- wave = "11" then -- Noise
+ -- TODO: implement noise function here:
+ value <= x"80"; -- remove this
+ end if;
+
+
+
+ if buf < unsigned(freq) then -- change frequency
+ buf <= buf + 1;
+ else
+ buf <= x"00";
+ if idx < (SAMPLE_SIZE-1) then -- moves to next index value
+ idx <= idx + 1;
+ else
+ idx <= x"00";
+ end if;
+ end if;
+
+ end if;
+ end process;
+
+end architecture;
diff --git a/basys3/basys3.srcs/apu_lut_reader_tb.vhd b/basys3/basys3.srcs/apu_lut_reader_tb.vhd
new file mode 100644
index 0000000..1b425bf
--- /dev/null
+++ b/basys3/basys3.srcs/apu_lut_reader_tb.vhd
@@ -0,0 +1,48 @@
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+library unisim;
+use unisim.vcomponents.all;
+
+entity apu_lut_reader_tb is
+end entity;
+
+architecture Behavioral of apu_lut_reader_tb is
+ component apu_lut_reader is
+ port (
+ clk : in std_logic;
+ rst : in std_logic;
+ freq : in std_logic_vector(11 downto 0);
+ wave : in std_logic_vector(1 downto 0);
+ value : out std_logic_vector(7 downto 0)
+ );
+ end component;
+
+ signal OK : boolean := false;
+
+ signal clk : std_logic := '0';
+ signal rst : std_logic := '0';
+ signal freq : std_logic_vector(11 downto 0) := (others => '0');
+ signal wave : std_logic_vector(1 downto 0) := (others => '0');
+
+begin
+
+ TB: process
+ begin
+ wave <= "00";
+ for I in 0 to 255 loop
+ clk <= '1';
+
+ -- freq <= '1';
+
+
+ wait for 1 ps;
+ clk <= '0';
+ wait for 1 ps;
+
+
+ end loop;
+ end process;
+
+end architecture;
diff --git a/basys3/basys3.srcs/apu_note_to_frequency.vhd b/basys3/basys3.srcs/apu_note_to_frequency.vhd
index 1e47b8e..810cef9 100644
--- a/basys3/basys3.srcs/apu_note_to_frequency.vhd
+++ b/basys3/basys3.srcs/apu_note_to_frequency.vhd
@@ -5,8 +5,8 @@ use ieee.numeric_std.all;
entity apu_note_to_frequency is port (
-- clk : in std_logic;
-- rst : in std_logic;
- data : in std_logic_vector(7 downto 0);
- freq : out std_logic_vector(11 downto 0)); --frequency
+ data : in std_logic_vector(6 downto 0);
+ freq : out std_logic_vector(11 downto 0)); -- frequency
end entity;
architecture Behavioral of apu_note_to_frequency is
@@ -14,22 +14,26 @@ architecture Behavioral of apu_note_to_frequency is
signal buff : std_logic_vector(15 downto 0) := (others => '0');
signal shift : integer;
begin
- shift <= to_integer(unsigned(data(2 downto 0)));
- buff_small <=
- x"f0" when data(7 downto 3) = (x"c" & '0') else -- C 496
- x"d0" when data(7 downto 3) = (x"c" & '1') else -- C# 464
- x"b0" when data(7 downto 3) = (x"d" & '0') else -- D 432
- x"a0" when data(7 downto 3) = (x"d" & '1') else -- D# 416
- x"80" when data(7 downto 3) = (x"e" & '0') else -- E 384
- x"70" when data(7 downto 3) = (x"f" & '0') else -- F 368
- x"58" when data(7 downto 3) = (x"f" & '1') else -- F# 344
- x"40" when data(7 downto 3) = (x"8" & '0') else -- G 320
- x"30" when data(7 downto 3) = (x"8" & '1') else -- G# 304
- x"20" when data(7 downto 3) = (x"a" & '0') else -- A 288
- x"10" when data(7 downto 3) = (x"a" & '1') else -- A# 272
- x"00" when data(7 downto 3) = (x"b" & '0') else -- B 256
- x"01";
- buff <= x"1" & buff_small;
- freq <= (others => '0') & buff(15 downto shift); -- bitshift values out (or div by powers of 2)
+ shift <= to_integer(unsigned( data(2 downto 0) ));
+
+ buff <=
+ x"1F0" when data(6 downto 3) = (x"1") else -- C 496
+ x"1D0" when data(6 downto 3) = (x"2") else -- C#/Db 464
+ x"1B0" when data(6 downto 3) = (x"3") else -- D 432
+ x"1A0" when data(6 downto 3) = (x"4") else -- D#/Eb 416
+ x"180" when data(6 downto 3) = (x"5") else -- E 384
+ x"170" when data(6 downto 3) = (x"6") else -- F 368
+ x"158" when data(6 downto 3) = (x"7") else -- F#/Gb 344
+ x"140" when data(6 downto 3) = (x"8") else -- G 320
+ x"130" when data(6 downto 3) = (x"9") else -- G#/Ab 304
+ x"120" when data(6 downto 3) = (x"A") else -- A 288
+ x"110" when data(6 downto 3) = (x"B") else -- A#/Bb 272
+ x"100" when data(6 downto 3) = (x"C") else -- B 256
+ x"000";
+
+ -- buff <= x"1" & buff_small;
+ freq <= std_logic_vector( shift_right(unsigned(buff), shift) );
+ -- freq <= (others => '0') & buff(11 downto shift); -- bitshift values out (or div by powers of 2) -- TODO: NO WORKY!!! (concat (others => '0');)
+
end architecture;
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_comp_tb.vhd b/basys3/basys3.srcs/ppu_comp_tb.vhd
new file mode 100644
index 0000000..e8f6893
--- /dev/null
+++ b/basys3/basys3.srcs/ppu_comp_tb.vhd
@@ -0,0 +1,44 @@
+library ieee;
+library unisim;
+use ieee.std_logic_1164.all;
+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_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..f47df48
--- /dev/null
+++ b/basys3/basys3.srcs/ppu_vga_tiny.vhd
@@ -0,0 +1,103 @@
+----------------------------------------------------------------------------------
+-- 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
+ clkCounter <= (others => '0');
+ -- 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;
diff --git a/basys3/basys3.xpr b/basys3/basys3.xpr
index 0c452cf..4060a21 100644
--- a/basys3/basys3.xpr
+++ b/basys3/basys3.xpr
@@ -166,6 +166,37 @@
<Attr Name="UsedIn" Val="simulation"/>
</FileInfo>
</File>
+ <File Path="$PSRCDIR/ppu_vga_tiny.vhd">
+ <FileInfo>
+ <Attr Name="UsedIn" Val="synthesis"/>
+ <Attr Name="UsedIn" Val="simulation"/>
+ </FileInfo>
+ </File>
+ <File Path="$PSRCDIR/ppu_comp.vhd">
+ <FileInfo>
+ <Attr Name="UsedIn" Val="synthesis"/>
+ <Attr Name="UsedIn" Val="simulation"/>
+ </FileInfo>
+ </File>
+ <File Path="$PSRCDIR/ppu_plut.vhd">
+ <FileInfo>
+ <Attr Name="UsedIn" Val="synthesis"/>
+ <Attr Name="UsedIn" Val="simulation"/>
+ </FileInfo>
+ </File>
+ <File Path="$PSRCDIR/ppu_vga_native.vhd">
+ <FileInfo>
+ <Attr Name="UsedIn" Val="synthesis"/>
+ <Attr Name="UsedIn" Val="simulation"/>
+ </FileInfo>
+ </File>
+ <File Path="$PSRCDIR/apu_lut_reader.vhd">
+ <FileInfo>
+ <Attr Name="UserDisabled" Val="1"/>
+ <Attr Name="UsedIn" Val="synthesis"/>
+ <Attr Name="UsedIn" Val="simulation"/>
+ </FileInfo>
+ </File>
<Config>
<Option Name="DesignMode" Val="RTL"/>
<Option Name="TopModule" Val="ppu"/>
diff --git a/test/sdl2/.gitignore b/test/sdl2/.gitignore
new file mode 100644
index 0000000..f0c9b81
--- /dev/null
+++ b/test/sdl2/.gitignore
@@ -0,0 +1,2 @@
+*.o
+main
diff --git a/test/sdl2/main.c b/test/sdl2/main.c
new file mode 100644
index 0000000..beddc3f
--- /dev/null
+++ b/test/sdl2/main.c
@@ -0,0 +1,48 @@
+#include <stdlib.h>
+#include <stdbool.h>
+#include <math.h>
+#include <SDL2/SDL.h>
+
+#define UPSCALE_FACTOR 3
+#define WIN_HEIGHT 240
+#define WIN_WIDTH 320
+#define FPS 60
+
+static void pixel(SDL_Renderer* r, unsigned px, unsigned py, unsigned cr, unsigned cg, unsigned cb) {
+ SDL_SetRenderDrawColor(r, cr, cg, cb, 255);
+ SDL_RenderFillRect(r, &(SDL_Rect) {.x = px * UPSCALE_FACTOR, .y = py * UPSCALE_FACTOR, .w = UPSCALE_FACTOR, .h = UPSCALE_FACTOR});
+}
+
+int main() {
+ SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS);
+ SDL_Window *window = SDL_CreateWindow("sdl2 test", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, WIN_WIDTH * UPSCALE_FACTOR, WIN_HEIGHT * UPSCALE_FACTOR, SDL_WINDOW_SHOWN);
+ SDL_Renderer *renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
+
+ SDL_Event e;
+ unsigned long frame = 0;
+ while (true) {
+ uint32_t start = SDL_GetTicks();
+ frame++;
+ while (SDL_PollEvent(&e)) if (e.type == SDL_QUIT) exit(0);
+
+ SDL_RenderClear(renderer);
+
+ for (unsigned i = 0; i < WIN_WIDTH; i++) {
+ for (unsigned j = 0; j < WIN_HEIGHT; j++) {
+ pixel(renderer, i, j, (unsigned)(sqrt(i * 20) + frame) % 255, (i * j + frame) % 255, (j * 20) % 255);
+ }
+ }
+
+ SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
+ SDL_RenderPresent(renderer);
+
+ uint32_t end = SDL_GetTicks();
+ int wait_for = 1000 / FPS - (end - start);
+ if (wait_for > 0) SDL_Delay(wait_for);
+ }
+
+ SDL_DestroyRenderer(renderer);
+ SDL_DestroyWindow(window);
+ SDL_Quit();
+ return 0;
+}
diff --git a/test/sdl2/makefile b/test/sdl2/makefile
new file mode 100644
index 0000000..4c26dc3
--- /dev/null
+++ b/test/sdl2/makefile
@@ -0,0 +1,18 @@
+CC = gcc
+LD = gcc
+RM = rm -f
+TARGET = main
+LFLAGS += -lSDL2 -lm
+OBJS += main.o
+
+all: $(TARGET)
+
+%.o: %.c
+ $(CC) -c $(CFLAGS) $< -o $@
+
+$(TARGET): $(OBJS)
+ $(LD) $^ $(LFLAGS) -o $@
+
+clean:
+ $(RM) $(TARGET) $(OBJS)
+
diff --git a/test/sdl2/readme.md b/test/sdl2/readme.md
new file mode 100644
index 0000000..940e315
--- /dev/null
+++ b/test/sdl2/readme.md
@@ -0,0 +1,6 @@
+# sdl2 test
+
+this is a simple POC that makes a window to draw PPU graphics to using SDL2.
+this code will be moved to the stm32/ppu directory, and the stm32's makefile
+will be edited to include a sim target for building the game for desktop
+debugging.