MIC-1
1 MIC-1 Description
2 mic1 simulator
2.1 Microcode Image
2.2 Memory Image
3 mcc microcode compiler
3.1 MAL microcode language
4 masm macroassembler
4.1 MAC-1 macro-assembly
5 HDL - General Purpose Hardware Description Language
8.12

MIC-1🔗ℹ

Jay McCarthy

The mic1 package provides tools for working with the MIC-1 processor architecture that appears in Andrew S. Tanenbaum’s textbook Structured Computer Organization.

    1 MIC-1 Description

    2 mic1 simulator

      2.1 Microcode Image

      2.2 Memory Image

    3 mcc microcode compiler

      3.1 MAL microcode language

    4 masm macroassembler

      4.1 MAC-1 macro-assembly

    5 HDL - General Purpose Hardware Description Language

1 MIC-1 Description🔗ℹ

The MIC-1 is a CPU with 16 general purpose 16-bit registers. Registers 5, 6, 7, 8, and 9 have default values 0000000000000000, 0000000000000001, 1111111111111111, 0000111111111111, and 0000000011111111 respectively.

It runs a single 256-instruction microprogram embedded in a control store ROM. Its ALU supports addition, bitwise AND, and bitwise negation. The ALU outputs flags for whether its result was negative or zero. The ALU is connected to a 1-bit shifter that can shift left, right, or not at all.

Its memory interface is two flags (one for reading, one for writing) as well as two 16-bit registers for interfacing with memory (the MAR–Memory Address Register–and MBR–Memory Buffer Register.) The top 4 bits of the MAR is ignored, so the MIC-1 has a 12-bit address space. Memory access is delayed by one cycle, during which the appropriate flag must be asserted. If both flags are asserted, then the external controller halts the machine.

The ALU’s A side is either a register or the MBR. The shifter result may be output to the MBR or any register. The MAR may be written from the ALU’s B side.

The top four words of memory (4092-4095) are wired to a UART. The first two connect to the receiver and the second two connect to the transmitter. The first of each holds an 8-bit character to be outputed in the bottom 8 bits. The second of each holds a 4 bit control flag in its lowest bits. The control bits are (from most to least significant): On, Interrupt, Done, Busy. The control bits are initialized to all zero. If the microprogram sets the On bit, then the component is enabled and stabilizes. The receiver stabilizes to not Done and Busy, while the transmitter stabilizes to Done and not Busy. When the receiver receives a character, it switches to Done and not Busy until the character is read by the CPU. When the program writes a character to the transmit buffer while the transmitter is On, then the transmitter switches to not Done and Busy, until the transmission is finished. The Interrupt flag is currently ignored by both components.

2 mic1 simulator🔗ℹ

raco mic1 option ... microcode-path memory-image-path simulates the execution of the MIC-1.

microcode-path must be a path to a file. If the extension is .prom, then it must be in the Microcode Image format. If the extension is .mc, then it must be in the MAL microcode language format and it will be compiled before loading.

memory-image-path must be a path to a file. If the extension is .o, then it must be in the Memory Image format. If the extension is .s, then it must be in the MAC-1 macro-assembly format and it will be compiled before loading.

It accepts the following options:

2.1 Microcode Image🔗ℹ

A microcode image matches the grammar PROM.

 

PROM

 ::= 

Line  ...

 

Line

 ::= 

Entry \n

 

Entry

 ::= 

MIR

 

  |  

# any sequence of character except \n

 

MIR

 ::= 

AMUX COND ALU SH MBR MAR RD WR ENC C B A ADDR

 

AMUX

 ::= 

0 ALU A side holds A register

 

  |  

1 ALU A side holds MBR

 

COND

 ::= 

00 Never jump

 

  |  

01 Jump on negative ALU output

 

  |  

10 Jump on zero ALU output

 

  |  

11 Always jump

 

ALU

 ::= 

00 A + B

 

  |  

01 A & B

 

  |  

10 A

 

  |  

