A new CPU Architecture- AURORA

Of my four big software/hardware projects, I have decided to build a new processor architecture. This is not a RISC architecture, but a hybrid architecture- a hybrid CISC-VLIW- full 64-bit data and address lines, and a 512-bit VLIW for packetization. It’s a two-ring (user/supervisor) processor, where the instruction set will be open-source, without a single piece of legacy instructions or seeking backward compatibility at all.

The 512-but packetization allows compiling several operations into one instruction for parallel processing, if the developer sees it as needed. This allows compilers written on AURORA the ability to make operations more efficient.

Here is the guide to the instruction set so far:

AURORA v0.13 defines 32 scalar instructions, plus the optional 512-bit packet format that bundles those same instructions. I checked the source archive’s ISA specification, assembler, decoder, and emulator. The reference below distinguishes the architectural rules from limitations in the current implementation.

Machine model and instruction encoding

AURORA is a little-endian, byte-addressed architecture with 64-bit integer registers, addresses, and program counter.

ComponentDefinition
General-purpose registers32 registers, R0–R31, each 64 bits
Zero registerNone; R0 is writable
Stack pointerConventionally R30; remains an ordinary register
Link registerConventionally R31; CALL and RET explicitly use it
Program counter64-bit PC
Arithmetic condition flagsNo carry, zero, sign, or overflow flags defined
Scalar alignmentInstructions may start at any byte address
Scalar lengthsCurrently 1, 3, 4, 5, or 10 bytes; packet slot lengths can represent 1–15
Packet alignmentMandatory 64-byte alignment
Integer byte orderLittle-endian, including instruction immediates
Privilege modesUser and Supervisor
Floating-point/vector registersNot defined in the current instruction set

Each scalar instruction begins with a one-byte opcode. Each register operand occupies one byte: bits 4–0 select the register, and bits 7–5 must be zero.

In the tables below, Rd is a destination register, Rs a source, and Ra/Rb additional sources. Instruction lengths include the opcode byte. All opcode values are hexadecimal.

Data movement — 2 instructions

OpcodeInstructionBytesOperation
10MOV Rd, Rs3Copy all 64 bits of Rs into Rd.
11MOVI Rd, imm6410Load a full 64-bit immediate into Rd.

Encodings:

MOV:  opcode, destination, source
MOVI: opcode, destination, immediate64

MOVI can load an entire 64-bit constant or address in one instruction:

MOVI R1, 0x123456789ABCDEF0
MOV  R2, R1

There are no separate high-half/low-half immediate instructions. The assembler supports symbol relocations for scalar MOVI, allowing the linker to fill in a 64-bit address.

Integer arithmetic and logic — 8 instructions

OpcodeInstructionBytesOperation
20ADD Rd, Ra, Rb4Rd = Ra + Rb, modulo \(2^{64}\).
21SUB Rd, Ra, Rb4Rd = Ra − Rb, modulo \(2^{64}\).
22AND Rd, Ra, Rb4Bitwise AND.
23OR Rd, Ra, Rb4Bitwise OR.
24XOR Rd, Ra, Rb4Bitwise exclusive OR.
25MUL Rd, Ra, Rb4Low 64 bits of the product.
26SHL Rd, Rs, imm84Logical left shift by imm8 & 63.
27SHR Rd, Rs, imm84Logical right shift by imm8 & 63.

The first six use this encoding:

opcode, destination, source_a, source_b

The shifts use:

opcode, destination, source, shift_immediate

Arithmetic wraps without setting flags or raising an integer-overflow exception. MUL is specified as the low half of an unsigned product; the low 64-bit result also matches two’s-complement signed multiplication.

Both shifts introduce zero bits. SHR is not an arithmetic, sign-preserving right shift. Shift counts are masked to six bits, so a count of 64 becomes zero.

There are no immediate forms of ADD, SUB, or the bitwise operations. A constant must first be placed in a register:

MOVI R2, 1
ADD  R1, R1, R2

Memory access — 8 instructions

All memory instructions are five bytes long and use a base register plus a signed 16-bit byte displacement:\[ \text{address} = R_\text{base} + \operatorname{signExtend}(\text{disp16}) \]

The displacement range is −32,768 through +32,767 bytes.

