Home page Wiki Blog Code


A risc cpu in verilog targeted at the iCEbreaker board

Fields and special registers

The opcodes for our instructions come in a few different formats

2opcode, R2, R1, nMOVER
2opcode, R2, byteLOADI
2opcode, R2, XPOP, PUSH, MARK
4opcode,cond,R1,XOffset hi, Offset loSETBRA
6opcode,R2,R1,R0byte 3, byte 2byte 2, byte 0LOADIL

All fields are 4 bits wide and X means 'dont care'. n is a 4 bit signed number, i.e can range from -8 to +7

The two offset bytes for the SETBRA instruction are a signed 16 but, big endian number.

Not all registers are general purpose, in fact because register 0 always contains 0 and register 1 always contains 1 we can do some clever tricks. Combined with the implied addition of the registers indicated in fields R1 and R1 (in format 1) we can for example increment any register.

MOVE r5,r5,r1 would add 1 to the value in register 5 and store the result in r5 again.

Also, because register 15 is the program counter (PC) we could jump to an address with LOADIL r15,#address

The full list of registers is shown below

0zerovalue always 0
1onevalue always 1
2r2/arg1general purposearg 1
3r3/arg2general purposearg 2
4r4/indexgeneral purposeindex in frame
5 - 6r5 - r10general purpose
11r11/linkgeneral purposereturn address
12r12/framegeneral purposeframe pointer
13flagsflags (bits[31:29]) and alu op (bits[7:0])
14spstack pointer (SP)
15pcprogram counter (PC)

Register 0 and 1 have a fixed value and the register 13 (flags) always has bit 31 fixed to 1. Bits 30 and 29 are the negative and zero flags respectively. The lower 8 bits hold the operation used by the ALU instruction.

Register 14 (SP) is used by the POP and PUSH instructions and register 15 (PC) is the program counter. The program counter can be assigned to directly but is normally manipulated by the JAL and SETBRA instructions.

In the C-compiler some of the registers have additional designations, those are indicated in the ABI columns.