CPU Chip

1. CPU Chip

The CPU (Central Processing Unit) is the brain of the Hack computer. It:

Executes instructions received from memory.

Handles both A-instructions (addressing) and C-instructions (computation).

Controls the Program Counter (PC).

Interfaces with Memory, ALU, and A/D registers.

It receives a 16-bit instruction and computes the next values for the outM, writeM, addressM, and pc outputs.

2. Truth Table

instruction[15] Type Operation
0 A-instruction Set A register to instruction[0..14]
1 C-instruction Perform ALU operation and control flow

Key outputs and behaviors:

input output Description
instruction outM ALU result, to be written to memory (if writeM = 1)
instruction[3] writeM Set to 1 if result is to be written to memory
instruction[0..2] jump bits Determine whether to jump based on ALU output
ALU out == 0 Jump if j1 or j2 is set Conditional jump logic
instruction[10..6] comp bits Determines ALU computation
instruction[5..3] dest bits Where to store ALU result (A, D, or M)
reset == 1 pc = 0 Forces PC to reset

3. Implementation (HDL)

The CPU combines the ALU, Register, and Program Counter (PC), and routes control based on instruction bits.

CHIP CPU {
    IN  inM[16],          // M value input  (from memory)
        instruction[16],  // current instruction
        reset;            // reset signal
    OUT outM[16],         // M value output (to memory)
        writeM,           // write M? (to memory)
        addressM[15],     // address (of memory)
        pc[15];           // program counter

    PARTS:
    // Decode type of instruction
    Not(in=instruction[15], out=isAInstruction);   // 0 = A-instruction, 1 = C-instruction

    // ALU input selection (a bit of C-instruction)
    Mux16(a=aOut, b=inM, sel=instruction[12], out=aluY);

    // ALU
    ALU(x=dOut, y=aluY,
        zx=instruction[11], nx=instruction[10],
        zy=instruction[9],  ny=instruction[8],
        f=instruction[7],   no=instruction[6],
        out=aluOut, zr=zr, ng=ng);

    // ----- Registers -----

    // A register input: if A-instruction → instruction[0..14]; if C-instruction → ALU output
    Mux16(a=instruction, b=aluOut, sel=instruction[15], out=aIn);

    // Load A if: A-instruction OR (C-instruction with dest[2] = 1)
    Or(a=isAInstruction, b=instruction[5], out=loadA);
    Register(in=aIn, load=loadA, out=aOut);

    // D register (C-instruction with dest[1] = 1)
    And(a=instruction[15], b=instruction[4], out=loadD);
    Register(in=aluOut, load=loadD, out=dOut);

    // ----- Memory interface -----

    // OutM = ALU output
    Assign(outM = aluOut);

    // AddressM = A register
    Assign(addressM = aOut[0..14]);

    // WriteM = C-instruction with dest[0] = 1
    And(a=instruction[15], b=instruction[3], out=writeM);

    // ----- Program Counter -----

    // Jump condition evaluation
    Not(in=zr, out=notZr);
    Not(in=ng, out=notNg);

    // Compute >0, ==0, <0
    And(a=notNg, b=notZr, out=pos);  // >0
    And(a=zr, b=true, out=zero);     // ==0
    And(a=ng, b=true, out=neg);      // <0

    // Instruction[2:0] = jump bits (JGT, JEQ, JLT)
    And(a=instruction[2], b=pos,  out=jgt);
    And(a=instruction[1], b=zero, out=jeq);
    And(a=instruction[0], b=neg,  out=jlt);

    Or(a=jgt, b=jeq, out=tmp1);
    Or(a=tmp1, b=jlt, out=jump);

    // Only allow jump if it’s a C-instruction
    And(a=instruction[15], b=jump, out=pcLoad);

    // Program Counter
    PC(in=aOut, load=pcLoad, inc=true, reset=reset, out=pc);
}