Altera_Forum
Honored Contributor
17 years agoVGA VHDL DE2 problem
Hi,
I'm currently trying to use the VGA capabilities of the ALTERA DE2 board to display a red screen with VHDL. The resolution i'm using is 640x480. I've written a code for it but it doesn't work, the monitor displays that it doesn't recieve a signal. I've run the simulation and i can't find the problem. Is there anyone who has an idea what i'm doing wrong? Here is my code:LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.numeric_std.ALL;
ENTITY vga IS
PORT (CLOCK_50 : IN std_logic; --50Mhz clock
KEY : IN std_logic_vector(3 downto 0); --RESET
VGA_B: OUT std_logic_vector(9 downto 0);
VGA_R: OUT std_logic_vector(9 downto 0);
VGA_G: OUT std_logic_vector(9 downto 0);
VGA_CLK : OUT std_logic;
VGA_BLANK :OUT std_logic; --active low
VGA_SYNC : OUT std_logic;
VGA_HS : OUT std_logic;
VGA_VS : OUT std_logic);
END vga;
ARCHITECTURE vg OF vga IS
SIGNAL line_fin : std_logic; --variable to determine if a line has finished drawing
SIGNAL line_count : integer; --variable for counting the amount of lines drawn
SIGNAL frame_fin : std_logic; --variable to determine if a frame had finished drawing
SIGNAL CLOCK_25 : std_logic; --25Mhz clock
CONSTANT P1 : integer := 24; --Front porch (horizontal)
CONSTANT P2 : integer := 48; --Back porch (horizontal)
CONSTANT HSYNC_TIME : integer := 95; -- H_Sync pulse lenght
CONSTANT V1 : integer := 11250; --Front porch (vertical)
CONSTANT V2 : integer := 25500; --Back porch (vertical)
CONSTANT VSYNC_TIME : integer := 1600; -- V_Sync pulse lenght
BEGIN
VGA_SYNC<= '0';
pixel_draw : PROCESS(CLOCK_25,KEY(0)) --for drawing pixels and generating blank pulses
VARIABLE hcount : INTEGER := 0;
VARIABLE vcount : INTEGER := 0;
BEGIN
IF KEY(0)= '0' THEN
hcount := 0;
vcount := 0;
line_fin <= '0';
frame_fin <= '0';
line_count <= 0;
VGA_BLANK <= '1';
ELSIF rising_edge(CLOCK_25) THEN
IF line_count < 480 THEN
IF hcount < 640 THEN
VGA_R <= "1111111111";--send pixel information each clock_cycle
VGA_B <= "0000000000";
VGA_G <= "0000000000";
VGA_BLANK <= '1';
hcount := hcount+1;
line_fin <= '0';
ELSIF hcount = 640 THEN
line_fin <= '1'; --line finished, pulse line_fin and start blank pulse
hcount := hcount+1;
VGA_BLANK <= '0';
ELSIF hcount >640 and hcount <= 640+P1+HSYNC_TIME+P2 THEN
hcount := hcount+1;--keep blank pulse low for a set amount of time
line_fin <= '0';
VGA_BLANK <= '0';
ELSE
hcount := 1; --reset counters and increment line_counter
line_count <= line_count+1;
END IF;
ELSIF line_count = 480 THEN
IF vcount < 1 THEN --frame is finished; pulse frame_fin and initiate vertical blank pulse
vcount := vcount+1;
VGA_BLANK <= '0';
frame_fin <= '1';
ELSIF vcount >= 1 and vcount < V1+V2+VSYNC_TIME THEN
vcount := vcount+1; --keep blank pulse low for a set amount of time
frame_fin <= '0';
VGA_BLANK <= '0';
ELSE
vcount := 0; -- reset counters and line_counter
VGA_BLANK <= '1';
line_count <= 0;
END IF;
END IF;
END IF;
END PROCESS;
horizontal_synchronisation : PROCESS(CLOCK_25,KEY(0))
VARIABLE hsync_counter : INTEGER := 0;
VARIABLE hsync_started : INTEGER := 0;
BEGIN
IF KEY(0)= '0' THEN
VGA_HS <= '1';
hsync_counter := 0;
hsync_started := 0;
ELSIF rising_edge(CLOCK_25) THEN
IF line_fin = '1' or hsync_started = 1 THEN
hsync_started:= 1;
IF hsync_counter <= P1 THEN
hsync_counter := hsync_counter+1;--hsync stays high during front porch
VGA_HS <= '1';
ELSIF hsync_counter >= P1-1 and hsync_counter <= HSYNC_TIME+P1 THEN
hsync_counter := hsync_counter+1;--hsync activated
VGA_HS <= '0';
ELSIF hsync_counter >= HSYNC_TIME+P1-1 and hsync_counter < HSYNC_TIME+P1+P2 THEN
hsync_counter := hsync_counter+1;--hsync stays high during back porch
VGA_HS <= '1';
ELSE
hsync_counter := 0;--reset variables and counters
VGA_HS <= '1';
hsync_started := 0;
END IF;
ELSE
VGA_HS <= '1';
END IF;
END IF;
END PROCESS;
vertical_synchronisation : PROCESS(CLOCK_25,KEY(0))
VARIABLE vsync_counter : INTEGER := 0;
VARIABLE vsync_started : INTEGER := 0;
BEGIN
IF KEY(0) = '0' THEN
VGA_VS <= '1';
vsync_counter := 0;
vsync_started := 0;
ELSIF rising_edge(CLOCK_25) THEN
IF frame_fin = '1' or vsync_started = 1 THEN
vsync_started := 1;
IF vsync_counter < V1-1 THEN
vsync_counter := vsync_counter+1;
VGA_VS <= '1';
ELSIF vsync_counter >= V1-1 and vsync_counter < VSYNC_TIME+V1-1 THEN
vsync_counter := vsync_counter+1;
VGA_VS <= '0';
ELSIF vsync_counter >= VSYNC_TIME+V1-1 and vsync_counter < VSYNC_TIME+V1+V2 THEN
vsync_counter := vsync_counter+1;
VGA_VS <= '1';
ELSE
vsync_counter := 0;
VGA_VS <= '1';
vsync_started := 0;
END IF;
ELSE
VGA_VS <= '1';
END IF;
END IF;
END PROCESS;
vga_clk_gen : PROCESS(CLOCK_50,KEY(0))--devides 50MHz clock in 2, making it a 25MHz clock
VARIABLE count : INTEGER := 0;
BEGIN
IF KEY(0)= '0' THEN
CLOCK_25 <= '0';
VGA_CLK <= '0';
count := 0;
ELSIF rising_edge(CLOCK_50) THEN
IF count = 0 THEN
CLOCK_25 <= '1'; --1 period of 50MHz high
VGA_CLK <= '1';
count := 1;
ELSIF count = 1 THEN
CLOCK_25 <= '0'; --1 period of 50MHz low
VGA_CLK <= '0';
count := 0;
END IF;
END IF;
END PROCESS;
END vg;
Here is my testfile for modelsim: LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY vga_test IS
END vga_test;
ARCHITECTURE vgt OF vga_test IS
SIGNAL KEY : std_logic_vector(3 downto 0);
SIGNAL CLOCK_50 : std_logic := '0';
SIGNAL VGA_HS : std_logic;
SIGNAL VGA_R : std_logic_vector(9 downto 0);
SIGNAL VGA_G : std_logic_vector(9 downto 0);
SIGNAL VGA_B : std_logic_vector(9 downto 0);
SIGNAL VGA_BLANK : std_logic;
SIGNAL VGA_SYNC : std_logic;
SIGNAL finished : boolean := FALSE;
BEGIN
hs : ENTITY work.vga PORT MAP (
KEY => KEY,
CLOCK_50 => CLOCK_50,
VGA_R => VGA_R,
VGA_G => VGA_G,
VGA_B => VGA_B,
VGA_HS => VGA_HS,
VGA_BLANK => VGA_BLANK,
VGA_SYNC => VGA_SYNC
);
CLOCK_50 <= NOT CLOCK_50 AFTER 10 ns WHEN not finished;
PROCESS
BEGIN
KEY <= "0000";
KEY(0) <= '0';
WAIT FOR 100 ns;
KEY(0) <= '1';
WAIT FOR 50 ms;
finished <= true;
WAIT;
END PROCESS;
END vgt;Thanks in advance, Roelof