1
+ // This file is part of www.nand2tetris.org
2
+ // and the book "The Elements of Computing Systems"
3
+ // by Nisan and Schocken, MIT Press.
4
+ // File name: projects/05/CPU.hdl
5
+
6
+ /**
7
+ * The Hack CPU (Central Processing unit), consisting of an ALU,
8
+ * two registers named A and D, and a program counter named PC.
9
+ * The CPU is designed to fetch and execute instructions written in
10
+ * the Hack machine language. In particular, functions as follows:
11
+ * Executes the inputted instruction according to the Hack machine
12
+ * language specification. The D and A in the language specification
13
+ * refer to CPU-resident registers, while M refers to the external
14
+ * memory location addressed by A, i.e. to Memory[A]. The inM input
15
+ * holds the value of this location. If the current instruction needs
16
+ * to write a value to M, the value is placed in outM, the address
17
+ * of the target location is placed in the addressM output, and the
18
+ * writeM control bit is asserted. (When writeM==0, any value may
19
+ * appear in outM). The outM and writeM outputs are combinational:
20
+ * they are affected instantaneously by the execution of the current
21
+ * instruction. The addressM and pc outputs are clocked: although they
22
+ * are affected by the execution of the current instruction, they commit
23
+ * to their new values only in the next time step. If reset==1 then the
24
+ * CPU jumps to address 0 (i.e. pc is set to 0 in next time step) rather
25
+ * than to the address resulting from executing the current instruction.
26
+ */
27
+
28
+ CHIP CPU {
29
+
30
+ IN inM[16], // M value input (M = contents of RAM[A])
31
+ instruction[16], // Instruction for execution
32
+ reset; // Signals whether to re-start the current
33
+ // program (reset==1) or continue executing
34
+ // the current program (reset==0).
35
+
36
+ OUT outM[16], // M value output
37
+ writeM, // Write to M?
38
+ addressM[15], // Address in data memory (of M)
39
+ pc[15]; // address of next instruction
40
+
41
+ PARTS:
42
+ // Put your code here:
43
+ And(a=instruction[15], b=instruction[15], out=isC);
44
+ Not(in=instruction[15], out=isA);
45
+
46
+ // For Cinstruction, if d1==1, means set Aregister as the destination of cmp which is result of ALU, then load it in ARegister
47
+ And(a=isC, b=instruction[5], out=aluout2A);
48
+ Mux16(a=instruction, b=aluout, sel=aluout2A, out=inAReg);
49
+
50
+ // if AReg needs to be load, load it
51
+ Or(a=isA, b=aluout2A, out=loadAReg);
52
+ ARegister(in=inAReg, load=loadAReg, out=ARegout, out[0..14]=addressM);
53
+
54
+ // define 1 input of ALU
55
+ And(a=isC, b=instruction[12], out=aset);
56
+ Mux16(a=ARegout, b=inM, sel=aset, out=aluin1);
57
+
58
+ // whether writeM is set
59
+ And(a=isC, b=instruction[3], out=writeM);
60
+
61
+ // whether write DReg
62
+ And(a=isC, b=instruction[4], out=writeDReg);
63
+ DRegister(in=aluout, load=writeDReg, out=DRegout);
64
+
65
+ And(a = isC, b = instruction[6], out = no);
66
+ And(a = isC, b = instruction[7], out = f);
67
+ And(a = isC, b = instruction[8], out = ny);
68
+ And(a = isC, b = instruction[9], out = zy);
69
+ And(a = isC, b = instruction[10], out = nx);
70
+ And(a = isC, b = instruction[11], out = zx);
71
+
72
+ ALU(x = DRegout, y = aluin1, zx = zx, nx = nx, zy = zy, ny = ny, f = f, no = no, out = aluout, out = outM, zr=zr, ng=ng);
73
+
74
+ And(a=isC, b=instruction[0], out=GT);
75
+ And(a=isC, b=instruction[1], out=EQ);
76
+ And(a=isC, b=instruction[2], out=LT);
77
+
78
+ And(a=ng, b=LT, out=LTJump);
79
+ And(a=zr, b=EQ, out=EQJump);
80
+
81
+ // output > 0
82
+ Not(in = ng, out = notNg);
83
+ Not(in = zr, out = notZr);
84
+ And(a = notNg, b = notZr, out = outGT);
85
+
86
+ And(a=outGT, b=GT, out=GTJump);
87
+
88
+ Or(a=LTJump, b=EQJump, out=jump0);
89
+ Or(a=jump0, b=GTJump, out=jump);
90
+
91
+ PC(in=ARegout, load=jump, inc=true, reset=reset, out[0..14]=pc);
92
+
93
+ }
0 commit comments