Electronic – Unable to figure out VGA [Verilog]

fpgaspartan 6verilogvga

After doing plenty of research on how to generate VGA signals and looking at a few code examples, I attempted to write my a simple VGA signal generator that just displays a single solid color on the screen. When viewing the simulation, the timing appears to be correct. When connected to a monitor, the monitor does not even acknowledge that a signal is being generated. This has got me stumped, any help would be appreciated.

I am using timing information found here: http://tinyvga.com/vga-timing/640×480@60Hz

Sync pulse generator:

module VGASyncPulseGenerator(
    input clk, //50Mhz input clock
    input rst,
    output HS, VS, //Sync Pulses
    output active //High when active area is being drawn
);

localparam HS_START = 16; // hSync start (end of front porch)
localparam HS_END = 16 + 96; // hSync end (start of back porch)
localparam HA_START = 16 + 96 + 48; // end of back porch
localparam LINE = 800; // Length of entire line;

localparam VS_START = 480 + 10; // vSync start (end of front porch)
localparam VS_END = 6480 + 10 + 2; // vSync end (start of back porck)
localparam VA_START = 0;
localparam FRAME = 525; // Length of entire frame

reg [10:0] hPos = 0;
reg [10:0] vPos = 0;

reg pixelStrobe = 0;

assign HS = ~((hPos >= HS_START) & (hPos < HS_END));
assign VS = ~((vPos >= VS_START) & (vPos < VS_END));

assign active = (hPos >= HA_START) & (vPos >= VA_START);

always @(posedge clk) begin //generate pixel clock at 25MHz
    pixelStrobe = ~pixelStrobe;
end

always @(posedge clk) begin
    if (pixelStrobe) begin
        if (hPos == LINE) begin
            hPos <= 0;
            vPos <= vPos + 1;
        end else hPos <= hPos + 1;
        if (vPos == FRAME) vPos <= 0;
    end
end



endmodule

Top module:

module VGATest(
    input clk, rst,
    output HS, VS,
    output [4:0] B,
    output [5:0] R,
    output [4:0] G
);

wire active;

assign R = (active) ? 5'd1 : 5'b0;
assign G = (active) ? 4'd16 : 4'b0;
assign B = (active) ? 4'd1 : 4'b0;

VGASyncPulseGenerator pulseGen(clk, rst, HS, VS, active);

endmodule

Best Answer

Problems I see in your code:

  • 640x480@60 uses a pixel clock of 25.175 MHz, not 25 MHz. The difference may be enough to keep some monitors from synchronizing. Consider using a PLL to generate the appropriate clock (50 MHz x72÷143 gives 25.1748 MHz, which is within 9 ppm), or targeting 800x600@72 instead, which uses a pixel clock of exactly 50 MHz.

  • The polarity of your sync pulses is wrong. 640x480@60 uses negative sync pulses -- HS and VS need to be low during sync, not high.

  • There's a typo in the definition of VS_END. You probably want to use the constant 480, not 6480.

Possible problems outside your code:

  • Do you have an appropriate constraints file? Are the signals being mapped to the right pins to reach the DAC?

  • Make sure your levels are correct. R/G/B are 0 to 0.7V; sync voltages aren't critical but should probably be 3.3V.