Bo Bayles
University of Missouri-Rolla: Computer Engineering 313
RISC Processor Design Part 1

Instruction Set Architecture

Introduction and Specifications

An instruction set for a small RISC CPU (henceforth "the processor") was designed according to the following specifications:

Register Definition

Data may be stored in 16 registers inside the processor. Each register is 16-bits wide. Table 1 below describes the processor's registers in detail.
Register Number Register Name(s) Description
00h $zero "Zero register" - Contains the constant value "00 00h, " not user-changeable.
01h, 02h, 03h, 04h $a0, $a1, $a2, $a3 "Argument registers" - User-changeable, intended to hold arguments to be passed by value during function calls.
05h, 06h $v0, $v1 "Value registers" - User-changeable, intended to hold the results of operations to be returned by value during function returns.
07h. 08h $mar, $mdr "Memory access registers" - $mar is intended to hold the address of a memory location, and $mdr is intended to hold the data to be read from or written to the address to which $mar points.
09h, 0Ah, 0Bh, 0Ch $t0, $t1, $t2, $t3 "Temporary registers" - User-changeable, intended to be used to store variables for general purpose computation.
0Dh $at "Assembler's temporary register" - Intended to be used by the assembler to store the result of logic operations and to expand pseudo-instructions.
0Eh $cond "Condition register" - Intended to be used to determine branching behavior.
0Fh $ra "Return address register" - Stores the return point for function calls.
Table 1: Register descriptions

Instruction Formats and Encoding

The processor's instruction set uses the following formats to encode instructions:

4444 Type

# # # # # # # # # # # # # # # #
4-bit Opcode 4-bit Register or Function Code 4-bit Register Code (Operand 2) 4-bit Register Code (Destination)
Used by: add, sub, logic, comp

484 Type

# # # # # # # # # # # # # # # #
4-bit Opcode 8-bit Immediate Data / Don't Care 4-bit Register Code (Destination) / Don't Care
Used by: addi, rol, ujmp, cjmp

4C Type

# # # # # # # # # # # # # # # #
4-bit Opcode 12-bit Immediate Data
Used by: call, lw, sw, ret, halt

Instruction Definition

The following notation is used:
Add
add [Destination Register], [Operand Register 1], [Operand Register 2]
Result: $(Destination) = $(Operand 1) + $(Operand 2)
Encoding:0000 #(Operand 1) #(Operand 2) #(Destination)
Add Immediate
addi [Destination Register], [8-bit signed immediate data]
Result: $(Destination) = $(Destination) + (Immediate Data)
Encoding: 0001 (8-bit signed immediate data) #(Destination)
Subtract
sub [Destination Register], [Operand Register 1], [Operand Register 2]
Result: $(Destination) = $(Operand 1) - $(Operand 2)
Encoding: 0010 #(Operand 1) #(Operand 2) #(Destination)
Logic
logic [Logical Operator], [Destination Register], [Operand Register]
Result: $(at) = operator{$(Destination), $(Operand 2)} The operator is specified by the following four-bit code: Other codes are reserved for future expansion.
Encoding: 0011 #(Logical Opcode) #(Operand 1) #(Destination)
Comparison
comp [Relational Operator], [Operand Register 1], [Operand Register 2]
Result: $(cond) = 01h, if the expression given by $(Operand 1) [Operator] $(Operand 2)is true;
$(cond) = 00h, if it is false. The operator is specified by the following four-bit code: Result: Other codes are reserved for future expansion.
Encoding: 0100 #(Relational Opcode) #(Operand 2) #(Operand 1)
Unconditional Jump
ujmp [8-bit signed offset]
Result: $(Program Counter) = $(Program Counter) + Offset + 1
Encoding:0101 (8-bit signed offset) ####
Conditional Jump
cjmp [8-bit signed offset]
Result: $(Program Counter) = $(Program Counter) + Offset, if $(cond) == 01h. $(cond) = $00h
Encoding: 0110 (8-bit signed offset) ####
Load word
lw
Result: $(mdr) = ${@(mar)} That is, the contents of the data memory at the (word) address stored in the (the least significant 12-bits of) mar are copied to mdr.
Encoding: 0111 #(mar) #### #(mdr)
Store word
sw
Result: ${@(mar)} = $(mdr) That is, the contents of mdr are copied to the data memory at the (word) address stored in (the least significant 9-bits of) mar.
Encoding: 1000 #(mar) #(mdr) ####
Rotate Left
rol [Destination Register]
Result: $(Destination) = $(Destination) * 2 That is, the contents of the destination register are rotated left the number of times indicated by immediate data.
Encoding: 1001 ######## #(Destination)
Call
call [12-bit function address]
Result: $(ra) = $(Program Counter) + 1
$(Program Counter) = 0000 $(12-bit address) That is, the address of the next instruction is saved in ra, and the program counter is set to the 12-bit word address in indicated by the address.
Encoding:1010 (12-bit function address)
Ret
ret
Result: $(Program Counter) = $(ra)
Encoding: 1011 #### #### ####
Halt
halt
Result: $(Program Counter) = $(Program Counter)-1 That is, the program counter is decremented to point back to the address of the halt instruction, and the CPU goes into an infinite "halt" loop.
Encoding: 1100 #### #### ####

