An update on minimig, and a (late) Happy New Year!

I know there wasn’t much updates on the minimig status, but with good (;)) reason: I’ve been pretty busy, so I had little time to work on minimig updates. I did spend quite some time on rewriting the CPU <-> minimig interface, which will hopefully reduce timing problems and enable me to finally add the ethernet Zorro interface. The CPU clock will also be reduced to 28MHz, hopefully that won’t affect the CPU speed much. This is quite a complex task, so don’t expect results immediately.

On the other hand, I’m trying to fix some smaller problems and bug reports, and the intermediate beta releases will be available as I work toward the v1.3 release. I already have the supporting scripts ready that will help me build the firmware & core, increase build numbers, git tag & commit, zip it up and upload it to the server. First of these releases is already available here:

Or, alternatively, there will be a .zip file that will always contain the last released version here:

Don’t expect too many changes though – each new release will probably only contain two or three small updates. In this release, just two changes are important: fixing the SDRAM refresh counter, which should help with RAM stability, and the OSD display fix for productivity video modes. More to follow soon, though! 😉

 

UPDATE:

The latest beta builds will be available here: https://somuch.guru/minimig/minimig-mist/#latest-beta

 

Cheers!

CPU (from: https://www.flickr.com/photos/2top/10402551773/)

qSoC – The OR1200 CPU

The OR1200 is a RISC-type, Harvard architecture (separate instruction and data buses) synthesizable CPU core, written by the OpenCores community.

It can be configured with a number of optional components, such as cache, MMU, FPU, timer, programmable interrupt controller, debug unit, etc. For sake of simplicity, I decided to disable most of the optional components, except the hardware multiplier and divider, all other features will be added if/when needed.

The OR1200 has standard GNU tools available, like gcc, binutils, and a few standard libraries, like uClibc and newlib. There is also an official port of linux available.

One of the requirements was that the CPU would be able to run with a 50MHz frequency on a CycloneIII – class FPGA. The hardware divider implementation used in OR1200 is a 8-cycle divider, which was on a critical timing path, and needed to be reduced to a 16-cycle divider, which, while slow, is still heaps faster than a software division implementation. The changes are in this commit: 01a18ffbbb86b074. There’s a testbench for the updated division code in this commit: 8232f830c60a1166.

There are other settings (defines) available in the or1200_defines.v file, you can tune some of them to get a better utilization or speed from the code. One of the things that I changed to get some more speed was the type of the compare used in the ALU (the change is in this commit: 337217f9511888c2).

The OR1200 version used here is not exactly in sync with the official OR1200 repository, as this core was split from the original a long time ago and changed a lot and the changes didn’t propagate back to the original repo. One of the important changes, besides some bug fixes, is the different bus – QMEM, replacing the original Wishbone bus.

With most of the optional components removed, and with the QMEM bus, the OR1200, as used in this project, is a nice, small but fast little softcore CPU.

SoC

qSoC, or how to build an FPGA SoC from scratch

Introduction

I’d like to talk about how to build a fast, lean, clean SoC machine. What is an SoC? An SoC, or a System On a Chip, is, simply put, a microprocessor with some common peripherals attached, like ROM, RAM, SDRAM controller, UART, SPI, GPIO, and other I/O ports or protocols, all tied up into a system. An SoC is not unlike a microcontroller, which also has a microprocessor bundled with some sort of memory and I/O, the distinction is more or less cosmetical.

An SoC can be used standalone, running barebone or a form of an operating system and communicating with the world outside of the FPGA, or alternatively, it can be used as a part of a larger system, incorporating bigger logic blocks and acting as a sort of support for it. The latter will be the focus of this and following posts.

What I want from the SoC is small footprint (small consumption of FPGA resources), good processing speed, and a well-defined interface to other parts of the FPGA or the outside world. What I have in mind will need at least these components:

  • CPU
  • a well-defined bus interface
  • ROM for the bootloader or the whole firmware
  • RAM, either internal or external SDRAM
  • ‘registers’, which is a catch-all phrase for access to memory-mapped I/O and other functions

CPU

So, let’s start with the CPU. There are a bunch of open-source CPU architectures available, and I’ll definitely want to try and incorporate more than just one into this SoC, so there’s a choice of power vs. resource consumption. But for now, I’ll start with the OpenCores OR1200 (or a slightly modified version of it), since that is the CPU core I’m most familiar with. Later on, I’ll definitely look into adding at least an AVR, an ARM and a RISC-V variants to this SoC.

The OR1200 is a nice, small and relatively simple Harvard architecture RISC CPU, loosely based on the MIPS architecture and instruction set. It is pretty configurable, so you can for example disable the hardware multiplication and division support to save logic gates, and run a software implementation instead. It also has support for cache and MMU, and an optional FPU unit, but I’m going to strip it of all those (unnecessary) addons and just keep the CPU core.

Bus

Next on the list is the bus interface. In my opinion, a well-defined bus interface is a cornerstone of a good SoC design, and must not be overlooked or brushed over quickly. All of the components in an SoC will communicate through this bus, so it best that it is well-designed and thought-through at the beginning, so there are no strange errors popping up all of a sudden, if you add a component somewhere down the line. There are quite some bus architectures intended for an SoC interconnect to choose from, like Wishbone, APB, AHB, etc., but I chose the QMEM bus, especially for its simplicity and speed. As will be explained later, the QMEM bus is not much more than a standard synchronous memory bus with added flow control and optional tags attached to it.

Memory

There’s not much to say about memory, besides that it is needed. At the very least, a small ROM is needed for the bootloader or a sort of a monitor program, that can write and read to memory and registers, and load firmware from the serial port or SD card, but I’ll talk about that later. Besides the ROM, the CPU will need some form of RAM, either from FPGA’s internal memory blocks, or an external memory like SRAM or SDRAM. The SoC should preferably support all of these variants.

I/O

The SoC will need support for some standard external communication protocols. The most important one is an UART, or a serial port, which can be used for debugging, controlling the SoC system with the help of the monitor firmware, uploading of new firmwares, etc. Another very useful protocol is an SPI master, so the SoC can talk to an SD card and load files from it. A GPIO (general purpose I/O controller) can be added to the SoC, so a range of pins can be controlled for digital I/O. I plan to add support for many other I/O channels later on, like a VGA controller, audio output, including sigma-delta DAC and DAC IC support, and other such interfaces.

Other important components

The SoC needs a couple of other standard components, like clock management, reset synchronization module, an interrupt controller, and a timer or two.

Frequency considerations

Another thing to consider is at what frequencies the SoC should run. Usually, in an ASIC product, this would need to be a balance between power consumption and processing speed, limited by the particular process node limitations. Luckily, for an FPGA project, power consumption is not so important, especially taking into account the large static power consumption of FPGAs, so the frequency can be more easily selected based on actual needs.

Personally, I like the trio of 25/50/100MHz frequencies, and I’ll explain what I mean and why.

An SoC will very probably contain an SDRAM controller, and the 100MHz is the max frequency of many SDRAM ICs. Of course, many can run at higher frequencies, up to 166MHz, but the 100MHz is a safe bet to work with any SDRAM IC.

Next up, the 50MHz is in my opinion a nice operating speed for most of the logic in the FPGA, as it nicely balances the required flip-flops for the asynchronous logic to work at this frequency, without wasting a lot of LEs. Any CPU for the qSoC should be capable to work (at least) at this frequency.

The 25MHz is the maximum speed an SD card operates over the SPI bus, and the 25MHz clock can be generated from toggling flip-flops running on the 50MHz clock obviously.

The 50MHz and 25MHz are also frequencies that can be used as pixel clocks for two VGA video resolutions: a 640×480 VGA with 25MHz pixel clock and a 800×600 SVGA with 50MHz clock.

There’s another benefit to using the frequencies that are nice multiples – you can program the PLL in the FPGA to generate these frequencies that are synchronous to each other, which means that you don’t have to use clock-domain crossing logic, since all three clocks can be edge-aligned. This way, you can save gates, plus you don’t have to deal with the headaches that CDC will definitely bring.

Code repository & structure

The repository for this SoC experiment (which I named qSoC for Qmem SoC) is here:

https://github.com/rkrajnc/qsoc

Currently, there’s only OR1200 CPU RTL code there, together with some QMEM modules and a testbench for the OR1200 divider.

I like to keep all files in the repository nicely organized into these directories:

  • rtl – for all common synthesizable Verilog / VHDL code
  • fw – for all common CPU firmware code
  • tools – for all tools / scripts needed for building / converting etc. files needed for the qSoC
  • bench – for Verilog top benchmark files
  • ver – for any scripts needed for verification / benchmarking
  • fpga – for any FPGA board specific files, like Quartus or ISE project files, sdc files etc.

The directory structure might change in the future, as I’d like to keep the projects I build with this SoC in the same repo, so I’ll probably have to add a project directory, with any project-specific files, but I’ll cross that bridge when I get to it.

Boards

I plan to support at least these boards:

More could be added in the future.

Planned projects

The first project I plan to make is a simple WAV audio player, so I’ll be able to test the sigma-delta implementation used in the minimig. After that, probably something involving a VGA controller, a character generator, perhaps a whole system capable of running simple 2D SDL games. Another interest is definitely some sound processing / generation projects, like a MIDI synthesizer, or an FPGA guitar effect. We’ll see.

 

Coming next up, a few more words on the selected CPU and its modifications.

RetroGear

Building a Pentium-era Retro PC, Part 1

I was cleaning my ‘junkyard’ and came across some of the floppies and CDs from my first PC computer, and I thought to myself, wouldn’t it be nice to play some of those old games on a real PC of that era, instead of using something like DosBox? Plus, it would allow me to get away from Amiga for a little while, which has been getting most of my attention lately. Of course, being the hoarder that I am, I was positive I already have most if not all of the hardware required. So, after a quick check with the very knowledgeable people on the vogons.org forum about appropriate pieces & bits, I went junk-diving (or, in this case loft-diving), and look what I dug out:

Mini-tower PC Retro-PC porn Turbo!

Score! This is pretty close to my first PC, which was something like a Pentium 200 (possibly MMX), with 16MB of memory, an S3 Trio64 graphics card and a Creative SoundBlaster 16. Notice the nice sticker I made (does the sticker remind anyone of anything, possibly this?) – this computer did run some old version of Slackware Linux and was used for a long time as a gateway/router box, with every slot filled with a NIC. It also had some Cisco iOS (Cisco, not Apple iOS!) emulator installed, I think it was Quagga (isn’t that a weird name for a project!).

Anyway, this box currently has inside:

  1. MSI MS5170 motherboard – nice MB with AT & ATX style power connectors, both EDO & SDRAM slots, four PCI slots and three ISA slots; Intel chipset, which could mean that only 64MB of memory is cacheable
  2. some unnamed power supply – works, and that’s what matters now
  3. 16MB of EDO DRAM
  4. Intel Pentium 233MMX
  5. some CDROM drive, some floppy drive, both working
  6. harddisk that will be replaced
  7. Turbo button, which, if you are not familiar with it, makes the PC go turbo fast! 😉

Here’s the other hardware I found:

3com 3C509B ISA network card

3com 3C509B ISA network card

3COM 3C905C PCI network card

3COM 3C905C PCI network card

Two 3COM network cards, if possible the old ISA card will be used as it supposedly uses less precious memory in DOS than newer PCI cards. Plus, it has a BNC connector, that has to count for something!

S3 VirgeDX PCI graphics card

S3 VirgeDX PCI graphics card

ATi Rage3D ii+ PCI graphics card

ATi Rage3D ii+ PCI graphics card

Two graphics cards, with the S3 VirgeDX being the preferred one because of better compatibility for DOS games.

And, last but not least, two crown jewels of my findings:

3Dfx Voodoo2 PCI card

3Dfx Voodoo2 PCI card

A 3Dfx Voodoo2! I had no idea I still had this, I thought I sold it ages ago. Well, I’m glad now that I didn’t, it will sure be a nice addition to my setup, although I’m still not too sure how much use will it get in a Pentium-era PC, maybe it would fit better in a Pentium3 setup (which I plan to do next, since I have parts for that too!).

Creative SoundBlaster AWE64 Gold ISA soundcard

Creative SoundBlaster AWE64 Gold ISA soundcard

Aaaaand … one of THE soundcards you wanted to have (but, at least in my case, didn’t) – the Creative SoundBlaster AWE64 Gold! This is perfect for my build, good compatibility with older Soundblasters & Adlib, and hopefully more sound quality than some of the previous Soundblasters. As for OPL compatibility, well I’ll see how it fares. Hopefully, I’ll be mostly using my external Roland SoundCanvas SC-55 for most games (and no, I don’t intend to get a MT-32, they are too pricey these days).

Besides the hardware already mentioned, I also have a ‘new’ CDROM drive and an 8GB Western Digital ‘DeathStar’ harddrive.

Having picked appropriate hardware, next up is software. I’m planning to use some form of DOS, probably the latest 6.22 version, together with Windows 98 SE. I just have to remember how to install these two so both OSes are available. If Win98 will be too much for this PC, I’ll have to find a version of Windows 95 somewhere.

To be continued!