OpcodeInstructionAccess widthOperation
30LD64 Rd, [Rb+disp16]64 bitsLoad a complete 64-bit value.
31ST64 Rs, [Rb+disp16]64 bitsStore a complete 64-bit value.
32LD8U Rd, [Rb+disp16]8 bitsLoad a byte and zero-extend to 64 bits.
33ST8 Rs, [Rb+disp16]8 bitsStore the low 8 bits of Rs.
34LD16U Rd, [Rb+disp16]16 bitsLoad and zero-extend to 64 bits.
35ST16 Rs, [Rb+disp16]16 bitsStore the low 16 bits of Rs.
36LD32U Rd, [Rb+disp16]32 bitsLoad and zero-extend to 64 bits.
37ST32 Rs, [Rb+disp16]32 bitsStore the low 32 bits of Rs.

Their binary layout is:

opcode, data_register, base_register, displacement16

Natural alignment is required:

WidthRequired address alignment
8 bits1 byte
16 bits2 bytes
32 bits4 bytes
64 bits8 bytes

For example:

LD64  R3, [R10+16]
LD8U  R4, [R10+1]
ST32  R5, [R10+8]

The assembler also accepts memory-first store syntax, such as ST32 [R10+8], R5.

There are no signed narrow-load instructions, indexed/scaled addressing modes, auto-increment addressing, or direct memory-to-memory moves. More elaborate address calculations use ordinary register arithmetic.

Control flow — 5 instructions

OpcodeInstructionBytesOperation
40JMP rel325Unconditional PC-relative jump.
41BRZ Rs, rel164Branch if the full 64-bit source register equals zero.
42BRNZ Rs, rel164Branch if the source register is nonzero.
43CALL rel325Save the following instruction’s address in R31, then branch.
44RET1Set PC to R31.

All relative offsets are measured from the first byte after the instruction:

target = instruction_address + instruction_length + signed_offset

JMP and CALL have signed 32-bit byte displacements; BRZ and BRNZ have signed 16-bit byte displacements.

There is no CMP instruction or condition-code register. Equality can be tested by subtracting or XORing two values and branching on the result:

XOR R3, R1, R2
BRZ R3, equal

CALL does not push a return address onto the stack. Nested functions must preserve R31 explicitly; the initial C compiler does this for functions containing calls.

The current ISA has no dedicated general-register indirect jump or indirect call. RET provides register-directed control transfer specifically through R31.

An assembler detail matters here: a symbolic operand such as CALL function resolves to a target address, but a numeric operand such as JMP 16 is interpreted as a relative displacement, not an absolute address.

System and privilege instructions — 6 instructions

OpcodeInstructionBytesOperation
50SVC1Enter the Supervisor exception handler.
51ERET1Return from an exception using saved status and PC.
52WFI1Advance PC and wait for an interrupt.
53MFSR Rd, csr83Read a system register into a GPR.
54MTSR csr8, Rs3Write a GPR value to a system register.
55TLBINV1Invalidate all cached address translations.

ERET, MFSR, MTSR, and TLBINV are Supervisor-only. The current emulator does not impose a Supervisor-only check on WFI.

SVC has no immediate syscall-number operand. Selecting a service and passing arguments are responsibilities of the operating-system ABI.

On exception entry, the processor:

  1. Saves STATUS in ESTATUS.
  2. Exchanges R30 and KSP if entering from User mode.
  3. Records the return/restart address in EPC and exception information in CAUSE and BADADDR.
  4. Clears the User and interrupt-enable bits.
  5. Transfers execution to EVEC.

For SVC, EPC points to the next instruction. ERET restores STATUS from ESTATUS, returns to EPC, and reverses the stack exchange when returning to User mode.

WFI allows device and timer activity to continue while the core is idle. An enabled pending interrupt wakes it.

TLBINV currently flushes the entire TLB. Writing PTBR or ASID does not implicitly flush it.

System-register map

The CSR selector is one byte, with these ten selectors implemented:

IDNameMeaning and behavior
0STATUSCurrent interrupt-enable, MMU-enable, and privilege bits.
1EVECException-handler entry address.
2EPCException return/restart address.
3CAUSEException or interrupt cause.
4BADADDRAddress associated with a fault.
5PTBRPhysical page-table root address; low 12 bits are cleared on write.
6ASIDAddress-space identifier used to tag translations.
7KSPStack-exchange register for User/Supervisor transitions.
8ESTATUSSaved status restored by ERET.
9TICKSReference emulator cycle counter; writes are ignored.

STATUS and ESTATUS use:

