Day 5: HDMI and VGA

So today I decided to start working on getting some video out of my board.

My DE-10 Nano comes with an HDMI port and a video encoder chip built right into it, so that makes a pretty obvious choice of video output. My first order of business was just to see if I could get my monitor to recognize a signal and display a black screen.

After reading through the datasheets of the included ADV7513 HDMI transmitter chip, I knew that first I had to program a pretty hefty number of registers over I2C to initialize my video output. At first I tried using a Verilog I2C master module interface to do this, but after trying unsuccessfully to get it to do absolutely anything at all in a simulator, I suddenly became very lazy and just copy pasted the HDMI config bits from the Nano’s own demo examples.

I wasn’t entirely sure if this worked, because my monitor didn’t seem to recognize any valid signal at this point, but I decided maybe the HDMI transmitter chip just needed an actual video signal and started working on that.

The cool thing about the ADV7513 is that although it outputs HDMI, what it takes as input is actually just a standard VGA video signal – right down to the hsync, vsync, active area, and pixel clock timings. The good news is generating a VGA signal is extremely easy. And because I’m driving this chip with a VGA signal, it would be trivial to modify my board to output a separate analog VGA signal later with almost no changes at all. And even further, because VGA timings are to some extent a slight modification of existing broadcast standards, it might even be possible to extend my board to output NTSC composite video later on! But that’s a problem for future me.

Anyway, back to generating a VGA signal. What I want to generate is a 640x480p@60Hz signal (the video co-processor will actually output a 320×240 image, but I will implement line-doubling and double each pixel horizontally to stretch this to the full screen). Given this, the VGA spec wants a full frame of 800×525 – 160 pixel clocks before the start of each visible scanline contains the front porch, a sync signal, and the back porch, and 45 scanlines after the end of the visible screen will contain an additional front porch, sync signal, and back porch. These offscreen areas are used to synchronize the signal horizontally and vertically (if you’re familiar with NTSC this may look very similar!)

VGA framerate is also 60÷1.001 (not precisely 60! this came from legacy NTSC standards once again), and that means I need to display 800 × 525 × ( 60 ÷ 1.001 ) = ~25175000 pixels per second. Therefore my pixel clock will be 25.175 MHz.

Unfortunately this isn’t a nice multiple of the 50MHz board clock, so I’ll make use of one of the Nano’s built-in PLLs instead to give me a nice precise fractional clock divider. Configuration of these is pretty simple, I just asked Quartus to instantiate the PLL Intel FPGA IP, chose Fractional-N Pll, and picked 25.175 as my output clock.

With that I threw together a quick VGA module, and (after a few attempts where I forgot to wire up the hsync, vsync, and data enable signals properly) that was apparently the missing piece. Once I was sending a VGA signal, the monitor seemed to accept the signal and stay on, albeit completely black. This also means the HDMI config bits I copied over were working fine!

A bit of fiddling later and I was able to prove that it was able to display colors and even a little grey box:

Now that I’ve got a video signal, my text task is to start working on the video co-processor!

Published by KillaMaaki

I'm a programmer, a gamer, and author of Unity Multiplayer Games by Packt Publishing.

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.