A goal for most of my electronic projects is to use them to learn about current technologies, not just to use them for the exploration of retro tech. Fortunately it is possible to combine these two goals. This is why I have pushed myself by including fairly up to date technology in my retro computers, starting with my first non trivial 6809 board a decade ago which included a hitherto unknown to me technology, CPLDs. The proper period-correct approach would have been to design the glue logic with discrete logic, but I felt it would be far more interesting, and beneficial to building my skills, to use a more up to date approach, hence the use of programmable logic.
With that in mind I have decided that my next FPGA development board should include a few things I’ve not yet looked at before, and have indeed actively avoided out of a mixture of fear, apprehension and perhaps even derision.
First up is HDMI. All my graphical displays so far have either used VGA or, going further back, PAL RGB. HDMI offers a few advantages over VGA, though the principle one is that still higher resolutions are available. A secondary advantage is that it is a digital signal so the picture quality should be better. Other benefits include optionally having sound carried on the same cable as the picture, and the fact that VGA is seen as a legacy technology by monitor manufacturers with no computer monitors built today including a VGA port.
Next, SDCards. All my previous designs have refrained from including an SDCard slot. I think this is a sound and justifiable decision when building computers with 1970s, 1980s and even 1990s era processors. Not only are they out of keeping aesthetically with the core of the computer, but they do not fit well technologically wise since they require 3.3V level shifters and attachment via SPI, which wasn’t really a popular choice back then. Nonetheless many retro enthusiasts include them on their boards, but of course that is up to them. The factors that make SDCards unappealing to me when building a retro computer make them appealing on a modern FPGA-centric board. I’ll be able to gain access to virtually unlimited mass storage and hardly any board space will be required; even less so if I stick to micro SDCards.
I now think it’s high-time I tackle interfacing some more up to date parallel memory busses. I’ve lost count of the number of projects I’ve completed that have made use of SRAMs, and whilst I’ve not fully explored the capabilities of 1980s era SIMMs that host DRAM ICs, I think it’s time I look at what’s probably the next in line in terms of complexity, and modernity, SDRAMs. Synchronous Dynamic RAMs are clocked instead of being controlled through asynchronous control lines. They also have increased bandwidth by exposing an array of multiple banks, which can be accessed in parallel. This does have the downside of making the memory controllers significantly more complicated then controllers for plain old asynchronous DRAM, but I think it sounds like an interesting challenge.
Lastly I want to look at powering the board via a USB-C plug and exposing a UART implemented in the FPGA via an FTDI IC onto that same USB socket.
Another idea that occurs to me is that a modular design would be useful. That way I could swap out a board with a HDMI connector and associated components with a board with a VGA interface. This would also give me a fallback if I could not get the HDMI side working. Plus I could use the board for other purposes and interfaces further down the line.
The next question, then, is what FPGA should I use?
The first decision to make is which manufacturer and family to use. The conclusion here was very easy: I’ve had great success with the Lattice iCE40UP FPGAs in two projects now. But what prevents me from reusing the iCE40UPs in QFN that I have now accumulated in my parts drawers is a lack of IO pins. If I want to have connections to an SDRAM, HDMI port, SDCard and perhaps a few buttons I am going to need more IO pins available then the 39 available on the 48 pin QFN part.
Fortunately the iCE40 was also made in the iCE40HX family, and within that family a 144 pin QFP version is available if one is, per the literature, happy to suffer some reduction is capabilities relative to the iCE40UP5 in QFN. All iCE40 FPGAs share common parts. They are configured the same way, have the same (if available) hardware peripherals, the same arrangement of power rails, etc. One downside to the HX is they lack the single port SRAM (1024KBit in the iCE40UP5), and they also lack the DSP hardware, which my softcore project makes use of for hardware multiply.
However there is a strange quirk in how Lattice present these part flavor’s capabilities. It seems that for marketing reasons Lattice downplays the amount of logic and the amount of BRAM in the mid-range iCE40HX4K parts. However, when looking into this and doing test builds with yosys and nextpnr that both the iCE40HX4K and iCE40HX8K have the same quantities of both, contrary to the datasheet. I assumed that this was a bug in the software and duly raised an issue for it, but it turns out that the capabilities of the 4K parts are reduced in the literature for marketing reasons. Very odd! I was glad that a 4K, in the usable to me QFP packaging, would suit my needs and be very close in capabilities to the UP5 I had used before.
The specification for the board, after some iteration on the design, is as follows:
- iCE40HX4K (PDF) in TQFP144
- 50 MHz primary clock
- Space for a secondary clock (unused at present)
- N25Q032 (PDF) 32 Mbit Config Flash
- Custom 10 pin IDC programming header for programming the flash or the FPGA
- FT231XS (PDF) USB to UART converter with USB-C socket doubling up as the source of 5V power.
- W9825G6KH (PDF) 4M x 4 Banks x 16 bits SDRAM (32 MByte)
- PS/2 port
- MiroSDCard slot
- RGB LED
- DS3231M (PDF) I2C Real Time Clock
- CR1220 battery slot
- Square wave output pin wired to FPGA
- AT24C2546 (PDF) I2C 32KByte EEPROM
- 4 push buttons
- 12 pin right angle PMOD (PDF) header
- 40 pin expansion header
- 27 general purpose IOs
- 2 clock output pins
- Shared I2C bus (2 pins)
I was quite pleased with the final specification. The RTC is perhaps unneeded, but why not? I never used it with the iCE40UP5 board, but perhaps this board would be different.
The inclusion of the PMOD header warrants some discussion.
All of my boards, be they FPGA development boards or full on retro computers, have included some kind of expansion connector. For instance the aforementioned iCE40UP5 board features a 6 pin general purpose IO header, simply because I was left with 6 unused IO pins on the FPGA. By chance I stumbled on the PMOD standard and realised that if I arranged my IO pins in a particular way I could make use of some ready made expansion boards. Everything from 7 segment LED displays to Ethernet is available with a standardised connector in a standardised PCB form factor. Plus it could still be used how I’ve always used these headers, by attaching ad-hoc wires to the pins.
Full disclosure: my initial board design, as presented here, contains a number of small errors, amongst them the arrangement of the PMOD header. This error, and one other, is corrected in my GitHub repository that holds the design for these boards.
Yes, these boards. I ordered a few other boards at the same time as the main one, including an example of an expansion board with an HDMI decoder and one with a VGA port and my standard choice of RGB DAC, a AD7123 (PDF). The VGA expansion board will be ignored here, as it isn’t terribly interesting.
The specifications for the HDMI board are as follows:
The HDMI transmitter performs a similar function to the ADV7123 RGB DAC: it transforms a set of 3 parallel busses (one for each of red, green and blue) into a collection of 4 differential signals used by HDMI. This will be discussed in detail when looking at the schematic for this expansion card.
Back on the development board then. First up, the FPGA, its decoupling capacitors, a buzzer, the oscillators, and the all important PCB holes:

