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; 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!