CPU Simulation
An 8-bit LEG-like CPU simulated in both C and Python, with a full instruction set and an interactive CLI.
- word size
- 8-bit
- registers (R0–R15)
- 16
- words of program memory
- 256
- implementations (C + Python)
- 2
Overview
This project is about understanding what a CPU actually does at the lowest level by building one from scratch — twice, in two different languages. The 8-bit LEG-like architecture is intentionally minimal: small enough to hold completely in your head, expressive enough to implement real programs. Implementing the same simulator in both C and Python forced a direct comparison of how each language handles bit manipulation, register state, and instruction dispatch.
Instruction Set
Eight opcodes, all ALU results targeting r0:
000— ADD:ra + rb → r0001— SUB:ra - rb → r0010— MOV: copy between registers011— IMMD: load immediate into register100— JMP_IF_ZERO: jump ifr0 == 0101— AND:ra & rb → r0110— OR:ra | rb → r0111— NOT:~ra → destination
Architecture
The simulated CPU models a classic fetch-decode-execute cycle. Each tick, the processor reads an instruction from 256-word program memory, decodes the opcode and operands, updates register state, and advances the program counter. The interactive CLI lets you program the machine, run it, and reset between programs.
What It Taught Me
- How the fetch-decode-execute cycle maps to real hardware behavior
- Instruction encoding tradeoffs at the bit level
- The practical difference between C's explicit bit manipulation and Python's high-level integer arithmetic
- Why accumulator-based ALU designs (everything targets
r0) simplify decode logic but complicate programs
These lessons fed directly into Cortex-VM's ISA design — particularly the choice of a proper register file over an accumulator model, and the decision to avoid implicit condition codes in favor of explicit comparison + branch instructions.