aboutsummaryrefslogtreecommitdiff
path: root/basys3/basys3.srcs/ppu_vga_native.vhd
blob: f5d9809e22272b68cb3a877b2c835f15e8845b5b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
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;