project05: base files

This commit is contained in:
2025-09-10 15:49:03 -04:00
parent e21e7d0d55
commit 1bc427b545
9 changed files with 705 additions and 0 deletions

161
05/CPU-external.tst Normal file
View File

@@ -0,0 +1,161 @@
// 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/5/CPU-external.tst
// Tests the CPU by setting the instruction input to various binary values that
// code Hack instructions, and outputting the values of the registers that are
// supposed to be affected by the instructions.
load CPU.hdl,
output-file CPU-external.out,
compare-to CPU-external.cmp,
// Tracks the time, the CPU inputs (inM, instruction, reset bit), and the CPU
// outputs (outM, writeM bit, address, pc).
output-list time%S1.3.1 inM%D0.6.0 instruction%B0.16.0 reset%B2.1.2 outM%D1.6.0 writeM%B3.1.2 addressM%D1.5.1 pc%D0.5.0;
set instruction %B0011000000111001, // @12345
tick, output, tock, output;
set instruction %B1110110000010000, // D=A
tick, output, tock, output;
set instruction %B0101101110100000, // @23456
tick, output, tock, output;
set instruction %B1110000111110000, // AD=A-D
tick, output, tock, output;
set instruction %B0000001111101011, // @1003
tick, output, tock, output;
set instruction %B1110001100001000, // M=D
tick, output, tock, output;
set instruction %B0000001111101100, // @1004
tick, output, tock, output;
set instruction %B1110001110011000, // MD=D-1
tick, output, tock, output;
set instruction %B0000001111101000, // @1000
tick, output, tock, output;
set instruction %B1111010011110000, // AD=D-M
set inM 11111,
tick, output, tock, output;
set instruction %B0000000000001110, // @14
tick, output, tock, output;
set instruction %B1110001100000100, // D;jlt
tick, output, tock, output;
set instruction %B0000001111100111, // @999
tick, output, tock, output;
set instruction %B1111110111100000, // A=M+1
tick, output, tock, output;
set instruction %B1110001100101000, // AM=D
tick, output, tock, output;
set instruction %B0000000000010101, // @21
tick, output, tock, output;
set instruction %B1110011111000010, // D+1;jeq
tick, output, tock, output;
set instruction %B0000000000000010, // @2
tick, output, tock, output;
set instruction %B1110000010111000, // AMD=D+A
tick, output, tock, output;
set instruction %B1111110111001000, // M=M+1
tick, output, tock, output;
set instruction %B1111110010101000, // AM=M-1
tick, output, tock, output;
set instruction %B0000001111101000, // @1000
tick, output, tock, output;
set instruction %B1110111010010000, // D=-1
tick, output, tock, output;
set instruction %B1110001100000001, // D;JGT
tick, output, tock, output;
set instruction %B1110001100000010, // D;JEQ
tick, output, tock, output;
set instruction %B1110001100000011, // D;JGE
tick, output, tock, output;
set instruction %B1110001100000100, // D;JLT
tick, output, tock, output;
set instruction %B1110001100000101, // D;JNE
tick, output, tock, output;
set instruction %B1110001100000110, // D;JLE
tick, output, tock, output;
set instruction %B1110001100000111, // D;JMP
tick, output, tock, output;
set instruction %B1110101010010000, // D=0
tick, output, tock, output;
set instruction %B1110001100000001, // D;JGT
tick, output, tock, output;
set instruction %B1110001100000010, // D;JEQ
tick, output, tock, output;
set instruction %B1110001100000011, // D;JGE
tick, output, tock, output;
set instruction %B1110001100000100, // D;JLT
tick, output, tock, output;
set instruction %B1110001100000101, // D;JNE
tick, output, tock, output;
set instruction %B1110001100000110, // D;JLE
tick, output, tock, output;
set instruction %B1110001100000111, // D;JMP
tick, output, tock, output;
set instruction %B1110111111010000, // D=1
tick, output, tock, output;
set instruction %B1110001100000001, // D;JGT
tick, output, tock, output;
set instruction %B1110001100000010, // D;JEQ
tick, output, tock, output;
set instruction %B1110001100000011, // D;JGE
tick, output, tock, output;
set instruction %B1110001100000100, // D;JLT
tick, output, tock, output;
set instruction %B1110001100000101, // D;JNE
tick, output, tock, output;
set instruction %B1110001100000110, // D;JLE
tick, output, tock, output;
set instruction %B1110001100000111, // D;JMP
tick, output, tock, output;
set reset 1;
tick, output, tock, output;
set instruction %B0111111111111111, // @32767
set reset 0;
tick, output, tock, output;

