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;