BitMeaning
0Interrupt enable
1MMU enable
2User mode

Other bits are discarded on writes in the current implementation. Unsupported CSR selectors raise an illegal-instruction exception.

The assembler currently expects numeric CSR selectors:

MFSR R1, 0
MTSR 5, R2
TLBINV

Execution and debugging — 3 instructions

OpcodeInstructionBytesOperation
00NOP1No operation.
01HALT1Stop the core; Supervisor-only.
FFBREAK1Debugger breakpoint operation.

In the reference emulator, BREAK sets the breakpoint indicator and halts execution. Although the ISA document describes it as a breakpoint trap, it does not currently enter the guest exception handler.

512-bit VLIW packet format

Packetization adds a container and scheduling metadata, not another set of arithmetic instructions.

Every packet is exactly 64 bytes, starts at a 64-byte-aligned address, and contains an eight-byte header followed by up to 56 bytes of instruction payload.

Byte offsetContents
0Packet marker F0
1, bits 3–0Format number; currently 0
1, bits 7–4Number of active slots minus one
2Stop mask: bit n places a stop after slot n
3Flags; must currently be zero
4Slot 0 length in low nibble; slot 1 length in high nibble
5Slot 2 and slot 3 lengths
6Slot 4 and slot 5 lengths
7Slot 6 and slot 7 lengths
8–63Scalar instructions followed by zero padding

A packet contains one through eight instructions. The sum of their lengths must not exceed 56 bytes. Nested packets are illegal.

Stop bits divide the packet into issue groups. Every instruction within a group reads the register values present at the beginning of that group. Register results become visible at the group boundary. The last active slot always ends a group.

For example:

.packet
    ADD R5, R1, R2
    XOR R6, R3, R4
.stop
    MUL R7, R5, R6
.endpacket

The ADD and XOR can execute independently. The stop makes their results available to MUL.

Without that stop, MUL would read the old values of R5 and R6. Two instructions in the same group may not write the same GPR.

Packetization does not guarantee eight operations per cycle. An implementation may execute a group serially or in parallel, provided it preserves the group’s architectural semantics.

Current packet eligibility

Instruction familyv0.13 reference emulator
NOP, MOV, MOVISupported
All eight arithmetic/logic instructionsSupported
LD64, LD8U, LD16U, LD32USupported
ST64Supported
ST8, ST16, ST32Rejected during packet execution
Jumps, conditional branches, calls, returnsProhibited
All six system instructionsProhibited
HALT, BREAKProhibited

There are two material implementation gaps:

  • Narrow stores: the assembler can encode them inside packets, but the emulator rejects them.
  • Memory ordering and exceptions: the specification calls for slot-ordered memory behavior and precise slot-order retirement. The emulator instead evaluates a group and defers its stores until the group ends. It therefore does not fully implement same-group store-to-load forwarding or the specified precise restart behavior.

For current programs, potentially aliasing memory operations should be placed in separate groups. Packet exception handling still needs development before treating it as a complete production implementation.

Address translation and exceptions

Version 0.13 retains the same instruction opcodes while expanding the MMU to cover the full 64-bit virtual address space.

Propertyv0.13 definition
Virtual address width64 bits
Architectural physical address width64 bits
Page size4 KiB
Page-table levelsSix
Address decomposition7/9/9/9/9/9 index bits, then 12 offset bits
Canonical-address restrictionNone
Reference TLB64 entries, ASID-tagged
Unimplemented physical destinationsFault rather than truncate the address

The defined exception causes are:

CauseMeaning
1Supervisor call
2Illegal instruction
3Alignment fault
4Instruction-fetch page fault
5Load page fault
6Store page fault
7Privilege fault
8Bus fault
0x100 + irq_lineHardware interrupt

Device access uses memory-mapped I/O; there are no separate IN or OUT instructions.

Instructions not yet defined

The current instruction set does not include division/remainder, high-half multiplication, carry/borrow arithmetic, arithmetic right shift, register-count shifts, rotates, signed narrow loads, ordered comparisons, conditional moves, dedicated stack operations, atomic read-modify-write operations, memory fences, floating point, SIMD, cryptographic instructions, or matrix operations.

The ISA reserves opcode range 80–EF and packet formats 1–15 for future expansion, but those reservations are not implemented extensions. Likewise, AURORA’s hardware-integrity goals do not yet introduce any additional instructions into this 32-opcode ISA.

Share

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *