← SEARCHABLE ARCHIVE
Nand2Tetris · 2026-05-18

Nand2Tetris — Kapitel 5

Hack-Rechnerarchitektur

INTERACTIVE READING MODE →

// Memory
//Eingabe: in[16], laden, Adresse[15]
//Ausgabe: out[16]
//Bewegung:
// address[0..13]  : RAM16K
//Adresse[14]=0: RAM-Bereich
// address[14]=1, address[13]=0 : Screen
// address[14]=1, address[13]=1 : Keyboard
//Die Tastatur ist schreibgeschützt, daher ist keine Last angeschlossen.

CHIP Memory {
    IN in[16], load, address[15];
    OUT out[16];

    PARTS:
    DMux4Way(in=load, sel=address[13..14],
             a=loadRamA, b=loadRamB, c=loadScreen, d=ignore);

    Or(a=loadRamA, b=loadRamB, out=loadRam);

    RAM16K(in=in, load=loadRam, address=address[0..13], out=ramOut);
    Screen(in=in, load=loadScreen, address=address[0..12], out=screenOut);
    Keyboard(out=keyboardOut);

    Mux4Way16(a=ramOut, b=ramOut, c=screenOut, d=keyboardOut,
              sel=address[13..14], out=out);
}
// CPU
//Eingabe: inM[16], Anweisung[16], Zurücksetzen
//Leistungsabgabe:
//outM[16]: Wert, der in den Speicher geschrieben werden soll
//writeM: Ob Wert in M ​​geschrieben werden soll
//addressM: Speicheradresse, auf die zugegriffen werden soll (A-Register)
//PC: nächste Befehlsadresse
//Bewegung:
//Handelt es sich um einen A-Befehl, wird der Befehlswert im A-Register gespeichert.
//Wenn es sich um eine C-Anweisung handelt, werden die ALU und die Register entsprechend den Feldern comp, dest und jump gesteuert.

CHIP CPU {
    IN  inM[16], instruction[16], reset;
    OUT outM[16], writeM, addressM[15], pc[15];

    PARTS:
    //Bestimmung des Befehlstyps
    Not(in=instruction[15], out=isA);
    And(a=instruction[15], b=true, out=isC);

    //Eine Registereingangsauswahl
    Mux16(a=instruction, b=aluOut, sel=isC, out=aInput);
    And(a=isC, b=instruction[5], out=loadAFromC);
    Or(a=isA, b=loadAFromC, out=loadA);
    ARegister(in=aInput, load=loadA, out=aOut, out[0..14]=addressM);

    //D-Register
    And(a=isC, b=instruction[4], out=loadD);
    DRegister(in=aluOut, load=loadD, out=dOut);

    //Auswahl des y-Eingangs der ALU: A, wenn ein Bit 0 ist, M, wenn ein Bit 1 ist
    Mux16(a=aOut, b=inM, sel=instruction[12], out=aluY);

    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,
        out=outM,
        zr=zr,
        ng=ng);

    //M bisschen dest
    And(a=isC, b=instruction[3], out=writeM);

    //Sprungberechnung
    Not(in=zr, out=notZr);
    Not(in=ng, out=notNg);
    And(a=notZr, b=notNg, out=positive);

    And(a=instruction[0], b=positive, out=jgt);
    And(a=instruction[1], b=zr, out=jeq);
    And(a=instruction[2], b=ng, out=jlt);

    Or(a=jgt, b=jeq, out=jump1);
    Or(a=jump1, b=jlt, out=jumpCond);
    And(a=isC, b=jumpCond, out=pcLoad);

    PC(in=aOut, load=pcLoad, inc=true, reset=reset, out[0..14]=pc);
}
// Computer
//Eingabe: Zurücksetzen
//Ausgabe: Keine
//Bewegung:
//Anweisungen von ROM32K lesen,
//CPU liest und schreibt Speicher,
//Der PC bestimmt die nächste Befehlsadresse

CHIP Computer {
    IN reset;

    PARTS:
    ROM32K(address=pc, out=instruction);
    CPU(inM=memOut, instruction=instruction, reset=reset,
        outM=outM, writeM=writeM, addressM=addressM, pc=pc);
    Memory(in=outM, load=writeM, address=addressM, out=memOut);
}