STRATA-16
16-bit deterministic processor
- DOCUMENT
- STRATA-16-DS
- STATUS
- SPECIFICATION
- DEPLOYMENT
- NONE
- PRIMITIVE
- NAND
- NAND CELLS
- 3,912
- FLIP-FLOPS
- 312
STRATA-16 is a 16-bit processor composed from a single computational primitive. It retires one instruction per external clock edge and produces a commitment to its architectural state on every transition. This document specifies the architecture. It does not describe a deployment: no contract exists, and every figure in it is derived from the implementation in this site.
1 FEATURES
ALL FIGURES DERIVED- 16-bit data path, 16 architectural registers
- 5-bit opcode field, all 32 instructions defined, no reserved space
- 2,048 words of program store, 32-bit instruction word
- 4 KB byte-addressed store with 16-bit access, little endian
- 64-word stack page, full descending, faults rather than wrapping
- Four condition flags: Z, N, C, V, taken from the adder chain
- Two byte-wide ports mapped into the store; no input or output instructions
- 5 execution phases, 3–5 visited per instruction
- 15 control points, 177 assertions across the set
- 3,912 NAND cells and 312 flip-flops, summed from the netlist
- Canonical encoding: one encoding per instruction, non-canonical words fault
- Deterministic replay: the same program and inputs produce the same commitments
2 ARCHITECTURAL STATE
312 BITS| ELEMENT | WIDTH | BITS |
|---|---|---|
| REGISTER FILE | 16 × 16 | 256 |
| INSTRUCTION REGISTER | 32 bit | 32 |
| PROGRAM COUNTER | 12 bit | 12 |
| STACK POINTER | 8 bit page offset | 8 |
| FLAGS | Z N C V | 4 |
| ARCHITECTURAL STATE | total | 312 |
| REGISTER | VALUE | NOTE |
|---|---|---|
| PC | 0x000 | first instruction word |
| IR | 0x00000000 | cleared, not fetched |
| SP | 0x80 | one word past the top of the page |
| R0 … RF | 0x0000 | all registers cleared |
| FLAGS | · · · · | all clear |
| STORE | 0x00 | 4,096 bytes cleared |
RESET is the only way back. A state transition is not reversible, so there is no undo and no rollback: a machine returns to this table or it continues forward.
3 INSTRUCTION WORD
32 BIT · 25 SIGNIFICANT| FIELD | BITS | WIDTH | CONTENT |
|---|---|---|---|
| RSV | 31:25 | 7 | zero in a canonical word |
| OP | 24:20 | 5 | opcode, 32 defined |
| RD | 19:16 | 4 | destination register, or a pointer register |
| RS | 15:12 | 4 | source register, or a pointer register |
| IMM/ADDR | 11:0 | 12 | immediate, RAM address, ROM address, or 4-bit shift distance |
CANONICAL FORM · A word is canonical when bits 31:25 are zero and every field the decoded instruction does not read is zero. A shift distance above 15 is not canonical. The decoder rejects any word that is not canonical, so exactly one encoding of an instruction exists and two machines can compare transitions without a normalisation step.
4 INSTRUCTION SET
32 OPCODES| OPCODE | MNEMONIC | OPERANDS | CLASS | FLAGS | Φ | DESCRIPTION |
|---|---|---|---|---|---|---|
| 00000 | NOP | — | CONTROL | — | 3 | No architectural state changes except the program counter. |
| 00001 | MOV | Rd, Rs | TRANSFER | — | 4 | Copies the source register into the destination register. |
| 00010 | LDI | Rd, #imm | TRANSFER | — | 4 | Loads a zero-extended twelve-bit immediate into the destination register. |
| 00011 | LOAD | Rd, [addr] | MEMORY | — | 5 | Reads a sixteen-bit word from an absolute RAM address into the destination register. |
| 00100 | LDR | Rd, [Rs] | MEMORY | — | 5 | Reads a word from the RAM address held in the source register. |
| 00101 | STORE | [addr], Rs | MEMORY | — | 5 | Writes the source register to an absolute RAM address. |
| 00110 | STR | [Rd], Rs | MEMORY | — | 5 | Writes the source register to the RAM address held in the destination register. |
| 00111 | PUSH | Rs | STACK | — | 5 | Decrements the stack pointer and writes the source register to the stack page. |
| 01000 | POP | Rd | STACK | — | 5 | Reads a word from the stack page into the destination register and increments the stack pointer. |
| 01001 | ADD | Rd, Rs | ARITHMETIC | ZNCV | 5 | Adds the source register to the destination register. |
| 01010 | ADDI | Rd, #imm | ARITHMETIC | ZNCV | 5 | Adds a zero-extended twelve-bit immediate to the destination register. |
| 01011 | SUB | Rd, Rs | ARITHMETIC | ZNCV | 5 | Subtracts the source register from the destination register. |
| 01100 | SUBI | Rd, #imm | ARITHMETIC | ZNCV | 5 | Subtracts a zero-extended twelve-bit immediate from the destination register. |
| 01101 | INC | Rd | ARITHMETIC | ZNCV | 5 | Adds one to the destination register. |
| 01110 | DEC | Rd | ARITHMETIC | ZNCV | 5 | Subtracts one from the destination register. |
| 01111 | NEG | Rd | ARITHMETIC | ZNCV | 5 | Replaces the destination register with its two's complement. |
| 10000 | AND | Rd, Rs | LOGIC | ZN | 5 | Bitwise conjunction of the destination and source registers. |
| 10001 | OR | Rd, Rs | LOGIC | ZN | 5 | Bitwise disjunction of the destination and source registers. |
| 10010 | XOR | Rd, Rs | LOGIC | ZN | 5 | Bitwise exclusive disjunction of the destination and source registers. |
| 10011 | NOT | Rd | LOGIC | ZN | 5 | Bitwise complement of the destination register. |
| 10100 | SHL | Rd, #n | SHIFT | ZNC | 5 | Shifts the destination register left by a four-bit distance. The last bit shifted out enters carry. |
| 10101 | SHR | Rd, #n | SHIFT | ZNC | 5 | Logical right shift. Vacated bits are filled with zero. |
| 10110 | ASR | Rd, #n | SHIFT | ZNC | 5 | Arithmetic right shift. Vacated bits are filled with the sign bit. |
| 10111 | CMP | Rd, Rs | COMPARE | ZNCV | 5 | Subtracts the source from the destination, writing flags and discarding the result. |
| 11000 | CMPI | Rd, #imm | COMPARE | ZNCV | 5 | Compares the destination register against a twelve-bit immediate. |
| 11001 | JMP | addr | CONTROL | — | 5 | Unconditional transfer of control to a ROM address. |
| 11010 | JMZ | addr | CONTROL | — | 5 | Transfers control if the zero flag is set. |
| 11011 | JNZ | addr | CONTROL | — | 5 | Transfers control if the zero flag is clear. |
| 11100 | JMN | addr | CONTROL | — | 5 | Transfers control if the negative flag is set. |
| 11101 | CALL | addr | CONTROL | — | 5 | Pushes the return address onto the stack page and transfers control. |
| 11110 | RET | — | CONTROL | — | 5 | Pops a return address from the stack page into the program counter. |
| 11111 | HALT | — | CONTROL | — | 3 | Stops the sequencer. The architectural state is retained and remains readable. |
5 EXECUTION PHASES
ONE INSTRUCTION PER PASS| PHASE | RUNS | ACTION |
|---|---|---|
| FETCH | ALWAYS | reads the word at the counter into the instruction register |
| DECODE | ALWAYS | resolves operand sources and the branch condition; derives the phase list |
| EXECUTE | IF ASSERTED | drives the arithmetic unit, the memory port or the pointer |
| WRITEBACK | IF ASSERTED | applies the register, store, flag, pointer and counter writes |
| COMMIT | ALWAYS | increments the cycle and produces the state commitment |
| INSTRUCTION | PHASES | LIST |
|---|---|---|
| NOP | 3 | F D C |
| MOV | 4 | F D W C |
| LDI | 4 | F D W C |
| ADD | 5 | F D E W C |
| LOAD | 5 | F D E W C |
| STORE | 5 | F D E W C |
| CALL | 5 | F D E W C |
| JMZ | 4 / 5 | F D E W C · untaken skips writeback |
| HALT | 3 | F D C |
A decision — a comparison and the branch that consumes its flags — costs 9 to 10 phases, measured over 180 samples of the DECIDE reference program.
6 STORE MAP
4 KB · BYTE ADDRESSED| REGION | FROM | TO | BYTES | NOTE |
|---|---|---|---|---|
| DATA | 0x000 | 0xEFF | 3,840 | general read/write |
| STACK | 0xF00 | 0xF7F | 128 | 64 words, full descending |
| RESERVED | 0xF80 | 0xFFB | 124 | reads 0x00, writes ignored |
| PORT IN | 0xFFC | 0xFFD | 2 | host → machine, 1 byte |
| PORT OUT | 0xFFE | 0xFFF | 2 | machine → host, 1 byte |
PORTS · The input port at 0xFFC reads a byte supplied by the host and its upper byte reads zero, so a sixteen-bit load returns a zero-extended value without masking. The output port at 0xFFE takes the low byte of a store; its upper byte ignores writes. Nothing is buffered: a port is read when a program reads it and written when a program writes it.
7 CONTROL POINTS
15 LINES · 177 ASSERTIONS| LINE | NAME | ASSERTED BY | INSTRUCTIONS |
|---|---|---|---|
| IR_LD | INSTRUCTION REGISTER LOAD | 32 | every instruction |
| PC_INC | PROGRAM COUNTER INCREMENT | 31 | NOP MOV LDI LOAD LDR STORE STR PUSH POP ADD ADDI SUB SUBI INC DEC NEG AND OR XOR NOT SHL SHR ASR CMP CMPI JMP JMZ JNZ JMN CALL RET |
| PC_LOAD | PROGRAM COUNTER LOAD | 6 | JMP JMZ JNZ JMN CALL RET |
| RA | REGISTER READ PORT A | 17 | STR ADD ADDI SUB SUBI INC DEC NEG AND OR XOR NOT SHL SHR ASR CMP CMPI |
| RB | REGISTER READ PORT B | 11 | MOV LDR STORE STR PUSH ADD SUB AND OR XOR CMP |
| IMM_SEL | IMMEDIATE SELECT | 16 | LDI LOAD STORE ADDI SUBI INC DEC SHL SHR ASR CMPI JMP JMZ JNZ JMN CALL |
| ALU_EN | ARITHMETIC UNIT ENABLE | 13 | ADD ADDI SUB SUBI INC DEC NEG AND OR XOR NOT CMP CMPI |
| SH_EN | SHIFTER ENABLE | 3 | SHL SHR ASR |
| FLG_WR | FLAG WRITE | 16 | ADD ADDI SUB SUBI INC DEC NEG AND OR XOR NOT SHL SHR ASR CMP CMPI |
| REG_WR | REGISTER WRITE | 19 | MOV LDI LOAD LDR POP ADD ADDI SUB SUBI INC DEC NEG AND OR XOR NOT SHL SHR ASR |
| MEM_RD | MEMORY READ | 4 | LOAD LDR POP RET |
| MEM_WR | MEMORY WRITE | 4 | STORE STR PUSH CALL |
| SP_DEC | STACK POINTER DECREMENT | 2 | PUSH CALL |
| SP_INC | STACK POINTER INCREMENT | 2 | POP RET |
| HALT_L | HALT LATCH | 1 | HALT |
The switching figure on the front of this document is the sum of this column: 177 assertions across 32 decoded instructions.
8 NETLIST
15 BLOCKS · 3,912 NAND| BLOCK | LAYER | NAND | FF | BUDGET | DERIVATION |
|---|---|---|---|---|---|
| ADDER | ARITHMETIC | 144 | — | 16 × full adder (9) | |
| LOGIC UNIT | ARITHMETIC | 160 | — | 16 × (AND 2 + OR 3 + XOR 4 + NOT 1) | |
| BARREL SHIFTER | ARITHMETIC | 256 | — | 4 stages × 16 × MUX2 (4) | |
| RESULT SELECT | ARITHMETIC | 192 | — | 16 × 4→1 MUX (3 × MUX2) | |
| FLAG UNIT | ARITHMETIC | 52 | 4 | Z: 15 × OR (3) + NOT (1) = 46 · N C V: 6 · 4 flip-flops | |
| READ PORT A | REGISTERS | 960 | — | 16 × 16→1 MUX (15 × MUX2 = 60) | |
| READ PORT B | REGISTERS | 960 | — | 16 × 16→1 MUX (15 × MUX2 = 60) | |
| REGISTER FILE | REGISTERS | 132 | 256 | 16 × AND4 (6) + 4 × NOT + 16 × AND2 (2) · 16 × 16 flip-flops | |
| COUNTER INCREMENT | CONTROL | 72 | 12 | 12 × half adder (6) · 12 flip-flops | |
| COUNTER SOURCE | CONTROL | 96 | — | 2 × (12 × MUX2) | |
| OPCODE DECODER | CONTROL | 261 | — | 32 × AND5 (8) + 5 × NOT | |
| MEMORY PORT | MEMORY | 242 | — | address 3→1 MUX 96 · word assembly 64 · port compare 82 | |
| STACK POINTER | MEMORY | 80 | 8 | 8 × half adder (6) + 8 × MUX2 · 8 flip-flops | |
| INSTRUCTION REGISTER | CONTROL | 64 | 32 | 32 × AND2 (2) load enable · 32 flip-flops | |
| CONTROL MATRIX | CONTROL | 241 | — | 24 control terms × 3 × OR (3) = 216 · 5 phase lines × AND2 = 10 · 15 glue |
9 FAULTS
5 DECLARED| CODE | RAISED WHEN | NOTE |
|---|---|---|
| PC_RANGE | Fetch from an address at or above the program store. | The counter is 12 bits and the store is 2048 words, so half the counter's range is outside it. A transfer there faults at the next fetch rather than reading nothing. |
| NON_CANONICAL | Fetch of a word with a reserved bit set, or with a field the instruction does not read set. | There is exactly one encoding of any instruction. A word that is not it is not executed. |
| STACK_OVERFLOW | PUSH or CALL with the stack pointer at the floor of the stack page. | The page is fixed at 64 words. The machine stops rather than writing outside it. |
| STACK_UNDERFLOW | POP or RET with the stack pointer at its reset value. | Returning from a frame that was never pushed is a fault, not an arbitrary jump. |
| MEM_RANGE | Reserved. No access can currently raise it: the address field is 12 bits and the store is 4096 bytes. | Declared so that the fault space is closed even though the address space cannot leave the store. |
A fault is a defined stop, not a crash. The instruction that raised it produces no transition except the fault itself: the counter stays on it, the store is unchanged, and the state remains readable. CHECK 04 asserts that randomised execution reaches no state outside this table.
10 VERIFICATION
5 CHECKS · RUN LOCALLY| CHECK | ESTABLISHES | QUICK | FULL | UNIT |
|---|---|---|---|---|
| CHECK 01 THE ARITHMETIC | Every arithmetic, logic and shift instruction produces the same result and the same four flags as the same operation built out of the primitive. | 4,096 | 1,048,576 | VECTORS |
| CHECK 02 AN INDEPENDENT MODEL | A second interpreter, sharing no execution code with the machine, reaches identical architectural state after every retired instruction. | 20,000 | 400,000 | RETIREMENTS |
| CHECK 03 THE SHIPPED PATH | The encoding is canonical and the text path is closed: an instruction word disassembles to text that reassembles to the identical word. | 8,192 | 131,072 | WORDS |
| CHECK 04 LIVENESS | Randomised execution never reaches an undefined architectural state. It either runs, halts, or raises one of the declared faults. | 60,000 | 1,200,000 | PHASES |
| CHECK 05 THE COMMITMENT | A machine replayed from its program and its inputs produces the identical sequence of state commitments. This is the property the contract requires. | 8,000 | 120,000 | COMMITMENTS |
No third party has audited this architecture. These checks run in the reader’s browser, against the same machine the interface operates, and each one states what a pass does not establish on the verification page.
11 OMISSIONS AND CONSEQUENCES
DELIBERATEThree exclusive disjunctions exchange two registers without a temporary. An opcode that can be written in the instruction set it would belong to does not earn a slot in a closed set.
Both ports are mapped into the store, so LOAD already reads and STORE already writes. Adding IN and OUT would have added two decoded opcodes and one more thing to verify, for no capability.
A multiply is a shift and an add in a loop, and the MULTIPLY reference program is that loop. The netlist stays at one adder, one logic unit and one shifter.
The clock is external and the machine is advanced by an edge it does not control. There is nothing to interrupt: between two edges the machine is not running.
All 32 opcodes are defined. A five-bit field cannot hold a thirty-third instruction, so the architecture is fixed at R0 rather than left open.
The counter is 12 bits and the program store is 2,048 words, so half the counter's range is outside it. That is why PC_RANGE is a declared fault rather than an impossibility.
12 REFERENCE PROGRAMS
6 LISTED; ACCUMULATE — the resident program
; Eight additions into one RAM word, then the word is cleared
; and the sequence restarts. The machine never halts.
.org 0x000
LDI R2, #17 ; addend
LDI R5, #0 ; iteration counter
LDI R1, #0
STORE [0x020], R1 ; clear the accumulator
work: LOAD R1, [0x020] ; read the accumulator
ADD R1, R2 ; accumulate
STORE [0x020], R1 ; commit it
MOV R3, R1 ; keep a copy for inspection
INC R5
CMPI R5, #8
JNZ work
LDI R5, #0 ; wrap the sequence
LDI R1, #0
STORE [0x020], R1
JMP work; DECIDE — a decision per pass over the input port
; The port word reads as a zero extended byte, so no masking
; is required before the comparison.
.org 0x000
read: LOAD R1, [0xFFC] ; host → machine
CMPI R1, #0x040
JMN low ; R1 < 0x40
CMPI R1, #0x0C0
JMN mid ; 0x40 ≤ R1 < 0xC0
high: LDI R3, #0x003
JMP emit
mid: LDI R3, #0x002
JMP emit
low: LDI R3, #0x001
emit: STORE [0xFFE], R3 ; machine → host
INC R4 ; decisions taken
JMP read; MULTIPLY — 13 × 11 by shift and add
; The architecture has no multiplier. It has a shifter and an
; adder, which is enough.
.org 0x000
LDI R1, #13 ; multiplicand
LDI R2, #11 ; multiplier
CALL mul
STORE [0x030], R3 ; product
HALT
mul: LDI R3, #0 ; product
LDI R4, #0x001 ; bit selector
mloop: MOV R5, R2
AND R5, R4 ; is this multiplier bit set?
JMZ skip
ADD R3, R1 ; accumulate the partial product
skip: SHL R1, #1
SHL R4, #1
CMPI R4, #0x100 ; eight bits consumed
JNZ mloop
RET; SEQUENCE — an additive sequence written through a pointer
; Register indirect stores walk the pointer forward two bytes
; per word.
.org 0x000
LDI R1, #0
LDI R2, #1
LDI R3, #0x040 ; write pointer
LDI R6, #16 ; words to write
fib: STR [R3], R1
MOV R4, R1
ADD R4, R2
MOV R1, R2
MOV R2, R4
ADDI R3, #2
DEC R6
JNZ fib
HALT; STACK WALK — the stack page is 64 words, full descending
; CALL pushes a return address through the same port PUSH uses.
.org 0x000
LDI R1, #0x0A1
LDI R2, #0x0B2
PUSH R1
PUSH R2
POP R3 ; R3 ← 0x0B2
POP R4 ; R4 ← 0x0A1
CALL depth
HALT
depth: PUSH R1
POP R5
RET; ECHO — the input/output boundary
; Nothing is buffered. The port is read when the program reads
; it and written when the program writes it.
.org 0x000
echo: LOAD R1, [0xFFC]
CMPI R1, #0
JMZ echo ; wait for a non zero byte
SHL R1, #1
STORE [0xFFE], R1
JMP echo