Home page Wiki Blog Code

Robin

A risc cpu in verilog targeted at the iCEbreaker board

ALU Opcodes

The ALU supports the usual operations, including multiplication and division. All operations are 32 bit, and set the negative and zero flags depending on the result. There are no carry or overflow signals generated. Multiplication is also 32 bit but two different operations are provided for the upper and lower 32 bits of the 64 bit result.

#OperationResult
0AddR1 + R0
1SubtractR1 - R0
4OrR1 | R0bitwise or
5AndR1 & R0bitwise and
6XorR1 ^ R0bitwise xor
7Not~R1R0 is ignored
8Cmpsign(R1 - R0)
9TestR1set flags
12Shift leftR1 << R0
13Shift rightR1 >> R0
14Multiply (low)R1 * R0lower 32 bits
15Multiply (high)R1 * R0upper 32 bits
16Divide (unsigned)R1 // R0
17Divide (signed)R1 // R0sign = sign(R1) ^ sign(R0)
18Remainder (unsigned)R1 - R0 * (R1 // R0)
19Remainder (signed)R1 - R0 * (R1 // R0)sign = sign(R1) ^ sign(R0)

ALU operations are performed by assigning the operation number to the lower byte of register 13 and the executing the ALU instruction. For example, to subtract register 5 and 4 and assign the result to register 6,the following assembly cold be used


	loadi	r13,#1
	alu	r6,r5,r4
	

The assembler provides built-in mnemonics for all operations so equivalently we could have written


	loadi	r13,#alu_sub
	alu	r6,r5,r4
	

Additionally the macro file provided with the assembler defines many shortcuts, so a shorter notation would be


	sub	r6,r5,r4
	

Note that the latter is shorter but if you would like to perform multiple identical operations on different sets of operands it is more efficient to explicitly load the operation code only once into register 13 and then perform the operations. using the marco would load register 13 anew every time.

Addition can also be performed with move r6,r5,r4. This example will add registers 4 and 5 but will not set any flags.