VHDL Code for VGA Controller: Syntax, Example, and Tips
A
VGA controller in VHDL manages timing signals like hsync and vsync to display images on a VGA monitor. It uses counters to generate pixel coordinates and sync pulses according to VGA standards. The controller outputs RGB signals and sync signals to drive the display.Syntax
A basic VGA controller in VHDL uses counters for horizontal and vertical pixel positions, and generates hsync and vsync signals based on timing parameters. It outputs RGB color signals and sync pulses.
- clk: input clock signal (usually 25 MHz for 640x480 VGA)
- hsync: horizontal sync output
- vsync: vertical sync output
- rgb: color output (usually 3 bits for R, G, B)
- h_count, v_count: counters for pixel position
vhdl
entity VGA_Controller is
Port (
clk : in std_logic;
hsync : out std_logic;
vsync : out std_logic;
rgb : out std_logic_vector(2 downto 0)
);
end VGA_Controller;
architecture Behavioral of VGA_Controller is
-- Timing constants for 640x480 @ 60Hz VGA
constant H_DISPLAY : integer := 640;
constant H_FRONT_PORCH: integer := 16;
constant H_SYNC_PULSE : integer := 96;
constant H_BACK_PORCH : integer := 48;
constant H_TOTAL : integer := H_DISPLAY + H_FRONT_PORCH + H_SYNC_PULSE + H_BACK_PORCH;
constant V_DISPLAY : integer := 480;
constant V_FRONT_PORCH: integer := 10;
constant V_SYNC_PULSE : integer := 2;
constant V_BACK_PORCH : integer := 33;
constant V_TOTAL : integer := V_DISPLAY + V_FRONT_PORCH + V_SYNC_PULSE + V_BACK_PORCH;
signal h_count : integer range 0 to H_TOTAL - 1 := 0;
signal v_count : integer range 0 to V_TOTAL - 1 := 0;
begin
-- Process to generate horizontal and vertical counters
process(clk)
begin
if rising_edge(clk) then
if h_count = H_TOTAL - 1 then
h_count <= 0;
if v_count = V_TOTAL - 1 then
v_count <= 0;
else
v_count <= v_count + 1;
end if;
else
h_count <= h_count + 1;
end if;
end if;
end process;
-- Generate hsync pulse (active low)
hsync <= '0' when (h_count >= H_DISPLAY + H_FRONT_PORCH and h_count < H_DISPLAY + H_FRONT_PORCH + H_SYNC_PULSE) else '1';
-- Generate vsync pulse (active low)
vsync <= '0' when (v_count >= V_DISPLAY + V_FRONT_PORCH and v_count < V_DISPLAY + V_FRONT_PORCH + V_SYNC_PULSE) else '1';
-- Generate RGB output (white color inside visible area, black outside)
rgb <= "111" when (h_count < H_DISPLAY and v_count < V_DISPLAY) else "000";
end Behavioral;Output
Outputs hsync and vsync pulses with RGB signals for 640x480 VGA timing; drives VGA monitor sync and color signals.
Example
This example shows a simple VGA controller generating sync signals and white pixels on the visible screen area. It uses a 25 MHz clock for standard 640x480 VGA timing.
vhdl
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity VGA_Controller is
Port (
clk : in std_logic;
hsync : out std_logic;
vsync : out std_logic;
rgb : out std_logic_vector(2 downto 0)
);
end VGA_Controller;
architecture Behavioral of VGA_Controller is
constant H_DISPLAY : integer := 640;
constant H_FRONT_PORCH: integer := 16;
constant H_SYNC_PULSE : integer := 96;
constant H_BACK_PORCH : integer := 48;
constant H_TOTAL : integer := H_DISPLAY + H_FRONT_PORCH + H_SYNC_PULSE + H_BACK_PORCH;
constant V_DISPLAY : integer := 480;
constant V_FRONT_PORCH: integer := 10;
constant V_SYNC_PULSE : integer := 2;
constant V_BACK_PORCH : integer := 33;
constant V_TOTAL : integer := V_DISPLAY + V_FRONT_PORCH + V_SYNC_PULSE + V_BACK_PORCH;
signal h_count : integer range 0 to H_TOTAL - 1 := 0;
signal v_count : integer range 0 to V_TOTAL - 1 := 0;
begin
process(clk)
begin
if rising_edge(clk) then
if h_count = H_TOTAL - 1 then
h_count <= 0;
if v_count = V_TOTAL - 1 then
v_count <= 0;
else
v_count <= v_count + 1;
end if;
else
h_count <= h_count + 1;
end if;
end if;
end process;
hsync <= '0' when (h_count >= H_DISPLAY + H_FRONT_PORCH and h_count < H_DISPLAY + H_FRONT_PORCH + H_SYNC_PULSE) else '1';
vsync <= '0' when (v_count >= V_DISPLAY + V_FRONT_PORCH and v_count < V_DISPLAY + V_FRONT_PORCH + V_SYNC_PULSE) else '1';
rgb <= "111" when (h_count < H_DISPLAY and v_count < V_DISPLAY) else "000";
end Behavioral;Output
Generates VGA sync signals and white pixels on visible area for 640x480 display.
Common Pitfalls
Common mistakes when writing a VGA controller in VHDL include:
- Using incorrect timing constants that do not match the VGA standard, causing no or distorted image.
- Not resetting counters properly, leading to sync signals that never toggle.
- Forgetting that
hsyncandvsyncare usually active low signals. - Driving RGB signals outside the visible area, which can cause flickering or noise.
Always verify timing values and test with a VGA monitor or simulator.
vhdl
wrong_hsync <= '1' when (h_count >= H_DISPLAY and h_count < H_DISPLAY + H_SYNC_PULSE) else '0'; -- Incorrect polarity -- Correct way: hsync <= '0' when (h_count >= H_DISPLAY + H_FRONT_PORCH and h_count < H_DISPLAY + H_FRONT_PORCH + H_SYNC_PULSE) else '1';
Quick Reference
Key timing parameters for 640x480 @ 60Hz VGA:
| Parameter | Value (pixels/lines) |
|---|---|
| Horizontal Display | 640 |
| Horizontal Front Porch | 16 |
| Horizontal Sync Pulse | 96 |
| Horizontal Back Porch | 48 |
| Horizontal Total | 800 |
| Vertical Display | 480 |
| Vertical Front Porch | 10 |
| Vertical Sync Pulse | 2 |
| Vertical Back Porch | 33 |
| Vertical Total | 525 |
Key Takeaways
Use correct VGA timing constants for horizontal and vertical sync signals.
Generate hsync and vsync pulses as active low signals based on counters.
Reset horizontal counter at end of line and vertical counter at end of frame.
Output RGB signals only during visible pixel area to avoid noise.
Test your VGA controller with a real monitor or simulation for correct timing.