« What my bench looks like after a little work | Main | CR2450 Coin Cell Charger »

Television + FPGA + Verilog

I love when people share their code on the internet, but have a complaint: short, obscure variable names. Also, a lack of whitespace. Most engineers aren’t the best at documentation, myself included. But I try my best to make my code very readable. It can be a pain type out 20 character variable names, but that’s where code completion, along with regular expressions and find & replace come in.

Surprisingly, unreadable code recently led me to do something I don’t often do: start from scratch. I was looking for a Verilog module to generate an NTSC signal, which is the analog television standard in North America and a few other places. There were plenty of VHDL snippets out there, and one or two Verilog, but I couldn’t make heads or tails of what the author was doing with it. So I got on Google and and found just about every document I could on the NTSC standard until it finally sunk in. I was just starting to get the hang of Verilog before I started this project, but having to go from timing specifications to an FPGA (Field Programmable Gate Array) really made it all sink in. The irony is that I really didn’t even want to generate a TV signal. I wanted to output video from my prototyping board to a VGA display, but I don’t have one. Normally they’re a dime a dozen on trash days here in NYC, until I needed one. But, I do have a small TV a neighbor threw out a few months ago.

So here I’m sharing my project. At the heart is a file named interlaced_ntsc.v, which generates 3 bit monochrome video signal. There’s one bit of code I borrowed, another file named 8x16_font_rom.v. It’s just a pixel lookup table for all the ASCII characters. Making a font rom is tedious, so I don’t feel bad about using that. The top project file is top_ntsc.v. It’s included only as reference to complete working project. You don’t need to use it unless you’re new to FPGA’s or Verilog.

Here’s the instantiation template for my NTSC code. There’s a few signals not listed, which are only needed for debugging with an oscilloscope. They’re documented in the code.

interlaced_ntsc.v instantiation template

interlaced_ntsc instance_name (                
    .clk( clk ),                              // input: 50 MHz clock input     
    .pixel_data( pixel_data ),                // input: brightness of pixel 0..5
    .pixel_y( pixel_y ),                      // output: current pixel's y coordinate (row number)
    .pixel_x( pixel_x ),                      // output: current pixel's x coordinate
    .pixel_is_visible( pixel_is_visible ),    // output: high when not a sync signal, but not necessarily visible on the screen
    .ntsc_out( ntsc_out )                     // output: the TV signal, fed to a 3 bit r2r DAC

The 50 MHz clock requirement is baked into the code right now. I’m trying to figure a way to improve that. If you need to use a different clock, adjust the timing constants in interlaced_ntsc.v. They’re pretty obvious.

That’s it. I’m the first one to admit that I’m frequently a hypocrite, so if there’s something you don’t understand, or needs more comments, please let me know. And if you see a way to improve it, definitely leave a comment.

Source Code

PrintView Printer Friendly Version

EmailEmail Article to Friend

References (16)

References allow you to track sources for this article, as well as articles that were written in response to this article.

Reader Comments

There are no comments for this journal entry. To create a new comment, use the form below.

PostPost a New Comment

Enter your information below to add a new comment.

My response is on my own website »
Author Email (optional):
Author URL (optional):
Some HTML allowed: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <code> <em> <i> <strike> <strong>