11 ! A

 

SH

 ::= 

00 No shift

 

  |  

01 Right shift

 

  |  

10 Left shift

 

MBR

 ::= 

0 Leave MBR unchanged

 

  |  

1 Write shifter output to MBR

 

MAR

 ::= 

0 Leave MAR unchanged

 

  |  

1 Write ALU B side to MAR

 

RD

 ::= 

0 Do not enable memory read

 

  |  

1 Read from memory

 

WR

 ::= 

0 Do not enable memory write

 

  |  

1 Write to memory

 

ENC

 ::= 

0 Do not save shifter output

 

  |  

1 Write shifter output to C register

 

C

 ::= 

4-bit register label

 

B

 ::= 

4-bit register label

 

A

 ::= 

4-bit register label

 

ADDR

 ::= 

8-bit microaddress

In addition, a microcode image may only contain up to 256 mir lines.

2.2 Memory Image🔗ℹ

A memory image matches the grammar Image.

 

Image

 ::= 

Line  ...

 

Line

 ::= 

Entry \n

 

Entry

 ::= 

Value

 

  |  

# any sequence of character except \n

 

Value

 ::= 

16-bit value written using the characters 0 and 1

In addition, a memory image may only contain up to 4096 value lines.

3 mcc microcode compiler🔗ℹ

raco mcc microcode-path compiles MAL microcode language into the Microcode Image format.

microcode-path must be a path to a file in the MAL microcode language format. raco mcc replaces the extension of this path with .prom and writes the corresponding Microcode Image.

3.1 MAL microcode language🔗ℹ

While it is possible to directly write in the Microcode Image format, it is extremely error-prone and tedious. MAL provides a convenient way to write microprograms.

MAL supports block comments in between { and }. Labels are sequences of any characters except   (,:;).

A MAL program matches the following grammar Program:

 

Program

 ::= 

 

  |  

\n   Program

 

  |  

Instruction   \n   Program

 

Instruction

 ::= 

 

  |  

Component   ;   Instruction

Instructions are composed of multiple Components. Each Component determines some fields of the Microcode Image. If two Components assign the same field differently, then a compilation error is raised. The following grammar specifies the various Components:

 

Component

 ::= 

mar   :=   BExpr Writes the ALU B side to MAR

 

  |  

Register   :=   ShExpr Writes the shifter output to given register

 

  |  

mbr   :=   ShExpr Writes the shifter output to MBR

 

  |  

alu   :=   AluExpr Sets the ALU output

 

  |  

if   Cond   then   goto   Label Sets the COND flag and the ADDR value

 

  |  

goto   Label Sets the COND flag to 11 and the ADDR value

 

  |  

rd Sets the RD flag

 

  |  

wr Sets the WR flag

The remaining nonterminals are specified by the following grammar:

 

Cond

 ::= 

n Jump on negative ALU output

 

  |  

z Jump on zero ALU output

 

ShExpr

 ::= 

AluExpr    Do not shift

 

  |  

lshift(   AluExpr   )    Left shift

 

  |  

rshift(   AluExpr   )    Right shift

 

AluExpr

 ::= 

AExpr   +   BExpr    Addition

 

  |  

band(   AExpr   ,   BExpr   )    Bitwise And

 

  |  

AExpr    Identity

 

  |  

inv(   AExpr   )    Bitwise Negation

 

AExpr

 ::= 

Register

 

  |  

mbr

 

BExpr

 ::= 

Register

 

Register

 ::= 

pc

 

  |  

ac

 

  |  

sp

 

  |  

sp

 

  |  

ir

 

  |  

tir

 

  |  

0

 

  |  

1

 

  |  

(-1)

 

  |  

amask

 

  |  

smask

 

  |  

a

 

  |  

b

 

  |  

c

 

  |  

d

 

  |  

e

 

  |  

f

If a MAL program produces an image greater than 256 instructions, then no error is raised during compilation.

