My day job is emergency medicine and occasionnally teaching. Setnex is what I work on in the gaps—evenings, weekends, post-call days. A side project with no deadline and no deliverable other than the spec itself.
So why spend that time designing a processor for a number system that no commercial hardware has used since 1958?
The premise
Every computer you've ever used thinks in binary: zeros and ones. It works, but binary carries baggage. Negative numbers require special encoding (two's complement). Comparison produces a pair of flags (carry and zero) that have to be interpreted in combination. The absence of information—NULL in SQL, NaN in floating point, None in Python—is always a special case bolted on top.
Balanced ternary is different. Each digit, called a trit, takes three values:
Negative numbers are native—just flip every trit (P becomes N, N becomes P, Z stays Z). No two's complement, no sign bit, no special case. Negation is literally free in hardware: swap two wires.
Comparison between two values produces a single trit—N for less, Z for equal, P for greater—instead of a pair of bits. One trit, three outcomes. Binary needs two bits to say the same thing.
And the "unknown" state? It's Z. Not a special value, not a sentinel, not a nullable wrapper. Just the middle of the scale.
What Setnex is
Setnex is a RISC instruction set architecture, inspired by RISC-V, designed from scratch for balanced ternary. Not a binary ISA with ternary bolted on. Every design decision—register encoding, flag semantics, instruction formats, comparison operators—is re-examined through the lens of base 3.
| Parameter | Value |
|---|---|
| Word width | 27 trits |
| Registers | 27 general-purpose (r0–r26) |
| Instruction width | 27 trits, fixed |
| Opcode | 4 trits (81 values) |
| Formats | 5 (R, I, J, U, B) |
| Address space | ±3.6 × 10¹² words |
| Logic modes | 5 (Kleene, Łukasiewicz, Heyting, RM3, B3) |
| License | Apache 2.0 |
27 is 3³. That number isn't a coincidence—it's a design principle. 27 trits per word, 27 registers, 27 CSR slots. The architecture is self-similar at every scale.
Instruction formats
Five formats, determined solely by the opcode. The decoder never inspects payload fields to figure out what it's looking at.
R format — register to register
I format — immediate
J format — conditional branch
U format — unconditional jump
B format — ternary three-way branch (v0.3)
The U format merges the unused rs1 field of unconditional jumps into the offset, multiplying range by 27 at no cost. The B format encodes a three-way branch in one instruction: P falls through, Z and N each carry an independent offset. Zero wasted trits.
Where it gets interesting
The arithmetic and memory instructions are predictable—any ISA has ADD, LOAD, STORE, branches. What makes Setnex specific to balanced ternary is a set of features that have no meaningful equivalent in binary.
Ternary flags
After every ALU operation, the FLAGS register is updated with two trits:
1 Negative numbers are native—just flip every trit (P becomes N, N becomes P, Z stays Z). No two's complement, no sign bit, no special case. Negation is literally free in hardware: swap two wires.| Trit | Name | Values |
|---|---|---|
| t[0] | sign | N = negative, Z = zero, P = positive |
| t[1] | carry | N = underflow, Z = none, P = overflow |
Every flag is fully ternary. The sign flag encodes three outcomes in one trit. The carry flag tells you which direction the overflow went. In binary, the sign is one bit, the zero flag is another, and you combine them mentally to figure out the comparison result. Here, CMP a, b writes a single trichotomy trit: N if a < b, Z if equal, P if a > b. One trit, done.
Configurable logic
The LMODE register selects the truth tables for all logic instructions. Five modes—Kleene, Łukasiewicz, Heyting, RM3, B3 (Bochvar)—differ in how they handle the indeterminate value Z. The logic instructions (TAND, TOR, TNOT, TIMPL) don't change; their meaning does. Same code, different epistemology, one register write.
This matters for the implication operator TIMPL. In Łukasiewicz mode, TIMPL(a, b) = P if and only if a ≤ b—it's a trit-parallel order test. In Heyting mode, the same instruction is more conservative about the unknown state. The application layer picks a policy; the hardware obeys. I wrote a longer article about TIMPL and its implications.
The comparison trio
Three instructions for trit-parallel comparison:
| Instruction | Question it answers | Binary equivalent |
|---|---|---|
| CONS | What do A and B agree on? | ~AND (partial) |
| ACONS | What's missing from the pair {A[i], B[i]}? | Nothing. Binary has no absent value. |
| TCMP | Who dominates at each position? | XOR + SUB (2 ops) |
These three are not redundant. CONS has a blind spot (CONS(Z,Z) and CONS(N,P) both return Z), which TCMP disambiguates. ACONS has no binary equivalent at all—in a two-state system, if you know one state and it's different, the other is determined. In a three-state system, it isn't. See the companion article for worked examples.
What Setnex is not
It is not a product. There is no chip, no compiler, no operating system. It's a specification—a document that defines encoding, semantics, and conventions precisely enough that someone could build those things. The companion project tritlib, a Python library for balanced ternary arithmetic, provides a software implementation to test against.
It is not a proof that ternary is "better" than binary. Ternary and binary are both Turing-complete; neither can compute anything the other can't. The claim is narrower: certain patterns—comparison, voting, three-valued logic, fault detection—express more naturally in balanced ternary, and a well-designed ISA can make that difference tangible at the instruction level.
It is not starting from zero. The theoretical foundation is over a century old (Łukasiewicz, 1920). The Setun computer ran balanced ternary in hardware in 1958. Over 100 papers on ternary CNTFET logic gates were published on IEEE Xplore between 2020 and 2024. In early 2025, Huawei published a patent for a ternary logic gate circuit. The pieces exist; what's missing is an ISA that thinks in ternary from the ground up, not one that maps binary conventions onto three-valued hardware.
The roadmap
v0.1 — Initial specification
Core architecture: 27-trit words, 27 registers, 3 formats (R, I, J), configurable ternary logic (Kleene, Łukasiewicz, Heyting, RM3, B3), CONS/ACONS, arithmetic, branches, exceptions, calling convention.
v0.2 — Ternary consistency
Fully ternary FLAGS (sign/carry). Trichotomy CMP. TCMP instruction. Format U for jumps. IRET atomic exception return. Saturating arithmetic (ADDS/SUBS). Extended multiply (MULH). Heyting as fourth logic mode. LST/MST terminology. Symmetric Euclidean division.
v0.3 — Ternary flag exploitation (current)
ADC/SBC carry chain with ternary carry. TSEL 3-way conditional select. BF trit-masked branch (6 conditions, 1 opcode). BRT3 three-way branch (format B, two independent offsets). Python simulator setnex-sim with assembler toolchain (setnex-asm / setnex-run).
v0.4 — Floating point, vectors, system
Ternary floating point (TFP, opcodes +8 to +14). Vector instructions. Memory protection. Interrupt controller.
v0.5 — Hardware
FPGA soft core (iCE40, open toolchain via nextpnr/yosys). ASIC exploration when CNTFET technology matures.
Why bother?
The honest answer is that it's interesting. Balanced ternary has a mathematical elegance—the symmetry around zero, the free negation, the trichotomy trit. Designing an ISA around it forces you to question every convention inherited from 70 years of binary computing. Why are flags binary? Why is division truncated toward zero? Why does comparison produce two bits instead of one? Most of the time the answer is "because binary." In balanced ternary, different answers emerge.
The practical answer is that the foundations are shifting. Ternary neural networks (BitNet-style {−1, 0, +1} weights) are an active area of research. CNTFET ternary gates are past the proof-of-concept stage. Huawei is filing patents. If ternary hardware does arrive, it will need an instruction set. Not a binary ISA awkwardly mapped onto three-state transistors, but one that was ternary from the first trit.
And if it never arrives? Then I'll have spent my evenings designing a clean RISC architecture with interesting comparison primitives, configurable multi-valued logic, and a flag system that encodes more information per trit than any binary processor. Worse ways to spend a Sunday.
Read more
The Ternary Trio: CONS, ACONS, and TIMPL—A deep dive into Setnex's comparison and logic primitives, with worked examples and application sketches.
Setnex ISA v0.3 specification—The full reference document (Apache 2.0).
setnex-sim—Python simulator and assembler toolchain. pip install setnex-sim.