In my last blog post, I talked about the process of programming an FPGA so that it would output digital RGB (red, green, blue) video signals to drive my Sony TV. I had successfully synthesized my Verilog code and turned it into a bitstream that I could use to program an iCEstick evaluation board, and now it was time to see if I could make things work in actual hardware. The iCEstick comes with a built-in 6×2 female header with 8 data pins, and also has through hole pads for an additional 16 data pins—more than enough connections for the signals needed to drive the TV. There are also 5 LEDs that can be turned on and off by the FPGA.
In addition to the red, green, and blue signals, there are also horizontal and vertical sync signals that need to be connected. First, a little explanation about how vintage TVs work. CRT TVs draw a picture by sweeping a beam of electrons across the screen. On the screen, there are hundreds of thousands of phosphor spots that light up when they are hit by the electron beam. In a color CRT TV, there are red, green, and blue phosphors (the primary colors of light, which can be combined in different intensities to form any color). The image is “painted” on the screen one line at a time by three separate electron beams (one each for red, green and blue). With the circuit I built there are a total of 240 lines that make up the full screen, or one frame. The electron beams start out aimed at the upper left-hand corner of the screen and are swept to the right to paint the first line of red, green and blue dots (the dots are small enough and so close together that your eye interprets the color combination of three RGB dots as a single spot on the screen). The intensity of each beam is controlled by the separate red, green, and blue (RGB) signals being fed to the TV, and this determines the color of each spot or pixel on the screen. Every time the electron beam reaches the end of a line, it has to be turned off and moved to the beginning of the next line (this is called “horizontal retrace”). The horizontal sync signal tells the TV when to go to the next line.
Once all 240 lines have been painted on the screen, The electron gun again has to be turned off and moved all the way back to the upper left-hand corner of the screen in preparation to start painting a new frame (this is called “vertical retrace”). The vertical sync signal tells the TV when to go back to the start of the frame, and the TV displays 60 frames per second, which is fast enough that your eyes and brain interpret it as a smoothly moving image. As a sanity check to verify that the FPGA circuit was actually operating, I added some additional Verilog code to blink one of the LEDs provided on the iCEstick. The code consists of a counter that increases by one every time there is a vertical sync. When the counter reaches 30, it toggles the LED. Since there are 60 frames per second, this makes the LED blink on and off once per second. So, if the LED is blinking at the right rate, I know that the vertical sync signal is working properly, a good indication that the FPGA is doing what it’s supposed to do.
With the FPGA programmed and the LED blinking correctly, I hooked everything up to the TV, switched to the RGB input, and…nothing happened! So, now it was time to do some troubleshooting. I’ve always enjoyed debugging electrical circuits; it’s like being a detective and following clues that are revealed by your test equipment to zero in on the culprit (or bug). At this point, I needed some help from an oscilloscope to see what the FPGA was actually doing. An oscilloscope allows you to see a visual representation of how the signals in an electrical circuit are changing with time. I expected to see a series of regular, short pulses for the horizontal sync signal (remember, one pulse every time the TV needs to start scanning a new line), as well as a much slower series of pulses for the vertical sync signal (one pulse every time the TV needs to start scanning a new frame, 60 pulses per second). I also looked at the R, G, and B signals to verify that they were correct. The image below shows the horizontal sync signal, with the blue signal below it.
Okay, this looks good! Notice how the blue signal only pulses in the time between the horizontal sync signals; the red, green and blue signals contain picture information, so they should only be doing something when the TV is not performing a horizontal or vertical retrace. So, why was there no picture? My next step was to make sure I understood how the TV worked and what kind of signals it was expecting. For digital RGB signals, which can either be on or off, many TVs and monitors from the same era as my Sony TV feed the incoming sync signals into some digital logic to combine horizontal and vertical into a single mixed signal called composite sync. This signal is then used internally by the TV to figure out how to draw each frame. When I finally found the circuit diagram for my TV, I immediately had one of those great “aha!” moments where you know (or at least think you know) exactly what the problem is. It turns out that in this particular TV, the horizontal sync (Hsync) and vertical sync (Vsync) signals are fed into an AND gate:
With digital circuitry, signals can either be high (typically positive voltage, in this case around 5 volts), or low (typically ground or 0 volts). When you feed two signals into an AND gate, the output is only high if both signals are high. If either signal is low (or both signals are low), the output is low. And, here’s the big aha: I was using positive sync polarity in my FPGA circuit (see the oscilloscope traces above), which means that each sync signal was normally low and only pulsed high for a short time when it was time for a retrace. So, the vertical sync signal was low the entire time that the TV was supposed to be drawing the frame (remember, vertical sync only pulses when the frame is complete and it is time to move the electron beam back to the top), and this meant that the output of the sync combining AND gate was also low. Effectively, the TV was killing the horizontal sync pulses and therefore couldn’t figure out where to start drawing each line! The built-in circuitry in the TV was smart enough to not even attempt to draw the lines without seeing valid sync signals. Notice in the simulation below that with positive sync polarity, the only time something makes it through the AND gate is during the vertical sync pulse, when a few horizontal sync pulses make it through (these are the only times that both inputs of the AND gate are high).
Luckily, the fix for this was simple: change from positive sync polarity to negative sync polarity. This means that the sync signals are normally high and only pulse low when it is time for a retrace. With this setup, the vertical sync signal is high the entire time the TV is supposed to be drawing the frame, therefore, negative pulses on the horizontal sync signal will still make it through to the output of the AND gate (remember, if only one of the inputs to the AND gate goes low, the output also goes low).
I made the change in my code, hooked everything up again, and…success!