# From Nand to Tetris(Nand2tetris) Project 5

1. Instruction. CPU can take address instruction and computing instruction, so how do we distinguish them? Remember all the instructions, data, or label are all represented by a 16 bit binary number. Noam and Shimon decided to use the first bit from left to right to represent the type of instruction. If the first bit is zero then it’s an address instruction, otherwise it’s a computing instruction. For example:
`0000 0000 0000 0001 will be translated into @1, this is an A-instruction.1000 0000 0000 0001 will be translated into D&A;JGT, and this is a C-instruction.`
1. outM: the result of the previous cycle of computation.
2. writeM: the load bit deciding whether we write to RAM or not.
3. addressM: the location of the the RAM slot that we want to write to.
4. PC: program counter, it could take a 16 bit data as input, and it has 3 load bits: inc, reset, load. this PC register is deciding which line of code to process, and if we reset the PC, all the program will be terminated and we are back to line 0.
`CHIP CPU {     IN  inM[16],         // M value input  (M = contents of RAM[A])     instruction[16], // Instruction for execution     reset;           // Signals whether to re-start     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:     //ARegister     Not(in=instruction[15], out=aload);     And(a=instruction[15], b=instruction[5], out=instructionloadA);     /** the first bit(instruction[15] and d1(instruction[5] is deciding whether we save the value to A-Regis, if the first bit is 1 and instruction[5] is 1, we are going to save the output to A-Register, because in the instruction, d1(instruction[5]) is deciding where to store value's when it is a C-Instruction. if the first bit is 0, no matter what, we will save the input to A-Register.*/     Or(a=aload, b=instructionloadA, out=aregload);     ARegister(in=mux1out, load=aregload, out=aregisterout, out[0..14]=addressM);     //DRegister     And(a=instruction[15], b=instruction[4], out=dregload);     /** only if the first bit is 1, and d2(instruction[4] is 1, then we save to D register */     DRegister(in=aluOut, load=dregload, out=alux);     //Mux1: the reason why we need this is for situations like A=A+1, to make it simple I'm testing to see if aload decide the output of Mux1, if Aload=1 means this is an A-instruction, then we will save this value into our a-register, if it is a c instruction, we will use our previous alu output.     //*************** REMEMBER: if it's not an A-instruction, we should never let the Mux's sel to take in the value of the instruction.*/     Mux16(a=aluOut, b=instruction, sel=aload, out=mux1out);     //Mux2     And(a=instruction[15], b=instruction[12], out=mux2load);     /** only if both of the first bit and the "a" bit is 1, then we start to use the value we get from M, otherwise we will work on A */     Mux16(a=aregisterout, b=inM, sel=mux2load, out=aluy);     //ALU     /** the load bit of the ALU is decided by instruction[6..11] */     /** I have to say that this design is really elegant, we have two numbers, how could the ALU output 1? well, first, it turns both input into 0, and negate them on the bit level, so both of them will be 1111 1111 1111 1111, and then add them up, we will get a 1111 1111 1111 1110, then we negate it again on the bit level, then we get 0000 0000 0000 0001, which is 1, this is awesome*/     ALU(x=alux, 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);     //PC     /** Program Counter is deciding where to jump to */     /** if the j bits(instruction[0..2]) are not 000, we should start to manipulate the PC's load bits */     Jmp(in=instruction, ng=ng, zr=zr, load=pcload, inc=inc);     PC(in=aregisterout, load=pcload, inc=inc, reset=reset,   out[0..14]=pc);     //WriteM     And(a=instruction[3], b=instruction[15], out=writeM);}CHIP Jmp {     IN  in[16], zr, ng;     OUT load, inc;     PARTS:     Not(in=ng, out=notng);     Not(in=zr, out=notzr);     //remember notng is not equal to pos!!!     And(a=notng, b=notzr, out=pos);     And(a=in[0], b=pos, out=checkpositive);     And(a=in[1], b=zr, out=checkzero);     And(a=in[2], b=ng, out=checknegative);     Or(a=checkpositive, b=checkzero, out=positiveorzero);     Or(a=positiveorzero, b=checknegative, out=preload);     And(a=in[15], b=preload, out=notinc, out=load);     Not(in=notinc, out=inc);     /** if the load bit is zero, then inc is 1, else, inc is 0 */}After we understand the CPU, let's look at the full picture. `

--

--

--

## More from Yizhe Wang

Designer transforming into a developer

Love podcasts or audiobooks? Learn on the go with our new app.

## Yizhe Wang

Designer transforming into a developer