This website was originally written in Ruby and hosted on the Raspberry Pi. It's now archived at GitHub for posterity!

Simulating A Quick And Dirty Microprocessor

In preparation for playing with the Papilio Pro and diving into VHDL or Verilog, I decided to further my understanding of processor architecture. Armed with the brilliant and free app Logisim, a Microprocessor Design Wikibook and a guide to logisim I set about learning how processors work, how they digest instructions and how they perform various actions.

The result is certainly not the best, most complete microprocessor ever put together in Logisim, but it was enough for me to learn the fundamentals.

To back it up I created my own assembly language, used to instruct the simulated processor to add, subtract and compare numbers. Here's an example ( prettyprint will choke on this imaginary language somewhat ):

start:
LN ACC 0x1
LN GP1 128
LN GP2 128
badger:
  CMP ACC GP1 -- Compare accumulator to GP1
  JUMP EQL done -- Jump to done if equal
  ADD ACC -- Add accumulator to itself
  JUMP UN dostuff -- Unconditional jump out to dostuff
LOOP badger

done:
MV GP4 ACC -- Move the value of accumulator into GP4

LOOP start -- Loop program indefinitely

dostuff: -- Pointless pseudo subroutine
  SUB GP2 GP2 ACC -- Subtract accumulator from GP2 and save result into GP2
JUMP UN badger -- Return to our loop

To actually run this code within Logisim, I created a counterpart compiler written in Ruby. It digests the instructions into hex and outputs into a .bin format that can be loaded directly into a Logisim ROM component. Nifty! You can download my Ruby assembly compiler here but it's by no means complete or even sane.

I found that the key to successfully putting together a design in Logisim was to throw away the tedious task of wiring things up, and make liberal use of "Tunnels". A tunnel in Logisim is simply a labelled signal which you can pop up anywhere on your canvas with ease. Labelling signals also makes them crystal clear, making things easier to wire up and debug.

I also cheated somewhat, and used a counter to create a 5 stage clock. Effectively creating distinct signals for Prep, Load, Act, Save, Next which I use to trigger various events. This abstracts away the complexity of timing and rising/falling edge, making it easier to get started on the logic itself.

My Microprocessor has 8-bit general purpose registers, all of which are addressable, a latching CMP operation, functional conditional and unconditional jump instructions and, of course, the ability to add or subtract values saved in registers from each other. Not exactly useful, but educational.

I make liberal use of "off-the-shelf" Logisim components like registers, counters, adders, ROM and decoders to speed up simulation. It's really important that you learn what these do, and how they do it, before you go any further! Circuit Coder on the iPad is a fantastic way to get started with the fundamentals.

Without further ado, you can download my work in Logisim and try it for yourself.

« Back to index Posted on 2013-03-20 by