Turbo ISA Reference

Architecture Overview

The Turbo ISA (Instruction Set Architecture) defines the interface between software and hardware. It specifies how instructions are encoded, what operations the CPU can perform, and how registers and memory are organized. Both the software simulator and the SystemVerilog hardware processor implement this same specification.

  • Word size: 32 bits — all instructions and data are 32-bit values
  • Design: RISC (Reduced Instruction Set Computer) — fixed-width instructions, load/store architecture
  • Memory model: Harvard — separate instruction and data memories, byte-addressable
  • Alignment: LOAD and STORE addresses must be word-aligned (multiples of 4)
  • Register file: 16 general-purpose registers (r0–r15)
  • Program counter: PC (special register, not directly addressable)

Register Roles

RegisterRole
r0Hardwired zero (reads as 0, writes ignored)
r1–r4Function arguments; r1 is the return register
r5–r11Caller-saved temporaries
r12–r13Callee-saved
r14Stack pointer (SP)
r15Link register (LR)

Instruction Formats

All instructions are exactly 32 bits.

R-type

[opcode:6][rd:4][rs1:4][rs2:4][funct:6][unused:8]

I-type

[opcode:6][rd:4][rs1:4][imm:18]

imm is signed 18-bit two's complement (range: −131072 to 131071).

B-type

[opcode:6][rs1:4][rs2:4][offset:18]

Branch target: PC + sign_extend(offset) × 4.

J-type

[opcode:6][rd:4][offset:22]

Jump target: PC + sign_extend(offset) × 4.

Opcode Map

The architecture defines 28 opcodes.

OpcodeMnemonicFormat
0x00ADDR-type
0x01SUBR-type
0x02MULR-type
0x03DIVR-type
0x04MODR-type
0x05ADDII-type
0x06SUBII-type
0x07ANDR-type
0x08ORR-type
0x09XORR-type
0x0ANOTR-type
0x0BSHLR-type
0x0CSHRR-type
0x0DASHRR-type
0x0EANDII-type
0x0FORII-type
0x10LOADI-type
0x11STOREI-type
0x12BEQB-type
0x13BNEB-type
0x14BLTB-type
0x15BGEB-type
0x16JMPJ-type
0x17JALJ-type
0x18JRR-type
0x19LUII-type
0x1AHALTR-type
0x1BNOPR-type

Instruction Semantics

Arithmetic

ADD ADD rd, rs1, rs2rd = rs1 + rs2

ADD r1, r2, r3   ; r2=5, r3=3 → r1=8

SUB SUB rd, rs1, rs2rd = rs1 − rs2

SUB r1, r2, r3   ; r2=10, r3=4 → r1=6

MUL MUL rd, rs1, rs2rd = rs1 × rs2

MUL r1, r2, r3   ; r2=7, r3=6 → r1=42

DIV DIV rd, rs1, rs2rd = rs1 / rs2 (signed, truncated toward zero; div by zero → 0)

DIV r1, r2, r3   ; r2=20, r3=3 → r1=6

MOD MOD rd, rs1, rs2rd = rs1 % rs2 (signed remainder; mod by zero → 0)

MOD r1, r2, r3   ; r2=20, r3=3 → r1=2

ADDI ADDI rd, rs1, immrd = rs1 + sign_extend(imm)

ADDI r1, r2, 10  ; r2=5 → r1=15

SUBI SUBI rd, rs1, immrd = rs1 − sign_extend(imm)

SUBI r1, r2, 3   ; r2=10 → r1=7

Logic and Shifts

AND AND rd, rs1, rs2Bitwise AND

AND r1, r2, r3   ; r2=0xFF, r3=0x0F → r1=0x0F

OR OR rd, rs1, rs2Bitwise OR

OR r1, r2, r3    ; r2=0xF0, r3=0x0F → r1=0xFF

XOR XOR rd, rs1, rs2Bitwise XOR

XOR r1, r2, r3   ; r2=0xFF, r3=0x0F → r1=0xF0

NOT NOT rd, rs1Bitwise NOT (rs2 must be r0)

NOT r1, r2       ; r2=0x00 → r1=0xFFFFFFFF

SHL SHL rd, rs1, rs2Logical shift left by rs2 & 0x1F

SHL r1, r2, r3   ; r2=1, r3=4 → r1=16

SHR SHR rd, rs1, rs2Logical shift right (zero-fill) by rs2 & 0x1F

SHR r1, r2, r3   ; r2=0x80, r3=4 → r1=0x08

ASHR ASHR rd, rs1, rs2Arithmetic shift right (sign-extends) by rs2 & 0x1F

ASHR r1, r2, r3  ; r2=0xFFFFFF00, r3=4 → r1=0xFFFFFFF0

ANDI ANDI rd, rs1, immBitwise AND with sign-extended immediate

ANDI r1, r2, 0xF ; r2=0xFF → r1=0x0F

ORI ORI rd, rs1, immBitwise OR with sign-extended immediate

ORI r1, r2, 0xF  ; r2=0xF0 → r1=0xFF

Memory

LOAD LOAD rd, rs1, immrd = memory[rs1 + sign_extend(imm)]

LOAD r1, r14, 0  ; load word at SP into r1

STORE STORE rs2, rs1, immmemory[rs1 + sign_extend(imm)] = rs2. STORE uses I-type encoding where the rd field carries the source register.

STORE r1, r14, 0 ; store r1 at address in SP

Branch and Jump

BEQ BEQ rs1, rs2, offsetBranch if rs1 == rs2

BEQ r1, r0, done ; if r1 == 0, jump to 'done'

BNE BNE rs1, rs2, offsetBranch if rs1 ≠ rs2

BNE r1, r2, loop ; if r1 != r2, jump to 'loop'

BLT BLT rs1, rs2, offsetBranch if rs1 < rs2 (signed)

BLT r1, r2, less ; if r1 < r2, jump to 'less'

BGE BGE rs1, rs2, offsetBranch if rs1 ≥ rs2 (signed)

BGE r1, r2, skip ; if r1 >= r2, jump to 'skip'

JMP JMP offsetUnconditional jump; rd must be r0. PC = PC + sign_extend(offset) × 4

JMP loop

JAL JAL rd, offsetrd = PC + 4, then PC = PC + sign_extend(offset) × 4

JAL r15, func    ; save return addr, call 'func'

JR JR rs1PC = rs1 (rs2 should be r0)

JR r15           ; return via link register

Special and System

LUI LUI rd, immrd = (imm & 0x3FFFF) << 14

LUI r1, 0x10     ; r1 = 0x10 << 14 = 0x00040000

HALT HALTStop execution. CPU halts, cycle counter freezes.

HALT

NOP NOPNo operation. Advance PC by 4.

NOP

Behavioral Rules

  • Arithmetic overflow wraps in two's complement modulo 232.
  • r0 is hardwired to zero.
  • Shift amount uses lower 5 bits of rs2 only.
  • Shifts by values ≥ 32 are undefined at ISA level and masked by implementation convention.

Turbo Binary File Format

A Turbo binary file has this exact layout:

  1. Magic: 4 bytes — TURB (0x54 0x55 0x52 0x42)
  2. Version: 4-byte little-endian u32, currently 1
  3. Instruction count: 4-byte little-endian u32
  4. Payload: instruction_count words, each 4-byte little-endian u32

Header size is 12 bytes (3 words). First instruction starts at byte offset 12. Files must be self-consistent: payload length must be instruction_count × 4.