Over the last few days I’ve been attempting to replace the OpenRisc control CPU within the DE1 and DE2 Minimig cores with EightThirtyTwo – and it’s fighting me every step of the way!
Firstly, why do I want to do this? It’s a long story…
One long-term goal of mine is to bring a port of the MIST’s AGA Minimig core to the Turbo Chameleon 64, and the DE1 port is a direct ancestor.
Unfortunately, there are problems even with that starting point. The DE1 core almost completely fills the rather modest Cyclone II FPGA – so much so that it takes ages to build. I also have a DE2, which has a similar but much larger FPGA. The DE2 build completes in a few minutes but doesn’t work! (In the past I’ve found it showed no signs of life at all; currently it actually boots but the control CPU constantly restarts itself. This may be peculiar to my particular board – I don’t know.)
I also found a version of the AGA core ported to ManuFerHi’s Sidewinder FPGA board (https://github.com/ManuFerHi/SidewinderFPGA/tree/master/Cores/Aga_V5). I don’t have this board but I attempted to port it to my newly-acquired DE10-lite (which has a Max10 FPGA, similar to the Cyclone III / Cyclone 10 LP used in the Chameleon64, but about twice as many logic elements and about three times as much block RAM – so an ideal debugging platform.) Needless to say it didn’t work! I don’t know whether I messed up in porting the core, whether something’s broken within the released source, or it might even be that the Max10 isn’t fast enough to run it. (Other problems are that the source code for the controller boot ROM is missing – so I have no idea whether it’s been modified – and likewise the loadable controller firmware has menus in Spanish, and lacks source.)
So I’ve gone back to basics, returned to the DE1 core, since I know that does at least work on hardware I own, and as a first step started replacing the OR1200 OpenRISC CPU with EightThirtyTwo. Why? Partly a vanity project, I must admit – but also because EightThirtyTwo is smaller and has better code density. (The core already uses 4kbytes of block RAM for a boot ROM, but has to place BSS and stack in external RAM. The same bootcode compiled for EightThirtyTwo will just fit – complete with its BSS data and stack – into the same 4kb boot ROM.) The reduced logic size is enough that the core doesn’t take so long to build any more, either.
But, of course, it doesn’t work!
Thus began one the most frustrating and fiddly debugging sessions I’ve undertaken in a while! Firstly, while at a quick glance EightThirtyTwo’s bus looks a lot like the QMEM bus used for the Minimig’s control module, it turns out they are not directly compatible. The subtlety that I missed at first reading is that for read operations the ‘ack’ pulse comes from peripherals a cycle before the data itself. Ack is generated combinationally, but since EightThirtyTwo also uses combinational logic between ‘ack’ and ‘req’ to drop ‘req’ as soon as data arrives, I ended with a combinational loop. It look me much longer than it should have done to figure that out!
So I need to delay ‘ack’ by one cycle. Problem solved, yes? Nope.
OpenRISC is a big-endian CPU. EightThirtyTwo can be either big- or little-endian, but all my recent development and testing has been done in little-endian mode. So naturally, I fell afoul of several subtle bugs that only appear in big-endian mode. The most interesting of these concerns arguments on the stack.
When pushing function arguments on the stack, the backend pushes 32-bits even for char and short values, so that the stack remains aligned. Unfortunately, when subsequently reading those values from the stack, it was using byte and short operations rather than reading a full word. In little-endian mode this doesn’t matter, since the first byte read will be the lowest-significant byte, no matter which data size is read. In big-endian mode, not so much!
The assembler and linker also lacked support for big-endian mode, so now was the ideal time to add support.
I’d like to say that I solved all the problems and the project now works. Unfortunately that’s far from the truth – it’s still very much a work-in-progress. But as always I’m learning lots along the path, and using EightThirtyTwo in a different context has shaken out some bugs I wouldn’t otherwise have found, so it’s all good!
Weren’t there some old versions of the AGA core, based on two tg68k cores?
I don’t think so – the DE1 port (ECS) originally used a pair of TG68s – and the Chameleon64 port still does – but I’m pretty sure Chaos migrated the DE1 to OpenRISC, then used that port as a starting point for the MiST AGA core (which has an onboard microcontroller anyway, so doesn’t need the second CPU at all.) I’d love to be proved wrong though!
Not this time, I was wrong, mixing ECS and AGA 😉
still was thinking would be easier to port 68k code than orisc …
Anyway, interesting reading, look forward to see the code working …
Yes, indeed – we had similar thoughts there. In fact I’ve put some time into porting the TG68-based ECS core to EightThirtyTwo as well. It still doesn’t work yet – I have it booting its own firmware, shows the splash-screen OSD window, and then the SPI communication with the Minimig breaks down and it doesn’t go any further. (Since the firmware’s written in C, though, the actual CPU it’s running on shouldn’t matter too much – the difficulties are more to do with the semantics of how particular CPUs interface with the rest of the project.) My next sub-goal is going to be adding some remote debugging facilities to the CPU.