[05/CPU] Implements most of the CPU

This includes:

- Handling of data i/o (for A/D/M)
- Handling the ALU properly (all 28 computations)
- Basic incremental PC (i/o)
- PC reset
- read/write to M

What's missing:

- Handling jumps
This commit is contained in:
Nemo 2020-05-28 19:58:12 +05:30
parent 69a32190dc
commit e7d72b1020
2 changed files with 117 additions and 17 deletions

View File

@ -6,23 +6,23 @@
/**
* 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 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
* 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.
* 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 {
@ -34,10 +34,85 @@ CHIP CPU {
// the current program (reset==0).
OUT outM[16], // M value output
writeM, // Write to M?
writeM, // Write to M?
addressM[15], // Address in data memory (of M)
pc[15]; // address of next instruction
PARTS:
// Put your code here:
}
// instructions[15] = instructionC
// Specifically, when C instruction
// instruction[14] = 1
// instruction[13] = 1
// instruction[12] = a
// instruction[11] = c1
// instruction[10] = c2
// instruction[9] = c3
// instruction[8] = c4
// instruction[7] = c5
// instruction[6] = c6
// instruction[5] = d1
// instruction[4] = d2
// instruction[3] = d3
// instruction[2] = j1
// instruction[1] = j2
// instruction[0] = j3
// we write to A based on the following truth table
// i[15] = true = instruction =C
// i[5] = true = d1 = true = write ALU output to register A
// i[15] | i[5] | write?| t1
// 0 | 0 | 1 | 1
// 0 | 1 | 1 | 1
// 1 | 0 | 0 | 1
// 1 | 1 | 1 | 0
Nand(a=instruction[15], b=instruction[5], out=t1);
Nand(a=t1, b=instruction[15], out=writeA);
// But the input to registerA is picked b/w instruction[0..14] | aluoutput
// depending on instructionA
// registerAInput = {
// [0, instruction[0..14]] if instruction[15] = 0
// aluoutput if instruction[15] = 1
// }
Mux16(a[15]=false,
a[0..14]=instruction[0..14],
b=aluoutput,
sel=instruction[15],
out=registerAInput);
// Register A
ARegister(in=registerAInput,
load=writeA,
out=registerA, out[0..14]=addressM);
// Register D (instruction[4] = d2)
DRegister(in=aluoutput, load=instruction[4], out=registerD);
// TODO: support jumps
PC(in=registerA, load=false, inc=true, reset=reset, out[0..14]=pc);
// the "a" bit = instruction[12] decides whether Y = registerA | inM
Mux16(a=registerA, b=inM, sel=instruction[12], out=y);
ALU(x=registerD,
y=y,
// control bits start
zx=instruction[11],
nx=instruction[10],
zy=instruction[9],
ny=instruction[8],
f=instruction[7],
no=instruction[6],
// control bits end
out=aluoutput,
out=outM,
zr=zr, ng=ng);
// if we are on instruction C, and d3 is true
And(a=instruction[3], b=instruction[15], out=writeM);
}

25
projects/05/CPU.out Normal file
View File

@ -0,0 +1,25 @@
|time| inM | instruction |reset| outM |writeM |addre| pc |DRegiste|
|0+ | 0|0011000000111001| 0 | 0| 0 | 0| 0| 0 |
|1 | 0|0011000000111001| 0 | 0| 0 |12345| 1| 0 |
|1+ | 0|1110110000010000| 0 | 12345| 0 |12345| 1| 12345 |
|2 | 0|1110110000010000| 0 | 12345| 0 |12345| 2| 12345 |
|2+ | 0|0101101110100000| 0 | -1| 0 |12345| 2| 12345 |
|3 | 0|0101101110100000| 0 | -1| 0 |23456| 3| 12345 |
|3+ | 0|1110000111010000| 0 | 11111| 0 |23456| 3| 11111 |
|4 | 0|1110000111010000| 0 | 12345| 0 |23456| 4| 11111 |
|4+ | 0|0000001111101000| 0 | -11111| 0 |23456| 4| 11111 |
|5 | 0|0000001111101000| 0 | -11111| 0 | 1000| 5| 11111 |
|5+ | 0|1110001100001000| 0 | 11111| 1 | 1000| 5| 11111 |
|6 | 0|1110001100001000| 0 | 11111| 1 | 1000| 6| 11111 |
|6+ | 0|0000001111101001| 0 | -11111| 0 | 1000| 6| 11111 |
|7 | 0|0000001111101001| 0 | -11111| 0 | 1001| 7| 11111 |
|7+ | 0|1110001110011000| 0 | 11110| 1 | 1001| 7| 11110 |
|8 | 0|1110001110011000| 0 | 11109| 1 | 1001| 8| 11110 |
|8+ | 0|0000001111101000| 0 | -11110| 0 | 1001| 8| 11110 |
|9 | 0|0000001111101000| 0 | -11110| 0 | 1000| 9| 11110 |
|9+ | 11111|1111010011010000| 0 | -1| 0 | 1000| 9| -1 |
|10 | 11111|1111010011010000| 0 | -11112| 0 | 1000| 10| -1 |
|10+ | 11111|0000000000001110| 0 | 1000| 0 | 1000| 10| -1 |
|11 | 11111|0000000000001110| 0 | 14| 0 | 14| 11| -1 |
|11+ | 11111|1110001100000100| 0 | -1| 0 | 14| 11| -1 |
|12 | 11111|1110001100000100| 0 | -1| 0 | 14| 12| -1 |