There are spaces on the board for two 5mm x 3mm oscillators, but only one (the “master”) is currently used. I’ve done experiments, using my earlier iCE40UP board, with the PLLs present in these FPGAs and am confident I can use a 50MHz oscillator to generate nearly any frequency I’d need.
Pin usage for the FPGA is divided up as follows:
- 25 for general purpose expansion
- 2 are wired to the cold boot selectors on the expansion header
- 2 for the I2C bus
- 1 for the RTC square wave
- 3 for the RGB LED
- 8 for the PMOD header
- 16 for SDRAM data
- 13 for SDRAM address
- 2 for SDRAM banking
- 8 for other SDRAM control
- 4 for the push buttons
- 4 for the PS/2 port
- 2 for the UART to FTDI
- 5 for the MicroSDCard (4 SPI, and a SDCard specific control)
- 1 for the very important buzzer
- 2 for clocks

Next the power and configuration flash section. There is very little different here from the iCE40UP development board discussed in an earlier post, except:
- The 2.5V power rail is provided by an AZ7117 (PDF) regulator, instead of being provided by a simple diode drop, since that gave inconsistent output.
- A 10 pin IDC header replaces a row of single-in-line header pins for the programmer board. This saves me from having to manually hook up about 8 wires.

Next, the SDRAM. Nothing really to say about this; all pins are wired directly to the FPGA.

The all important “Misc.” sheet. This contains:
- PS/2 port: This is a duplicate of the iCE40UP dev board PS/2 wiring, and contains a very large error (corrected in the design on GitHub).
- MicroSDCard: The wiring was deduced when looking around at other projects that include SDCards, and was also prototyped with a Pi Pico board.
- USB FTDI: The FT231XS wiring came from the datasheet.
- RGB LED and buttons: Nothing to say about them really.
- PMOD Header.
The ultimate source for the PS/2 wiring was the MAXI030 schematic. The iCE40UP dev board borrowed its arrangement, and this board borrows that boards arrangement. MAXI030 uses a EPF10KE FPGA, which is an early 2000s-era part which uses 3.3V for IO, but is fully 5V tolerant. The PS/2 port functioned well on MAXI030.
However, the iCE40UP’s design, and this board’s design, does not factor in the fact that no iCE40 FPGAs have 5V tolerant IO lines.
The solution is to add Schotkey clamping diodes to constrain the 5V high level voltage from the PS/2 device to within 0V and 3.3V Curiously I built this board without these clamping diodes and have so far received no ill effects, but I believe this is down to luck only.
Credit goes to Dru Nelson for pointing out this problem with my iCE40UP5 board.
This sheet contains another problem: the pinout for the PMOD header is reversed; basically the pinning matches a peripheral board, and not a main board. I was very annoyed when I spotted this issue. The header can still be used with PMOD device, but they must be inserted upside down.
Both problems are fixed in the versions published on the GitHub repository for this project.

