A Reversible Processor, End to End
Every thread of this module now gets tied. We have adiabatic circuits that recover their charge,
power clocks to feed them, and
an instruction set
whose every operation is invertible. The remaining question is the architect's: can you
assemble these into a complete, working processor — ALU, registers, program counter, memory — with
no destructive step anywhere in the datapath? The MIT Pendulum group answered by
building one. This lesson walks the machine block by block, meets the two silicon case studies, and
tallies the honest costs.
The datapath, block by block
Step through the diagram: each block of a conventional processor reappears, redesigned around
exchange and in-place update. Every arrow is two-headed, because every path must carry traffic both
ways — the same wires that compute the forward step must be able to uncompute it.
What each block gives up, and gets
- The ALU is built from
reversible
adders: add-in-place (r_1 \mathrel{+}= r_2), subtract,
negate, XOR — controlled operations that update one operand while preserving what is needed to undo
them. There is no "result bus" writing over a third register; the result lives where an operand
was, and the operation's inverse is another ALU operation.
- The register file abandons the destructive write port. Access is
exchange-based: reading a value out for an in-place update and writing the result
back are two halves of one round trip, and moving data between registers is EXCH. Nothing is ever
clobbered, so nothing need be logged.
- The program counter is the sneakiest block. PC updates happen every single
instruction, and an ordinary jump erases the origin. The paired-branch (come-from) discipline from
the previous lesson is implemented in hardware: branch instructions carry both directions, so the
machine can always compute the previous PC from the current state — forwards and backwards
execution use the same wires with the roles of "next" and "previous" swapped.
- Memory is accessed by exchange: EXCH r,
M[a] swaps a register with a memory word. A load is simultaneously a store; the
memory never forgets, it only trades. (The exchanged-out value must of course go somewhere
deliberate — usually a register the program has arranged to be empty, or the garbage stack.)
- Garbage management scales Bennett's trick to machine level: expanding
instructions push intermediate values onto a garbage stack; when a procedure
finishes, its results are copied out reversibly and the procedure's inverse runs, popping the
garbage stack back to empty — compute, copy, uncompute, at subroutine granularity.
Silicon proof and honest arithmetic
The MIT group carried this all the way to fabrication. The Pendulum processor
implemented the PISA instruction set with a fully reversible datapath; its companion study
Tick explored the same discipline in a conventionally-clocked implementation,
separating the architectural questions from the adiabatic-circuit ones. Between them they showed the
two claims this module has been building to: a reversible ISA can be implemented without
hidden erasures, and the datapath tricks (exchange memory, paired branches, garbage stacks) work as
real hardware, not just on whiteboards.
The honest costs, in round numbers: reversible programs need more instructions (an
expanding/contracting pair where one destructive instruction sufficed), wider state
(garbage in flight, come-from bookkeeping), and roughly a factor of ~2 in
instruction count and datapath width for typical code — plus the speed the adiabatic substrate
trades for its energy savings. Overheads are polynomial-mild, not exponential; the bet of the whole
field is that as the energy ceiling tightens, a constant-factor tax will look cheap next to a
10^4-fold energy win.
- ALU: in-place reversible arithmetic (r_1 \mathrel{+}= r_2,
XOR, NEG) — every operation's inverse is also an ALU operation;
- registers and memory: exchange-based access — swaps replace destructive reads
and writes;
- PC: invertible updates via paired-branch (come-from) information;
- garbage: a stack of intermediates, retired by Bennett-style uncomputation at
procedure boundaries;
- cost: instruction-count and width overheads around 2× for typical code —
constant-factor, not asymptotic.
Sit with what this machine can do that no ordinary computer can: press a button and the program runs
backwards — actually backwards, the PC retreating, sums unsumming, swaps unswapping —
because the current state uniquely determines the previous one, all the way to the start.
Every debugger you have used fakes this with logs, snapshots and replays, burning memory to
reconstruct a past the processor destroyed. A reversible processor never destroyed it. Crash at
instruction one billion? Put the machine in reverse and drive back to the bug, inspecting any state
on the way. The same trick powers speculative simulation (guess, explore, provably roll back) — a
reminder that reversibility is not only a thermodynamic virtue; it is a feature.
A tempting shortcut: compile your program to PISA, run it on an ordinary CMOS core, collect the
energy savings. You will collect nothing — in fact you'll pay the ~2× overhead tax for the privilege.
On conventional hardware every register update still slams capacitors against a fixed rail at
\tfrac{1}{2}CV^2 a switch, whether or not the operation was logically
invertible. The stack only pays off end to end: reversible ISA so that the
logic can be fully adiabatic, fully adiabatic circuits so that charge can be recovered,
resonant power clocks so that the recovered charge is banked rather than burned. Remove any
layer and the energy argument collapses to the floor below it. (Tick, run conventionally, was an
architecture experiment — not an energy machine.) Logical reversibility is necessary for
ultra-low-energy computing; it is nowhere near sufficient.