Close
0%
0%

HDMI PMOD

An HDMI breakout board for the high-speed PMOD slots on the Arty A7 35T

Similar projects worth following
This project is a high-speed PMOD to HDMI breakout board. There are no active components on this board, so the host card must have TMDS transmitters, as is the case with my Arty A7 35T dev board. Only the three color channels and the clock are hooked up directly to the PMOD connector due to the limited number of pins, with the rest of the signals hooked up to a 0.1" header on the side. This shouldn't be much of a problem, since I'll be hard-coding the resolutions and refresh rates anyways.

I have always been drawn to LEDs and visual projects. In college I made an RGB light strip controller for my apartment, and a 5x5x5 RGB LED cube that took in an audio signal and pulsed with detected bass notes. There's just something about LEDs that make a project so much more tangible without requiring 3D modeling software or shop work. I think this project is the natural progression of that.

To play around with video though requires that I have hardware that supports it. My Arty A7 35T dev board unfortunately has no video output, which means I either had to buy something off the shelf or make my own breakout board. There are plenty of expansion boards out there in the wild already, but none of them tickled my fancy. For example, there is this VGA PMOD from Digilent, or this DVI PMOD from 1BitSqured. I wanted something more modern than the VGA, and both use two PMOD connectors! Lucky for me, the Artix 7 chip on my board has TMDS and LVDS transceivers, and my board routes out a few of them as diff pairs to the PMOD connectors. As an added bonus, some smart individuals have already used these ports for exactly this purpose (see Domipheus Labs and Mike Vine). I thought about ordering Mike's PCB, but ideally I'd like to target 1080p 60 Hz and I'm not sure if the routing would hold up at that frequency. I'm not even sure if the Artix 7 chip's transceivers are even capable of switching at the rate needed for that, so this is something that I will need to do more research on.

  • Rev 2 PCB, TMDS and SERDES working

    Alexander Wranovsky04/27/2021 at 22:38 0 comments

    Oops... PCB v2

    Shortly after my last post, I did a quick connectivity check, and I found that I screwed up the HDMI connector footprint! The pin numbers ended up being reversed from what they should have been. I'm not sure whether I did that, or if I downloaded the footprint that way, but shame on me for not double checking.

    After fixing the footprint, I reordered and reassembled the board. Much better now!

    For those curious, I tested this by hooking up an HDMI to DVI cable, and then checking with an ohmmeter. I compared the actual pinout with a diagram for DVI.

    Setting up TMDS IO and SERDES

    Before this, I had never directly instantiated any of the Xilinx primitives or done any advanced IO stuff away from work, so I wanted a way to test it separately from the display logic. To do this, I made a project that sets up the clocks with a PLL, a SERDES module for serializing the data, and an output buffer. I also made a linear feedback shift register to generate a pseudo-random sequence of 10-bit integers. An OUT_FIFO module is also present to separate the pixel clock domain from a potential logic clock domain in future designs.

    The result is a random bit pattern clocked out at 250 megabits/s (twice the 125 MHz TMDS clock, since the OSERDES modules are configured in DDR mode). I recently purchased an SDS2352X-E oscilloscope from Siglent to measure precisely this type of signal. With a bandwidth of 350 MHz, we're able to capture the fundamental at 125 MHz loud and clear, and probably around 80% of the third harmonic at 375 MHz. On top of that, it has optional 50 Ohm inputs, which is essential when making DIY probes for high-speed stuff. For around $850 brand-new, it's the best budget high-speed scope I could find without trolling eBay.

    Nothing works the first try

    This being such a simple design, I thought I could get away without simulating it. That, however, quickly proved to be wrong. I loaded a bitstream onto my board, hooked up the scope, and... nothing. Normally I would pull out Verilator at this point, but this design directly instantiates Xilinx primitives that Verilator has no model for. To get around this, I used xsim, which is the simulator that comes bundled with Vivado. Lucky for me, FuseSoC/Edalize has an xsim backend, which makes using it as easy as adding a couple lines to my core config file. I think I could potentially compile some of the models for Verilator but using xsim was definitely the path of least resistance here.

    Once setting up xsim, I ran the simulation. The results surprised me to say the least. Everything seemed to work just fine! The clocks were running, the SERDES module was serializing, and the differential outputs were swinging. As frustrating as this was, it narrowed down the problem to some sort of inconsistency between my dev board PCB and my design.

    Sure enough, this was it. My scope can only terminate to ground, so I had configured the design for 2.5V LVDS instead of 3.3V TMDS, which requires pullup resistors to 3.3V. The IO bank for this PMOD, though, is hardwired for 3.3V. This means the 2.5V configuration was probably putting the IO bank into an over-voltage protection mode! Switching the configuration to 3.3V TMDS and terminating to 3.3V fixed the problem.

    Test setup

    Here's an image to do the talking for me.

    The circuit diagram for a single end of the differential pair is pictured below. If I were using LVDS, I could have hooked up the SMA cable and connector directly to the PMOD interface, but TMDS termination requires that I have a high impedance between my scope and the circuit under test. I picked a 2450 Ohm resistor because it gives an attenuation close to 50:1, which is one of the options that my scope lets me select. In reality though, the resistor I had available was closer to 2.2 kOhm, which gives an attenuation of 45:1.

    If you have never used one of these transmission line probes before, they are surprisingly high bandwidth...

    Read more »

  • PCBs Assembled

    Alexander Wranovsky01/23/2021 at 22:37 0 comments

    PCB Assembly

    The PCBs that I ordered came in this week, and they look nice! I am surprised at how tiny they feel compared to how they looked on my monitor. An assembled PCB plugged into my Arty A7 board is shown below. I didn't solder the header or resistors connected to the sideband signals, since I'm not planning on using those yet.

    Admittedly it took me two attempts to get the HDMI connector soldered down correctly. I have a Hakko FX-888D iron which works well enough, but a hot air station and some solder paste would have definitely helped with the 0.5 mm pitch pins on the HDMI connector. I tried doing it the quick and dirty way the first time around by swiping across all of the pins, and then cleaning up with some solder wick. You can see how well that turned out below.

    On my second attempt I applied some flux to each pin, and then hit each one individually with a tinned iron. This still required some cleanup with the solder wick, but the result is much prettier. Here's a closeup.

    OpenEMS Simulation Progress

    I did spend a weekend trying to import the PCB into OpenEMS, but ran into some problems with the tools I tried. I first tried pcbmodelgen, which converts Kicad PCBs into an Octave/Matlab description of the geometry the mesh needed for simulation. While the examples worked fine for me, I couldn't figure out how to make it work with four layer boards. Next I tried pcb-rnd. It has a plugin for reading Kicad PCBs, but I think the version of Kicad I am using is too new for it. Upon importing my PCB, it puked with a message about the file format being unrecognized.

    For Gentoo users, I created ebuilds for both pcbmodelgen and pcb-rnd, which you can access here and here. The pcb-rnd ebuild is pretty lazy, and could have been done better had I taken the time to learn the project's replacement for autotools.

    I still plan to do a simulation at some point, but it will require some more work. I think the route forward will require that I either make changes to pcbmodelgen or roll my own tool. Whichever way I choose will probably warrant its own post, so stay tuned here for any updates.

    Next Steps

    Testing the PCB is the next thing in the queue for me. I'm hoping I can simply load up the project from Domipheus Labs and hit go. Once that's done, I will work on writing my own module in Verilog and packaging it up with FuseSoC.

  • Layout complete

    Alexander Wranovsky12/21/2020 at 04:39 0 comments

    I started doing layout with JLCPCB's 2-layer stackup, but I quickly realized that I wasn't going to be able to hit 100 ohm differential mode characteristic impedance with such a thick dielectric. Lucky for me, JLCPCB offers 4-layer boards for just a couple more dollars. They offer two separate 4 layer stackups: JLC7628 and JLC2313. I went with JLC2313 since the thinner dielectric shrinks your trace width when controlling the impedance.

    I also made a couple changes to the schematic, including swizzling around the TMDS pairs to make routing easier, and adding in some missing pull-ups and pull-downs.

    I have also been playing around with the OpenEMS 3D field solver in my spare time, and I would really like to plug this board into it and see how well it holds up. I used JLCPCB's calculator for choosing track width and spacing, and I am curious how accurate it is. I might potentially create some S-parameters for the board as well, but we'll see.

View all 3 project logs

Enjoy this project?

Share

Discussions

Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates