CHIP CPU { IN inM[16], instruction[16], reset; OUT outM[16], writeM, addressM[15], pc[15]; PARTS: Or(a=instruction[15], b=false, out=isCInstruction); Not(in=instruction[15], out=isAInstruction); And(a=isCInstruction, b=instruction[5], out=isCWriteA); Or(a=isAInstruction, b=isCWriteA, out=loadA); Mux16(a=instruction, b=outALU, sel=isCWriteA, out=inAReg); ARegister(in=inAReg, load=loadA, out=outAreg, out[0..14]=addressM); And(a=isCInstruction, b=instruction[4], out=loadD); DRegister(in=outALU, load=loadD, out=outDReg); Mux16(a=outAreg, b=inM, sel=instruction[12], out=outAorM); ALU( x=outDReg, y=outAorM, zx=instruction[11], nx=instruction[10], zy=instruction[9], ny=instruction[8], f=instruction[7], no=instruction[6], out=outALU, out=outM, zr=isZeroOut, ng=isNegOut ); Not(in=isNegOut, out=isNonNeg); Not(in=isZeroOut, out=isNonZero); And(a=isNonNeg, b=isNonZero, out=isPositive); And(a=isCInstruction, b=instruction[3], out=writeM); And(a=isPositive, b=instruction[0], out=JGT); And(a=isZeroOut, b=instruction[1], out=JEQ); And(a=isNegOut, b=instruction[2], out=JLT); Or(a=JEQ, b=JLT, out=JLE); Or(a=JLE, b=JGT, out=jumpToA); And(a=isCInstruction, b=jumpToA, out=loadPC); Not(in=loadPC, out=PCinc); PC( in=outAreg, inc=PCinc, load=loadPC, reset=reset, out[0..14]=pc ); } CHIP Memory { IN in[16], load, address[15]; OUT out[16]; PARTS: DMux4Way(in=load, sel=address[13..14], a=selRam1, b=selRam2, c=selScreen, d=selKbd); Or(a=selRam1, b=selRam2, out=selRam); RAM16K(in=in, load=selRam, address=address[0..13], out=outRam); Screen(in=in, load=selScreen, address=address[0..12], out=outScreen); Keyboard(out=outKbd); Mux4Way16( a=outRam, b=outRam, c=outScreen, d=outKbd, sel=address[13..14], out=out ); } 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 ); } CHIP Bit { IN in, load; OUT out; PARTS: Mux(a=dffOut, b=in, sel=load, out=muxOut); DFF(in=muxOut, out=dffOut); Or(a=false, b=dffOut, out=out); // } CHIP PC { IN in[16],load,inc,reset; OUT out[16]; PARTS: Inc16(in=regOutput, out=regOutputInc); Mux16(a=regOutput, b=regOutputInc, sel=inc, out=out1); Mux16(a=out1, b=in, sel=load, out=out2); Mux16(a=out2, b=false, sel=reset, out=regInput); // load == load OR inc OR reset !!! Or(a=load, b=inc, out=loadOrInc); Or(a=loadOrInc, b=reset, out=loadOrIncOrReset); Register(in=regInput, load=loadOrIncOrReset, out=regOutput); Or16(a=false, b=regOutput, out=out); // dummy OR gate for output } CHIP RAM8 { IN in[16], load, address[3]; OUT out[16]; // 8 registers PARTS: DMux8Way(in=load, sel=address, a=sel0, b=sel1, c=sel2, d=sel3, e=sel4, f=sel5, g=sel6, h=sel7 ); Register(in=in, load=sel0, out=r0); Register(in=in, load=sel1, out=r1); Register(in=in, load=sel2, out=r2); Register(in=in, load=sel3, out=r3); Register(in=in, load=sel4, out=r4); Register(in=in, load=sel5, out=r5); Register(in=in, load=sel6, out=r6); Register(in=in, load=sel7, out=r7); Mux8Way16( a=r0, b=r1, c=r2, d=r3, e=r4, f=r5, g=r6, h=r7, sel=address, out=out); } CHIP RAM64 { IN in[16], load, address[6]; OUT out[16]; PARTS: // 0..2 - low bits select the register, 3..5 select the bank (one of RAM8 chips) DMux8Way(in=load, sel=address[3..5], a=sel0, b=sel1, c=sel2, d=sel3, e=sel4, f=sel5, g=sel6, h=sel7 ); RAM8(in=in, load=sel0, address=address[0..2], out=r0); RAM8(in=in, load=sel1, address=address[0..2], out=r1); RAM8(in=in, load=sel2, address=address[0..2], out=r2); RAM8(in=in, load=sel3, address=address[0..2], out=r3); RAM8(in=in, load=sel4, address=address[0..2], out=r4); RAM8(in=in, load=sel5, address=address[0..2], out=r5); RAM8(in=in, load=sel6, address=address[0..2], out=r6); RAM8(in=in, load=sel7, address=address[0..2], out=r7); Mux8Way16( a=r0, b=r1, c=r2, d=r3, e=r4, f=r5, g=r6, h=r7, sel=address[3..5], out=out); } CHIP Register { IN in[16], load; OUT out[16]; PARTS: Bit(in=in[0], load=load, out=out[0]); Bit(in=in[1], load=load, out=out[1]); Bit(in=in[2], load=load, out=out[2]); Bit(in=in[3], load=load, out=out[3]); Bit(in=in[4], load=load, out=out[4]); Bit(in=in[5], load=load, out=out[5]); Bit(in=in[6], load=load, out=out[6]); Bit(in=in[7], load=load, out=out[7]); Bit(in=in[8], load=load, out=out[8]); Bit(in=in[9], load=load, out=out[9]); Bit(in=in[10], load=load, out=out[10]); Bit(in=in[11], load=load, out=out[11]); Bit(in=in[12], load=load, out=out[12]); Bit(in=in[13], load=load, out=out[13]); Bit(in=in[14], load=load, out=out[14]); Bit(in=in[15], load=load, out=out[15]); } CHIP RAM4K { IN in[16], load, address[12]; OUT out[16]; PARTS: DMux8Way(in=load, sel=address[9..11], a=sel0, b=sel1, c=sel2, d=sel3, e=sel4, f=sel5, g=sel6, h=sel7 ); RAM512(in=in, load=sel0, address=address[0..8], out=r0); RAM512(in=in, load=sel1, address=address[0..8], out=r1); RAM512(in=in, load=sel2, address=address[0..8], out=r2); RAM512(in=in, load=sel3, address=address[0..8], out=r3); RAM512(in=in, load=sel4, address=address[0..8], out=r4); RAM512(in=in, load=sel5, address=address[0..8], out=r5); RAM512(in=in, load=sel6, address=address[0..8], out=r6); RAM512(in=in, load=sel7, address=address[0..8], out=r7); Mux8Way16( a=r0, b=r1, c=r2, d=r3, e=r4, f=r5, g=r6, h=r7, sel=address[9..11], out=out); } CHIP RAM16K { IN in[16], load, address[14]; OUT out[16]; PARTS: DMux4Way(in=load, sel=address[12..13], a=sel0, b=sel1, c=sel2, d=sel3 ); RAM4K(in=in, load=sel0, address=address[0..11], out=r0); RAM4K(in=in, load=sel1, address=address[0..11], out=r1); RAM4K(in=in, load=sel2, address=address[0..11], out=r2); RAM4K(in=in, load=sel3, address=address[0..11], out=r3); Mux4Way16( a=r0, b=r1, c=r2, d=r3, sel=address[12..13], out=out); } CHIP RAM512 { IN in[16], load, address[9]; OUT out[16]; PARTS: DMux8Way(in=load, sel=address[6..8], a=sel0, b=sel1, c=sel2, d=sel3, e=sel4, f=sel5, g=sel6, h=sel7 ); RAM64(in=in, load=sel0, address=address[0..5], out=r0); RAM64(in=in, load=sel1, address=address[0..5], out=r1); RAM64(in=in, load=sel2, address=address[0..5], out=r2); RAM64(in=in, load=sel3, address=address[0..5], out=r3); RAM64(in=in, load=sel4, address=address[0..5], out=r4); RAM64(in=in, load=sel5, address=address[0..5], out=r5); RAM64(in=in, load=sel6, address=address[0..5], out=r6); RAM64(in=in, load=sel7, address=address[0..5], out=r7); Mux8Way16( a=r0, b=r1, c=r2, d=r3, e=r4, f=r5, g=r6, h=r7, sel=address[6..8], out=out); }