0

I'm implementing the XGA (1024x768) video protocol with an Altera FPGA. I have images displaying, with correct color and crisp vertical display (i.e., setting every nth vertical pixel to black results in a sharp horizontal line w/o aliasing). However, the horizontal display (vertical lines) is very skewed, with the 1-pixel-wide lines being "smeared" across a 3 to 4 pixel width. Additionally, the width of the display signal is too wide. Attempting to create an even height and width grid results in the cells being wider than they are tall.

I've checked all of my timings via logic analyzer against these values, and they are extremely accurate, to within hundredths precision.

Based on this problem description, any ideas on where to look for debugging? Considering that the vertical is spot-on, I'm thinking it has something to do with my horizontal sync? VGA signal generation code:

module vga_sig_gen
(
    clk,
    reset_n,
    vga_BLANK_N,
    vga_SYNC_N,
    vga_HS,
    vga_VS,
    vga_R,
    vga_G,
    vga_B
);

// XGA signals
input clk;
input reset_n;
output reg vga_BLANK_N;
output reg vga_SYNC_N;
output reg vga_HS;
output reg vga_VS;
output reg [7:0] vga_R;
output reg [7:0] vga_G;
output reg [7:0] vga_B;

// Frame/line position
reg [11:0] hor_pos;
reg [9:0] vert_pos;

always @ (posedge clk) begin
    if(!reset_n) begin
        {vga_R, vga_G, vga_B} <= 24'h000000;
        hor_pos <= 12'd0;
        vert_pos <= 10'd0;
    end
    else begin
        // Update RGB values
        {vga_R, vga_G, vga_B} <= (hor_pos % 48 == 0) || (vert_pos % 48 == 0) ? 24'd0 : 24'hB93E06;

        // Update line/fram position
        hor_pos <= (hor_pos == 12'd1343) ? 12'd0 : hor_pos + 12'd1;
        if(hor_pos == 12'd1343) begin
            if(vert_pos == 10'd805) begin
                vert_pos <= 10'd0;
            end
            else begin
                vert_pos <= vert_pos + 10'd1;
            end
        end
    end

    // Generate VGA signals
    vga_BLANK_N <= ((hor_pos > 12'd319) && (vert_pos > 10'd37)) ? 1'b1 : 1'b0;
    vga_HS <= ((hor_pos > 12'd23) && (hor_pos < 12'd160)) ? 1'b0 : 1'b1;
    vga_VS <= ((vert_pos > 10'd2) && (vert_pos < 10'd9)) ? 1'b0 : 1'b1;
    vga_SYNC_N <= 1'b0;
end

endmodule 
Connor Spangler
  • 805
  • 2
  • 12
  • 29

2 Answers2

2

It looks like you're trying to make a grid by sending out a black pixel every 48 pixels. Is that correct?

Based on what you're saying, you may have a setup-time issue on your vga_R/G/B registers. This is probably because if your explicit use of %48, which is not a simple operation

A simpler solution may be to add another counter that counts from 0-47, and output a black pixel whenever that counter is equal to 47. You will need this counter for both vertical and horizontal

John
  • 46
  • 1
0

The problem was that the native aspect ratio of my LCD monitor was causing the stretching. John's answer could be the cause if the internal clock was too slow to handle it, however at 50 MHz with a 65 MHz PLL multiplier this wasn't an issue (as revealed by the oscilloscope).

Connor Spangler
  • 805
  • 2
  • 12
  • 29