Pumping 1080p video out of an FPGA

fpga-pumping-1080p

[Hamster] admits this 1080p HDMI hack for an FPGA doesn’t put a signal that’s fully up to specifications. But as you can see in the image above it does output a 1920×1080 image at 60 Hz, which is the size and frequency of full HD video. It falls just short due to some jitter, which may be just fine if this is only being used for early prototyping and will be replaced with a dedicated encoder later in the design process.

Here he’s chosen a Pipistrello board but thinks that any device which has a Spartan 6 chip with the differential pairs connected to an HDMI socket will work. The difficulty of the task comes in serializing four output channels at 1500 Mb/s each. Because of this just coding your logic isn’t going to work. After roughing out the design [Hamster] went back in and chose to manually place some of the components to ensure that data from each channel arrives at the same time.

While you’re messing with HDMI you may also want to give this overlay hack a try.

14 thoughts on “Pumping 1080p video out of an FPGA

  1. His site seems to be having trouble, but it loaded after several minutes. I’m amazed that the connection didn’t time out!

    1. I think you might have missed the time scales involved here. I believe this to be well outside of the synchronous domain that the Xilinx tools are designed to work in.

      Each bit of the DVI-D signal is 660ps. On a Spartan 6 propagation delays through a CLB (Logic Block) are around 250ps. The smallest routing delay between CLBs is about 350ps. Setup and hold times for the flip-flops are about 600ps.

      However, if there is a better way to do it I am all ears and very, very keen to see/try it – manual placement / timing is a real P.I.T.A.

      1. That’s the “magic” of the fitter. It will insert delays and route things accordingly when presented with timing it needs to meet. Yes, there are cases where it will say “sorry, you gave me a constraint that I can’t meet”.

      2. I recently completed a PCIe soft IP core design; the connection between the core and the PHY was 250MHz (4ns). You’re required to use time constraints (and give it an idea of how long each trace is between the FPGA and PHY) to get it to work. That was using a device without built-in PHYs; the same device (Altera Cyclone IV) comes in a variant that has hardware transcievers capable of 5Gbps, and the newer devices can go much faster yet.

        Constraining your design is essential to getting these things to work. It’s generally frowned upon to manually place anything because as clock rates climb and circuit complexity increases it’s almost impossible to know better than the fitter about what should go where. You instead say “these signals have these constraints” and let the fitter do the work.

        It’s not only possible to achieve these data rates without manually placing — it is actually recommended. Learn to love the constraint system; it’s the only way to do it in a repeatable and scalable manner.

      1. Why didnt you just use GTP? Im a total fpga noob, but I was under the pmpression spartan 6 GTP was able of driving 1080p easily.

        btw:
        over a year ago I was very interested in making SATA network card, there is one commercial product (or at least some stupid software patents). I couldnt find an answer if two PC motherboards can talk raw data over SATA without any hub/router, patent I found talked about hub like device that emulated a harddisk both ways – instead of pure network interface you had to exchange data by reading/writing sectors.

        I know “in the old days” some projects used IDE port for RAW data transfers, there was EEPROM programmer using IDE port called ideflasher, there was also some custom TV out for car computer. I think I also remember some data acquisition card using IDE port.

        I wonder whats the cheapest FPGA with enough 6Gbit serdes ports to link two computers using SATA 3.0

  2. Xilinx has an app note with how to do HDMI in/out, but you can’t publish the code they use. It doesn’t look like the PDF has any such gag order, nor does the user guide related to this stuff.

    The thing that’s really necessary here is an OSERDES. That’s the Verilog name for a special bit of hardware in the Spartan 6 used to make serial IO faster than the FPGA system clock. There’s some other clocking related stuff and some special transmitter/receivers to handle the +/- wire pairs used in HDMI. All this stuff is outlined in the app note and the Select IO resource guide. However, this approach will only work on the Spartan 6, and not all FPGAs are created equal (The Atlys is Xilinx’s testbed in the app note).

    This should help:

    http://www.xilinx.com/support/documentation/user_guides/ug381.pdf

    Here’s the application note. It links to the code I used a year-ish ago:

    http://www.xilinx.com/support/documentation/application_notes/xapp495_S6TMDS_Video_Interface.pdf

    1. You missed the essential bit of the hack – the Spartan 6 OSERDES2 can only run up to 1050Mb/s, however 1080p needs 1500Mb/s. To make this work I’ve implemented a QDR output within the FPGA’s fabric.

      The method used in XAPP495 is only good for 720p or 1080i, but can not be used to implement 1080p.

      1. Actually, the output pins themselves are only guaranteed to work up to 1050 Mb/s, as well. The atlys app note tends to work (out of spec) at 1080P60, but in either case you *WILL* probably want a heat sink. The App note also has a receiver. In both cases, you don’t need a full encoder/decoder, but having an external HDMI buffer helps alot from a signal integrity point of view if you want to stably do higher data rates.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s