36
05/CPU.hdl Normal file
View File

@@ -0,0 +1,36 @@
// 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/5/CPU.hdl
/**
* The Hack Central Processing unit (CPU).
* Parses the binary code in the instruction input and executes it according to the
* Hack machine language specification. In the case of a C-instruction, computes the
* function specified by the instruction. If the instruction specifies to read a memory
* value, the inM input is expected to contain this value. If the instruction specifies
* to write a value to the memory, sets the outM output to this value, sets the addressM
* output to the target address, and asserts the writeM output (when writeM = 0, any
* value may appear in outM).
* If the reset input is 0, computes the address of the next instruction and sets the
* pc output to that value. If the reset input is 1, sets pc to 0.
* Note: The outM and writeM outputs are combinational: they are affected by the
* instruction's execution during the current cycle. The addressM and pc outputs are
* clocked: although they are affected by the instruction's execution, they commit to
* their new values only in the next cycle.
*/
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:
//// Replace this comment with your code.
}

161
05/CPU.tst Normal file
View File

@@ -0,0 +1,161 @@
// 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/5/CPU.tst
// Tests the CPU by setting the instruction input to various binary values that
// code Hack instructions, and outputting the values of the registers that are
// supposed to be affected by the instructions.
load CPU.hdl,
output-file CPU.out,
compare-to CPU.cmp,
// Tracks the time, the CPU inputs (inM, instruction, reset bit), the CPU
// outputs (outM, writeM bit, address, pc), and the value of the D-register.
output-list time%S1.3.1 inM%D0.6.0 instruction%B0.16.0 reset%B2.1.2 outM%D1.6.0 writeM%B3.1.2 addressM%D1.5.1 pc%D0.5.0 DRegister[]%D1.7.1;
set instruction %B0011000000111001, // @12345
tick, output, tock, output;
set instruction %B1110110000010000, // D=A
tick, output, tock, output;
set instruction %B0101101110100000, // @23456
tick, output, tock, output;
set instruction %B1110000111110000, // AD=A-D
tick, output, tock, output;
set instruction %B0000001111101011, // @1003
tick, output, tock, output;
set instruction %B1110001100001000, // M=D
tick, output, tock, output;
set instruction %B0000001111101100, // @1004
tick, output, tock, output;
set instruction %B1110001110011000, // MD=D-1
tick, output, tock, output;
set instruction %B0000001111101000, // @1000
tick, output, tock, output;
set instruction %B1111010011110000, // AD=D-M
set inM 11111,
tick, output, tock, output;
set instruction %B0000000000001110, // @14
tick, output, tock, output;
set instruction %B1110001100000100, // D;jlt
tick, output, tock, output;
set instruction %B0000001111100111, // @999
tick, output, tock, output;
set instruction %B1111110111100000, // A=M+1
tick, output, tock, output;
set instruction %B1110001100101000, // AM=D
tick, output, tock, output;
set instruction %B0000000000010101, // @21
tick, output, tock, output;
set instruction %B1110011111000010, // D+1;jeq
tick, output, tock, output;
set instruction %B0000000000000010, // @2
tick, output, tock, output;
set instruction %B1110000010111000, // AMD=D+A
tick, output, tock, output;
set instruction %B1111110111001000, // M=M+1
tick, output, tock, output;
set instruction %B1111110010101000, // AM=M-1
tick, output, tock, output;
set instruction %B0000001111101000, // @1000
tick, output, tock, output;
set instruction %B1110111010010000, // D=-1
tick, output, tock, output;
set instruction %B1110001100000001, // D;JGT
tick, output, tock, output;
set instruction %B1110001100000010, // D;JEQ
tick, output, tock, output;
set instruction %B1110001100000011, // D;JGE
tick, output, tock, output;
set instruction %B1110001100000100, // D;JLT
tick, output, tock, output;
set instruction %B1110001100000101, // D;JNE
tick, output, tock, output;
set instruction %B1110001100000110, // D;JLE
tick, output, tock, output;
set instruction %B1110001100000111, // D;JMP
tick, output, tock, output;
set instruction %B1110101010010000, // D=0
tick, output, tock, output;
set instruction %B1110001100000001, // D;JGT
tick, output, tock, output;
set instruction %B1110001100000010, // D;JEQ
tick, output, tock, output;
set instruction %B1110001100000011, // D;JGE
tick, output, tock, output;
set instruction %B1110001100000100, // D;JLT
tick, output, tock, output;
set instruction %B1110001100000101, // D;JNE
tick, output, tock, output;
set instruction %B1110001100000110, // D;JLE
tick, output, tock, output;
set instruction %B1110001100000111, // D;JMP
tick, output, tock, output;
set instruction %B1110111111010000, // D=1
tick, output, tock, output;
set instruction %B1110001100000001, // D;JGT
tick, output, tock, output;
set instruction %B1110001100000010, // D;JEQ
tick, output, tock, output;
set instruction %B1110001100000011, // D;JGE
tick, output, tock, output;
set instruction %B1110001100000100, // D;JLT
tick, output, tock, output;
set instruction %B1110001100000101, // D;JNE
tick, output, tock, output;
set instruction %B1110001100000110, // D;JLE
tick, output, tock, output;
set instruction %B1110001100000111, // D;JMP
tick, output, tock, output;
set reset 1;
tick, output, tock, output;
set instruction %B0111111111111111, // @32767
set reset 0;
tick, output, tock, output;