Next, I2C. This is exactly the same as used by the iCE40UP5 board, so I’ll move right along.

Lastly, for this board, the expansion header. Note that there are pins for both the 3.3V and 5V power rails. This was done to provide flexibility in the parts that can be used on the expansion cards, and because I knew at the outset that HDMI requires a 5V power rail to be offered up to the connected screen.
Also present is the I2C bus, as used by the RTC and EEPROM. And lastly the master and secondary clocks are routed onto this header, for whatever use an expansion card requires.
Next, the schematic for the HDMI expansion card.

While I briefly pondered the idea of generating the HDMI signals from within the FPGA itself, I discounted the idea of the grounds of complexity. Plus there was another reason it wasn’t a viable approach, for me: the iCE40 parts do not have differential outputs, which are required by the Transition-minimized differential signaling used by HDMI, available as an IO standard on many modern FPGAs and instead external resistors must be used, per the Technical Note FPGA-TN-02213-1.8. So instead I opted for a HDMI “controller”; an IC that would turn a clocked collection of parallel busses (the colour intensities) into the differential signals used by HDMI.
The IC driving the HDMI port I chose is a Texas Instruments TPF410 (PDF) PanelBus digital transmitter. It can drive both HDMI and DVI panels. Sufficient pins are available on the expansion connector for 6 bits of each of the red, green and blue colour intensities, yielding 262144 colours. The other signals required by the IC are, in this design:
- HDMICLK: the pixel clock is produced by the PLL in the FPGA, which is fed the 50Mhz master clock.
- DE: a Data Enable signal tells the controller that the current clock interval is used for pixel data (high) or not.
- VSYNC, HSYNC: vertical and horizontal synchronisation.
- HPD: a “hot plug detect” signal, wired to the screen and not the expansion connector, which is used to indicate if a screen is attached.
- MSEN: another “monitor sense” related pin used to link the screen detection back to the expansion header and the FPGA.
- I2SCLK, I2SSDA: the system wide I2C bus
The main thing that complicates the usage of this IC is the fact it can be configured two ways: either via its I2C bus, or via special control pins. Whilst using control pins seemed simpler, for maximum flexibility I2C is better so I took that approach. I already had a I2C master in my previous FPGA designs, as well.
The connections required by the HDMI transmitter were derived through a mixture of reading the datasheet and looking at other people’s projects that used the part.
In the bottom right of the sheet are ESD protection diodes (PDF). That is, they protect against electrostatic discharge. These ESD diodes are in a tiny SMT package and at this point, just drawing up the schematic, I was starting to get worried about how I was going to solder up these boards!
This schematic features a first for my usage of KiCAD: hierarchical sheets. I’ve been meaning to play with these for a while. Instead of just using global labels across all the sheets, the sheets are linked together like modules in a program. In this case the I2SBCLK, I2SDIN and I2SLRCK pins from the expansion connector are fed into a second sheet, which routes those signals into its own local versions: BCK, DIN and LRCK.
This “sub sheet” contains the schematic for an I2S DAC, which makes use of a PCM5100A (PDF) I2S DAC to give sound output to the FPGA for further experiments.

You can see the external (to the sheet) signals on the left of the IC.
The output of the DAC goes directly to a trusty 3.5mm stereo jack.
What would have been ideal is to bypass the usage of an external DAC entirely and instead find a HDMI transmitter that would encode an audio signal into the HDMI differential outputs. Unfortunately a brief search for such an IC didn’t turn up anything, plus it would have added still more complexity to a design with enough new, to me, parts. And really, the I2S DAC was added for the knowledge gained: though previous designs, such as my VGA graphics card, have included an I2S DAC, I’ve never actually done anything with one. Hopefully this board will be different.
The next post will go over the board routing for both boards, briefly cover two other boards related to this project, and then talk about how the bring up for the board went. Spoiler: it went quite well….
Cool board!
One thing I’ve been meaning to design (for 10 years or so) is something with an ICE40HX and a 68SEC000 (the 3.3V, fully static 68k) and a few megs of SRAM. It just seems like a good match, and I think that would make an interesting playground for an updated classic microcomputer.
It would. I’d limit myself to an FPGA or CPLD that couldn’t accommodate the processor, but that’s just my tastes. I like, with those older processors, to leave the processor as king of the transistor count. That way the design, largely, remains period correct with only a few compromises like SRAM instead of DRAM. But it all depends what your goals are. The 68SEC000 sure is an interesting one.