ISA Manual

Instruction Set Architecture (ISA)

Complete technical specifications, bitwise encoding, and behavioral semantics for the VerySimpleCPU 32-bit computing architecture.

32-Bit Instruction Word (IW) Structure

Unified 16K Word Memory

Every instruction in VerySimpleCPU is encoded into a single 32-bit unsigned integer (Instruction Word - IW). The 32 bits are cleanly partitioned into four dedicated fields:

Bits 31 – 29
opcode
3 bits (0 – 7)
Bit 28
i
1 bit (Flag)
Bits 27 – 14
A
14 bits (Address)
Bits 13 – 0
B
14 bits (Addr / Immed)
opcode [31:29]
Selects one of the 8 fundamental instruction families (ADD, NAND, SRL, LT, CP, CPI, BZJ, MUL).
i flag [28]
Immediate Mode Flag: When i = 1, field B is treated as an immediate numerical constant. When i = 0, field B is an address pointer (mem[B]).
Field A [27:14]
Destination memory address (0 – 16,383) where operation results are written back.
Field B [13:0]
Source operand address (when i = 0) or an immediate literal integer (when i = 1).
ADD A B Arithmetic
{op: 0, i: 0}
mem[A] = mem[A] + mem[B]

Unsigned addition. Reads the 32-bit values from Address A and Address B, sums them together, and writes the 32-bit result into Address A.

0: ADD 20 21 // mem[20] = mem[20] + mem[21]
ADDi A B Arithmetic Immediate
{op: 0, i: 1}
mem[A] = mem[A] + B

Unsigned addition immediate. Adds the literal constant integer B directly to the value stored in Address A.

0: ADDi 20 14 // mem[20] = mem[20] + 14
NAND A B Bitwise Logic
{op: 1, i: 0}
mem[A] = ~(mem[A] & mem[B])

Bitwise NOT-AND. Computes the logical bitwise AND of values at Address A and Address B, inverts all 32 bits, and stores the result in Address A.

0: NAND 10 11 // Useful for building NOT, AND, OR gates
NANDi A B Bitwise Immediate
{op: 1, i: 1}
mem[A] = ~(mem[A] & B)

Bitwise NAND with an immediate constant. If B is 0, inverting 0 yields 0xFFFFFFFF (4,294,967,295), effectively flipping all bits.

0: NANDi 10 0 // Flips all bits of mem[10] to 1s
SRL A B Bit Shift
{op: 2, i: 0}
mem[A] = (mem[B] < 32) ? (mem[A] >> mem[B]) : (mem[A] << (mem[B] - 32))

Shift operation based on mem[B]. If shift amount is < 32, performs logical right shift. If ≥ 32, performs left shift by (mem[B] - 32) bits.

0: SRL 10 11 // Shifts mem[10] by the count in mem[11]
SRLi A B Bit Shift Immediate
{op: 2, i: 1}
mem[A] = (B < 32) ? (mem[A] >> B) : (mem[A] << (B - 32))

Immediate bit shift. Shifting right by 1 divides by 2; shifting left by 1 multiplies by 2.

0: SRLi 10 1 // Divide mem[10] by 2 (Right shift by 1)
LT A B Arithmetic Comparison
{op: 3, i: 0}
mem[A] = (mem[A] < mem[B]) ? 1 : 0

Less-than comparison between two memory values. Sets Address A to 1 if mem[A] < mem[B], otherwise sets it to 0.

0: LT 10 11 // mem[10] becomes 1 if mem[10] < mem[11]
LTi A B Arithmetic Comparison Immediate
{op: 3, i: 1}
mem[A] = (mem[A] < B) ? 1 : 0

Less-than comparison with an immediate integer constant B. Sets Address A to 1 if smaller, else 0.

0: LTi 10 50 // Checks if variable in 10 is < 50
CP A B Data Transfer
{op: 4, i: 0}
mem[A] = mem[B]

Direct copy between memory locations. Copies the 32-bit data value from Address B into Address A.

0: CP 21 20 // Copies value of address 20 into address 21
CPi A B Data Transfer Immediate
{op: 4, i: 1}
mem[A] = B

Copy immediate numerical constant. Writes the integer literal B directly into Address A (overwriting prior content).

0: CPi 20 42 // Sets mem[20] = 42
CPI A B Pointer Dereference (Read)
{op: 5, i: 0}
mem[A] = mem[ mem[B] ]

Copy Indirect (Pointer Read). Reads the address pointer stored in Address B, fetches data at that target address, and writes it into Address A.

0: CPI 10 50 // Reads from address pointed by mem[50]
CPIi A B Pointer Dereference (Write)
{op: 5, i: 1}
mem[ mem[A] ] = mem[B]

Immediate Copy Indirect (Pointer Write). Reads the target address from Address A, and writes the value from Address B into that target address.

0: CPIi 50 10 // Writes value of mem[10] to target in mem[50]
BZJ A B Conditional Branch
{op: 6, i: 0}
PC = (mem[B] == 0) ? mem[A] : (PC + 1)

Branch on Zero. If value at Address B is 0, jumps execution to the address stored in mem[A]. Otherwise, proceeds to the next sequential instruction.

0: BZJ 30 15 // Jumps to address in mem[30] if mem[15] == 0
BZJi A B Unconditional Jump / Halt
{op: 6, i: 1}
PC = mem[A] + B

Jump / Relative Branch. Adds immediate offset B to the value in Address A and sets the Program Counter (PC). Standard Halt Loop: If Address 50 holds 0, X: BZJi 50 X jumps to itself forever, gracefully halting the program.

2: BZJi 50 2 // Safe halt loop when mem[50] == 0
MUL A B Arithmetic
{op: 7, i: 0}
mem[A] = mem[A] * mem[B]

Unsigned multiplication. Multiplies 32-bit values from Address A and Address B and stores lower 32 bits into Address A.

0: MUL 20 21 // mem[20] = mem[20] * mem[21]
MULi A B Arithmetic Immediate
{op: 7, i: 1}
mem[A] = mem[A] * B

Unsigned multiplication immediate. Multiplies value at Address A directly by literal integer constant B.

0: MULi 20 110 // mem[20] = mem[20] * 110

Architecture Guidelines & Safety Tips

Best Practices
1. Graceful Halt Loop

Every VerySimpleCPU program should terminate with a self-referencing jump:

50: 0
X: BZJi 50 X

(With Address 50 initialized to 0, the PC evaluates 0 + X = X, staying in place safely without crashing into uninitialized memory).

2. Logical NOT Emulation

There is no standalone NOT instruction in the hardware, because NAND is functionally complete:

NOT(A) ≡ NAND A A or NANDi A 0

Both operations invert every bit in Address A.

3. Pointer Arithmetic

Array and pointer indexing is performed by combining CPi, ADD, and CPI:

1. Store base address in pointer variable.
2. Add index offset with ADDi or ADD.
3. Dereference with CPI (read) or CPIi (write).