|
// 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/05/CPU.hdl
/**
* The Hack CPU (Central Processing unit), consisting of an ALU,
* two registers named A and D, and a program counter named PC.
* The CPU is designed to fetch and execute instructions written in
* the Hack machine language. In particular, functions as follows:
* Executes the inputted instruction according to the Hack machine
* language specification. The D and A in the language specification
* refer to CPU-resident registers, while M refers to the external
* memory location addressed by A, i.e. to Memory[A]. The inM input
* holds the value of this location. If the current instruction needs
* to write a value to M, the value is placed in outM, the address
* of the target location is placed in the addressM output, and the
* writeM control bit is asserted. (When writeM==0, any value may
* appear in outM). The outM and writeM outputs are combinational:
* they are affected instantaneously by the execution of the current
* instruction. The addressM and pc outputs are clocked: although they
* are affected by the execution of the current instruction, they commit
* to their new values only in the next time step. If reset==1 then the
* CPU jumps to address 0 (i.e. pc is set to 0 in next time step) rather
* than to the address resulting from executing the current instruction.
*/
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:
// Put your code here:
And(a=instruction[15],b=instruction[3],out=writeM); //1
//ARegister
Not(in=instruction[15],out=nTout); //2
Or(a=nTout,b=instruction[5],out=loadA); //3
Mux16(a=instruction,b=ALUout,sel=instruction[15],out=ARegin);
ARegister(in=ARegin,load=loadA,out=ARegout,out[15]=t1,out[14]=addressM[14],out[13]=addressM[13],out[12]=addressM[12],out[11]=addressM[11],out[10]=addressM[10],out[9]=addressM[9],out[8]=addressM[8],out[7]=addressM[7],out[6]=addressM[6],out[5]=addressM[5],out[4]=addressM[4],out[3]=addressM[3],out[2]=addressM[2],out[1]=addressM[1],out[0]=addressM[0]);
//DRegister
And(a=instruction[15],b=instruction[4],out=loadD); //4
DRegister(in=ALUout,load=loadD,out=DRegout);
Mux16(a=ARegout,b=inM,sel=instruction[12],out=inMout);
ALU(x=DRegout,y=inMout,zx=instruction[11],nx=instruction[10],zy=instruction[9],ny=instruction[8],f=instruction[7],no=instruction[6],out=ALUout,zr=zr1,ng=ng1);
Not16(in=ALUout,out=nALUout); //5
Not16(in=nALUout,out=outM); //6
And(a=instruction[1],b=zr1,out=and1); //7
And(a=instruction[2],b=ng1,out=and2); //8
Not(in=zr1,out=nzr1); //9
Not(in=ng1,out=nng1); //10
And(a=instruction[0],b=nzr1,out=and3); //11
And(a=and3,b=nng1,out=and4); //12
And(a=instruction[2],b=instruction[1],out=and5); //13
And(a=instruction[0],b=and5,out=and6); //14
Or(a=and1,b=and2,out=or1); //15
Or(a=and4,b=and6,out=or2); //16
Or(a=or1,b=or2,out=loadPC); //17
Not(in=loadPC,out=incrPC); //18
PC(in=ARegout,load=loadPC,inc=incrPC,reset=reset,out[15]=t2,out[14]=pc[14],out[13]=pc[13],out[12]=pc[12],out[11]=pc[11],out[10]=pc[10],out[9]=pc[9],out[8]=pc[8],out[7]=pc[7],out[6]=pc[6],out[5]=pc[5],out[4]=pc[4],out[3]=pc[3],out[2]=pc[2],out[1]=pc[1],out[0]=pc[0]);
}
|