For examples see the Github repository, specifically: fib.mc implements Fibonacci and macro-v1.mc implements an interpreter for compiled MAC-1 macro-assembly.

4 masm macroassembler🔗ℹ

raco masm asm-path compiles MAC-1 macro-assembly into the Memory Image format.

asm-path must be a path to a file in the MAC-1 macro-assembly format. raco masm replaces the extension of this path with .o and writes the corresponding Memory Image.

4.1 MAC-1 macro-assembly🔗ℹ

The MAC-1 is a low-level virtual machine implemented by a MIC-1 microprogram. It exposes a single register (AC) to programmers and has an internal state defined by two other registers (PC and SP).

The assembly language supports line comments starting with the ; character. Whitespace is never significant. Literal integers are supported in decimal format. Literal strings compile to packed 16-bit words with early characters in least significant bits.

Labels are any alphanumeric character sequence starting with an alphabetic character and ending in :. A label definition is a label not in an argument position or immediately after a label definition.

The character sequence .LOC followed by a literal nonnegative integer skips the given amount of space in the resulting image, filling it with 1111111111111111.

The following instructions are recognized:

Mnemonic

Encoding

Instruction

Semantics

LODD Arg

0000xxxxxxxxxxxx

Load Direct

AC := Mem[X]

STOD Arg

0001xxxxxxxxxxxx

Store Direct

Mem[X] := AC

ADDD Arg

0010xxxxxxxxxxxx

Add Direct

AC := AC + Mem[X]

SUBD Arg

0011xxxxxxxxxxxx

Subtract Direct

AC := AC - Mem[X]

JPOS Arg

0100xxxxxxxxxxxx

Jump on non-negative

If AC ≥ 0, PC := X

JZER Arg

0101xxxxxxxxxxxx

Jump on zero

If AC = 0, PC := X

JUMP Arg

0110xxxxxxxxxxxx

Jump

PC := X

LOCO Arg

0111xxxxxxxxxxxx

Load Constant

AC := X

LODL Arg

1000xxxxxxxxxxxx

Load Local

AC := Mem[SP + X]

STOL Arg

1001xxxxxxxxxxxx

Store Local

Mem[SP + X] := AC

ADDL Arg

1010xxxxxxxxxxxx

Add Local

AC := AC + Mem[SP + X]

SUBL Arg

1011xxxxxxxxxxxx

Subtract Local

AC := AC - Mem[SP + X]

JNEG Arg

1100xxxxxxxxxxxx

Jump on negative

If AC < 0, PC := X

JNZE Arg

1101xxxxxxxxxxxx

Jump unless zero

If AC ≠ 0, PC := X

CALL Arg

1110xxxxxxxxxxxx

Call

SP := SP - 1; Mem[SP] := PC; PC := X

PSHI

1111000000000000

Push Indirect

SP := SP - 1; Mem[SP] := Mem[AC]

POPI

1111001000000000

Pop Indirect

Mem[AC] := Mem[SP]; SP := SP + 1

PUSH

1111010000000000

Push

SP := SP - 1; Mem[SP] := AC

POP

1111011000000000

Pop

AC := Mem[SP]; SP := SP + 1

RETN

1111100000000000

Return

PC := Mem[SP]; SP := SP + 1

SWAP

1111101000000000

Swap AC & SP

AC :=: SP

INSP Arg

11111100yyyyyyyy

Increment SP

SP := SP + Y

DESP Arg

11111110yyyyyyyy

Decrement SP

SP := SP - Y

HALT

1111111100000000

Halt

Halt processor

If a MAC-1 program produces an image greater than 4096 instructions, then no error is raised during compilation.

For examples see the Github repository, specifically: fib.s implements Fibonacci and IO_str_and_echo.s implements an echo program.

5 HDL - General Purpose Hardware Description Language🔗ℹ

 (require mic1/hdl) package: mic1

The implementation contains a general purpose hardware description language that compiles circuits to networks of NAND gates. The network can be simulated in Racket or via C compilation. In the future it may be documented.