22
05/Computer.hdl Normal file
View File

@@ -0,0 +1,22 @@
// 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/5/Computer.hdl
/**
* The Hack computer, consisting of CPU, ROM and RAM.
* When reset = 0, the program stored in the ROM executes.
* When reset = 1, the program's execution restarts.
* Thus, to start running the currently loaded program,
* set reset to 1, and then set it to 0.
* From this point onwards, the user is at the mercy of the software.
* Depending on the program's code, and whether the code is correct,
* the screen may show some output, the user may be expected to enter
* some input using the keyboard, or the program may do some procerssing.
*/
CHIP Computer {
IN reset;
PARTS:
//// Replace this comment with your code.
}

35
05/ComputerAdd.tst Normal file
View File

@@ -0,0 +1,35 @@
// 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/5/ComputerAdd.tst
// Tests the Computer chip by having it execute the program Add.hack.
// The program adds up the constants 2 and 3 and writes the result in RAM[0].
load Computer.hdl,
output-file ComputerAdd.out,
compare-to ComputerAdd.cmp,
// Tracks the values of the time, reset bit, A-register, D-register,
// program counter, R0, R1, and R2.
output-list time%S1.3.1 reset%B2.1.2 ARegister[0]%D1.7.1 DRegister[0]%D1.7.1 PC[]%D0.4.0 RAM16K[0]%D1.7.1 RAM16K[1]%D1.7.1 RAM16K[2]%D1.7.1;
// Loads the binary program Add.hack into the computer's instruction memory
ROM32K load Add.hack,
output;
// First run (at the beginning PC=0)
repeat 6 {
tick, tock, output;
}
// Resets the PC
set reset 1,
set RAM16K[0] 0,
tick, tock, output;
// Second run, to check that the PC was reset correctly.
set reset 0,
repeat 6 {
tick, tock, output;
}

41
05/ComputerMax.tst Normal file
View File

