S2 microprogramming system


The first thing you need to know is the data path of S2.  It consists of memory 4M 32-bit word (20000 in the simulator), R0..R31 registers, IR (instruction reg), PC (program counter), MAR (mem address reg), T (temp, output of alu).  

<fig S2 data path>

Data path

The path from registers to alu and back via tbus contains 5 multiplexors:

r -- select {mbus,tbus,pc} to rin, input of reg.
d -- select destination reg.
x -- select source1 reg. to port1 of alu
y -- select source2 reg. to ry
z -- select {ry,im} to port2 of alu

The memory data path consists of MAR, PC with 2 mux:

a -- select source to MAR {ads,pc,tbus}
j -- jump, select source to PC update {pc+1,ads,p1}

Register Transfer Level

The behaviour of each S2 instruction is described in Register Transfer Level (RTL) with the following notation:

dest = source
dest = M[MAR]     memory read
M[MAR] = source   memory write

selection in a mux is denoted:  mux_choice.

The field in IR is denoted: op, r1, r2, r3, xop, ads, im where each field is situated at:

L-format   op:5 r1:5 ads:22
D-format   op:5 r1:5 r2:5 im:17
X-format   op:5 r1:5 r2:5 r3:5 xop:12

S2 instruction meaning in RTL

instruction fetch
:fetch
MAR = PC
PC = PC+1
IR = M[MAR]

ld r1 ads     R[r1] = M[ads]

:lda
MAR = ads
R[r1] = M[MAR]

ld r1 @d r2   R[r1] = M[R[r2]+d]

:ldd
T = R[r2] + im
MAR = T
R[r1] = M[MAR]

ld r1 +r2 r3  R[r1] = M[R[r2]+R[r3]]

:ldx
T = R[r2] + R[r3]
MAR = T
R[r1] = M[MAR]

st ads r1     M[ads] = R[r1]

:st
MAR = ads
T = R[r1]
M[MAR] = T

st @d r2 r1   M[R[r2]+d] = R[r1]

:std
T = R[r2] + im
MAR = T
T = R[r1]
M[MAR] = T

st +r2 r3 r1  M[R[r2]+R[r3]] = R[r1]

:stx
T = R[r2] + R[r3]
MAR = T
T = R[r1]
M[MAR] = T

add r1 r2 r3   R[r1] = R[r2] + R[r3]

:add
T = R[r2] + R[r3]
R[r1] = T

add r1 r2 #im  R[r1] = R[r2] + im

:addi
T = R[r2] + im
R[r1] = T

similar sequence for all alu operations

jmp cond ads   if cond is true PC = ads
:jcc
if cond is true PC = ads

jal r1 ads     jump and link to ads, call
:jal
R[r1] = PC
PC = ads

jr r1          jump reg, return
:jr
PC = R[r1]


Microprogramming


To control a data path, each control signal will have a control bit associated with it.  

<fig microprogram control>

Each control bit can be regard as an event that occurs in that cycle.  All the combinational part, the multiplexor choice, the alu function, etc. will be initiated at the beginning of the cycle (on positive edge clock) and their outputs will be used at the mid cycle (on negative edge).  This is when
the latching to registers occurred.

<fig micro cycle>

To write the RTL steps into the actual microprogram, the selector's choice  and the explicit clocking the registers must be specified.  These signals are named:

mux_choice
lreg

The multiplexor signals:

x_r1, x_r2  -- source to alu port1
y_r3        -- source to ry
z_ry, z_im  -- source to alu port2
d_r1        -- source to reg. number
a_ads, a_pc, a_tbus -- source to MAR
j_pc1, j_ads, j_p1  -- source to PC
r_mbus, r_tbus, r_pc, r_ads -- source to reg

The alu has the following functions:

alu_add, alu_sub, alu_mul, alu_div
alu_and, alu_or, alu_xor, alu_shl
alu_shr, alu_pass1, alu_pass2

with a special alu_op connects a mapping of {op,xop} to the correct alu functions (with a table look up or a ROM).

The memory control signals are:

mr    -- memory read to mbus
mw     -- memory write from tbus

The latching to register signals are;

