The Wombat simulator is based on a design by Dale Skrien. The design is an example architecture for his CPU Sim simulator. This version was adapted by Dan Bennett with the addition of several instructions.
Memory
Input/Output
ALU
Control Unit
The Wombat hardware consists of one general purpose register, called an accumulator, four special purpose registers, a control unit, an ALU (or Arithmetic Logic Unit), and an internal bus. Associated with the CPU is a memory, and an I/O unit. The instruction set consists of 15 instructions, requiring an opcode of 4 bits, with 12 bits of the 16 bit word remaining for operands. This limits the addressable memory to 212 bytes.
Memory is byte addressable, but all instructions must be word aligned. Furthermore all data access is performed on word aligned boundaries on word sized data.
The register set consists of the accumulator (ACC) , the instruction register (IR), the program counter (PC), the memory address register (MAR), and the memory data register (MDR). Input and output are accomplished through the input register (inREG) and output register (outREG). All registers are 16 bits wide and are initialized to zero. Each register will be discussed in turn.
The accumulator is only general purpose register available. It is the target for all computations, input and memory loads. The value stored in the accumulator is the left hand source for all arithmetic operations, memory stores and output. The accumulator is initialized to zero. The ACC supports direct transfer to and from the ALU.
The program counter contains the address of the next instruction to be fetched. Initialized to 0, this register supports increment by two.
The instruction register holds the current instruction. This register supports extraction of the opcode or top four (12-15) and, operand or bottom 12 (0-11) bits of a word.
The MAR holds the address for memory access. This is a portion of the memory management unit (MMU). This register can be loaded from either the bus or from the MDR.
The MDR holds data transferred to, or from memory. The MDR can read and write to the bus, but also supports direct transfer to the MAR.
Wombat’s memory is byte addressable, however all transfers are performed at the word level, on word aligned boundaries. This is a big-endian machine, so bits 8through 11 are stored in the even byte and bits 0 through 7 are stored in the odd byte.
Memory files are stored in a format compatible with version 2.0 of TkGate. In this case, each block of values is proceeded by a block header in the form ”address”. The address is given in hexadecimal. The block header is the only entry on the line. A block of data, in hexadecimal, follows the heading. Data should be words (16 bits) delimited by spaces. A data block ends with a blank line. Figure 2.1 is the compiled version of the example program bigger.
Register Transfer Notation (RTN) used for this document employs the following conventions.
Table 2.1 instructions are supported in the enhanced wombat instruction set.
Mnemonic | OpCode | Operand | Operand Bits | RTN |
STOP | 0 | Stop Execution | ||
LOAD | 1 | address | 0 through 11 | ACC ← M[address] |
STORE | 2 | address | 0 through 11 | M[address] ← ACC |
READ | 3 | Input | ||
ACC ← inREG | ||||
WRITE | 4 | outREG ← ACC | ||
Output | ||||
ADD | 5 | address | 0 through 11 | ACC ← ACC + M[address] |
SUBTRACT | 6 | address | 0 through 11 | ACC ← ACC - M[address] |
MULTIPLY | 7 | address | 0 through 11 | ACC ← ACC * M[address] |
DIVIDE | 8 | address | 0 through 11 | ACC ← ACC / M[address] |
JMPZ | 9 | address | 0 through 11 | if (ACC == 0) |
PC ← address | ||||
JMPN | A | address | 0 through 11 | if (ACC < 0) |
PC ← address | ||||
JMP | B | address | 0 through 11 | PC ← address |
ADDI | C | immediate | 0 through 11 | ACC ← ACC + immediate |
LOADI | D | address | 0 through 11 | ACC ← M[M[address]] |
STOREI | E | address | 0 through 11 | M[M[address]] ← ACC |
The assembler is currently in beta version. It has weak syntax error diagnostic reporting.
The assembler is line oriented and only one instruction is permitted per line. All elements are delimited by white space.
The general form of an assembly line are:
Comments begin with either a semicolon (;) or with two slashes (//) and end with the end of the line. As such, a comment must be the last item on a line.
The assembler supports signed integer literals in four formats: binary, octal, decimal and hex. Decimal values are the default and are represented as integers. Rules for encoding other values are given in table 3.1
Format | Prefix | Example |
Binary | bx | -bx0011001000001001 |
Octal | ox | ox1734 |
Decimal | -1234 | |
Hexadecimal | hx | hx3245 |
The instruction set is given in table 2.1 with Mnemonics listed in the first column. Mnemonics are case insensitive but must be delimited by white space.
Labels are case sensitive, must begin with an alpha character and contain only letters, digits and the underscore. A label must not be a reserved word. Labels can be used in place of any operand. All labels must be resolved in the first pass of the assembler.
In order for a label to be resolved, it must be declared. Labels are declared as an optional first element of a line. A label declaration consists of a legal label followed by a colon. Multiple labels can point to the same address.
Data is declared with a data line. Such a line must begin with a label, contain the assembly directive .data, a size (in bytes) and a value. The byte size must be even. All words are assigned the same value.
The directive:
sets aside three words (6 bytes) at the current memory location. Each word is initialized to -1.
The current version of the assembler expects the filename of the source code to be the last argument given. Other arguments are listed in table 3.2.
Flag | Arguments | Explanation |
-o | output file name | The default output file is a.out. This flag will override the default and use the next argument as the output file name. |
-v | Verbose. | A small amount of diagnostic information is printed when the -v flag is used. |
-t | Symbol Table. | Print the labels encountered in the program along with addresses. |
Examples of command line use include:
Assembles bigger.a to produce the executable file a.out.
Assembles bigger.a to produce the executable file bigger.
The following code examples represent the test cases for the was assembler. The source code for these programs in available in the progs directory in the WOMBAT source code tree.
Please note, the text processing package may have wrapped some of the lines in the code listing in this document. Comments extending over multiple lines are not legal in WOMBAT assembly.
This program will read two values from the user and print the larger of the two.
A simple looping program to compute i2 for 0 <= i <= 10. This program demonstrates use of a loop control variable (LCV), the addi and jmpz instructions.
This program uses the Linear congenital method for random number generation. (Xn+1 ≡ (aXn + c)%m). The program asks the user for a seed value and generates ten random values based upon that seed.
This program demonstrates array access.
There are two version of the simulator. An instruction level based simulator and a microcode level GUI simulation.
The text version of the simulator is called sim. Sim supports the command line arguments listed in table 4.1. The last arugment to sim must be the name of a wombat machine language file.