@@ -0,0 +1,41 @@
// 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/5/ComputerMax.tst
// Tests the Computer chip by having it execute the program Max.hack.
// The program computes maximum(R0, R1) and writes the result in RAM[2].
load Computer.hdl,
output-file ComputerMax.out,
compare-to ComputerMax.cmp,
// Tracks the values of the time, reset bit, A-register, D-register,
// program counter, R0, R1, and R2.
output-list time%S1.3.1 reset%B2.1.2 ARegister[]%D1.7.1 DRegister[]%D1.7.1 PC[]%D0.4.0 RAM16K[0]%D1.7.1 RAM16K[1]%D1.7.1 RAM16K[2]%D1.7.1;
// Loads the binary program Add.hack into the computer's instruction memory
ROM32K load Max.hack,
// first run: computes max(3,5)
set RAM16K[0] 3,
set RAM16K[1] 5,
output;
repeat 14 {
tick, tock, output;
}
// resets the PC
set reset 1,
tick, tock, output;
// second run: computes max(23456,12345)
set reset 0,
set RAM16K[0] 23456,
set RAM16K[1] 12345,
output;
// The run on these inputs requires less cycles (different branching)
repeat 10 {
tick, tock, output;
}

29
05/ComputerRect.tst Normal file
View File

@@ -0,0 +1,29 @@
// 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/5/ComputerRect.tst
// Tests the Computer chip by having it execute the program Rect.hack.
// The program draws a rectangle of width 16 pixels and length RAM[0]
// at the top left corner of the screen.
load Computer.hdl,
output-file ComputerRect.out,
compare-to ComputerRect.cmp,
// Tracks the values of the time, A-register, D-register, program counter, R0, R1, and R2.
output-list time%S1.3.1 ARegister[]%D1.7.1 DRegister[]%D1.7.1 PC[]%D0.4.0 RAM16K[0]%D1.7.1 RAM16K[1]%D1.7.1 RAM16K[2]%D1.7.1;
// Loads the binary program Rect.hack into the computer's instruction memory
ROM32K load Rect.hack,
echo "Before you run this script, select the 'Screen' option from the 'View' menu";
echo "A small rectangle should be drawn at the top left of the screen (the 'Screen' option of the 'View' menu should be selected.)";
// Draws a rectangle consisting of 4 rows (each 16 pixels wide)
set RAM16K[0] 4,
output;
repeat 63 {
tick, tock, output;
}

29
05/Memory.hdl Normal file
View File

@@ -0,0 +1,29 @@
// 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/5/Memory.hdl
/**
* The complete address space of the Hack computer's memory,
* including RAM and memory-mapped I/O.
* The chip facilitates read and write operations, as follows:
* Read: out(t) = Memory[address(t)](t)
* Write: if load(t-1) then Memory[address(t-1)](t) = in(t-1)
* In words: the chip always outputs the value stored at the memory
* location specified by address. If load=1, the in value is loaded
* into the memory location specified by address. This value becomes
* available through the out output from the next time step onward.
* Address space rules:
* Only the upper 16K+8K+1 words of the Memory chip are used.
* Access to address>0x6000 is invalid. Access to any address in
* the range 0x4000-0x5FFF results in accessing the screen memory
* map. Access to address 0x6000 results in accessing the keyboard
* memory map. The behavior in these addresses is described in the Screen
* and Keyboard chip specifications given in the lectures and the book.
*/
CHIP Memory {
IN in[16], load, address[15];
OUT out[16];
PARTS:
//// Replace this comment with your code.
}

191
05/Memory.tst Normal file
View File

