VGA controller VHDL code
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_i : in STD_LOGIC; sw_i : in STD_LOGIC_VECTOR (15 downto 0); -- (11 downto 8) is RED, (7 downto 4) is GREEN, (3 downto 0) is BLUE -- Writing directly to RAM and from RAM to VGA interface. -- Writing when sw_i(15) is high -- VGA Output Signals vga_hs_o : out STD_LOGIC; -- Horizontal sync puls to VGA interface vga_vs_o : out STD_LOGIC; -- Vertical sync puls to VGA interface vga_red_o : out STD_LOGIC_VECTOR (3 downto 0); -- Red to VGA interface vga_green_o : out STD_LOGIC_VECTOR (3 downto 0); -- Green to VGA interface vga_blue_o : out STD_LOGIC_VECTOR (3 downto 0) -- Blue to VGA interface );
end Vga;
architecture Behavioral of Vga is
-- Component Declarations
-- 25.2MHz Clock COMPONENT clk_wiz_25_2MHz PORT (
clk_in_100MHz: in STD_LOGIC; clk_out_25_2: out STD_LOGIC; reset : in STD_LOGIC; locked : out STD_LOGIC );
END COMPONENT;
-- Ram block for pixels COMPONENT PIX_RAM
PORT ( clka : IN STD_LOGIC; ena : IN STD_LOGIC; wea : IN STD_LOGIC_VECTOR(0 DOWNTO 0); addra : IN STD_LOGIC_VECTOR(18 DOWNTO 0); dina : IN STD_LOGIC_VECTOR(11 DOWNTO 0); douta : OUT STD_LOGIC_VECTOR(11 DOWNTO 0) );
END COMPONENT;
-- Constants for VGA Resolutions
640x480 60Hz-------
constant WIDTH : natural := 640; constant HEIGHT : natural := 480;
constant H_FP : natural := 16; --H front porch width (pixels) constant H_PW : natural := 96; --H sync pulse width (pixels) constant H_TOT : natural := 800; --H total period (pixels)
constant V_FP : natural := 10; --V front porch width (lines) constant V_PW : natural := 2; --V sync pulse width (lines) constant V_TOT : natural := 525; --V total period (lines)
-- VGA signals: Counters, Sync, Red, Gree, Blue
-- Activates the screen when it is in the frame area signal SCREEN_ON : std_logic;
-- Horizontal and Vertical counters signal h_count : std_logic_vector(11 downto 0) := (others =>'0'); signal v_count : std_logic_vector(11 downto 0) := (others =>'0');
-- signal for the VGA interface signal vga_red : std_logic_vector(3 downto 0); signal vga_blue : std_logic_vector(3 downto 0); signal vga_green : std_logic_vector(3 downto 0);
-- CLOCK signals
signal pxl_clk: std_logic; -- pxl_clk is 25.2MHz signal reset: std_logic := '0';
-- RAM signals
signal data_out : std_logic_vector(11 downto 0) := (others =>'0'); signal data_inn : std_logic_vector(11 downto 0) := (others =>'0'); signal address : std_logic_vector(18 downto 0) := (others =>'0'); signal write : std_logic_vector(0 downto 0) ;
begin
--------------------------- -- PORT MAPS --------------------------- -- PIXELGENERATOR - pxl_clk=25.2MHz PIXELGENERATOR : clk_wiz_25_2MHz PORT MAP (--clock inn clk_in_100MHz => clk_i, --clock out clk_out_25_2 => pxl_clk, --reset active high reset => reset, --status and controll signals locked => open ); -- RAM RAM : PIX_RAM PORT MAP ( clka => clk_i, ena => '1', wea => write, addra => address, dina => data_inn, douta => data_out );
-- Generate Horizontal, Vertical counters and the Sync signals
-- Horizontal counter process (pxl_clk) begin if (rising_edge(pxl_clk)) then if (h_count = (H_TOT - 1)) then h_count <= (others =>'0'); else h_count <= h_count + 1; end if; end if; end process; -- Vertical counter process (pxl_clk) begin if (rising_edge(pxl_clk)) then if ((h_count = (H_TOT - 1)) and (v_count = (V_TOT - 1))) then v_count <= (others =>'0'); elsif (h_count = (H_TOT - 1)) then v_count <= v_count + 1; end if; end if; end process; -- Horizontal sync process (pxl_clk) begin if (rising_edge(pxl_clk)) then if (h_count >= (H_FP + WIDTH - 1)) and (h_count < (H_FP + WIDTH + H_PW - 1)) then vga_hs_o <= '1'; else vga_hs_o <= '0'; end if; end if; end process; -- Vertical sync process (pxl_clk) begin if (rising_edge(pxl_clk)) then if (v_count >= (V_FP + HEIGHT - 1)) and (v_count < (V_FP + HEIGHT + V_PW - 1)) then vga_vs_o <= '1'; else vga_vs_o <= '0'; end if; end if; end process;
-- RAM interface
-- Synchronizing reading and writing of adresses with the VGA interface
process (pxl_clk) begin if (rising_edge(pxl_clk)) then if h_count < WIDTH and v_count < HEIGHT then address <= address + 1; else address <= (others =>'0'); end if; end if; end process;
-- SCREEN ON
-- screening signal SCREEN_ON <= '1' when h_count < WIDTH and v_count < HEIGHT else '0';
-- Turn Off VGA RBG Signals if outside of the active screen -- Make a 4-bit AND logic with the R, G and B signals
vga_red_o <= (SCREEN_ON & SCREEN_ON & SCREEN_ON & SCREEN_ON) and vga_red; vga_green_o <= (SCREEN_ON & SCREEN_ON & SCREEN_ON & SCREEN_ON) and vga_green; vga_blue_o <= (SCREEN_ON & SCREEN_ON & SCREEN_ON & SCREEN_ON) and vga_blue; -------------------- -- Rerouting signals -------------------- vga_red <= data_out(11 downto 8); vga_green <= data_out(7 downto 4); vga_blue <= data_out(3 downto 0); data_inn <= sw_i(11 downto 0); -- (11 downto 8) is RED, (7 downto 4) is GREEN, (3 downto 0) is BLUE write <= sw_i(15 downto 15); -- Activ high when writing to BRAM
end Behavioral;