Assembling C Language Constructs

The following examples illustrate how the supported C-language constructs can be implemented with the processor's instruction set.
C-Language Code Equivalent Assembly Code
int main() {
int a = 0; add $t0, $zero, $zero ;add the zero constants together and ;store the result in a temporary ;register
int b = a; add $t1, $t0, $zero ;Use another temporary register for ;the second variable.
int c = b + 1; $addi $t3, 1 $add $t3, $t3, $t2 ;Load the immediate value 1 to a ;temporary register, then add with ;the other register to get the sum.
int d[10];
if ( a == b ) a = a - b; else a = b & c; comp !=, $t0, $t1 ;Set the not-equal condition flag if ;appropriate. The assembler would replace ;the != symbol with the appropriate ;function code. cjmp Else ;The assembler would calculate the ;address of Else. sub $t0, $t0, $t1 ujmp Out1 ;Skip over the else condition. Else: logic AND, $t0, $t Out1:
while ( b != a ) b = c | a; comp ==, $t2, $t1 cjmp Out2 ;Jump past the loop if equal logic OR, $t3, $t1 ujmp Out1 Out2:
for (a = 0; a < b; a++) d[a] = 2; add $t0, $zero, $zero ;a=0 addi $mar, 0000 1010 1010b ;set up mar to store d Forloop: comp >, $t0, $t1 cjmp Out3 add $mdr, $zero, $zero addi $mdr, 2 sw addi $mar, 1 ;increment mar addi $t0, 1 ujmp Forloop Out3:
fn(&a, b, 3) } add $a0, $t1, $zero ;Copy b to argument register to pass ;it by value addi $a1, 3 ;Move 3 to an argument register also call Fn
int fn(int &i, int j, int k) { i = 2*j+k; k = i*4; return k; } Fn: add $t2, $a0, $zero ;Copy argument 2 to a temp register. rol $t2, 1 ;Multiply the temp register by 2 add $t0, $t2, $a1 ;Add the temp register and the 3rd ;argument, store in the first. rol $a1, 2 ;Multiply the 3rd argument by 4 add $v0, $a1, $zero ;Copy the return value to the return ;value register. ret
The example program illustrates all of supported the C-language constructs except for the greater than, less than or equal to, and greater than or equal two comparison operations. These can easily be implemented by using the logic command with the appropriate function code-the if-else structure depicted in the program could have just as easily done some other comparison. The assembly code shown can be translated into machine code by an assembler given the encoding in the Instruction Definition section. The assembler would have to convert the label arguments for jumps and calls to offsets and addresses, respectively, as well as convert the arguments to the logical and comparison operations.

Conclusion

Although it is subject to future revision, the preceding register and instruction specifications serve as the starting point for the design of the processor. The specification of the processor's data path and control unit functionality are forthcoming, and will serve to eventually implement a physical instance of the processor.