Simulator
CPU
Computer CPU Simulator
Kacper Walczak · 28-04-2024
Lets build a CPU simulator.
Introduction
In this article we will build a simulator of the CPU. It will be a simple model of the CPU that will allow us to understand how the CPU works.
To fully understand how to build quantum computer we need to know how regular version of the computer works.
This article is a part of Quantum Computing series:
- Computer CPU Simulator # You are here
What is the CPU?
CPU is a Central Processing Unit. It is a part of the computer that is responsible for executing instructions. It is a brain of the computer.
What is an instruction?
Instruction is a command that CPU executes. It is a simple command that tells CPU what to do. For example, ADD instruction tells CPU to add two numbers.
How to add two numbers?
To add two numbers we need to use ADD instruction. It takes two numbers as an input and returns a sum of them.
But how to tell CPU to add two numbers? We need to use a programming language. Let's use Python.
def add(a, b):
return a + b
add(1, 2) # 3How processor sees it?
Assume we got 4-bit system, e.g. [0001] = 1, [0010] = 2, [0011] = 3, etc.
Let's see how processor sees it. We will use a simple model of the CPU that will allow us to understand how the CPU works.
ADD 1 2
# result in bits => 0001 + 0010 = 0011How to build a CPU simulator?
We will use TypeScript to build a CPU simulator.
Build interfaces for the CPU and instruction
type Bit = 0 | 1;
type Word = Bit[];
interface CPU {
memory: (Word | number)[];
registers: Word[];
instructionPointer: number;
halted: boolean;
}
class CPU {
constructor() {
this.memory = [];
this.registers = [];
this.instructionPointer = 0;
this.halted = false;
}
}
interface Instruction {
name: string;
operandsCount: number;
execute: (cpu: CPU, operands: Word[]) => void;
}Build instructions
const Opcode = {
ADD: 0b0000
}
const instructions: Record<number, Instruction> = {
[Opcode.ADD]: {
name: "ADD",
operandsCount: 2,
execute: (cpu, operands) => {
const [a, b] = operands;
const result = add(a, b);
cpu.registers[0] = result;
},
},
// ...
};
function add(a: Word, b: Word): Word {
if (a.length !== b.length) {
throw new Error("Words must have the same length");
}
const result: Word = [];
let carry = 0;
for (let i = 0; i < a.length; i++) {
const sum = a[i] + b[i] + carry;
const bit = sum % 2 as Bit;
carry = sum > 1 ? 1 : 0;
result.push(bit);
}
return result;
}Build the simulator loop
const cpu = new CPU();
// cpu.memory = [...insertInstructionsWithOperandsHereFromFileEtc]
while (!cpu.halted) {
const instruction = instructions[cpu.memory[cpu.instructionPointer] as number];
const operands = cpu.memory.slice(
cpu.instructionPointer + 1,
cpu.instructionPointer + 1 + instruction.operandsCount
) as Word[];
instruction.execute(cpu, operands);
cpu.instructionPointer += instruction.operandsCount + 1;
if (cpu.instructionPointer >= cpu.memory.length) {
cpu.halted = true;
}
}How to use CPU simulator?
We will use CPU simulator to add two numbers.
const cpu = new CPU();
cpu.memory = [
Opcode.ADD, // +
[0,0,0,1], // 1
[0,0,1,0], // 2
];
while (!cpu.halted) {
const instruction = instructions[cpu.memory[cpu.instructionPointer] as number];
const operands = cpu.memory.slice(
cpu.instructionPointer + 1,
cpu.instructionPointer + 1 + instruction.operandsCount
) as Word[];
instruction.execute(cpu, operands);
cpu.instructionPointer += instruction.operandsCount + 1;
if (cpu.instructionPointer >= cpu.memory.length) {
cpu.halted = true;
}
}
console.log(cpu.registers[0]); // result stored in the first register = [0011] = 3Improvements
Consider adding more instructions and more complex operations to the CPU simulator. More like real assembler.
const Opcode = {
ADD: 0b0000,
SUB: 0b0001,
MUL: 0b0010,
DIV: 0b0011,
MOV: 0b0100,
JMP: 0b0101,
JZ: 0b0110,
JNZ: 0b0111,
// ...
}
// ADD R1 R2 R3 => R1 = R2 + R3 *R1, R2, R3... are registers
const instructions: Record<number, Instruction> = {
[Opcode.ADD]: {
name: "ADD",
operandsCount: 3,
execute: (cpu, operands) => {
const [a, b, c] = operands;
a = add(b, c);
},
}
};
// More "real" assembler instructions
// ADD R1 R2 R3 => R1 = R2 + R3
// SUB R1 R2 R3 => R1 = R2 - R3
// MUL R1 R2 R3 => R1 = R2 * R3
// DIV R1 R2 R3 => R1 = R2 / R3
// MOV R1 R2 => R1 = R2
// JMP 0x1234 => jump to address 0x1234
// JZ 0x1234 => jump to address 0x1234 if zero flag is set
// JNZ 0x1234 => jump to address 0x1234 if zero flag is not set
// ...Full code
Visit GitHub full Typescript CPU simulator file here (opens in a new tab).
Conclusion
In this article we have learned how to build a basic CPU simulator.
READ
Latest readings
Readings are sites which will help you with detailed
information about given topic. Read latest ones from Learn.
06-03-2026
Build your own local voice assistant powered by Ollama.
06-03-2026
Generate YouTube thumbnails with FastAPI and Ollama.
05-09-2024
Compare Neo4j and Tigergraph databases, which is easier to work with, etc.