--------------------------------------------------------------------- -- vga_top.vhd Beispiel für VGA-Ansteuerung --------------------------------------------------------------------- -- G. Kemnitz -- 15.12.2004 --------------------------------------------------------------------- library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity vga is Port ( CLK : in std_logic; hs : out std_logic:='1'; -- horizontaler Sync-Impuls (Zeile) vs : out std_logic:='1'; -- vertikaler Sync-Impuls (Bild) rgb : out std_logic_vector(2 downto 0)); -- RGB-Signal end vga; architecture Behavioral of vga is signal Takt25MHz: std_logic; signal hCounter: integer range 0 to 799:=0; signal vCounter: integer range 0 to 520:=0; signal hBlack: std_logic:='1'; signal vBlack: std_logic:='1'; -- darstellbare Bildschirmfarben constant schwarz: std_logic_vector(2 downto 0):="000"; constant rot: std_logic_vector(2 downto 0):="100"; constant gruen: std_logic_vector(2 downto 0):="010"; constant blau: std_logic_vector(2 downto 0):="001"; constant gelb: std_logic_vector(2 downto 0):="110"; constant cyan: std_logic_vector(2 downto 0):="011"; constant violett: std_logic_vector(2 downto 0):="101"; constant weis: std_logic_vector(2 downto 0):="111"; -- Festwertspeicher mit einem Bild (1 Bit pro Pixel) type rom_type is array (0 to 31) of std_logic_vector (31 downto 0); constant Bild : rom_type := ("11111111111111111111111111111111", -- Zeile 0 "10000000000000000000000000000001", -- Zeile 1 "10000000000000011111100000000001", -- Zeile 2 "10000000000001110000111000000001", -- Zeile 3 "10000000000011000000001100000001", -- Zeile 4 "10000001000100000000000010000001", -- Zeile 5 "10000000110000000000000000001001", -- Zeile 6 "10000000011100000000000000010001", -- Zeile 7 "10000000001111000000000000100001", -- Zeile 8 "10000000000011111000000011000001", -- Zeile 9 "10000000000000000000000100000001", -- Zeile 10 "10000000000000000000000010000001", -- Zeile 11 "10000000000111000000001100000001", -- Zeile 12 "10000000001000100001110000000001", -- Zeile 13 "10000000000000011110000000000001", -- Zeile 14 "10000000000000000000000000000001", -- Zeile 15 "10000000000000000000000000000001", -- Zeile 16 "10000000010000000000000000000001", -- Zeile 17 "10000000111000000000000000000001", -- Zeile 18 "10000000111000000000000000000001", -- Zeile 19 "10000000111110000000000000000001", -- Zeile 20 "10000001001110000000000000000001", -- Zeile 21 "10000001001111000000000000000001", -- Zeile 22 "10000010000111000000000000000001", -- Zeile 23 "10000010000111100000000000000001", -- Zeile 24 "10000011111111100000000000000001", -- Zeile 25 "10000100000011110000000000000001", -- Zeile 26 "10000100000001110000000000000001", -- Zeile 27 "10011110000111111100000000000001", -- Zeile 28 "10000000000000000000000000000001", -- Zeile 29 "10000000000000000000000000000001", -- Zeile 30 "11111111111111111111111111111111"); -- Zeile 31 begin --========================================================================== -- Erzeugen eines 50 MHz Taktes ---------------------------------------------------------------------------- process(CLK) begin if(CLK = '1' and CLK'EVENT) then Takt25MHz <= not Takt25MHz; end if; end process; ---------------------------------------------------------------------------- process(Takt25MHz) variable vsl_hCt, vsl_vCt: std_logic_vector(9 downto 0); variable Zeilenwechsel: std_logic; variable tmp: std_logic_vector(31 downto 0); begin if(Takt25MHz = '1' and Takt25MHz'EVENT) then --========================================================================== -- Zähler Pixel in der Zeile, Zeilensynchronisation und Zeilenaustastlücke ---------------------------------------------------------------------------- hCounter<=hCounter +1; Zeilenwechsel:='0'; case hCounter is when 95 => hs<='0'; -- Zeilen-Sync aus when 143 => hBlack<='0'; -- schwarzer Rand aus when 783 => hBlack<='1'; -- schwarzer Rand ein when 799 => hCounter<=0; -- Zeilenwechsel Zeilenwechsel:='1'; hs<='1'; -- Zeilen-Sync ein when others => null; end case; --========================================================================== -- Zeilenzähler, Bildsynchronisation und Bildaustastlücke ---------------------------------------------------------------------------- if Zeilenwechsel='1' then vCounter<=vCounter+1; case vCounter is when 1 => vs<='0'; when 30 => vBlack<='0'; when 511 => vBlack<='1'; when 520 => vCounter<=0; vs<='1'; when others => null; end case; end if; --========================================================================== -- Erzeugung von Bildelementen ---------------------------------------------------------------------------- -- Umwandlung von Pixel- und Zeilenzähler in Bitvektoren vsl_vCt:=CONV_STD_LOGIC_VECTOR(vCounter, 10); vsl_hCt:=CONV_STD_LOGIC_VECTOR(hCounter, 10); if hBlack='1' or vBlack='1' then rgb<=schwarz; else -- vertikale Linie if hCounter=222 then rgb<=rot; -- horizontale Linie elsif vCounter=178 then rgb<=gruen; -- schräge Linie elsif vCounter=hCounter then rgb<=blau; -- Quadrat elsif vsl_hCt(9 downto 6)=x"4" and vsl_vCt(9 downto 6)=x"3" then rgb<=violett; -- Raster elsif vsl_hCt(3 downto 0)=x"2" or vsl_vCt(3 downto 0)=x"2" then rgb<=schwarz; -- Bild aus dem Speicher elsif vsl_hCt(9 downto 6)=x"5" and vsl_vCt(9 downto 6)=x"6" then tmp:=Bild(CONV_INTEGER(vsl_vCt(5 downto 1))); if tmp(CONV_INTEGER(vsl_hCt(5 downto 1)))='1' then rgb<=gelb; else rgb<=cyan; end if; -- Hintergrundfarbe else rgb <= weis; end if; end if; end if; end process; end Behavioral;