Close

DVI / HDMI Pmod for an iCE40 FPGA

dan-osheaDan O'Shea wrote 12/11/2018 at 02:09 • 3 min read • Like

Here is a proof-of-concept for DVI / HDMI output implemented on an iCE40 FPGA:

I set myself the challenge (masochistically, says the wife) of designing a DVI / HDMI Pmod to translate the iCE40's 3.3V LVCMOS / single-ended outputs into the TMDS (Transition-Minimised Differential Signalling) / CML (Current Mode Logic) signals used by DVI / HDMI.

Mike Field's work showed how to achieve DVI output on an FPGA that has built-in TMDS outputs, or even LVDS outputs (at 720p over a 1.5m HDMI cable). The problem is that while the iCE40 FPGAs do have LVDS inputs, they do not actually have LVDS outputs. They can 'emulate' LVDS outputs using two LVCMOS outputs and three external resistors, that "should be surface mounted as close as possible to the FPGA output pins" - which would mean designing an entire custom FPGA board, not just a custom Pmod add-on!

So, in search of an alternative I started out by posting a question on reddit, and one answer led me to a helpful article (written over 15 years ago in 2003!) with a nice clear table outlining what I had been fruitlessly searching for - the electrical characteristics of CML!

Another answer mentioned Black Mesa Labs, who do have two designs for DVI Pmods - but they use RGB signalling and rely on a conversion chip (TFP410) to generate the digital DVI data (a chip which costs around five times more than the combined cost of the two chips I am using here), and they require 7 to 16 FPGA outputs depending on the colour depth - whereas my concept manually generates the DVI data and uses only 4 FPGA outputs regardless of colour depth.

I also found another project working towards DVI on an iCE40 using AC-coupling, but with no voltage-level conversion? The link from there to an application note discussing the use of AC-coupling when translating between single-ended and differential signalling was another important bread-crumb on the path though.

The design that I landed on was to use the fastest 3.3V to 1.2V level-shifter I could find (SN74AXC8T245), and then feed the 1.2V outputs into a dedicated DVI / HDMI level-shifter (PTN3366) to achieve proper TMDS / CML outputs. The single-ended to differential conversion happens by connecting the 1.2V signals (AC-coupled through capacitors) to the PTN3366's positive inputs, with the PTN3366's negative inputs (AC-coupled through capacitors) connected to ground. There is an LDO onboard to provide the 1.2V supply needed, and a step-up converter to provide the 5V required on the HDMI connector. There is a solder-jumper to optionally tie the connector's shield to ground, only because I had read so much conflicting information on whether it should be grounded or not.

The code is based on Mike Field's work and uses the iCE40's DDR output mode to get 250MHz outputs from a 125MHz clock. As a proof-of-concept, it works! But only very experimentally at the moment - small changes here and there in the code sometimes throw the whole thing off... at first I was getting some weird interference / glitchy vertical lines, until I switched to using a short 0.5m HDMI cable. The one monitor I have here with a HDMI input now displays the test pattern no problem, but my TV does not like it - a lot seems to depend on the tolerance of the screen being used...

Anyway, even though this is definitely right at the edge of what both the iCE40 and I seem capable of, I'm glad to have at least met the challenge set for myself!

Like

Discussions

Splinedrive wrote 02/20/2021 at 09:47 point

i have done an implementation from scratch https://github.com/splinedrive/my_hdmi_device  . You will find code for icestick, blackicemx and ulx3s. I use for ice40k a pmod works only with passive resistors and works great with long cables. BTW. Icestick based on h1kx and has only 1k luts.

  Are you sure? yes | no

K.C. Lee wrote 10/05/2019 at 11:48 point

From that EDN article and table, you could have used AC coupling along with the LVDS 3 resistors emulation to a proper differential output to interface to CML.  

Pseudo diff are meh for high speed signals. Your failure to match impedance is what cause glitches.  hint: Single ended driver impedance =/= what's terminated at the CML side.  Hell even a series termination would have reduced the glitch - reflections due to impedance mismatch. Also a *high* amplitude signal (1.2V) would have *high* amplitude of reflection.

The LVDS emulation have both impedance matching and proper amplitude.  Looking for short cuts without trying to read and understand the spec is asking for trouble in high speed circuits.

 Face palm.

  Are you sure? yes | no

beefok99 wrote 11/13/2019 at 01:32 point

Would you please go into more detail about what you're saying here? I understand what you mean about the LVDS 3 resistor emulation, but are you basically stating that this design wouldn't need the SN74AXC8T245 provided that it used the LVDS 3 resistor emulation, and you would input that into the PTN3366? (Also having actual differential P/N signals with proper impedance?)

I'm experimenting with this concept further, and I'm still trying to figure this out. Thanks!

edit: Okay, maybe I can't do that! :) (still reading/learning..)

  Are you sure? yes | no

Frank Buss wrote 12/12/2018 at 16:30 point

Nice project, but I don't know if it is worth the trouble. E.g. with the relatively cheap DE10 Nano, you would have integrated HDMI output, and the Cyclone 5 with the integrated hard ARM core is much more powerful than any iCE40. But might be useful for some smaller projects.

  Are you sure? yes | no

davedarko wrote 12/12/2018 at 16:45 point

you and your whataboutism. "Der Weg ist das Ziel" :P 

  Are you sure? yes | no

Dan O'Shea wrote 12/13/2018 at 11:03 point

Absolutely, you are correct - I've also seen several affordable little boards using a Spartan-3A for DVI / HDMI. But a lot of people have already invested (both financially and emotionally!) in the iCE40 hardware and the IceStorm open-source toolchain, and my goal was mostly just to show that this is achievable... 😅

  Are you sure? yes | no

davedarko wrote 12/11/2018 at 11:34 point

Do you plan on open sourcing the design files for the pcb? Really digging all your projects and that you make this one work, but the layout is triggering me :D

Thanks for sharing!

  Are you sure? yes | no

davedarko wrote 12/12/2018 at 10:27 point

Great! oh dear - that is an unhappy hdmi to levelshifter pin config situation right from the beginning :D

  Are you sure? yes | no

davedarko wrote 12/12/2018 at 13:03 point

I've opened it in an older EAGLE version and the traces are all unrouted - not sure this was on purpose. Anyway - did you do any impedance matching for the pairs and is there a reason there's no sign of a ground plane?

  Are you sure? yes | no

Dan O'Shea wrote 12/12/2018 at 13:49 point

I wanted to avoid triggering you any further than you have already been :) So removed the traces / ground plane - the PCB is a blank canvas, please feel free to paint a masterpiece upon it! I did not have a lot of time to devote to this PCB design, so for me "it's ugly but it works" was far enough...

  Are you sure? yes | no

davedarko wrote 12/12/2018 at 14:17 point

I mean it works and that's awesome :) I'll see that I can finish, populate and test it at one point - I have no idea what I'm doing with FPGAs though and am no engineer btw. - I just like the challenge to make the board look "better" - maybe it even improves stuff - maybe it's a complete fail.

Thank you for sharing everything! 

  Are you sure? yes | no