EmbDev.net

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


von Naketo I. (naketo)


Rate this post
useful
not useful
Hi,

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:
1
//----------------pixel counters----------------
2
always@(posedge CLK or posedge RESET) begin
3
    if(RESET) h_count <= 11'd 0;
4
    else if (h_count >= 11'd 1039) h_count <= 11'd 0;
5
    else h_count <= h_count + 11'd 1;
6
end
7
8
always@(posedge CLK or posedge RESET) begin
9
    if(RESET) v_count <= 10'd 0;
10
    else if (v_count >= 10'd 665) v_count <= 10'd 0;
11
    else if (h_count == 11'd 1039) v_count <= v_count + 10'd 1;
12
    else v_count <= v_count;
13
end
14
15
//----------------h- and v- sync----------------
16
always@(posedge CLK or posedge RESET) begin 
17
  if(RESET) VGA_HSYNC <= 1'b 0;
18
  else VGA_HSYNC <= (h_count >= 11'd 0) & (h_count <= 11'd 919);
19
end
20
21
always@(posedge CLK or posedge RESET) begin 
22
  if(RESET) VGA_VSYNC <= 1'b 0;
23
  else VGA_VSYNC <= (v_count >= 10'd 0) & (v_count <= 10'd 659);
24
end
25
26
//----------------a frame counter and a flag----------------
27
always@(posedge CLK or posedge RESET) begin
28
    if(RESET) frame_count <= 6'd 0;
29
    else if (frame_count >= 6'd 49) frame_count <= 6'd 0;
30
    else if(v_count == 10'd 665) frame_count <= frame_count + 6'd 1;
31
    else frame_count <= frame_count;
32
end
33
34
always@(posedge CLK or posedge RESET) begin
35
    if(RESET) color_flag <= 1'd 0;
36
    else if (frame_count == 6'd 49) color_flag <= ~(color_flag);
37
    else color_flag <= color_flag;
38
end
39
40
//----------------RGB control----------------
41
always@(posedge CLK or posedge RESET) begin
42
    if(RESET) VGA_RGB <=  3'b 000;
43
    else if(display) begin //display is high when counters in valid range
44
        casez({tree, star, snow})  //these are outputs from submodules that decides the "shapes" of objects on screen
45
            3'b ??1: VGA_RGB <= 3'b 111;  //white snow
46
            3'b ?10: VGA_RGB <= (color_flag) ? (3'b 110) : (3'b 111);
47
                //switching between yellow and white
48
            3'b 100: VGA_RGB <= 3'b 010;  //green tree
49
            default: VGA_RGB <= 3'b 001;  //blue background
50
    endcase
51
  end
52
  else VGA_RGB <= 3'b 000;  //for transitions
53
end

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?

Please log in before posting. Registration is free and takes only a minute.
Existing account
Do you have a Google/GoogleMail account? No registration required!
Log in with Google account
No account? Register here.