// This file is part of www.nand2tetris.org // and the book "The Elements of Computing Systems" // by Nisan and Schocken, MIT Press. // File name: projects/5/CPU.hdl /** * The Hack Central Processing unit (CPU). * Parses the binary code in the instruction input and executes it according to the * Hack machine language specification. In the case of a C-instruction, computes the * function specified by the instruction. If the instruction specifies to read a memory * value, the inM input is expected to contain this value. If the instruction specifies * to write a value to the memory, sets the outM output to this value, sets the addressM * output to the target address, and asserts the writeM output (when writeM = 0, any * value may appear in outM). * If the reset input is 0, computes the address of the next instruction and sets the * pc output to that value. If the reset input is 1, sets pc to 0. * Note: The outM and writeM outputs are combinational: they are affected by the * instruction's execution during the current cycle. The addressM and pc outputs are * clocked: although they are affected by the instruction's execution, they commit to * their new values only in the next cycle. */ CHIP CPU { IN inM[16], // M value input (M = contents of RAM[A]) instruction[16], // Instruction for execution reset; // Signals whether to re-start the current // program (reset==1) or continue executing // the current program (reset==0). OUT outM[16], // M value output writeM, // Write to M? addressM[15], // Address in data memory (of M) pc[15]; // address of next instruction PARTS: Not(in=instruction[15], out=ai); Not(in=ai, out=ci); And(a=ci, b=instruction[5], out=wa); Mux16(a=instruction, b=alu, sel=wa, out=a); Or(a=ai, b=wa, out=la); ARegister(in=a, load=la, out=ao); Mux16(a=ao, b=inM, sel=instruction[12], out=am); And(a=ci, b=instruction[4], out=ld); DRegister(in=alu, load=ld, out=do); ALU(x=do, y=am, zx=instruction[11], nx=instruction[10], zy=instruction[9], ny=instruction[8], f=instruction[7], no=instruction[6], out=alu, zr=zr, ng=ng); Or16(a=false, b=ao, out[0..14]=addressM); Or16(a=false, b=alu, out=outM); And(a=ci, b=instruction[3], out=writeM); And(a=zr, b=instruction[1], out=jeq); And(a=ng, b=instruction[2], out=jlt); Or(a=zr, b=ng, out=zon); Not(in=zon, out=p); And(a=p, b=instruction[0], out=jgt); Or(a=jeq, b=jlt, out=jle); Or(a=jle, b=jgt, out=j); And(a=ci, b=j, out=l); Not(in=l, out=i); PC(in=ao, inc=i, load=l, reset=reset, out[0..14]=pc); }