This is an attempt to document my home-brew CPU design, called (rather grandiosely) System/1. I've been kicking the idea around for several years, and decided it was about time I got around to actually building it — and what's the point in building something if you can't bore people with the details?
Rather than a serious project, it is instead merely an effort to see if I can build a working machine despite having no real experience in electronics or logic design to speak of. This might be worth bearing in mind, should anything described herein strike you as eye-rollingly daft!
These pages are currently a work-in-progress, even more so than the project itself; I hope to catch up on progress so far shortly, and describe more fully the bits I've built and the design as it stands today.
— Ben A L Jemmett, 1st January 2015.
The System/1 project is one I've been mulling over since I was at university, although it's only in the last couple of years that I've had the (perhaps misplaced) confidence in my knowledge of basic electronics to think I can pull it off.
The original design, such as it was, came to me whilst contemplating using a small PIC microcontroller to emulate a larger machine, hanging a memory bus off a set of shift registers. Once I started thinking about what I could conceivably put together without requiring seemingly-expensive PCBs and equipment, I ended up with a fairly small design and naïvely envisaged building it on a set of Veroboards with flying leads connecting them...
The project soon evolved in a more sensible direction as I undertook a number of smaller electronics projects to get my eye in — buying a house furnished me with ideas for things I could build to make sure I understood the basic principles I'd need — and the idea of PCB design and fabrication no longer seems at all prohibitive. However, I've stuck with the original plan to use DIP ICs on perfboard for the most part, both to ensure it looks sufficiently home-brewed and because that way I can use common prototyping boards along with a backplane and connectors acquired cheaply from eBay.
Of course, some people think this is a daft way to approach the build, and they may well be right; it's tempting to pick up a VHDL or Verilog primer and have a go at building it inside an FPGA instead. Having contemplated the 'big box of boards' model for so long, though, I'm going to build it my way first and leave the fancy stuff for the Mk. II!
System/1 is a 32-bit Von Neumann machine in the RISC style, with 16 general-purpose registers and a load/store instruction set. Operations are performed bit-serially, mainly through laziness; although this does cause machine cycles to be inordinately long in terms of clock cycles, it dramatically reduces the amount of wiring required!
(Obviously I quickly realised that the bit-serial approach could not exactly be novel, since both it and its pros and cons are fairly obvious, but I was somewhat amused to discover — via Glen and his description of his rather more ambitious home-brew system on the EEVblog forum — that it had been implemented commercially at least once in the past, by no less an organisation than DEC in their PDP-8/S. Serendipitously, this news came shortly after Roger furnished me with a little BALJ logo in the same style as DEC's, for use in identifying my beer glass at his barbecue-and-drinking events. Obviously this meant that I simply had to use it for System/1, so you might notice it in various board photographs — but I digress...)
The machine does not currently include a MMU of any description, although the memory bus has been laid out in such a way that one may theoretically be interposed between the CPU and memory at a later date. There is no separate I/O space — all I/O devices are memory-mapped — and a single external interrupt is provided for such devices to signal that they require attention.
The planned instruction set does not include any pre- or post-increment addressing modes, nor does the machine have any native support for a stack; in order to support interrupts despite having nowhere to push the current execution state, the CPU runs code in interrupt context using a second set of program counter and flags registers. This allows it to avoid disturbing the normal program flow without requiring it to copy those registers to and from memory when entering or leaving an interrupt.
System/1 is being constructed out of 74HC-series logic chips, as a set of Eurocard-sized prototyping boards on a 96-way backplane with DIN 41612 connectors; this seemed a sensible form factor given the original intention of using DIP ICs throughout for an suitably home-brewed look! Intra-board connections are made using very fine self-fluxing solderable enamel wires and a wiring pencil; the backplane connections are made using wire-wrap.
The CPU itself will, when complete, be split across nine boards:
- The main register file, which contains the selection logic for the 16 general-purpose registers and two program counters, and hosts eighteen identical sub-boards (one for each register)
- The arithmetic logic unit, which implements addition and subtraction (using two's-complement for signed numbers) as well as the standard bitwise logical operations — AND, OR, XOR and NOT
- The shifter, providing left- and right-shift and rotation operations
- A word concatenator and 'four generator' board, which is used to glue together two 16-bit values — for instance, to form a 32-bit constant from two 16-bit immediate literals — as well as providing a constant stream of 4s used by other parts of the system
- The flags register and conditional evaluation board, which (as with the dual program counters) includes two separate flags registers
- The memory interface, implementing 32-bit address and data buses and control logic to allow 8-bit writes and signed or unsigned reads as well as the native 32-bit accesses
- The clock and machine cycle generator, providing top-level control signals to the system
- The instruction word and control unit, which provides appropriate control signals to the other units based on the current machine cycle and instruction being executed
- The front panel interface board, allowing the user to view and modify the state of each register and access memory contents
The external components of the system — memory and I/O devices — are connected via the memory interface board using a pair of ribbon cables; a 34-way cable carries the data bus, with a 50-way cable carrying the address bus and control signals. The completed system will include:
- A RAM board containing 2MB or 4MB of SRAM (as one or two banks of four 512K x 8 chips)
- A ROM board containing up to 256KB of ROM (as one or two banks of either four 8K x 8 or 32K x 8 EEPROMs)
- An I/O board, which will provide a 16-bit IDE interface and six 8-bit I/O connectors with decoded device selection and register-addressing signals to allow straightforward interfacing of additional devices such as UARTs
- A serial interface allowing connection to a host computer for downloading code, or to a terminal so I have some way of communicating with the thing!
An ongoing chronology of System/1's construction, to give the Statlers and Waldorfs out there something to laugh at when I make the inevitable daft mistakes.
- 8th March, 2018 (backdated) - Shifty-looking characters hanging around (serial) ports
- 23rd December, 2017 (backdated) - On the dangers of foolish shortcuts
- 28th November, 2017 (backdated) - Driving the serial interface prototype from software
- 23rd November, 2017 (backdated) - Thinking about peripheral device connections
- 20th August, 2017 (backdated) - Learning to talk to the outside world