Intel® FPGA University Program
University Program Material, Education Boards, and Laboratory Exercises

VGA VHDL DE2 problem

Altera_Forum
Honored Contributor II
2,393 Views

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
0 Kudos
7 Replies
Altera_Forum
Honored Contributor II
783 Views

I attached a working 640x480 driver for debug / comparison. 

 

If the timing is off the nicer LCD monitors will just reject the signal. It can be helpful to plug it into an older CRT to get more information about what went wrong.
0 Kudos
Altera_Forum
Honored Contributor II
783 Views

Hi, 

 

Thanks for your reply. I did some timing analysis with my oscilloscope and i measured some frequency's. The timing is the same as in the document i was using: 

http://www.epanorama.net/documents/pc/vga_timing.html 

 

I also tried a old crt monitor, this doesn't work either. It displays that the singals are "out of range". Maybe the document is wrong? 

 

I'm going to try your verilog file now. 

 

Roelof
0 Kudos
Altera_Forum
Honored Contributor II
783 Views

The verilog file works after a few changes, i'm trying to convert it to vhdl.  

 

Roelof
0 Kudos
Altera_Forum
Honored Contributor II
783 Views

Hello I work with the board DE2, i'm spanish but i study in france and i forgot my inglish so excuse my if i make one mistake. My proyect is the show a controls board of a car in a touch-screen LCD. I dont know how start. If you can helps me with the control vga i do the rest. Thanks.

0 Kudos
Altera_Forum
Honored Contributor II
783 Views

Hi hencel, 

 

I tried to make the vhdl code to work, but there is a tiny flaw in the code. When I checked my signals with an oscilloscope or with my simulation, it looked like it should work. After a while I decided to learn verilog because it is very hard to keep vhdl compact. Verilog might be a bit harder but if you can read it it's much more convenient (well-organized). If you only know VHDL you could try to alter my code in the first post, I only have a working verilog driver.  

 

There are a lot of universities who use the de2 board, if you check their websites there are lots of examples how to use VGA in both verilog and VHDL.  

 

If you dont know how VGA works, you could check: 

http://www.epanorama.net/documents/pc/vga_timing.html 

 

For the list of links of universities: 

http://www.terasic.com.tw/cgi-bin/page/archive.pl?language=english&categoryno=39&no=30 

 

This link helped me a lot: 

http://www1.cs.columbia.edu/~sedwards/classes/2007/4840/video.pdf (http://www1.cs.columbia.edu/%7esedwards/classes/2007/4840/video.pdf

 

-Roelof
0 Kudos
Altera_Forum
Honored Contributor II
783 Views

Merci beaucoup. Thanks you very much.:)

0 Kudos
Altera_Forum
Honored Contributor II
783 Views

 

--- Quote Start ---  

I attached a working 640x480 driver for debug / comparison. 

 

If the timing is off the nicer LCD monitors will just reject the signal. It can be helpful to plug it into an older CRT to get more information about what went wrong. 

--- Quote End ---  

 

 

Should this code put anything out on the VGA or is it just a driver. Sorry im confused!?:confused:
0 Kudos
Reply