lmar    -- load MAR
lpc    -- load PC
lir    -- load IR
lr    -- load R
lt    -- load T

Finally, the microprogram sequence can be altered by the following control signals:

decode    -- multiway branch on opcode: op,xop
jmp    -- unconditional branch
jF    -- branch if test condition is false
jT    -- branch if test condition is true

where test condition is taken from the field r1 with the following meaning:
0 always, 1 eq, 2 neq, 3 lt, 4 le, 5 ge, 6 gt

These signal are defined in the begining of the microprogram source.  They should not be changed as they are associated with the simulator.  A microcycle is defined in a microword by writing the event that will occur in that cycle.  A microprogram composed of the sequence of these microwords.

Microprogram syntax


The syntax for a microprogram is:

.. comment, a line begin with .. is ignored
.s
signal definition (must not edit)
.m
body of microprogram
.e

Each microword is:

[:label]  (signal name)*  ;   

";" signifies the end of the current microword.  When using the signal {jmp, jT, jF} a label must be specified by "/label".

Example

Here is the sample of the microprogram for S2:

.m
:fetch
    a_pc lmar j_pc1 lpc ;
    mr r_mbus lir decode ;

The instruction fetch cycle begins with

MAR = PC, PC = PC + 1

the mux a selects ads (from IR) to source MAR and PC is updated to PC+1 by selecting j_pc1 and lpc.  The next cycle is reading the memory to IR and do a multiway branch on opcode (op from IR).

IR = M[MAR], decode

mr reads the memory at the address specified by MAR to mbus. lir latches the data from mbus.

Next example is the add instruction, after fetching the instruction, the microprogram does a multiway branch to the associated micro-address depended on the opcode.  

:add
    x_r2 y_r3 z_ry alu_add lt ;
    r_tbus d_r1 lr jmp /fetch ;

The first microword specified reading two registers to alu, alu then adds them and output to T.   x_r2 selects R[r2] to port1 of alu.  y_r3 selects R[r3] to the wire ry.  z_ry selects ry to port2 of alu.  alu_add does the add.  lt  latches the output of alu.  The second cycle writes the result (T) back to the destination register. r_tbus selects tbus to the input of register.  d_r1 specifies the number of register R[r1].  lr writes the data to the specified register.  At the end of executing the add instruction, the microprogram branches back to the fetching the next instruction, jmp /fetch.

The full microprogram is listed below.  It should be read side-by-side with the RTL description.

..    S2 microprogram v1.0
..    14 Feb 2005
.m
:fetch
    a_pc lmar j_pc1 lpc ;
    mr lir decode ;
:add
    x_r2 y_r3 z_ry alu_add lt ;
    r_tbus d_r1 lr jmp /fetch ;

:bop
    x_r2 y_r3 z_ry alu_op lt ;
    r_tbus d_r1 lr jmp /fetch ;
:opim
    x_r2 z_im alu_op lt ;
    r_tbus d_r1 lr jmp /fetch ;
:lda
    a_ads lmar ;
    mr r_mbus d_r1 lr jmp /fetch ;
:ldi
    d_r1 r_ads lr jmp /fetch ;
:ldd
    x_r2 z_im alu_add lt ;
    a_tbus lmar ;    
    mr r_mbus d_r1 lr jmp /fetch ;
:ldx
    x_r2 y_r3 z_ry alu_add lt ;
    a_tbus lmar ;
    mr r_mbus d_r1 lr jmp /fetch ;
:sta
    a_ads lmar x_r1 alu_pass1 lt ;
    mw jmp /fetch ;
:std
    x_r2 z_im alu_add lt ;
    a_tbus lmar x_r1 alu_pass1 lt ;
    mw jmp /fetch ;
:stx
    x_r2 y_r3 z_ry alu_add lt ;
    a_tbus lmar x_r1 alu_pass1 lt ;
    mw jmp /fetch ;
:jcc
    jF /fetch ;
    j_ads lpc jmp /fetch ;
:jal
    r_pc d_r1 lr j_ads lpc jmp /fetch ;
:jr
    x_r1 j_p1 lpc jmp /fetch ;
:trap
    jmp /fetch ;
.e

last update 15 Feb 2005