Porting socz80 (a retro microcomputer) to DE0-nano
UPDATE: Mikolas has added support for the DE2-70 board. Check his repo here: https://github.com/mikolas/socz80-de0_nano
Due to my intrinsic, chronic curiosity, for a long time I wanted to get a in touch with FPGA and related technologies (Verilog, VHDL, etc…), and experience the feeling of total control, having both hardware and software subdued to my control (well, not so much, due to the mysterious and semi-secret process of synthetization and fitting done by the tools involved in the process, but you get the idea).
So finally, some months ago, I bought a DE0-nano. This is a small but nicely built device, easily programmable with an integrated USB Blaster, and with a relatively low price (~70 €), which makes it perfect for learning and practicing a little.
After a few project of blinking LEDs and playing with clocks and PLLs, I’ve decided to take a step further and seek for a challenge. Then I came across the socz80 project, an amazingly cool project for building a Z80 compatible computer in FPGA-synthetizable VHDL. The code was targeted for the Papilo Pro board, which is a Xilinx based device (the FPGA world is divided between two major makers, Xilinx and Altera), so I decided to give a try and port it to the DE0-nano.
After a few hours dealing with timing problems, I managed to get it running. This is how I’ve done it.
Changes made on the design
* **Remove missing devices**: I don't have a second UART nor any SPI connected device, so I've removed those blocks for the top level file.
* **Replace Xilinx components**: Both Xilinx and Altera provide ready-to-use components to be implemented in your designs, and the ones from one maker must be replaced for equivalent devices from the other. In this case, I had to replace the PLL, IOBUF and Internal Block RAM components. It was quite straightforward, though.
* **Create a Quartus project**: Here I decided to do something similar to the way ORPSoC works, creating a TCL file which can be used with Quartus tools to rebuild the entire environment, without filling my directory with a bunch of pregenerated files. I've also added a brain-dead Makefile which does all required steps automatically.
* **Rewire the board**: All PIN assignments needed to be reconfigured for accommodating to the DE0-nano.
* **Remove Block RAM based cache for SDRAM**: After assembling the first design, TimeQuest warned me that trying to run it at 100 Mhz (the frequency for which is originally designed) on the DE0-nano will break the time constrains, resulting in unexpected results. And well, it was quite right. After running it for a bit, memory contents got easily corrupted. When this happens, you have no other option than reducing the frequency (which required changes on the SDRAM Controller) or removing some components for making the design a bit simpler. I've decided for the latter, and removing the Block RAM based cache resulted in a design which barely accommodated to the timing, but was quite stable when running on the board.
* **Disable back-to-back optimization for write operations on SDRAM Controller**: For some reason (not surprising though, as the DE0-nano SDRAM device is not the same as the one integrated on the Papilo Pro) the SDRAM controller was behaving weird when processing continuous write operations, like the ones generated by 16 bit accesses (primarily, when you're working with the stack). Disabling back-to-back for write operations solved the problem, in exchange for losing some performance.
Trying it for yourself
If you want to try it, you’ll need:
* **A DE0-nano board** (I suppose other Altera based devices should work by just changing the PIN assignments).
* **An USB-to-Serial cable**. I'm using [this one](https://www.olimex.com/Products/Components/Cables/USB-Serial-Cable/USB-Serial-Cable-F/) from Olimex.
* **A computer with Altera's Quartus II tools** (Web Edition works nicely).
When you’re ready, follow these steps:
1. Clone my repository: `git clone https://github.com/slp/socz80-de0_nano`
2. Ensure you have the Quartus tools on your **$PATH**.
3. Connect the USB-to-serial cable to the DE0-nano. I've configured **PINs 2 and 4 from GPIO1 as RX and TX respectively**.
4. Connect the USB-to-serial cable to your computer and open the serial device with a terminal application. On GNU/Linux, **minicom** or **screen** can be used.
5. Connect the DE0-nano board to your computer, using the provided cable.
6. From the base directory of the recently cloned repository, run `make load`.
If everything as gone nicely and well, you should see something like this on your terminal:
If you reached this point, take a look at the tarball from the original project to see what kind of cool stuff (running CP/M, among others) you can do with your “new” computer. TODO
* **Adding an storage device**: The Papilo Pro board has pretty decent amount of non-volatile memory on-board, but this is not the case for DE0-nano, which only features a 2KB EEPROM. Adding some kind of storage (an SPI-based SD card?) would be great for storing CP/M disks.
* **Reducing the operating frequency**: In its current state, I can't add more components to the design without making it unstable, due to the timing constrains I talked about before. Reducing the frequency will sacrifice some performance, but in exchange I'll get plenty of room for restoring the Block RAM based cache and experimenting with newer components.
* **Do some cool stuff**: I'm thinking about playing a bit with the Z80 core, adding instructions, changing its default behavior and so on.
Final words
Low level programming is fun, but doing it on a computer you can modify as you wish, is just amazing.