Composite video from FPGA Nov 2, 2016

Last week’s setup was just for warm-up – I wanted to understand the signal generation before bringing it over to an FPGA. Here is the same signal, generated by the same µC, but passing its data through the FPGA:

We’re now all set to turn those code loops into raw gates and counters. As expected, the FPGA is much faster and easily able to generate single-pixel lines on the screen:

Verilog code for this is surprisingly simple:

module top (
    input clk,
    output vout, sync_
);

reg [2:0] count;
wire clk10 = count[2];
always @(posedge clk) begin
    if (count == 4)
        count <= 0;
    else
        count <= count + 1;
end

reg [9:0] xpos;
reg [8:0] ypos;
always @(posedge clk10) begin
    if (xpos == 639) begin
        xpos <= 0;
        if (ypos == 311)
            ypos <= 0;
        else
            ypos <= ypos + 1;
    end else
        xpos <= xpos + 1;
end

wire active = xpos < 490 && ypos < 268;
wire hsync = 528 <= xpos && xpos < 575;
wire vsync = 276 <= ypos && ypos < 279;

assign vout = active && (xpos == 0 || xpos == 489 || ypos == 0 || ypos == 267);
assign sync_ = active || !(hsync || vsync);

endmodule

As you can see, the visible (“active”) area can display up to 490 x 268 pixels.

Add three I/O pin definitions, one 470 Ω and one 1 kΩ resistor, an optional 1 nF filtering cap between output and ground, and you’ve got everything needed to display data on an attached monitor or TV set.

But not all monitors show such a composite signal in the same way, unfortunately:

The other problem is that while composite video is easy to generate and only needs a simple shielded cable to hook up, it’s not really well-suited for the display of digital information, graphics, fonts, and such - its artifacts tend to lead to very fuzzy images due to imprecise resolution matching.

So I’ve decided to switch to 640x480 VGA, and the results look considerably better:

That’s the full 640x480 image showing on a 7” 1024x600 LCD display, with precise 4:5 pixel stretching in both directions.

It uses a 25 MHz clock: 1 pixel every 40 ns.

All in all, I found that creating this setup in an FPGA was a worthwhile exercise for me, and trivial to convert to VGA afterwards.

And Verilog is even starting to make sense!

Weblog © Jean-Claude Wippler. Generated by Hugo.