A complete CPU emulator written in C++ with a modular architecture.
The project includes a custom instruction set, a full assembler, and sample assembly programs.
- Modular architecture: CPU parts are organized into dedicated classes/structs.
- Complete ISA: 16-bit instruction set covering arithmetic, logic, memory, and control flow.
- Assembler support: Label handling and literal parsing are built in.
- Debug tooling: Instruction tracing and CPU state inspection are available.
- Memory-mapped I/O: Character output support via mapped memory range.
- Example programs: Includes Timer, Hello World, and Fibonacci demos.
makeBuild output: cpu_emulator
./cpu_emulatorAvailable commands:
load <file>- Assemble and load a program filerun- Execute continuously until haltstep- Execute one instruction cyclegpr- Show General Purpose Registersspr- Show Special Purpose Registersram [addr] [len]- Dump RAMstate- Print full CPU statetrace on/off- Toggle instruction trace outputreset- Reset emulator statehelp- Show command listquit/exit- Leave the emulator
Run and execute a program in one command:
./cpu_emulator programs/hello.asm run
./cpu_emulator programs/fibonacci.asm run
./cpu_emulator programs/timer.asm run$ ./cpu_emulator
> load programs/fibonacci.asm
Program loaded: 25 instructions
Labels:
start: 0x0
loop: 0x1a
done: 0x3a
> trace on
Trace enabled
> step
=== Cycle 1 ===
PC: 0x0000
[FETCH] Instruction at PC: 0xb000
[DECODE] LDI R0, #0
[EXECUTE] R0 = 0
[STORE] PC updated to 0x0002
=== CPU State ===
Cycle: 1
=== General Purpose Registers ===
R0: 0x0000 (0)
R1: 0x0000 (0)
...
> run
> state
# Build
make
# Run with trace to see every instruction
./cpu_emulator programs/factorial.asm run
# Or interactive mode to inspect step by step
./cpu_emulator
> load programs/factorial.asm
> trace on
> run
> dec 0x0100 1 # should show 120
> spr # SP should be back at 0xFFFF (stack fully unwound)
> ram 0xFDEF 32 # inspect software stack area
- GPRs (General Purpose Registers): 8 registers (
R0-R7), each 16-bit - SPRs (Special Purpose Registers):
PC(Program Counter),SP(Stack Pointer),FLAGS
Handles arithmetic and logical operations, and updates status flags:
- Overflow
- Carry
- Zero
- Negative
Coordinates the fetch-decode-execute cycle, controls instruction flow, and updates the program counter.
- Instruction Bus: Bidirectional instruction fetch communication
- Info Bus: Data movement between components
- Control Bus: One-way control signaling from the Control Unit
- 64KB address space
- Byte-addressable, word-aligned
- Memory-mapped I/O at
0xFF00-0xFFFF
Core instruction groups:
- Arithmetic:
ADD,SUB - Logic:
AND,OR,XOR,NOT - Shifts:
SHL,SHR - Memory:
LD,ST - Immediate:
LDI - Control Flow:
JMP,JZ,JNZ,HLT
Prints Hello, World! via memory-mapped output.
Calculates the first 10 Fibonacci values and stores results in memory.
Shows Fetch/Compute/Store style execution by counting from 10 down to 0.
Recursive factorial of 5 using CALL/RET instructions. Demonstrates function calls,
stack frames, and recursion on the CPU.
C reference implementation: programs/factorial.c
- docs/ISA.md - Full instruction set reference
- docs/CPU_SCHEMATIC.md - CPU architecture reference
- docs/MEMORY_LAYOUT.md - Memory layout, function calls, and recursion (factorial)
CPU Architecture Diagram
- Modularity: Components are isolated and clearly defined
- Traceability: Control flow is visible in trace output
- Debuggability: Registers, memory, and complete state are easy to inspect
- Extensibility: Instruction set and components can be expanded easily
- Instructions are 16 bits wide
- Memory uses little-endian format
- Immediate values are 6-bit signed (
-32to31) - Program Counter increments by 2 bytes per instruction
- Stack Pointer initializes at
0xFFFF(top of memory)
This project is part of a System Software(CMPE220) Course assignment.
