Porting a Core, DeMiSTified – Part 1 – 2020-02-24
There are many FPGA cores out there which could be ported to the Turbo Chameleon 64 cartridge. In some cases it’s just a question of somebody doing the legwork, in other cases it gets a little bit more involved – but can we do anything to make the amount of work required more manageable?
Long-time readers will know by now that I don’t ask that kind of question out loud unless I already know that the answer is yes!
What makes porting a core difficult? In a nutshell, feature set mapping.
The more similar two boards are, the easier a job you will have in porting cores from one to the other. If the boards have the same type and amount of SDRAM that helps a great deal. If the FPGAs themselves have a similar technology level, all the better. At a first glance, these two considerations make the MiST board and Turbo Chameleon 64 cartridge good candidates for porting, since they both use a Cyclone III (or Cyclone 10LP in the case of TC64V2, which is very similar) with 25,000 logic elements and both have 32 megabytes of SDRAM. What complicates matters is that the MiST board has an onboard ARM microcontroller which takes an active role in loading the core, uploading ROM files and providing input to each core, so on boards which don’t have this microcontroller this missing functionality must be replaced somehow.
Provided we have some spare space within the FPGA we can include an extra CPU core on the design, and give this the task of imitating MiST’s ARM microcontroller – this is precisely the application I had in mind when I embarked upon the EightThirtyTwo project, so naturally this is the CPU I will use for what follows.
In the interests of starting out simply, I will select a MiST core to be ported based on the following criteria:
- The MiST core needs to leave at least 2,500 logic elements free to give us headroom for our extra CPU core and supporting logic, as well as any board-specific modules that might be needed.
- There must be plenty of block RAM free. The supporting CPU either has to run entirely from block RAM, in which case we’re probably going to need at least 16K of ROM/RAM space – or it needs to bootstrap a larger firmware into SDRAM. The latter option is what the Minimig core does, but it’s not possible to do this in a general way, since it requires an extra port into the core’s SDRAM controller, and for there to be some spare space in the SDRAM memory map. In other words, the second method requires invasive changes to the core being ported, and I want to avoid that as much as possible.
- Finally, the core must use static ROM files, uploaded using MiST’s standard mechanism, rather than disk images which require constant service from the microcontroller; the latter will probably require a more complete firmware and more invasive changes as described in the previous point.
For these reasons, I’ve selected MiST’s NES core as a starting point, and it’s my hope that once this is done, it will then be relatively trivial to port the Sega Master System core as well.
My aim is to make as few changes to the underlying core (the “Guest” core) as possible, at least initially. The approach I will take, therefore, is to create a “wrapper” for each target board which hosts the guest core; the guest core won’t know that it’s not running on MiST.
I will initially have three target boards – the two versions of Turbo Chameleon 64, and also DE10-lite, which is the board I use for development. I chose this because the MAX10 FPGA is the same technology level as the Cyclone III and 10LP (counts logic elements the same way, uses M9Ks for block RAM, defines PLLs the same way) but it’s relatively cheap, has twice as many logic elements and has about three times as much block RAM. This makes it ideal for debugging.