Forum: FPGA, VHDL & Verilog I don't really understand how VGA controlling works

von Naketo I. (naketo)

Rate this post
0 useful
not useful

I'm an FPGA beginner and have trouble understanding how VGA control 
signals and VGA interact, and how to correctly generate VGA control 
signals (with Verilog) for more complicated specifications:

1. Seemingly, the low portions in horizontal- and vertical- sync signals 
correspond to transitioning from one row to the next, and transitioning 
from the bottom-right corner to the upper-left corner, respectively. But 
is the VGA "controlled" by those low signals? Do those low signals 
"tell" the VGA to switch to next row or jump back to the starting point?

2. Are the back porch and front porch there to satisfy setup time and 
hold time? Are the durations of porches given in VGA timing table only 
required minima (i.e. can I setup porches to be much longer than the 
given values in the table?)

3. This is what confuses me the most: From the two continuous 
horizontal- and vertical- sync signals, how on earth does the VGA know 
(or do I know) EXACTLY which point on screen it is displaying? If timing 
is the only factor, does that mean I must pay a lot of attention to 
match RPG control signals and h-sync and v-sync signals perfectly? If 
the answer is yes, then I have even more problems which I can only 
describe using my assignment as an example:

In this assignment we use a built-in 50MHz clock and the pixels of the 
VGA is specified to be 800x600. The framerate is specified to be 72Hz. 
The VGA timing table gives the following sync signal structures:

h-sync:| 0---back-porch(104)---103 | 104---row display(800)---903 | 
904---front-porch(16)---919 | 920__pulse width(120)__1039 |

v-sync:| 0---back-porch(23)---22 | 23---row display(600)---622 | 
623---front-porch(37)---659 | 660__pulse width(6)__665 |

This seems to mean that for each pixel in a row on screen I spend 1 
clock cycle (20ns) on it. However, for many complicated cases, I would 
want to control the color of a pixel depending on its location on screen 
and perhaps a lot of additional conditions such as the relation of 
current position with another location, certain states, and whatnot.
Now, if the location of the pixel depends on horizontal and vertical 
pixel counters, and the color depends further on the location, how can I 
match them in time? Also, what if my logic has to spend more than 20ns 
to decide the color of a pixel? Will that completely crash the image on 
the VGA screen?

Actually I've somehow completed my assignment, but I find my code messy 
and I totally have no idea why it worked:

For example, a portion of the assignment required us to show a star that 
changes its color every 0.5sec. My implementation looks like:
//----------------pixel counters----------------
always@(posedge CLK or posedge RESET) begin
    if(RESET) h_count <= 11'd 0;
    else if (h_count >= 11'd 1039) h_count <= 11'd 0;
    else h_count <= h_count + 11'd 1;

always@(posedge CLK or posedge RESET) begin
    if(RESET) v_count <= 10'd 0;
    else if (v_count >= 10'd 665) v_count <= 10'd 0;
    else if (h_count == 11'd 1039) v_count <= v_count + 10'd 1;
    else v_count <= v_count;

//----------------h- and v- sync----------------
always@(posedge CLK or posedge RESET) begin 
  if(RESET) VGA_HSYNC <= 1'b 0;
  else VGA_HSYNC <= (h_count >= 11'd 0) & (h_count <= 11'd 919);

always@(posedge CLK or posedge RESET) begin 
  if(RESET) VGA_VSYNC <= 1'b 0;
  else VGA_VSYNC <= (v_count >= 10'd 0) & (v_count <= 10'd 659);

//----------------a frame counter and a flag----------------
always@(posedge CLK or posedge RESET) begin
    if(RESET) frame_count <= 6'd 0;
    else if (frame_count >= 6'd 49) frame_count <= 6'd 0;
    else if(v_count == 10'd 665) frame_count <= frame_count + 6'd 1;
    else frame_count <= frame_count;

always@(posedge CLK or posedge RESET) begin
    if(RESET) color_flag <= 1'd 0;
    else if (frame_count == 6'd 49) color_flag <= ~(color_flag);
    else color_flag <= color_flag;

//----------------RGB control----------------
always@(posedge CLK or posedge RESET) begin
    if(RESET) VGA_RGB <=  3'b 000;
    else if(display) begin //display is high when counters in valid range
        casez({tree, star, snow})  //these are outputs from submodules that decides the "shapes" of objects on screen
            3'b ??1: VGA_RGB <= 3'b 111;  //white snow
            3'b ?10: VGA_RGB <= (color_flag) ? (3'b 110) : (3'b 111);
                //switching between yellow and white
            3'b 100: VGA_RGB <= 3'b 010;  //green tree
            default: VGA_RGB <= 3'b 001;  //blue background
  else VGA_RGB <= 3'b 000;  //for transitions

It seems to me that my h_count and v_count directly decides my VGA_HSYNC 
and VGA_VSYNC. But my VGA_RGB depends at least on color_flag, which 
further depends on frame_count, which depends on h_count and v_count. 
Shouldn't that cause delay of a few clock cycles? The code was 
synthesized and did produced what I wanted to display. So how on earth 
did my VGA_RGB sync with VGA_HSYNC and VGA_VSYNC in time??? Do I 
overthink this issue? Or was I just lucky? what did I miss?


Entering an e-mail address is optional. If you want to receive reply notifications by e-mail, please log in.

Rules — please read before posting

  • Post long source code as attachment, not in the text
  • Posting advertisements is forbidden.

Formatting options

  • [c]C code[/c]
  • [avrasm]AVR assembler code[/avrasm]
  • [vhdl]VHDL code[/vhdl]
  • [code]code in other languages, ASCII drawings[/code]
  • [math]formula (LaTeX syntax)[/math]

Bild automatisch verkleinern, falls nötig
Note: the original post is older than 6 months. Please don't ask any new questions in this thread, but start a new one.