@@ -0,0 +1,191 @@
// 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/Memory.tst
// Tests the Memory chip by inputting values to selected addresses,
// verifying that these addresses were indeed written to, and verifying
// that other addresses were not accessed by mistake. In particular, we
// focus on probing the registers in addresses 'lower RAM', 'upper RAM',
// and 'Screen', which correspond to 0, %X2000, and %X4000 in Hexadecimal
// (0, 8192 (8K), and 16385 (16K+1) in decimal).
load Memory.hdl,
output-file Memory.out,
compare-to Memory.cmp,
output-list in%D1.6.1 load%B2.1.2 address%B1.15.1 out%D1.6.1;
echo "Before you run this script, select the 'Screen' option from the 'View' menu";
// We've noticed a common design mistake in several students' Memory.hdl files.
// This error leads to zeros being written in the offset of inactive memory segments
// instead of the intended location. To identify this issue, the test should check not
// only for incorrect writes into the wrong segment but also for any unexpected changes.
// To prepare for this, we've initialized the memory with a specific number in the areas
// where these erroneous writes might happen.
//// Sets RAM[2000], RAM[4000] = 12345 (for the following overwrite test)
set in 12345, set load 1, set address %X2000, tick, output; tock, output;
set address %X4000, tick, output; tock, output;
set in -1, // Sets RAM[0] = -1
set load 1,
set address 0,
tick,
output;
tock,
output;
set in 9999, // RAM[0] holds value
set load 0,
tick,
output;
tock,
output;
set address %X2000, // Did not also write to upper RAM or Screen
eval,
output;
set address %X4000,
eval,
output;
//// Sets RAM[0], RAM[4000] = 12345 (for following overwrite test)
set in 12345, set load 1, set address %X0000, tick, output; tock, output;
set address %X4000, tick, output; tock, output;
set in 2222, // Sets RAM[2000] = 2222
set load 1,
set address %X2000,
tick,
output;
tock,
output;
set in 9999, // RAM[2000] holds value
set load 0,
tick,
output;
tock,
output;
set address 0, // Did not also write to lower RAM or Screen
eval,
output;
set address %X4000,
eval,
output;
set load 0, // Low order address bits connected
set address %X0001, eval, output;
set address %X0002, eval, output;
set address %X0004, eval, output;
set address %X0008, eval, output;
set address %X0010, eval, output;
set address %X0020, eval, output;
set address %X0040, eval, output;
set address %X0080, eval, output;
set address %X0100, eval, output;
set address %X0200, eval, output;
set address %X0400, eval, output;
set address %X0800, eval, output;
set address %X1000, eval, output;
set address %X2000, eval, output;
set address %X1234, // RAM[1234] = 1234
set in 1234,
set load 1,
tick,
output;
tock,
output;
set load 0,
set address %X2234, // Did not also write to upper RAM or Screen
eval, output;
set address %X6234,
eval, output;
set address %X2345, // RAM[2345] = 2345
set in 2345,
set load 1,
tick,
output;
tock,
output;
set load 0,
set address %X0345, // Did not also write to lower RAM or Screen
eval, output;
set address %X4345,
eval, output;
//// Clears the overwrite detection value from the screen
set in 0, set load 1, set address %X4000, tick, output; tock, output;
// Keyboard test
set address 24576,
echo "Click the Keyboard icon and hold down the 'K' key (uppercase) until you see the next message...",
// It's important to keep holding the key down since if the system is busy,
// the memory will zero itself before being outputted.
while out <> 75 {
tick, tock, // tick, tock prevents hang if sync. parts used in KB path.
}
clear-echo,
output;
// Screen test
//// Sets RAM[0FCF], RAM[2FCF] = 12345 (for following overwrite test)
set in 12345, set load 1, set address %X0FCF, tick, output; tock, output;
set address %X2FCF, tick, output; tock, output;
set load 1,
set in -1,
set address %X4FCF,
tick,
tock,
output,
set address %X504F,
tick,
tock,
output;
set address %X0FCF, // Did not also write to lower or upper RAM
eval,
output;
set address %X2FCF,
eval,
output;
set load 0, // Low order address bits connected
set address %X4FCE, eval, output;
set address %X4FCD, eval, output;
set address %X4FCB, eval, output;
set address %X4FC7, eval, output;
set address %X4FDF, eval, output;
set address %X4FEF, eval, output;
set address %X4F8F, eval, output;
set address %X4F4F, eval, output;
set address %X4ECF, eval, output;
set address %X4DCF, eval, output;
set address %X4BCF, eval, output;
set address %X47CF, eval, output;
set address %X5FCF, eval, output;
set load 0,
set address 24576,
echo "Two horizontal lines should be in the middle of the screen. Hold down 'Y' (uppercase) until you see the next message ...",
// It's important to keep holding the key down since if the system is busy,
// the memory will zero itself before being outputted.
while out <> 89 {
tick, tock, // tick, tock prevents hang if sync. parts used in KB path.
}
clear-echo,
output;