Behold: a complete Nintendo Entertainment System cloned in an FPGA! Originally written in VHDL by Brent Allen and myself while at Washington State University, I’ve recently revisited this project and begun both: rewriting it in Verilog, and adding many new features (like support for more complex games requiring memory mappers).
Way back in 2006, Brent and I found ourselves taking a digital logic course. We’d already succeeded in vastly over-complicating the penultimate lab (a simple single-channel frequency synthesizer; which we each extended to support multichannel MIDI playback in an FPGA – but I digress). So, what were we to do with all of our spare time? – clone a NES, of course!
We didn’t know exactly what we were getting ourselves in to. We knew it was possible, though not commonly done; at the time, only one person – Kevin Horton – had posted any information about successfully doing so (I’m aware of at least one more now: Jonathon Donaldson’s VeriNES).
There was a lot going for the project: emulator developers had already done an incredible job of reverse-engineering every piece of the NES, to the point of having cycle-accurate behavioral descriptions of the majority of the NES’ internal logic. The NES’ CPU was a 6502 derivative, for which several open-source HDL implementations existed (though this proved to be somewhat of a red-herring, as only one of those implementations proved sufficiently accurate to run even a basic game – and we still had to correct a few bugs and add missing instructions to it).
Just a couple of weeks (and many pots of coffee) later, we had ourselves a working NES – or, at least, a NES that worked well enough to play Super Mario Bros. We were ecstatic – and, perhaps, somewhat behind on our other coursework.
Playing SMB was as far as we took the original project. At the time, we weren’t terribly anxious to implement a whole slew of mappers, as that could have easily been a far larger task than the whole rest of the project (having now done so, I can say that it absolutely is [more difficult]!).
I recently made the mistake of browsing through my old VHDL from this project. I knew it wasn’t great when originally I wrote it, but – after having become a Verilog convert and spending a few years gainfully employed as an FPGA developer – seeing it again just made me cringe. A complete re-write was in order.
Thus far, I’ve made a bunch of enhancements:
- Completely re-wrote the PPU in Verilog (and fixed all sorts of obscure bugs in the process – and, by fixed, I mean that I actually implemented many of the NES’ quirks and bugs)
- Re-wrote the top-level and various wrappers in Verilog, leaving just the APU and CPU core in VHDL (eventually, they too will be re-written)
- Moved all RAM and ROM storage into an external PSRAM, which made using mappers practical (previously, everything had to fit within the FPGA’s very limited 48KB of RAM)
- Implemented an iNES parser
- Implemented a plethora of mappers
- Implemented an EPP interface to the Nexys’ USB microcontroller, so games could be loaded over USB (previously, they had to be stored within the FPGA’s block RAM when the bitstream file was generated)
There is, as always, much more to do. But, it now plays Super Mario Bros. 3 (and a rather lot of other non-trivial games), so I’m pretty satisfied.
Top items on my to-do list include: fleshing out the project description here, and packaging some of the source-code for release (particularly the PPU, since it’s in the best shape, and likely of the greatest interest – being the single trickiest part in the NES and all).
All of the hardware required for this project is readily available from commercial sources (mostly Digilent) – no custom boards required (though Brent and I have long intended to design a cartridge interface board, so we could test our clone against the real thing):