├── 0-Xor ├── .gitignore ├── tb │ ├── Not.cmp │ ├── Nand.cmp │ ├── And.cmp │ ├── Or.cmp │ ├── Xor.cmp │ ├── Not_tb.v │ ├── And_tb.v │ ├── Nand_tb.v │ ├── Or_tb.v │ └── Xor_tb.v ├── Not.v ├── And.v ├── Nand.v ├── Or.v ├── Xor.v ├── Makefile └── Readme.md ├── 1-ALU ├── .gitignore ├── img │ └── ALU.png ├── tb │ ├── Or8Way.cmp │ ├── HalfAdder.cmp │ ├── Not16.cmp │ ├── Mux.cmp │ ├── FullAdder.cmp │ ├── Add16.cmp │ ├── And16.cmp │ ├── Mux16.cmp │ ├── Or8Way_tb.v │ ├── Not16_tb.v │ ├── HalfAdder_tb.v │ ├── Mux_tb.v │ ├── FullAdder_tb.v │ ├── Add16_tb.v │ ├── And16_tb.v │ ├── Mux16_tb.v │ ├── ALU.cmp │ └── ALU_tb.v ├── Not.v ├── And.v ├── Nand.v ├── Or.v ├── HalfAdder.v ├── Xor.v ├── Or8Way.v ├── FullAdder.v ├── Mux.v ├── Not16.v ├── And16.v ├── Mux16.v ├── Add16.v ├── Readme.md ├── Makefile └── ALU.v ├── 2-CPU ├── .gitignore ├── img │ └── CPU.png ├── Not.v ├── And.v ├── Nand.v ├── Or.v ├── HalfAdder.v ├── Makefile ├── Xor.v ├── Or8Way.v ├── FullAdder.v ├── Mux.v ├── Not16.v ├── And16.v ├── Mux16.v ├── Add16.v ├── ALU.v ├── CPU.v ├── Readme.md └── tb │ ├── CPU.cmp │ └── CPU_tb.v ├── 3-Hack ├── .gitignore ├── img │ └── Hack1.png ├── Makefile ├── blinky.asm ├── Not.v ├── blinky.hack ├── And.v ├── Nand.v ├── Or.v ├── HalfAdder.v ├── Xor.v ├── Or8Way.v ├── FullAdder.v ├── ROM.v ├── Mux.v ├── Not16.v ├── Reset.v ├── And16.v ├── Mux16.v ├── Memory.v ├── Add16.v ├── Hack.v ├── ALU.v ├── CPU.v └── Readme.md └── README.md /0-Xor/.gitignore: -------------------------------------------------------------------------------- 1 | *.out 2 | *.vcd -------------------------------------------------------------------------------- /1-ALU/.gitignore: -------------------------------------------------------------------------------- 1 | *.out 2 | *.vcd 3 | .vs/ 4 | -------------------------------------------------------------------------------- /2-CPU/.gitignore: -------------------------------------------------------------------------------- 1 | *.out 2 | *.vcd 3 | .vs/ 4 | -------------------------------------------------------------------------------- /3-Hack/.gitignore: -------------------------------------------------------------------------------- 1 | *.out 2 | *.vcd 3 | .vs/ 4 | -------------------------------------------------------------------------------- /0-Xor/tb/Not.cmp: -------------------------------------------------------------------------------- 1 | | in | out | 2 | | 0 | 1 | 3 | | 1 | 0 | 4 | -------------------------------------------------------------------------------- /1-ALU/img/ALU.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wuhanstudio/nand2tetris-iverilog/HEAD/1-ALU/img/ALU.png -------------------------------------------------------------------------------- /2-CPU/img/CPU.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wuhanstudio/nand2tetris-iverilog/HEAD/2-CPU/img/CPU.png -------------------------------------------------------------------------------- /0-Xor/tb/Nand.cmp: -------------------------------------------------------------------------------- 1 | | a | b |out| 2 | | 0 | 0 | 1 | 3 | | 0 | 1 | 1 | 4 | | 1 | 0 | 1 | 5 | | 1 | 1 | 0 | 6 | -------------------------------------------------------------------------------- /3-Hack/img/Hack1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wuhanstudio/nand2tetris-iverilog/HEAD/3-Hack/img/Hack1.png -------------------------------------------------------------------------------- /0-Xor/tb/And.cmp: -------------------------------------------------------------------------------- 1 | | a | b | out | 2 | | 0 | 0 | 0 | 3 | | 0 | 1 | 0 | 4 | | 1 | 0 | 0 | 5 | | 1 | 1 | 1 | 6 | -------------------------------------------------------------------------------- /0-Xor/tb/Or.cmp: -------------------------------------------------------------------------------- 1 | | a | b | out | 2 | | 0 | 0 | 0 | 3 | | 0 | 1 | 1 | 4 | | 1 | 0 | 1 | 5 | | 1 | 1 | 1 | 6 | -------------------------------------------------------------------------------- /0-Xor/tb/Xor.cmp: -------------------------------------------------------------------------------- 1 | | a | b | out | 2 | | 0 | 0 | 0 | 3 | | 0 | 1 | 1 | 4 | | 1 | 0 | 1 | 5 | | 1 | 1 | 0 | 6 | -------------------------------------------------------------------------------- /1-ALU/tb/Or8Way.cmp: -------------------------------------------------------------------------------- 1 | | in | out | 2 | | 00000000 | 0 | 3 | | 11111111 | 1 | 4 | | 00010000 | 1 | 5 | | 00000001 | 1 | 6 | | 00100110 | 1 | 7 | -------------------------------------------------------------------------------- /1-ALU/tb/HalfAdder.cmp: -------------------------------------------------------------------------------- 1 | | a | b | sum | carry | 2 | | 0 | 0 | 0 | 0 | 3 | | 0 | 1 | 1 | 0 | 4 | | 1 | 0 | 1 | 0 | 5 | | 1 | 1 | 0 | 1 | 6 | -------------------------------------------------------------------------------- /3-Hack/Makefile: -------------------------------------------------------------------------------- 1 | 2 | all Hack_test.out: 3 | iverilog -o Hack_test.out *.v 4 | 5 | run Hack_tb.vcd: Hack_test.out 6 | vvp Hack_test.out 7 | 8 | sim: Hack_tb.vcd 9 | gtkwave Hack_tb.vcd 10 | 11 | clean: 12 | rm -f *.out *.vcd -------------------------------------------------------------------------------- /3-Hack/blinky.asm: -------------------------------------------------------------------------------- 1 | @0 2 | (LOOP) 3 | @100 4 | D=A 5 | @0 6 | M=D 7 | (WAIT2) 8 | D=0 9 | (WAIT) 10 | @WAIT 11 | D=D+1 12 | D;JNE 13 | @0 14 | MD=M-1 15 | @WAIT2 16 | D;JNE 17 | 18 | @8192 //write LED 19 | M=M+1 20 | 21 | @LOOP 22 | 0;JMP 23 | -------------------------------------------------------------------------------- /1-ALU/tb/Not16.cmp: -------------------------------------------------------------------------------- 1 | | in | out | 2 | | 0000000000000000 | 1111111111111111 | 3 | | 1111111111111111 | 0000000000000000 | 4 | | 1010101010101010 | 0101010101010101 | 5 | | 0011110011000011 | 1100001100111100 | 6 | | 0001001000110100 | 1110110111001011 | 7 | -------------------------------------------------------------------------------- /0-Xor/Not.v: -------------------------------------------------------------------------------- 1 | /** 2 | * Not gate: 3 | * out = not in 4 | */ 5 | `default_nettype none 6 | 7 | module Not( 8 | input wire in, 9 | output wire out 10 | ); 11 | 12 | // your implementation comes here: 13 | 14 | Nand Nand_1(in, in, out); 15 | 16 | endmodule 17 | -------------------------------------------------------------------------------- /1-ALU/Not.v: -------------------------------------------------------------------------------- 1 | /** 2 | * Not gate: 3 | * out = not in 4 | */ 5 | `default_nettype none 6 | 7 | module Not( 8 | input wire in, 9 | output wire out 10 | ); 11 | 12 | // your implementation comes here: 13 | 14 | Nand Nand_1(in, in, out); 15 | 16 | endmodule 17 | -------------------------------------------------------------------------------- /2-CPU/Not.v: -------------------------------------------------------------------------------- 1 | /** 2 | * Not gate: 3 | * out = not in 4 | */ 5 | `default_nettype none 6 | 7 | module Not( 8 | input wire in, 9 | output wire out 10 | ); 11 | 12 | // your implementation comes here: 13 | 14 | Nand Nand_1(in, in, out); 15 | 16 | endmodule 17 | -------------------------------------------------------------------------------- /3-Hack/Not.v: -------------------------------------------------------------------------------- 1 | /** 2 | * Not gate: 3 | * out = not in 4 | */ 5 | `default_nettype none 6 | 7 | module Not( 8 | input wire in, 9 | output wire out 10 | ); 11 | 12 | // your implementation comes here: 13 | 14 | Nand Nand_1(in, in, out); 15 | 16 | endmodule 17 | -------------------------------------------------------------------------------- /1-ALU/tb/Mux.cmp: -------------------------------------------------------------------------------- 1 | | a | b | sel | out | 2 | | 0 | 0 | 0 | 0 | 3 | | 0 | 0 | 1 | 0 | 4 | | 0 | 1 | 0 | 0 | 5 | | 0 | 1 | 1 | 1 | 6 | | 1 | 0 | 0 | 1 | 7 | | 1 | 0 | 1 | 0 | 8 | | 1 | 1 | 0 | 1 | 9 | | 1 | 1 | 1 | 1 | 10 | -------------------------------------------------------------------------------- /3-Hack/blinky.hack: -------------------------------------------------------------------------------- 1 | 0000000000000000 2 | 0000000001100100 3 | 1110110000010000 4 | 0000000000000000 5 | 1110001100001000 6 | 1110101010010000 7 | 0000000000000110 8 | 1110011111010000 9 | 1110001100000101 10 | 0000000000000000 11 | 1111110010011000 12 | 0000000000000101 13 | 1110001100000101 14 | 0010000000000000 15 | 1111110111001000 16 | 0000000000000001 17 | 1110101010000111 18 | 19 | -------------------------------------------------------------------------------- /0-Xor/And.v: -------------------------------------------------------------------------------- 1 | /** 2 | * And gate: 3 | * out = 1 if (a == 1 and b == 1) 4 | * 0 otherwise 5 | */ 6 | 7 | `default_nettype none 8 | 9 | module And( 10 | input wire a, 11 | input wire b, 12 | output wire out 13 | ); 14 | 15 | // your implementation comes here: 16 | 17 | wire n_out; 18 | 19 | nand(n_out, a, b); 20 | nand(out, n_out, n_out); 21 | 22 | endmodule 23 | -------------------------------------------------------------------------------- /1-ALU/And.v: -------------------------------------------------------------------------------- 1 | /** 2 | * And gate: 3 | * out = 1 if (a == 1 and b == 1) 4 | * 0 otherwise 5 | */ 6 | 7 | `default_nettype none 8 | 9 | module And( 10 | input wire a, 11 | input wire b, 12 | output wire out 13 | ); 14 | 15 | // your implementation comes here: 16 | 17 | wire n_out; 18 | 19 | nand(n_out, a, b); 20 | nand(out, n_out, n_out); 21 | 22 | endmodule 23 | -------------------------------------------------------------------------------- /2-CPU/And.v: -------------------------------------------------------------------------------- 1 | /** 2 | * And gate: 3 | * out = 1 if (a == 1 and b == 1) 4 | * 0 otherwise 5 | */ 6 | 7 | `default_nettype none 8 | 9 | module And( 10 | input wire a, 11 | input wire b, 12 | output wire out 13 | ); 14 | 15 | // your implementation comes here: 16 | 17 | wire n_out; 18 | 19 | nand(n_out, a, b); 20 | nand(out, n_out, n_out); 21 | 22 | endmodule 23 | -------------------------------------------------------------------------------- /3-Hack/And.v: -------------------------------------------------------------------------------- 1 | /** 2 | * And gate: 3 | * out = 1 if (a == 1 and b == 1) 4 | * 0 otherwise 5 | */ 6 | 7 | `default_nettype none 8 | 9 | module And( 10 | input wire a, 11 | input wire b, 12 | output wire out 13 | ); 14 | 15 | // your implementation comes here: 16 | 17 | wire n_out; 18 | 19 | nand(n_out, a, b); 20 | nand(out, n_out, n_out); 21 | 22 | endmodule 23 | -------------------------------------------------------------------------------- /0-Xor/Nand.v: -------------------------------------------------------------------------------- 1 | /** 2 | * Nand gate: 3 | * out = 0 if (a == 1 and b == 1) 4 | * 1 otherwise 5 | * 6 | * This module is implemented using verilog primitives 7 | */ 8 | 9 | `default_nettype none 10 | 11 | module Nand( 12 | input wire a, 13 | input wire b, 14 | output wire out 15 | ); 16 | 17 | // your implementation comes here: 18 | 19 | nand(out,a,b); 20 | 21 | endmodule 22 | -------------------------------------------------------------------------------- /1-ALU/Nand.v: -------------------------------------------------------------------------------- 1 | /** 2 | * Nand gate: 3 | * out = 0 if (a == 1 and b == 1) 4 | * 1 otherwise 5 | * 6 | * This module is implemented using verilog primitives 7 | */ 8 | 9 | `default_nettype none 10 | 11 | module Nand( 12 | input wire a, 13 | input wire b, 14 | output wire out 15 | ); 16 | 17 | // your implementation comes here: 18 | 19 | nand(out,a,b); 20 | 21 | endmodule 22 | -------------------------------------------------------------------------------- /2-CPU/Nand.v: -------------------------------------------------------------------------------- 1 | /** 2 | * Nand gate: 3 | * out = 0 if (a == 1 and b == 1) 4 | * 1 otherwise 5 | * 6 | * This module is implemented using verilog primitives 7 | */ 8 | 9 | `default_nettype none 10 | 11 | module Nand( 12 | input wire a, 13 | input wire b, 14 | output wire out 15 | ); 16 | 17 | // your implementation comes here: 18 | 19 | nand(out,a,b); 20 | 21 | endmodule 22 | -------------------------------------------------------------------------------- /0-Xor/Or.v: -------------------------------------------------------------------------------- 1 | /** 2 | * Or gate: 3 | * out = 1 if (a == 1 or b == 1) 4 | * 0 otherwise 5 | */ 6 | `default_nettype none 7 | 8 | module Or( 9 | input wire a, 10 | input wire b, 11 | output wire out 12 | ); 13 | 14 | // your implementation comes here: 15 | 16 | wire n_a, n_b; 17 | 18 | Not not_a(a, n_a); 19 | Not not_b(b, n_b); 20 | Nand Nand_1(n_a, n_b, out); 21 | 22 | endmodule 23 | -------------------------------------------------------------------------------- /1-ALU/Or.v: -------------------------------------------------------------------------------- 1 | /** 2 | * Or gate: 3 | * out = 1 if (a == 1 or b == 1) 4 | * 0 otherwise 5 | */ 6 | `default_nettype none 7 | 8 | module Or( 9 | input wire a, 10 | input wire b, 11 | output wire out 12 | ); 13 | 14 | // your implementation comes here: 15 | 16 | wire n_a, n_b; 17 | 18 | Not not_a(a, n_a); 19 | Not not_b(b, n_b); 20 | Nand Nand_1(n_a, n_b, out); 21 | 22 | endmodule 23 | -------------------------------------------------------------------------------- /2-CPU/Or.v: -------------------------------------------------------------------------------- 1 | /** 2 | * Or gate: 3 | * out = 1 if (a == 1 or b == 1) 4 | * 0 otherwise 5 | */ 6 | `default_nettype none 7 | 8 | module Or( 9 | input wire a, 10 | input wire b, 11 | output wire out 12 | ); 13 | 14 | // your implementation comes here: 15 | 16 | wire n_a, n_b; 17 | 18 | Not not_a(a, n_a); 19 | Not not_b(b, n_b); 20 | Nand Nand_1(n_a, n_b, out); 21 | 22 | endmodule 23 | -------------------------------------------------------------------------------- /3-Hack/Nand.v: -------------------------------------------------------------------------------- 1 | /** 2 | * Nand gate: 3 | * out = 0 if (a == 1 and b == 1) 4 | * 1 otherwise 5 | * 6 | * This module is implemented using verilog primitives 7 | */ 8 | 9 | `default_nettype none 10 | 11 | module Nand( 12 | input wire a, 13 | input wire b, 14 | output wire out 15 | ); 16 | 17 | // your implementation comes here: 18 | 19 | nand(out,a,b); 20 | 21 | endmodule 22 | -------------------------------------------------------------------------------- /3-Hack/Or.v: -------------------------------------------------------------------------------- 1 | /** 2 | * Or gate: 3 | * out = 1 if (a == 1 or b == 1) 4 | * 0 otherwise 5 | */ 6 | `default_nettype none 7 | 8 | module Or( 9 | input wire a, 10 | input wire b, 11 | output wire out 12 | ); 13 | 14 | // your implementation comes here: 15 | 16 | wire n_a, n_b; 17 | 18 | Not not_a(a, n_a); 19 | Not not_b(b, n_b); 20 | Nand Nand_1(n_a, n_b, out); 21 | 22 | endmodule 23 | -------------------------------------------------------------------------------- /1-ALU/tb/FullAdder.cmp: -------------------------------------------------------------------------------- 1 | | a | b | c | sum | carry | 2 | | 0 | 0 | 0 | 0 | 0 | 3 | | 0 | 0 | 1 | 1 | 0 | 4 | | 0 | 1 | 0 | 1 | 0 | 5 | | 0 | 1 | 1 | 0 | 1 | 6 | | 1 | 0 | 0 | 1 | 0 | 7 | | 1 | 0 | 1 | 0 | 1 | 8 | | 1 | 1 | 0 | 0 | 1 | 9 | | 1 | 1 | 1 | 1 | 1 | 10 | -------------------------------------------------------------------------------- /1-ALU/HalfAdder.v: -------------------------------------------------------------------------------- 1 | /** 2 | * Computes the sum of two bits. 3 | */ 4 | `default_nettype none 5 | module HalfAdder( 6 | input wire a, //1-bit input 7 | input wire b, //1-bit inpur 8 | output wire sum, //Right bit of a + b 9 | output wire carry //Lef bit of a + b 10 | ); 11 | 12 | // your implementation comes here: 13 | 14 | Xor Xor_1(a, b, sum); 15 | And And_1(a, b, carry); 16 | 17 | endmodule 18 | -------------------------------------------------------------------------------- /1-ALU/tb/Add16.cmp: -------------------------------------------------------------------------------- 1 | | a | b | out | 2 | | 0000000000000000 | 0000000000000000 | 0000000000000000 | 3 | | 0000000000000000 | 1111111111111111 | 1111111111111111 | 4 | | 1111111111111111 | 1111111111111111 | 1111111111111110 | 5 | | 1010101010101010 | 0101010101010101 | 1111111111111111 | 6 | | 0011110011000011 | 0000111111110000 | 0100110010110011 | 7 | | 0001001000110100 | 1001100001110110 | 1010101010101010 | 8 | -------------------------------------------------------------------------------- /1-ALU/tb/And16.cmp: -------------------------------------------------------------------------------- 1 | | a | b | out | 2 | | 0000000000000000 | 0000000000000000 | 0000000000000000 | 3 | | 0000000000000000 | 1111111111111111 | 0000000000000000 | 4 | | 1111111111111111 | 1111111111111111 | 1111111111111111 | 5 | | 1010101010101010 | 0101010101010101 | 0000000000000000 | 6 | | 0011110011000011 | 0000111111110000 | 0000110011000000 | 7 | | 0001001000110100 | 1001100001110110 | 0001000000110100 | 8 | -------------------------------------------------------------------------------- /2-CPU/HalfAdder.v: -------------------------------------------------------------------------------- 1 | /** 2 | * Computes the sum of two bits. 3 | */ 4 | `default_nettype none 5 | module HalfAdder( 6 | input wire a, //1-bit input 7 | input wire b, //1-bit inpur 8 | output wire sum, //Right bit of a + b 9 | output wire carry //Lef bit of a + b 10 | ); 11 | 12 | // your implementation comes here: 13 | 14 | Xor Xor_1(a, b, sum); 15 | And And_1(a, b, carry); 16 | 17 | endmodule 18 | -------------------------------------------------------------------------------- /3-Hack/HalfAdder.v: -------------------------------------------------------------------------------- 1 | /** 2 | * Computes the sum of two bits. 3 | */ 4 | `default_nettype none 5 | module HalfAdder( 6 | input wire a, //1-bit input 7 | input wire b, //1-bit inpur 8 | output wire sum, //Right bit of a + b 9 | output wire carry //Lef bit of a + b 10 | ); 11 | 12 | // your implementation comes here: 13 | 14 | Xor Xor_1(a, b, sum); 15 | And And_1(a, b, carry); 16 | 17 | endmodule 18 | -------------------------------------------------------------------------------- /2-CPU/Makefile: -------------------------------------------------------------------------------- 1 | 2 | all CPU_test.out: 3 | iverilog -o CPU_test.out tb/CPU_tb.v *.v 4 | 5 | run CPU_tb.vcd: CPU_test.out 6 | vvp CPU_test.out 7 | 8 | sim: CPU_tb.vcd 9 | gtkwave CPU_tb.vcd 10 | 11 | cpu_test: tb/CPU_tb.v *.v 12 | @iverilog -o CPU_test.out tb/CPU_tb.v *.v 13 | @vvp CPU_test.out 14 | @diff CPU.out tb/CPU.cmp 15 | @echo "--- CPU PASS ---" 16 | 17 | test: cpu_test 18 | @echo "" 19 | @echo "--- ALL PASS ---\n" 20 | 21 | clean: 22 | rm -f *.out *.vcd -------------------------------------------------------------------------------- /0-Xor/Xor.v: -------------------------------------------------------------------------------- 1 | /** 2 | * Exclusive-or gate: 3 | * out = not (a == b) 4 | */ 5 | `default_nettype none 6 | 7 | module Xor( 8 | input wire a, 9 | input wire b, 10 | output wire out 11 | ); 12 | 13 | // your implementation comes here: 14 | 15 | // assign out = a ^ b; 16 | 17 | wire n_a, n_b, n_a_b, n_b_a; 18 | 19 | Not not_a(a, n_a); 20 | Not not_b(b, n_b); 21 | And and_n_a_b(n_a, b, n_a_b); 22 | And and_n_b_a(a, n_b, n_b_a); 23 | Or or_o(n_a_b, n_b_a, out); 24 | 25 | endmodule 26 | -------------------------------------------------------------------------------- /1-ALU/Xor.v: -------------------------------------------------------------------------------- 1 | /** 2 | * Exclusive-or gate: 3 | * out = not (a == b) 4 | */ 5 | `default_nettype none 6 | 7 | module Xor( 8 | input wire a, 9 | input wire b, 10 | output wire out 11 | ); 12 | 13 | // your implementation comes here: 14 | 15 | // assign out = a ^ b; 16 | 17 | wire n_a, n_b, n_a_b, n_b_a; 18 | 19 | Not not_a(a, n_a); 20 | Not not_b(b, n_b); 21 | And and_n_a_b(n_a, b, n_a_b); 22 | And and_n_b_a(a, n_b, n_b_a); 23 | Or or_o(n_a_b, n_b_a, out); 24 | 25 | endmodule 26 | -------------------------------------------------------------------------------- /2-CPU/Xor.v: -------------------------------------------------------------------------------- 1 | /** 2 | * Exclusive-or gate: 3 | * out = not (a == b) 4 | */ 5 | `default_nettype none 6 | 7 | module Xor( 8 | input wire a, 9 | input wire b, 10 | output wire out 11 | ); 12 | 13 | // your implementation comes here: 14 | 15 | // assign out = a ^ b; 16 | 17 | wire n_a, n_b, n_a_b, n_b_a; 18 | 19 | Not not_a(a, n_a); 20 | Not not_b(b, n_b); 21 | And and_n_a_b(n_a, b, n_a_b); 22 | And and_n_b_a(a, n_b, n_b_a); 23 | Or or_o(n_a_b, n_b_a, out); 24 | 25 | endmodule 26 | -------------------------------------------------------------------------------- /3-Hack/Xor.v: -------------------------------------------------------------------------------- 1 | /** 2 | * Exclusive-or gate: 3 | * out = not (a == b) 4 | */ 5 | `default_nettype none 6 | 7 | module Xor( 8 | input wire a, 9 | input wire b, 10 | output wire out 11 | ); 12 | 13 | // your implementation comes here: 14 | 15 | // assign out = a ^ b; 16 | 17 | wire n_a, n_b, n_a_b, n_b_a; 18 | 19 | Not not_a(a, n_a); 20 | Not not_b(b, n_b); 21 | And and_n_a_b(n_a, b, n_a_b); 22 | And and_n_b_a(a, n_b, n_b_a); 23 | Or or_o(n_a_b, n_b_a, out); 24 | 25 | endmodule 26 | -------------------------------------------------------------------------------- /1-ALU/Or8Way.v: -------------------------------------------------------------------------------- 1 | /** 2 | * 8-way Or: 3 | * out = (in[0] or in[1] or ... or in[7]) 4 | */ 5 | `default_nettype none 6 | 7 | module Or8Way( 8 | input wire [7:0] in, 9 | output wire out 10 | ); 11 | 12 | // your implementation comes here: 13 | 14 | wire out0, out1, out2, out3, out4, out5; 15 | 16 | Or Or_0(in[0], in[1], out0); 17 | Or Or_1(out0, in[2], out1); 18 | Or Or_2(out1, in[3], out2); 19 | Or Or_3(out2, in[4], out3); 20 | Or Or_4(out3, in[5], out4); 21 | Or Or_5(out4, in[6], out5); 22 | Or Or_6(out5, in[7], out); 23 | 24 | endmodule 25 | -------------------------------------------------------------------------------- /2-CPU/Or8Way.v: -------------------------------------------------------------------------------- 1 | /** 2 | * 8-way Or: 3 | * out = (in[0] or in[1] or ... or in[7]) 4 | */ 5 | `default_nettype none 6 | 7 | module Or8Way( 8 | input wire [7:0] in, 9 | output wire out 10 | ); 11 | 12 | // your implementation comes here: 13 | 14 | wire out0, out1, out2, out3, out4, out5; 15 | 16 | Or Or_0(in[0], in[1], out0); 17 | Or Or_1(out0, in[2], out1); 18 | Or Or_2(out1, in[3], out2); 19 | Or Or_3(out2, in[4], out3); 20 | Or Or_4(out3, in[5], out4); 21 | Or Or_5(out4, in[6], out5); 22 | Or Or_6(out5, in[7], out); 23 | 24 | endmodule 25 | -------------------------------------------------------------------------------- /3-Hack/Or8Way.v: -------------------------------------------------------------------------------- 1 | /** 2 | * 8-way Or: 3 | * out = (in[0] or in[1] or ... or in[7]) 4 | */ 5 | `default_nettype none 6 | 7 | module Or8Way( 8 | input wire [7:0] in, 9 | output wire out 10 | ); 11 | 12 | // your implementation comes here: 13 | 14 | wire out0, out1, out2, out3, out4, out5; 15 | 16 | Or Or_0(in[0], in[1], out0); 17 | Or Or_1(out0, in[2], out1); 18 | Or Or_2(out1, in[3], out2); 19 | Or Or_3(out2, in[4], out3); 20 | Or Or_4(out3, in[5], out4); 21 | Or Or_5(out4, in[6], out5); 22 | Or Or_6(out5, in[7], out); 23 | 24 | endmodule 25 | -------------------------------------------------------------------------------- /1-ALU/tb/Mux16.cmp: -------------------------------------------------------------------------------- 1 | | a | b | sel | out | 2 | | 0000000000000000 | 0000000000000000 | 0 | 0000000000000000 | 3 | | 0000000000000000 | 0000000000000000 | 1 | 0000000000000000 | 4 | | 0000000000000000 | 0001001000110100 | 0 | 0000000000000000 | 5 | | 0000000000000000 | 0001001000110100 | 1 | 0001001000110100 | 6 | | 1001100001110110 | 0000000000000000 | 0 | 1001100001110110 | 7 | | 1001100001110110 | 0000000000000000 | 1 | 0000000000000000 | 8 | | 1010101010101010 | 0101010101010101 | 0 | 1010101010101010 | 9 | | 1010101010101010 | 0101010101010101 | 1 | 0101010101010101 | 10 | -------------------------------------------------------------------------------- /1-ALU/FullAdder.v: -------------------------------------------------------------------------------- 1 | /** 2 | * Computes the sum of three bits. 3 | */ 4 | `default_nettype none 5 | 6 | module FullAdder( 7 | input wire a, //1-bit input 8 | input wire b, //1-bit input 9 | input wire c, //1-bit input 10 | output wire sum, //Right bit of a + b + c 11 | output wire carry //Left bit of a + b + c 12 | ); 13 | 14 | // your implementation comes here: 15 | 16 | wire sums, carrys, carryss, throw; 17 | 18 | HalfAdder HalfAdder_0(a, b, sums, carrys); 19 | HalfAdder HalfAdde1(sums, c, sum, carryss); 20 | HalfAdder HalfAdde2(carrys, carryss, carry, throw); 21 | 22 | endmodule 23 | -------------------------------------------------------------------------------- /2-CPU/FullAdder.v: -------------------------------------------------------------------------------- 1 | /** 2 | * Computes the sum of three bits. 3 | */ 4 | `default_nettype none 5 | 6 | module FullAdder( 7 | input wire a, //1-bit input 8 | input wire b, //1-bit input 9 | input wire c, //1-bit input 10 | output wire sum, //Right bit of a + b + c 11 | output wire carry //Left bit of a + b + c 12 | ); 13 | 14 | // your implementation comes here: 15 | 16 | wire sums, carrys, carryss, throw; 17 | 18 | HalfAdder HalfAdder_0(a, b, sums, carrys); 19 | HalfAdder HalfAdde1(sums, c, sum, carryss); 20 | HalfAdder HalfAdde2(carrys, carryss, carry, throw); 21 | 22 | endmodule 23 | -------------------------------------------------------------------------------- /3-Hack/FullAdder.v: -------------------------------------------------------------------------------- 1 | /** 2 | * Computes the sum of three bits. 3 | */ 4 | `default_nettype none 5 | 6 | module FullAdder( 7 | input wire a, //1-bit input 8 | input wire b, //1-bit input 9 | input wire c, //1-bit input 10 | output wire sum, //Right bit of a + b + c 11 | output wire carry //Left bit of a + b + c 12 | ); 13 | 14 | // your implementation comes here: 15 | 16 | wire sums, carrys, carryss, throw; 17 | 18 | HalfAdder HalfAdder_0(a, b, sums, carrys); 19 | HalfAdder HalfAdde1(sums, c, sum, carryss); 20 | HalfAdder HalfAdde2(carrys, carryss, carry, throw); 21 | 22 | endmodule 23 | -------------------------------------------------------------------------------- /0-Xor/tb/Not_tb.v: -------------------------------------------------------------------------------- 1 | `default_nettype none 2 | module Not_tb(); 3 | 4 | integer file; 5 | 6 | reg a = 0; 7 | wire out; 8 | 9 | Not Not_1( 10 | .in(a), 11 | .out(out) 12 | ); 13 | 14 | task display; 15 | #1 $fwrite(file, "| %1b | %1b |\n", a, out); 16 | endtask 17 | 18 | initial begin 19 | $dumpfile("Not_tb.vcd"); 20 | $dumpvars(0, Not_tb); 21 | file = $fopen("Not.out","w"); 22 | $fwrite(file, "| in | out |\n"); 23 | 24 | a=0; 25 | display(); 26 | 27 | a=1; 28 | display(); 29 | 30 | $finish(); 31 | end 32 | 33 | endmodule 34 | -------------------------------------------------------------------------------- /3-Hack/ROM.v: -------------------------------------------------------------------------------- 1 | /** 2 | * The module rom provides access to the instruction memory 3 | * of hack. The instruction memory is read only (ROM) and 4 | * preloaded with 4Kx16bit of Hackcode. 5 | * 6 | * The signal data (16bit) provides the instruction at memory address 7 | * data = ROM[address] 8 | */ 9 | 10 | module ROM( 11 | input wire [15:0] address, 12 | output wire [15:0] data 13 | ); 14 | 15 | // your implementation comes here: 16 | 17 | // ROM file of hack 18 | parameter ROMFILE = "./blinky.hack"; 19 | 20 | reg [15:0] regROM [0:1023]; 21 | assign data = regROM[address]; 22 | initial begin 23 | $readmemb(ROMFILE,regROM); 24 | end 25 | 26 | endmodule 27 | -------------------------------------------------------------------------------- /1-ALU/Mux.v: -------------------------------------------------------------------------------- 1 | /** 2 | * Multiplexor: 3 | * out = a if sel == 0 4 | * b otherwise 5 | */ 6 | `default_nettype none 7 | 8 | module Mux( 9 | input wire a, 10 | input wire b, 11 | input wire sel, 12 | output wire out 13 | ); 14 | 15 | // your implementation comes here: 16 | 17 | wire ab, nota, notb, not_sel, b_sel, and2_out, and3_out, and4_out, and5_out, or1_out; 18 | 19 | Not not_1(a, nota); 20 | Not not_2(b, notb); 21 | Not not_3(sel, not_sel); 22 | And and_1(b, sel, b_sel); 23 | And and_2(nota, b_sel, and2_out); 24 | And and_3(a, notb, and3_out); 25 | And and_4(and3_out, not_sel, and4_out); 26 | And and_5(a, b, ab); 27 | Or or_1(and2_out, and4_out, or1_out); 28 | Or or_2(or1_out, ab, out); 29 | 30 | endmodule 31 | -------------------------------------------------------------------------------- /2-CPU/Mux.v: -------------------------------------------------------------------------------- 1 | /** 2 | * Multiplexor: 3 | * out = a if sel == 0 4 | * b otherwise 5 | */ 6 | `default_nettype none 7 | 8 | module Mux( 9 | input wire a, 10 | input wire b, 11 | input wire sel, 12 | output wire out 13 | ); 14 | 15 | // your implementation comes here: 16 | 17 | wire ab, nota, notb, not_sel, b_sel, and2_out, and3_out, and4_out, and5_out, or1_out; 18 | 19 | Not not_1(a, nota); 20 | Not not_2(b, notb); 21 | Not not_3(sel, not_sel); 22 | And and_1(b, sel, b_sel); 23 | And and_2(nota, b_sel, and2_out); 24 | And and_3(a, notb, and3_out); 25 | And and_4(and3_out, not_sel, and4_out); 26 | And and_5(a, b, ab); 27 | Or or_1(and2_out, and4_out, or1_out); 28 | Or or_2(or1_out, ab, out); 29 | 30 | endmodule 31 | -------------------------------------------------------------------------------- /3-Hack/Mux.v: -------------------------------------------------------------------------------- 1 | /** 2 | * Multiplexor: 3 | * out = a if sel == 0 4 | * b otherwise 5 | */ 6 | `default_nettype none 7 | 8 | module Mux( 9 | input wire a, 10 | input wire b, 11 | input wire sel, 12 | output wire out 13 | ); 14 | 15 | // your implementation comes here: 16 | 17 | wire ab, nota, notb, not_sel, b_sel, and2_out, and3_out, and4_out, and5_out, or1_out; 18 | 19 | Not not_1(a, nota); 20 | Not not_2(b, notb); 21 | Not not_3(sel, not_sel); 22 | And and_1(b, sel, b_sel); 23 | And and_2(nota, b_sel, and2_out); 24 | And and_3(a, notb, and3_out); 25 | And and_4(and3_out, not_sel, and4_out); 26 | And and_5(a, b, ab); 27 | Or or_1(and2_out, and4_out, or1_out); 28 | Or or_2(or1_out, ab, out); 29 | 30 | endmodule 31 | -------------------------------------------------------------------------------- /1-ALU/Not16.v: -------------------------------------------------------------------------------- 1 | /** 2 | * 16-bit Not: 3 | * for i=0..15: out[i] = not in[i] 4 | */ 5 | `default_nettype none 6 | 7 | module Not16( 8 | input wire [15:0] in, 9 | output wire [15:0] out 10 | ); 11 | 12 | // your implementation comes here: 13 | 14 | Not Not0(in[0], out[0]); 15 | Not Not1(in[1], out[1]); 16 | Not Not2(in[2], out[2]); 17 | Not Not3(in[3], out[3]); 18 | Not Not4(in[4], out[4]); 19 | Not Not5(in[5], out[5]); 20 | Not Not6(in[6], out[6]); 21 | Not Not7(in[7], out[7]); 22 | Not Not8(in[8], out[8]); 23 | Not Not9(in[9], out[9]); 24 | Not Not10(in[10], out[10]); 25 | Not Not11(in[11], out[11]); 26 | Not Not12(in[12], out[12]); 27 | Not Not13(in[13], out[13]); 28 | Not Not14(in[14], out[14]); 29 | Not Not15(in[15], out[15]); 30 | 31 | endmodule 32 | -------------------------------------------------------------------------------- /2-CPU/Not16.v: -------------------------------------------------------------------------------- 1 | /** 2 | * 16-bit Not: 3 | * for i=0..15: out[i] = not in[i] 4 | */ 5 | `default_nettype none 6 | 7 | module Not16( 8 | input wire [15:0] in, 9 | output wire [15:0] out 10 | ); 11 | 12 | // your implementation comes here: 13 | 14 | Not Not0(in[0], out[0]); 15 | Not Not1(in[1], out[1]); 16 | Not Not2(in[2], out[2]); 17 | Not Not3(in[3], out[3]); 18 | Not Not4(in[4], out[4]); 19 | Not Not5(in[5], out[5]); 20 | Not Not6(in[6], out[6]); 21 | Not Not7(in[7], out[7]); 22 | Not Not8(in[8], out[8]); 23 | Not Not9(in[9], out[9]); 24 | Not Not10(in[10], out[10]); 25 | Not Not11(in[11], out[11]); 26 | Not Not12(in[12], out[12]); 27 | Not Not13(in[13], out[13]); 28 | Not Not14(in[14], out[14]); 29 | Not Not15(in[15], out[15]); 30 | 31 | endmodule 32 | -------------------------------------------------------------------------------- /3-Hack/Not16.v: -------------------------------------------------------------------------------- 1 | /** 2 | * 16-bit Not: 3 | * for i=0..15: out[i] = not in[i] 4 | */ 5 | `default_nettype none 6 | 7 | module Not16( 8 | input wire [15:0] in, 9 | output wire [15:0] out 10 | ); 11 | 12 | // your implementation comes here: 13 | 14 | Not Not0(in[0], out[0]); 15 | Not Not1(in[1], out[1]); 16 | Not Not2(in[2], out[2]); 17 | Not Not3(in[3], out[3]); 18 | Not Not4(in[4], out[4]); 19 | Not Not5(in[5], out[5]); 20 | Not Not6(in[6], out[6]); 21 | Not Not7(in[7], out[7]); 22 | Not Not8(in[8], out[8]); 23 | Not Not9(in[9], out[9]); 24 | Not Not10(in[10], out[10]); 25 | Not Not11(in[11], out[11]); 26 | Not Not12(in[12], out[12]); 27 | Not Not13(in[13], out[13]); 28 | Not Not14(in[14], out[14]); 29 | Not Not15(in[15], out[15]); 30 | 31 | endmodule 32 | -------------------------------------------------------------------------------- /0-Xor/tb/And_tb.v: -------------------------------------------------------------------------------- 1 | `default_nettype none 2 | module And_tb(); 3 | 4 | integer file; 5 | 6 | reg a = 0; 7 | reg b = 0; 8 | wire out; 9 | 10 | And And( 11 | .a(a), 12 | .b(b), 13 | .out(out) 14 | ); 15 | 16 | task display; 17 | #1 $fwrite(file, "| %1b | %1b | %1b |\n", a,b,out); 18 | endtask 19 | 20 | initial begin 21 | $dumpfile("And_tb.vcd"); 22 | $dumpvars(0, And_tb); 23 | file = $fopen("And.out","w"); 24 | $fwrite(file, "| a | b | out |\n"); 25 | 26 | a=0;b=0; 27 | display(); 28 | 29 | a=0;b=1; 30 | display(); 31 | 32 | a=1;b=0; 33 | display(); 34 | 35 | a=1;b=1; 36 | display(); 37 | $finish(); 38 | end 39 | 40 | endmodule 41 | -------------------------------------------------------------------------------- /0-Xor/tb/Nand_tb.v: -------------------------------------------------------------------------------- 1 | `default_nettype none 2 | module Nand_tb(); 3 | 4 | integer file; 5 | 6 | reg a = 0; 7 | reg b = 0; 8 | wire out; 9 | 10 | Nand Nand( 11 | .a(a), 12 | .b(b), 13 | .out(out) 14 | ); 15 | 16 | task display; 17 | #1 $fwrite(file, "| %1b | %1b | %1b |\n", a,b,out); 18 | endtask 19 | 20 | initial begin 21 | $dumpfile("Nand_tb.vcd"); 22 | $dumpvars(0, Nand_tb); 23 | file = $fopen("Nand.out","w"); 24 | $fwrite(file, "| a | b |out|\n"); 25 | 26 | a=0;b=0; 27 | display(); 28 | 29 | a=0;b=1; 30 | display(); 31 | 32 | a=1;b=0; 33 | display(); 34 | 35 | a=1;b=1; 36 | display(); 37 | $finish(); 38 | end 39 | 40 | endmodule 41 | -------------------------------------------------------------------------------- /0-Xor/tb/Or_tb.v: -------------------------------------------------------------------------------- 1 | `default_nettype none 2 | module Or_tb(); 3 | 4 | integer file; 5 | 6 | reg a = 0; 7 | reg b = 0; 8 | wire out; 9 | 10 | Or Or_0( 11 | .a(a), 12 | .b(b), 13 | .out(out) 14 | ); 15 | 16 | task display; 17 | #1 $fwrite(file, "| %1b | %1b | %1b |\n", a,b,out); 18 | endtask 19 | 20 | initial begin 21 | $dumpfile("Or_tb.vcd"); 22 | $dumpvars(0, Or_tb); 23 | file = $fopen("Or.out","w"); 24 | $fwrite(file, "| a | b | out |\n"); 25 | 26 | a=0;b=0; 27 | display(); 28 | 29 | a=0;b=1; 30 | display(); 31 | 32 | a=1;b=0; 33 | display(); 34 | 35 | a=1;b=1; 36 | display(); 37 | $finish(); 38 | end 39 | 40 | endmodule 41 | -------------------------------------------------------------------------------- /0-Xor/tb/Xor_tb.v: -------------------------------------------------------------------------------- 1 | `default_nettype none 2 | module Xor_tb(); 3 | 4 | integer file; 5 | 6 | reg a = 0; 7 | reg b = 0; 8 | wire out; 9 | 10 | Xor Xor_0( 11 | .a(a), 12 | .b(b), 13 | .out(out) 14 | ); 15 | 16 | task display; 17 | #1 $fwrite(file, "| %1b | %1b | %1b |\n", a,b,out); 18 | endtask 19 | 20 | initial begin 21 | $dumpfile("Xor_tb.vcd"); 22 | $dumpvars(0, Xor_tb); 23 | file = $fopen("Xor.out","w"); 24 | $fwrite(file, "| a | b | out |\n"); 25 | 26 | a=0;b=0; 27 | display(); 28 | 29 | a=0;b=1; 30 | display(); 31 | 32 | a=1;b=0; 33 | display(); 34 | 35 | a=1;b=1; 36 | display(); 37 | $finish(); 38 | end 39 | 40 | endmodule 41 | -------------------------------------------------------------------------------- /3-Hack/Reset.v: -------------------------------------------------------------------------------- 1 | /** 2 | * The module rst delivers a reset signal at power up which 3 | * is clocked by clk. 4 | * 5 | * The timing diagram should be: 6 | * ------------------------------------------- 7 | * clk 0 | 1 | 0 | 1 | 0 | 1 | 0 | 1 ... 8 | * ------------------------------------------- 9 | * reset 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 ... 10 | * ------------------------------------------- 11 | */ 12 | 13 | module Reset( 14 | input wire clk, 15 | output wire reset 16 | ); 17 | 18 | // your implementation comes here: 19 | 20 | // remember that you did it 21 | reg done = 0; 22 | always @(posedge clk) 23 | done <= 1; 24 | 25 | // reset it on start 26 | reg reset_r = 0; 27 | always @(posedge clk) begin 28 | if (done==0) reset_r <=1; 29 | else reset_r <= 0; 30 | end 31 | 32 | assign reset = reset_r; 33 | 34 | endmodule 35 | -------------------------------------------------------------------------------- /1-ALU/tb/Or8Way_tb.v: -------------------------------------------------------------------------------- 1 | `default_nettype none 2 | module Or8Way_tb(); 3 | 4 | integer file; 5 | 6 | reg [7:0] in; 7 | wire out; 8 | 9 | Or8Way Or8Way_1( 10 | .in(in), 11 | .out(out) 12 | ); 13 | 14 | task display; 15 | #1 $fwrite(file, "| %1b | %1b |\n", in, out); 16 | endtask 17 | 18 | initial begin 19 | $dumpfile("Or8Way_tb.vcd"); 20 | $dumpvars(0, Or8Way_tb); 21 | file = $fopen("Or8Way.out","w"); 22 | $fwrite(file, "| in | out |\n"); 23 | 24 | in = 8'b00000000; 25 | display(); 26 | 27 | in = 8'b11111111; 28 | display(); 29 | 30 | in = 8'b00010000; 31 | display(); 32 | 33 | in = 8'b00000001; 34 | display(); 35 | 36 | in = 8'b00100110; 37 | display(); 38 | 39 | $finish(); 40 | end 41 | 42 | endmodule 43 | -------------------------------------------------------------------------------- /1-ALU/And16.v: -------------------------------------------------------------------------------- 1 | /** 2 | * 16-bit bitwise And: 3 | * for i = 0..15: out[i] = (a[i] and b[i]) 4 | */ 5 | 6 | `default_nettype none 7 | module And16( 8 | input wire [15:0] a, 9 | input wire [15:0] b, 10 | output wire [15:0] out 11 | ); 12 | 13 | // your implementation comes here: 14 | 15 | And And_0(a[0], b[0], out[0]); 16 | And And_1(a[1], b[1], out[1]); 17 | And And_2(a[2], b[2], out[2]); 18 | And And_3(a[3], b[3], out[3]); 19 | And And_4(a[4], b[4], out[4]); 20 | And And_5(a[5], b[5], out[5]); 21 | And And_6(a[6], b[6], out[6]); 22 | And And_7(a[7], b[7], out[7]); 23 | And And_8(a[8], b[8], out[8]); 24 | And And_9(a[9], b[9], out[9]); 25 | And And_10(a[10], b[10], out[10]); 26 | And And_11(a[11], b[11], out[11]); 27 | And And_12(a[12], b[12], out[12]); 28 | And And_13(a[13], b[13], out[13]); 29 | And And_14(a[14], b[14], out[14]); 30 | And And_15(a[15], b[15], out[15]); 31 | 32 | endmodule 33 | -------------------------------------------------------------------------------- /2-CPU/And16.v: -------------------------------------------------------------------------------- 1 | /** 2 | * 16-bit bitwise And: 3 | * for i = 0..15: out[i] = (a[i] and b[i]) 4 | */ 5 | 6 | `default_nettype none 7 | module And16( 8 | input wire [15:0] a, 9 | input wire [15:0] b, 10 | output wire [15:0] out 11 | ); 12 | 13 | // your implementation comes here: 14 | 15 | And And_0(a[0], b[0], out[0]); 16 | And And_1(a[1], b[1], out[1]); 17 | And And_2(a[2], b[2], out[2]); 18 | And And_3(a[3], b[3], out[3]); 19 | And And_4(a[4], b[4], out[4]); 20 | And And_5(a[5], b[5], out[5]); 21 | And And_6(a[6], b[6], out[6]); 22 | And And_7(a[7], b[7], out[7]); 23 | And And_8(a[8], b[8], out[8]); 24 | And And_9(a[9], b[9], out[9]); 25 | And And_10(a[10], b[10], out[10]); 26 | And And_11(a[11], b[11], out[11]); 27 | And And_12(a[12], b[12], out[12]); 28 | And And_13(a[13], b[13], out[13]); 29 | And And_14(a[14], b[14], out[14]); 30 | And And_15(a[15], b[15], out[15]); 31 | 32 | endmodule 33 | -------------------------------------------------------------------------------- /3-Hack/And16.v: -------------------------------------------------------------------------------- 1 | /** 2 | * 16-bit bitwise And: 3 | * for i = 0..15: out[i] = (a[i] and b[i]) 4 | */ 5 | 6 | `default_nettype none 7 | module And16( 8 | input wire [15:0] a, 9 | input wire [15:0] b, 10 | output wire [15:0] out 11 | ); 12 | 13 | // your implementation comes here: 14 | 15 | And And_0(a[0], b[0], out[0]); 16 | And And_1(a[1], b[1], out[1]); 17 | And And_2(a[2], b[2], out[2]); 18 | And And_3(a[3], b[3], out[3]); 19 | And And_4(a[4], b[4], out[4]); 20 | And And_5(a[5], b[5], out[5]); 21 | And And_6(a[6], b[6], out[6]); 22 | And And_7(a[7], b[7], out[7]); 23 | And And_8(a[8], b[8], out[8]); 24 | And And_9(a[9], b[9], out[9]); 25 | And And_10(a[10], b[10], out[10]); 26 | And And_11(a[11], b[11], out[11]); 27 | And And_12(a[12], b[12], out[12]); 28 | And And_13(a[13], b[13], out[13]); 29 | And And_14(a[14], b[14], out[14]); 30 | And And_15(a[15], b[15], out[15]); 31 | 32 | endmodule 33 | -------------------------------------------------------------------------------- /1-ALU/tb/Not16_tb.v: -------------------------------------------------------------------------------- 1 | `default_nettype none 2 | module Not16_tb(); 3 | 4 | integer file; 5 | 6 | reg [15:0] in; 7 | wire [15:0] out; 8 | 9 | Not16 Not16_1( 10 | .in(in), 11 | .out(out) 12 | ); 13 | 14 | task display; 15 | #1 $fwrite(file, "| %1b | %1b |\n", in, out); 16 | endtask 17 | 18 | initial begin 19 | $dumpfile("Not16_tb.vcd"); 20 | $dumpvars(0, Not16_tb); 21 | file = $fopen("Not16.out","w"); 22 | $fwrite(file, "| in | out |\n"); 23 | 24 | in = 16'b0000000000000000; 25 | display(); 26 | 27 | in = 16'b1111111111111111; 28 | display(); 29 | 30 | in = 16'b1010101010101010; 31 | display(); 32 | 33 | in = 16'b0011110011000011; 34 | display(); 35 | 36 | in = 16'b0001001000110100; 37 | display(); 38 | 39 | $finish(); 40 | end 41 | 42 | endmodule 43 | -------------------------------------------------------------------------------- /1-ALU/tb/HalfAdder_tb.v: -------------------------------------------------------------------------------- 1 | `default_nettype none 2 | module HalfAdder_tb(); 3 | 4 | integer file; 5 | 6 | reg a = 0; 7 | reg b = 0; 8 | wire sum, carry; 9 | 10 | HalfAdder HalfAdder_1( 11 | .a(a), 12 | .b(b), 13 | .sum(sum), 14 | .carry(carry) 15 | ); 16 | 17 | task display; 18 | #1 $fwrite(file, "| %1b | %1b | %1b | %1b |\n", a, b, sum, carry); 19 | endtask 20 | 21 | initial begin 22 | $dumpfile("HalfAdder_tb.vcd"); 23 | $dumpvars(0, HalfAdder_tb); 24 | file = $fopen("HalfAdder.out","w"); 25 | $fwrite(file, "| a | b | sum | carry |\n"); 26 | 27 | a = 0; 28 | display(); 29 | 30 | b = 1; 31 | display(); 32 | 33 | a = 1; 34 | b = 0; 35 | display(); 36 | 37 | a = 1; 38 | b = 1; 39 | display(); 40 | 41 | $finish(); 42 | end 43 | 44 | endmodule 45 | -------------------------------------------------------------------------------- /1-ALU/Mux16.v: -------------------------------------------------------------------------------- 1 | /** 2 | * 16-bit multiplexor: 3 | * for i = 0..15 out[i] = a[i] if sel == 0 4 | * b[i] if sel == 1 5 | */ 6 | `default_nettype none 7 | 8 | module Mux16( 9 | input wire [15:0] a, 10 | input wire [15:0] b, 11 | input wire sel, 12 | output wire [15:0] out 13 | ); 14 | 15 | // your implementation comes here: 16 | 17 | Mux Mux_0(a[0], b[0], sel, out[0]); 18 | Mux Mux_1(a[1], b[1], sel, out[1]); 19 | Mux Mux_2(a[2], b[2], sel, out[2]); 20 | Mux Mux_3(a[3], b[3], sel, out[3]); 21 | Mux Mux_4(a[4], b[4], sel, out[4]); 22 | Mux Mux_5(a[5], b[5], sel, out[5]); 23 | Mux Mux_6(a[6], b[6], sel, out[6]); 24 | Mux Mux_7(a[7], b[7], sel, out[7]); 25 | Mux Mux_8(a[8], b[8], sel, out[8]); 26 | Mux Mux_9(a[9], b[9], sel, out[9]); 27 | Mux Mux_10(a[10], b[10], sel, out[10]); 28 | Mux Mux_11(a[11], b[11], sel, out[11]); 29 | Mux Mux_12(a[12], b[12], sel, out[12]); 30 | Mux Mux_13(a[13], b[13], sel, out[13]); 31 | Mux Mux_14(a[14], b[14], sel, out[14]); 32 | Mux Mux_15(a[15], b[15], sel, out[15]); 33 | 34 | endmodule 35 | -------------------------------------------------------------------------------- /2-CPU/Mux16.v: -------------------------------------------------------------------------------- 1 | /** 2 | * 16-bit multiplexor: 3 | * for i = 0..15 out[i] = a[i] if sel == 0 4 | * b[i] if sel == 1 5 | */ 6 | `default_nettype none 7 | 8 | module Mux16( 9 | input wire [15:0] a, 10 | input wire [15:0] b, 11 | input wire sel, 12 | output wire [15:0] out 13 | ); 14 | 15 | // your implementation comes here: 16 | 17 | Mux Mux_0(a[0], b[0], sel, out[0]); 18 | Mux Mux_1(a[1], b[1], sel, out[1]); 19 | Mux Mux_2(a[2], b[2], sel, out[2]); 20 | Mux Mux_3(a[3], b[3], sel, out[3]); 21 | Mux Mux_4(a[4], b[4], sel, out[4]); 22 | Mux Mux_5(a[5], b[5], sel, out[5]); 23 | Mux Mux_6(a[6], b[6], sel, out[6]); 24 | Mux Mux_7(a[7], b[7], sel, out[7]); 25 | Mux Mux_8(a[8], b[8], sel, out[8]); 26 | Mux Mux_9(a[9], b[9], sel, out[9]); 27 | Mux Mux_10(a[10], b[10], sel, out[10]); 28 | Mux Mux_11(a[11], b[11], sel, out[11]); 29 | Mux Mux_12(a[12], b[12], sel, out[12]); 30 | Mux Mux_13(a[13], b[13], sel, out[13]); 31 | Mux Mux_14(a[14], b[14], sel, out[14]); 32 | Mux Mux_15(a[15], b[15], sel, out[15]); 33 | 34 | endmodule 35 | -------------------------------------------------------------------------------- /3-Hack/Mux16.v: -------------------------------------------------------------------------------- 1 | /** 2 | * 16-bit multiplexor: 3 | * for i = 0..15 out[i] = a[i] if sel == 0 4 | * b[i] if sel == 1 5 | */ 6 | `default_nettype none 7 | 8 | module Mux16( 9 | input wire [15:0] a, 10 | input wire [15:0] b, 11 | input wire sel, 12 | output wire [15:0] out 13 | ); 14 | 15 | // your implementation comes here: 16 | 17 | Mux Mux_0(a[0], b[0], sel, out[0]); 18 | Mux Mux_1(a[1], b[1], sel, out[1]); 19 | Mux Mux_2(a[2], b[2], sel, out[2]); 20 | Mux Mux_3(a[3], b[3], sel, out[3]); 21 | Mux Mux_4(a[4], b[4], sel, out[4]); 22 | Mux Mux_5(a[5], b[5], sel, out[5]); 23 | Mux Mux_6(a[6], b[6], sel, out[6]); 24 | Mux Mux_7(a[7], b[7], sel, out[7]); 25 | Mux Mux_8(a[8], b[8], sel, out[8]); 26 | Mux Mux_9(a[9], b[9], sel, out[9]); 27 | Mux Mux_10(a[10], b[10], sel, out[10]); 28 | Mux Mux_11(a[11], b[11], sel, out[11]); 29 | Mux Mux_12(a[12], b[12], sel, out[12]); 30 | Mux Mux_13(a[13], b[13], sel, out[13]); 31 | Mux Mux_14(a[14], b[14], sel, out[14]); 32 | Mux Mux_15(a[15], b[15], sel, out[15]); 33 | 34 | endmodule 35 | -------------------------------------------------------------------------------- /1-ALU/tb/Mux_tb.v: -------------------------------------------------------------------------------- 1 | `default_nettype none 2 | module Mux_tb(); 3 | 4 | integer file; 5 | 6 | reg a = 0; 7 | reg b = 0; 8 | reg sel = 0; 9 | wire out; 10 | 11 | Mux Mux_1( 12 | .a(a), 13 | .b(b), 14 | .sel(sel), 15 | .out(out) 16 | ); 17 | 18 | task display; 19 | #1 $fwrite(file, "| %1b | %1b | %1b | %1b |\n", a, b, sel, out); 20 | endtask 21 | 22 | initial begin 23 | $dumpfile("Mux_tb.vcd"); 24 | $dumpvars(0, Mux_tb); 25 | file = $fopen("Mux.out","w"); 26 | $fwrite(file, "| a | b | sel | out |\n"); 27 | 28 | a = 0; 29 | display(); 30 | 31 | sel = 1; 32 | display(); 33 | 34 | sel = 0; 35 | b = 1; 36 | display(); 37 | 38 | sel = 1; 39 | display(); 40 | 41 | a = 1; 42 | b = 0; 43 | sel = 0; 44 | display(); 45 | 46 | sel = 1; 47 | display(); 48 | 49 | sel = 0; 50 | b = 1; 51 | display(); 52 | 53 | sel = 1; 54 | display(); 55 | 56 | $finish(); 57 | end 58 | 59 | endmodule 60 | -------------------------------------------------------------------------------- /1-ALU/tb/FullAdder_tb.v: -------------------------------------------------------------------------------- 1 | `default_nettype none 2 | module FullAdder_tb(); 3 | 4 | integer file; 5 | 6 | reg a = 0; 7 | reg b = 0; 8 | reg c = 0; 9 | wire sum, carry; 10 | 11 | FullAdder FullAdder_1( 12 | .a(a), 13 | .b(b), 14 | .c(c), 15 | .sum(sum), 16 | .carry(carry) 17 | ); 18 | 19 | task display; 20 | #1 $fwrite(file, "| %1b | %1b | %1b | %1b | %1b |\n", a, b, c, sum, carry); 21 | endtask 22 | 23 | initial begin 24 | $dumpfile("FullAdder_tb.vcd"); 25 | $dumpvars(0, FullAdder_tb); 26 | file = $fopen("FullAdder.out","w"); 27 | $fwrite(file, "| a | b | c | sum | carry |\n"); 28 | 29 | a = 0; 30 | display(); 31 | 32 | c = 1; 33 | display(); 34 | 35 | c = 0; 36 | b = 1; 37 | display(); 38 | 39 | c = 1; 40 | display(); 41 | 42 | a = 1; 43 | b = 0; 44 | c = 0; 45 | display(); 46 | 47 | c = 1; 48 | display(); 49 | 50 | c = 0; 51 | b = 1; 52 | display(); 53 | 54 | c = 1; 55 | display(); 56 | 57 | $finish(); 58 | end 59 | 60 | endmodule 61 | -------------------------------------------------------------------------------- /1-ALU/tb/Add16_tb.v: -------------------------------------------------------------------------------- 1 | `default_nettype none 2 | module Add16_tb(); 3 | 4 | integer file; 5 | 6 | reg [15:0] a; 7 | reg [15:0] b; 8 | wire [15:0] out; 9 | 10 | Add16 Add16_1( 11 | .a(a), 12 | .b(b), 13 | .out(out) 14 | ); 15 | 16 | task display; 17 | #1 $fwrite(file, "| %1b | %1b | %1b |\n", a, b, out); 18 | endtask 19 | 20 | initial begin 21 | $dumpfile("Add16_tb.vcd"); 22 | $dumpvars(0, Add16_tb); 23 | file = $fopen("Add16.out","w"); 24 | $fwrite(file, "| a | b | out |\n"); 25 | 26 | a = 16'b0000000000000000; 27 | b = 16'b0000000000000000; 28 | display(); 29 | 30 | a = 16'b0000000000000000; 31 | b = 16'b1111111111111111; 32 | display(); 33 | 34 | a = 16'b1111111111111111; 35 | b = 16'b1111111111111111; 36 | display(); 37 | 38 | a = 16'b1010101010101010; 39 | b = 16'b0101010101010101; 40 | display(); 41 | 42 | a = 16'b0011110011000011; 43 | b = 16'b0000111111110000; 44 | display(); 45 | 46 | a = 16'b0001001000110100; 47 | b = 16'b1001100001110110; 48 | display(); 49 | 50 | $finish(); 51 | end 52 | 53 | endmodule 54 | -------------------------------------------------------------------------------- /1-ALU/tb/And16_tb.v: -------------------------------------------------------------------------------- 1 | `default_nettype none 2 | module And16_tb(); 3 | 4 | integer file; 5 | 6 | reg [15:0] a; 7 | reg [15:0] b; 8 | wire [15:0] out; 9 | 10 | And16 And16_1( 11 | .a(a), 12 | .b(b), 13 | .out(out) 14 | ); 15 | 16 | task display; 17 | #1 $fwrite(file, "| %1b | %1b | %1b |\n", a, b, out); 18 | endtask 19 | 20 | initial begin 21 | $dumpfile("And16_tb.vcd"); 22 | $dumpvars(0, And16_tb); 23 | file = $fopen("And16.out","w"); 24 | $fwrite(file, "| a | b | out |\n"); 25 | 26 | a = 16'b0000000000000000; 27 | b = 16'b0000000000000000; 28 | display(); 29 | 30 | a = 16'b0000000000000000; 31 | b = 16'b1111111111111111; 32 | display(); 33 | 34 | a = 16'b1111111111111111; 35 | b = 16'b1111111111111111; 36 | display(); 37 | 38 | a = 16'b1010101010101010; 39 | b = 16'b0101010101010101; 40 | display(); 41 | 42 | a = 16'b0011110011000011; 43 | b = 16'b0000111111110000; 44 | display(); 45 | 46 | a = 16'b0001001000110100; 47 | b = 16'b1001100001110110; 48 | display(); 49 | 50 | $finish(); 51 | end 52 | 53 | endmodule 54 | -------------------------------------------------------------------------------- /0-Xor/Makefile: -------------------------------------------------------------------------------- 1 | all Xor_test.out: tb/Xor_tb.v Xor.v Or.v Not.v And.v Nand.v 2 | iverilog -o Xor_test.out tb/Xor_tb.v Xor.v Or.v Not.v And.v Nand.v 3 | 4 | run Xor_tb.vcd: Xor_test.out 5 | vvp Xor_test.out 6 | 7 | sim: Xor_tb.vcd 8 | gtkwave Xor_tb.vcd 9 | 10 | nand_test: tb/Nand_tb.v Nand.v 11 | @iverilog -o Nand_test.out tb/Nand_tb.v Nand.v 12 | @vvp Nand_test.out 13 | @diff Nand.out tb/Nand.cmp 14 | @echo "--- NAND PASS ---" 15 | 16 | not_test: tb/Not_tb.v Not.v Nand.v 17 | @iverilog -o Not_test.out tb/Not_tb.v Not.v Nand.v 18 | @vvp Not_test.out 19 | @diff Not.out tb/Not.cmp 20 | @echo "--- Not PASS ---" 21 | 22 | and_test: tb/And_tb.v And.v Nand.v 23 | @iverilog -o And_test.out tb/And_tb.v And.v Nand.v 24 | @vvp And_test.out 25 | @diff And.out tb/And.cmp 26 | @echo "--- AND PASS ---" 27 | 28 | or_test: tb/Or_tb.v Or.v Not.v Nand.v 29 | @iverilog -o Or_test.out tb/Or_tb.v Or.v Not.v Nand.v 30 | @vvp Or_test.out 31 | @diff Or.out tb/Or.cmp 32 | @echo "--- OR PASS ---" 33 | 34 | xor_test: tb/Xor_tb.v Xor.v Not.v And.v Or.v Nand.v 35 | @iverilog -o Xor_test.out tb/Xor_tb.v Xor.v Not.v And.v Or.v Nand.v 36 | @vvp Xor_test.out 37 | @diff Xor.out tb/Xor.cmp 38 | @echo "--- XOR PASS ---" 39 | 40 | test: nand_test not_test and_test or_test xor_test 41 | @echo "" 42 | @echo "--- ALL PASS ---\n" 43 | 44 | clean: 45 | rm -f *.vcd *.out -------------------------------------------------------------------------------- /1-ALU/tb/Mux16_tb.v: -------------------------------------------------------------------------------- 1 | `default_nettype none 2 | module Mux16_tb(); 3 | 4 | integer file; 5 | 6 | reg [15:0] a; 7 | reg [15:0] b; 8 | reg sel = 0; 9 | wire [15:0] out; 10 | 11 | Mux16 Mux16_1( 12 | .a(a), 13 | .b(b), 14 | .sel(sel), 15 | .out(out) 16 | ); 17 | 18 | task display; 19 | #1 $fwrite(file, "| %1b | %1b | %1b | %1b |\n", a, b, sel, out); 20 | endtask 21 | 22 | initial begin 23 | $dumpfile("Mux16_tb.vcd"); 24 | $dumpvars(0, Mux16_tb); 25 | file = $fopen("Mux16.out","w"); 26 | $fwrite(file, "| a | b | sel | out |\n"); 27 | 28 | a = 16'b0000000000000000; 29 | b = 16'b0000000000000000; 30 | display(); 31 | 32 | sel = 1; 33 | display(); 34 | 35 | sel = 0; 36 | b = 16'b0001001000110100; 37 | display(); 38 | 39 | sel = 1; 40 | display(); 41 | 42 | a = 16'b1001100001110110; 43 | b = 16'b0000000000000000; 44 | sel = 0; 45 | display(); 46 | 47 | sel = 1; 48 | display(); 49 | 50 | a = 16'b1010101010101010; 51 | b = 16'b0101010101010101; 52 | sel = 0; 53 | display(); 54 | 55 | sel = 1; 56 | display(); 57 | 58 | $finish(); 59 | end 60 | 61 | endmodule 62 | -------------------------------------------------------------------------------- /3-Hack/Memory.v: -------------------------------------------------------------------------------- 1 | /* 2 | * The module mem provides access to memory RAM 3 | * and memory mapped IO 4 | * In our Minimal-Hack-Project we will use 4Kx16 Bit RAM 5 | * 6 | * address | memory 7 | * ---------------- 8 | * 0-4047 | RAM 9 | * 8192 | but 10 | * 8193 | led 11 | * 12 | * WRITE: 13 | * When load is set to 1, 16 bit dataW are stored to Memory address 14 | * at next clock cycle. M[address] <= dataW 15 | * READ: 16 | * dataR provides data stored in Memory at address. 17 | * dataR = M[address] 18 | * 19 | */ 20 | 21 | module Memory( 22 | input wire clk, 23 | input wire [15:0] address, 24 | input wire [15:0] dataW, 25 | output wire [15:0] dataR, 26 | input wire load, 27 | input wire [1:0] but, 28 | output wire [1:0] led 29 | ); 30 | 31 | // your implementation comes here: 32 | 33 | // Read Memory 34 | assign dataR = (address[13]==0)? regRAM[address[11:0]] : memGPIO; 35 | wire [15:0] memGPIO; 36 | assign memGPIO = (address[0]==0)? regLED : but; 37 | 38 | // Write to RAM 39 | reg [15:0] regRAM [0:8191]; 40 | always @(posedge clk) begin 41 | if (load & (address[13]==0)) regRAM[address[11:0]] <= dataW; 42 | end 43 | 44 | // leds 45 | assign led = regLED[1:0]; 46 | reg [15:0] regLED = 0; 47 | always @(posedge clk) begin 48 | if (load & (address==8192)) regLED <= dataW; 49 | else regLED <= regLED; 50 | end 51 | 52 | endmodule 53 | -------------------------------------------------------------------------------- /1-ALU/Add16.v: -------------------------------------------------------------------------------- 1 | /** 2 | * Adds two 16-bit values. 3 | * The most significant carry bit is ignored. 4 | * out = a + b (16 bit) 5 | */ 6 | 7 | `default_nettype none 8 | module Add16( 9 | input wire [15:0] a, 10 | input wire [15:0] b, 11 | output wire [15:0] out 12 | ); 13 | 14 | // your implementation comes here: 15 | 16 | wire carry0, carry1, carry2, carry3, carry4, carry5, carry6, carry7, carry8, carry9, carry10, carry11, carry12, carry13, carry14, carry15; 17 | 18 | HalfAdder HalfAdder_0(a[0], b[0], out[0], carry0); 19 | FullAdder FullAdder_1(a[1], b[1], carry0, out[1], carry1); 20 | FullAdder FullAdder_2(a[2], b[2], carry1, out[2], carry2); 21 | FullAdder FullAdder_3(a[3], b[3], carry2, out[3], carry3); 22 | FullAdder FullAdder_4(a[4], b[4], carry3, out[4], carry4); 23 | FullAdder FullAdder_5(a[5], b[5], carry4, out[5], carry5); 24 | FullAdder FullAdder_6(a[6], b[6], carry5, out[6], carry6); 25 | FullAdder FullAdder_7(a[7], b[7], carry6, out[7], carry7); 26 | FullAdder FullAdder_8(a[8], b[8], carry7, out[8], carry8); 27 | FullAdder FullAdder_9(a[9], b[9], carry8, out[9], carry9); 28 | FullAdder FullAdder_10(a[10], b[10], carry9, out[10], carry10); 29 | FullAdder FullAdder_11(a[11], b[11], carry10, out[11], carry11); 30 | FullAdder FullAdder_12(a[12], b[12], carry11, out[12], carry12); 31 | FullAdder FullAdder_13(a[13], b[13], carry12, out[13], carry13); 32 | FullAdder FullAdder_14(a[14], b[14], carry13, out[14], carry14); 33 | FullAdder FullAdder_15(a[15], b[15], carry14, out[15], carry15); 34 | 35 | endmodule 36 | -------------------------------------------------------------------------------- /2-CPU/Add16.v: -------------------------------------------------------------------------------- 1 | /** 2 | * Adds two 16-bit values. 3 | * The most significant carry bit is ignored. 4 | * out = a + b (16 bit) 5 | */ 6 | 7 | `default_nettype none 8 | module Add16( 9 | input wire [15:0] a, 10 | input wire [15:0] b, 11 | output wire [15:0] out 12 | ); 13 | 14 | // your implementation comes here: 15 | 16 | wire carry0, carry1, carry2, carry3, carry4, carry5, carry6, carry7, carry8, carry9, carry10, carry11, carry12, carry13, carry14, carry15; 17 | 18 | HalfAdder HalfAdder_0(a[0], b[0], out[0], carry0); 19 | FullAdder FullAdder_1(a[1], b[1], carry0, out[1], carry1); 20 | FullAdder FullAdder_2(a[2], b[2], carry1, out[2], carry2); 21 | FullAdder FullAdder_3(a[3], b[3], carry2, out[3], carry3); 22 | FullAdder FullAdder_4(a[4], b[4], carry3, out[4], carry4); 23 | FullAdder FullAdder_5(a[5], b[5], carry4, out[5], carry5); 24 | FullAdder FullAdder_6(a[6], b[6], carry5, out[6], carry6); 25 | FullAdder FullAdder_7(a[7], b[7], carry6, out[7], carry7); 26 | FullAdder FullAdder_8(a[8], b[8], carry7, out[8], carry8); 27 | FullAdder FullAdder_9(a[9], b[9], carry8, out[9], carry9); 28 | FullAdder FullAdder_10(a[10], b[10], carry9, out[10], carry10); 29 | FullAdder FullAdder_11(a[11], b[11], carry10, out[11], carry11); 30 | FullAdder FullAdder_12(a[12], b[12], carry11, out[12], carry12); 31 | FullAdder FullAdder_13(a[13], b[13], carry12, out[13], carry13); 32 | FullAdder FullAdder_14(a[14], b[14], carry13, out[14], carry14); 33 | FullAdder FullAdder_15(a[15], b[15], carry14, out[15], carry15); 34 | 35 | endmodule 36 | -------------------------------------------------------------------------------- /3-Hack/Add16.v: -------------------------------------------------------------------------------- 1 | /** 2 | * Adds two 16-bit values. 3 | * The most significant carry bit is ignored. 4 | * out = a + b (16 bit) 5 | */ 6 | 7 | `default_nettype none 8 | module Add16( 9 | input wire [15:0] a, 10 | input wire [15:0] b, 11 | output wire [15:0] out 12 | ); 13 | 14 | // your implementation comes here: 15 | 16 | wire carry0, carry1, carry2, carry3, carry4, carry5, carry6, carry7, carry8, carry9, carry10, carry11, carry12, carry13, carry14, carry15; 17 | 18 | HalfAdder HalfAdder_0(a[0], b[0], out[0], carry0); 19 | FullAdder FullAdder_1(a[1], b[1], carry0, out[1], carry1); 20 | FullAdder FullAdder_2(a[2], b[2], carry1, out[2], carry2); 21 | FullAdder FullAdder_3(a[3], b[3], carry2, out[3], carry3); 22 | FullAdder FullAdder_4(a[4], b[4], carry3, out[4], carry4); 23 | FullAdder FullAdder_5(a[5], b[5], carry4, out[5], carry5); 24 | FullAdder FullAdder_6(a[6], b[6], carry5, out[6], carry6); 25 | FullAdder FullAdder_7(a[7], b[7], carry6, out[7], carry7); 26 | FullAdder FullAdder_8(a[8], b[8], carry7, out[8], carry8); 27 | FullAdder FullAdder_9(a[9], b[9], carry8, out[9], carry9); 28 | FullAdder FullAdder_10(a[10], b[10], carry9, out[10], carry10); 29 | FullAdder FullAdder_11(a[11], b[11], carry10, out[11], carry11); 30 | FullAdder FullAdder_12(a[12], b[12], carry11, out[12], carry12); 31 | FullAdder FullAdder_13(a[13], b[13], carry12, out[13], carry13); 32 | FullAdder FullAdder_14(a[14], b[14], carry13, out[14], carry14); 33 | FullAdder FullAdder_15(a[15], b[15], carry14, out[15], carry15); 34 | 35 | endmodule 36 | -------------------------------------------------------------------------------- /3-Hack/Hack.v: -------------------------------------------------------------------------------- 1 | /** 2 | * The module hack is our top-level module 3 | * It connects the external pins of our fpga (hack.pcf) 4 | * to the internal components (cpu,mem,clk,rst,rom) 5 | * 6 | */ 7 | 8 | `default_nettype none 9 | module hack( // top level module 10 | input wire clk, 11 | input wire [1:0] but, // buttons (0 if pressed, 1 if released) 12 | output wire [1:0] led // leds (0 off, 1 on) 13 | ); 14 | 15 | // your implementation comes here: 16 | 17 | // reset logic 18 | wire reset; 19 | Reset Reset_0(.clk(clk),.reset(reset)); 20 | 21 | // hack cpu (nand2tetris) 22 | wire [15:0] pc; 23 | wire [15:0] instruction; 24 | wire [15:0] addressM; 25 | wire [15:0] inM; 26 | wire loadM; 27 | wire [15:0] outM; 28 | CPU CPU_0( 29 | .clk(clk), 30 | .inM(inM), // M value input (M = contents of RAM[A]) 31 | .instruction(instruction), // Instruction for execution 32 | .reset(reset), // Signals whether to re-start the current 33 | // program (rstn==0) or continue executing 34 | // the current program (rstn==1). 35 | .outM(outM), // M value output 36 | .loadM(loadM), // Write to M? 37 | .addressM(addressM), // Address in data memory to Read(of M) 38 | .pc(pc) // address of next instruction 39 | ); 40 | 41 | // rom stores hack code 42 | ROM ROM_0( 43 | .address(pc), 44 | .data(instruction) 45 | ); 46 | 47 | // mem gives access to ram and io 48 | Memory Memory_0( 49 | .clk(clk), 50 | .address(addressM), 51 | .dataR(inM), 52 | .dataW(outM), 53 | .load(loadM), 54 | .but(but), 55 | .led(led) 56 | ); 57 | 58 | endmodule 59 | -------------------------------------------------------------------------------- /1-ALU/Readme.md: -------------------------------------------------------------------------------- 1 | ## Step 1 - ALU 2 | We'll use what we have built in the last section to build an ALU. To accomplish this part, try: 3 | 4 | ``` 5 | make test 6 | ``` 7 | 8 | you should see: 9 | 10 | ``` 11 | --- MUX PASS --- 12 | --- MUX16 PASS --- 13 | --- NOT16 PASS --- 14 | --- AND16 PASS --- 15 | --- OR8WAY PASS --- 16 | --- HALFADDER PASS --- 17 | --- FULLADDER PASS --- 18 | --- ADD16 PASS --- 19 | --- ALU PASS --- 20 | 21 | --- ALL PASS --- 22 | ``` 23 | 24 | To make this happen, you need to implement several gates (around 10 lines of code each): 25 | 26 | - Mux.v 27 | - Not16.v 28 | - And16.v 29 | - Mux16.v 30 | - Or8Way.v 31 | - HalfAdder.v 32 | - FullAdder.v 33 | - Add16.v 34 | - ALU.v 35 | 36 | Still, you can test them one by one: 37 | 38 | ``` 39 | make mux_test 40 | make mux16_test 41 | make not16_test 42 | make and16_test 43 | make or8way_test 44 | make halfadder_test 45 | make fulladder_test 46 | make add16_test 47 | make alu_test 48 | ``` 49 | 50 | **When testing, be careful with the difference between LF (Linux) and CRLF (Windows).** 51 | 52 | ### What is ALU? 53 | 54 | The ALU (Arithmetic Logic Unit). 55 | 56 | ![](img/ALU.png) 57 | 58 | Computes one of the following functions: x+y, x-y, y-x, 0, 1, -1, x, y, -x, -y, !x, !y, x+1, y+1, x-1, y-1, x&y, x|y on two 16-bit inputs, according to 6 input bits denoted zx,nx,zy,ny,f,no. In addition, the ALU computes two 1-bit outputs: if the ALU output == 0, zr is set to 1; otherwise zr is set to 0; if the ALU output < 0, ng is set to 1; otherwise ng is set to 0. 59 | 60 | Implementation: the ALU logic manipulates the x and y inputs and operates on the resulting values, as follows: 61 | * if (zx == 1) set x = 0 16-bit constant 62 | * if (nx == 1) set x = !x bitwise not 63 | * if (zy == 1) set y = 0 16-bit constant 64 | * if (ny == 1) set y = !y bitwise not 65 | * if (f == 1) set out = x + y integer 2's complement addition 66 | * if (f == 0) set out = x & y bitwise and 67 | * if (no == 1) set out = !out bitwise not 68 | * if (out == 0) set zr = 1 69 | * if (out < 0) set ng = 1 70 | 71 | ----- 72 | 73 | **Congratulations**, you are now ready to build your CPU in the next section. 74 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Building a 16-bit CPU from Scratch on FPGA (nand2tetris) 2 | 3 | - Some may ask how many lines of code are required to design a simple programmable CPU? 4 | 5 | - The answer is **less than 350 lines of verilog code**. 6 | 7 | ``` 8 | Starting from a single Nand gate, you'll build a 16-bit blinky CPU that runs on real-world FPGAs. 9 | ``` 10 | 11 | ### Prerequisites 12 | 13 | A small laptop is enough for this project. No extra hardware required. 14 | 15 | Software to be installed: 16 | 17 | - Make 18 | - iverilog 19 | - gtkwave 20 | 21 | If you'd like to run this CPU on real FPGAs, here's the synthesis report in Lattice Diamond: 22 | 23 | ``` 24 | Design Summary 25 | Number of registers: 152 out of 4635 (3%) 26 | PFU registers: 152 out of 4320 (4%) 27 | PIO registers: 0 out of 315 (0%) 28 | Number of SLICEs: 134 out of 2160 (6%) 29 | SLICEs as Logic/ROM: 134 out of 2160 (6%) 30 | SLICEs as RAM: 0 out of 1620 (0%) 31 | SLICEs as Carry: 10 out of 2160 (0%) 32 | Number of LUT4s: 267 out of 4320 (6%) 33 | Number used as logic LUTs: 247 34 | Number used as distributed RAM: 0 35 | Number used as ripple logic: 20 36 | Number used as shift registers: 0 37 | Number of PIO sites used: 5 + 4(JTAG) out of 105 (9%) 38 | Number of block RAMs: 4 out of 10 (40%) 39 | Number of GSRs: 0 out of 1 (0%) 40 | ``` 41 | 42 | It's so tiny that virtually any randomly chosen FPGA should work. 43 | 44 | ### Instructions 45 | 46 | > Detailed instructions will be given under each directory. 47 | 48 | #### Step 1 - Environment Setup 49 | 50 | Build useful gates starting from a single Nand gate. 51 | 52 | - Nand.v 53 | - Not.v 54 | - And.v 55 | - Or.v 56 | - Xor.v 57 | 58 | #### Step 2 - ALU 59 | 60 | Time to build an ALU. 61 | 62 | - Mux.v 63 | - Not16.v 64 | - And16.v 65 | - Mux16.v 66 | - Or8Way.v 67 | - HalfAdder.v 68 | - FullAdder.v 69 | - Add16.v 70 | - ALU.v 71 | 72 | #### Step 3 - CPU 73 | 74 | A working 16-bit CPU: 75 | 76 | - CPU.v 77 | 78 | #### Step 4 - Computer 79 | 80 | A programmable computer with input (buttons) and output (LEDs): 81 | 82 | - Reset.v 83 | - Memory.v 84 | - Rom.v 85 | - Hack.v 86 | 87 | ![](./3-Hack/img/Hack1.png) 88 | 89 | ### Related Projects 90 | 91 | - https://www.nand2tetris.org/ 92 | - https://gitlab.com/x653/nand2tetris-fpga/ 93 | - https://github.com/theapi/nand2tetris_fpga -------------------------------------------------------------------------------- /1-ALU/Makefile: -------------------------------------------------------------------------------- 1 | 2 | all ALU_test.out: 3 | iverilog -o ALU_test.out tb/ALU_tb.v And.v And16.v Nand.v Not.v Not16.v Or.v Or8Way.v Xor.v Mux.v Mux16.v HalfAdder.v FullAdder.v Add16.v ALU.v 4 | 5 | run ALU_tb.vcd: ALU_test.out 6 | vvp ALU_test.out 7 | 8 | sim: ALU_tb.vcd 9 | gtkwave ALU_tb.vcd 10 | 11 | mux_test: tb/Mux_tb.v Mux.v Not.v And.v Or.v Nand.v 12 | @iverilog -o Mux_test.out tb/Mux_tb.v Mux.v Not.v And.v Or.v Nand.v 13 | @vvp Mux_test.out 14 | @diff Mux.out tb/Mux.cmp 15 | @echo "--- MUX PASS ---" 16 | 17 | mux16_test: tb/Mux16_tb.v Mux16.v Mux.v Not.v And.v Or.v Nand.v 18 | @iverilog -o Mux16_test.out tb/Mux16_tb.v Mux16.v Mux.v Not.v And.v Or.v Nand.v 19 | @vvp Mux16_test.out 20 | @diff Mux16.out tb/Mux16.cmp 21 | @echo "--- MUX16 PASS ---" 22 | 23 | not16_test: tb/Not16_tb.v Not16.v Not.v Nand.v 24 | @iverilog -o Not16_test.out tb/Not16_tb.v Not16.v Not.v Nand.v 25 | @vvp Not16_test.out 26 | @diff Not16.out tb/Not16.cmp 27 | @echo "--- NOT16 PASS ---" 28 | 29 | and16_test: tb/And16_tb.v And16.v And.v Nand.v 30 | @iverilog -o And16_test.out tb/And16_tb.v And16.v And.v Nand.v 31 | @vvp And16_test.out 32 | @diff And16.out tb/And16.cmp 33 | @echo "--- AND16 PASS ---" 34 | 35 | or8way_test: tb/Or8Way_tb.v Or8Way.v Or.v Not.v Nand.v 36 | @iverilog -o Or8Way_test.out tb/Or8Way_tb.v Or8Way.v Or.v Not.v Nand.v 37 | @vvp Or8Way_test.out 38 | @diff Or8Way.out tb/Or8Way.cmp 39 | @echo "--- OR8WAY PASS ---" 40 | 41 | halfadder_test: tb/HalfAdder_tb.v HalfAdder.v Xor.v Not.v Or.v And.v Nand.v 42 | @iverilog -o HalfAdder_test.out tb/HalfAdder_tb.v HalfAdder.v Xor.v Not.v Or.v And.v Nand.v 43 | @vvp HalfAdder_test.out 44 | @diff HalfAdder.out tb/HalfAdder.cmp 45 | @echo "--- HALFADDER PASS ---" 46 | 47 | fulladder_test: tb/FullAdder_tb.v FullAdder.v HalfAdder.v Xor.v Not.v Or.v And.v Nand.v 48 | @iverilog -o FullAdder_test.out tb/FullAdder_tb.v FullAdder.v HalfAdder.v Xor.v Not.v Or.v And.v Nand.v 49 | @vvp FullAdder_test.out 50 | @diff FullAdder.out tb/FullAdder.cmp 51 | @echo "--- FULLADDER PASS ---" 52 | 53 | add16_test: tb/Add16_tb.v Add16.v FullAdder.v HalfAdder.v Xor.v Not.v Or.v And.v Nand.v 54 | @iverilog -o Add16_test.out tb/Add16_tb.v Add16.v FullAdder.v HalfAdder.v Xor.v Not.v Or.v And.v Nand.v 55 | @vvp Add16_test.out 56 | @diff Add16.out tb/Add16.cmp 57 | @echo "--- ADD16 PASS ---" 58 | 59 | alu_test: tb/ALU_tb.v ALU.v Add16.v FullAdder.v HalfAdder.v Mux16.v Not16.v And16.v Or8Way.v Mux.v Xor.v Not.v Or.v And.v Nand.v 60 | @iverilog -o ALU_test.out tb/ALU_tb.v ALU.v Add16.v FullAdder.v HalfAdder.v Mux16.v Not16.v And16.v Or8Way.v Mux.v Xor.v Not.v Or.v And.v Nand.v 61 | @vvp ALU_test.out 62 | @diff ALU.out tb/ALU.cmp 63 | @echo "--- ALU PASS ---" 64 | 65 | test: mux_test mux16_test not16_test and16_test or8way_test halfadder_test fulladder_test add16_test alu_test 66 | @echo "" 67 | @echo "--- ALL PASS ---\n" 68 | 69 | clean: 70 | rm -f *.out *.vcd -------------------------------------------------------------------------------- /1-ALU/ALU.v: -------------------------------------------------------------------------------- 1 | /** 2 | * The ALU (Arithmetic Logic Unit). 3 | * Computes one of the following functions: 4 | * x+y, x-y, y-x, 0, 1, -1, x, y, -x, -y, !x, !y, 5 | * x+1, y+1, x-1, y-1, x&y, x|y on two 16-bit inputs, 6 | * according to 6 input bits denoted zx,nx,zy,ny,f,no. 7 | * In addition, the ALU computes two 1-bit outputs: 8 | * if the ALU output == 0, zr is set to 1; otherwise zr is set to 0; 9 | * if the ALU output < 0, ng is set to 1; otherwise ng is set to 0. 10 | */ 11 | 12 | // Implementation: the ALU logic manipulates the x and y inputs 13 | // and operates on the resulting values, as follows: 14 | // if (zx == 1) set x = 0 // 16-bit constant 15 | // if (nx == 1) set x = !x // bitwise not 16 | // if (zy == 1) set y = 0 // 16-bit constant 17 | // if (ny == 1) set y = !y // bitwise not 18 | // if (f == 1) set out = x + y // integer 2's complement addition 19 | // if (f == 0) set out = x & y // bitwise and 20 | // if (no == 1) set out = !out // bitwise not 21 | // if (out == 0) set zr = 1 22 | // if (out < 0) set ng = 1 23 | 24 | `default_nettype none 25 | module ALU( 26 | input wire [15:0] x, // input x (16 bit) 27 | input wire [15:0] y, // input y (16 bit) 28 | input wire zx, // zero the x input? 29 | input wire nx, // negate the x input? 30 | input wire zy, // zero the y input? 31 | input wire ny, // negate the y input? 32 | input wire f, // compute out = x + y (if 1) or x & y (if 0) 33 | input wire no, // negate the out output? 34 | output wire [15:0] out, // 16-bit output 35 | output wire zr, // 1 if (out == 0), 0 otherwise 36 | output wire ng // 1 if (out < 0), 0 otherwise 37 | ); 38 | 39 | // your implementation comes here: 40 | 41 | wire [15:0] inzx; 42 | wire [15:0] notx; 43 | wire [15:0] inzxnx; 44 | wire [15:0] inzy; 45 | wire [15:0] noty; 46 | wire [15:0] inzyny; 47 | wire [15:0] addxy; 48 | wire [15:0] andxy; 49 | wire [15:0] outzxnxzynyf; 50 | wire [15:0] notoutzxnxzynyf; 51 | wire [7:0] finalOutLow; 52 | wire [7:0] finalOutHigh; 53 | wire zr1; 54 | wire zr2; 55 | wire nzr; 56 | wire [15:0] sout; 57 | wire[15:0] out_temp; 58 | wire[15:0] ng_temp; 59 | 60 | Mux16 Mux16_0(x, 16'b0, zx, inzx); 61 | Not16 Not16_0(inzx, notx); 62 | Mux16 Mux16_1(inzx, notx, nx, inzxnx); 63 | 64 | Mux16 Mux16_2(y, 16'b0, zy, inzy); 65 | Not16 Not16_1(inzy, noty); 66 | Mux16 Mux16_3(inzy, noty, ny, inzyny); 67 | 68 | Add16 Add16_0(inzxnx, inzyny, addxy); 69 | And16 Add16_1(inzxnx, inzyny, andxy); 70 | 71 | Mux16 Mux16_4(andxy, addxy, f, outzxnxzynyf); 72 | 73 | Not16 Not16_2(outzxnxzynyf, notoutzxnxzynyf); 74 | Mux16 Mux16_5(outzxnxzynyf, notoutzxnxzynyf, no, sout); 75 | 76 | And16 And16_2(sout, 16'b1111111111111111, out_temp); 77 | assign finalOutLow = out_temp[7:0]; 78 | assign finalOutHigh = out_temp[15:8]; 79 | 80 | Or8Way Or8Way_0(finalOutLow, zr1); 81 | Or8Way Or8Way_1(finalOutHigh, zr2); 82 | Or Or_0(zr1, zr2, nzr); 83 | Not Not_0(nzr, zr); 84 | 85 | And16 And16_3(sout, 16'b1111111111111111, ng_temp); 86 | assign ng = ng_temp[15]; 87 | 88 | And16 And16_4(sout, 16'b1111111111111111, out); 89 | 90 | endmodule 91 | -------------------------------------------------------------------------------- /2-CPU/ALU.v: -------------------------------------------------------------------------------- 1 | /** 2 | * The ALU (Arithmetic Logic Unit). 3 | * Computes one of the following functions: 4 | * x+y, x-y, y-x, 0, 1, -1, x, y, -x, -y, !x, !y, 5 | * x+1, y+1, x-1, y-1, x&y, x|y on two 16-bit inputs, 6 | * according to 6 input bits denoted zx,nx,zy,ny,f,no. 7 | * In addition, the ALU computes two 1-bit outputs: 8 | * if the ALU output == 0, zr is set to 1; otherwise zr is set to 0; 9 | * if the ALU output < 0, ng is set to 1; otherwise ng is set to 0. 10 | */ 11 | 12 | // Implementation: the ALU logic manipulates the x and y inputs 13 | // and operates on the resulting values, as follows: 14 | // if (zx == 1) set x = 0 // 16-bit constant 15 | // if (nx == 1) set x = !x // bitwise not 16 | // if (zy == 1) set y = 0 // 16-bit constant 17 | // if (ny == 1) set y = !y // bitwise not 18 | // if (f == 1) set out = x + y // integer 2's complement addition 19 | // if (f == 0) set out = x & y // bitwise and 20 | // if (no == 1) set out = !out // bitwise not 21 | // if (out == 0) set zr = 1 22 | // if (out < 0) set ng = 1 23 | 24 | `default_nettype none 25 | module ALU( 26 | input wire [15:0] x, // input x (16 bit) 27 | input wire [15:0] y, // input y (16 bit) 28 | input wire zx, // zero the x input? 29 | input wire nx, // negate the x input? 30 | input wire zy, // zero the y input? 31 | input wire ny, // negate the y input? 32 | input wire f, // compute out = x + y (if 1) or x & y (if 0) 33 | input wire no, // negate the out output? 34 | output wire [15:0] out, // 16-bit output 35 | output wire zr, // 1 if (out == 0), 0 otherwise 36 | output wire ng // 1 if (out < 0), 0 otherwise 37 | ); 38 | 39 | // your implementation comes here: 40 | 41 | wire [15:0] inzx; 42 | wire [15:0] notx; 43 | wire [15:0] inzxnx; 44 | wire [15:0] inzy; 45 | wire [15:0] noty; 46 | wire [15:0] inzyny; 47 | wire [15:0] addxy; 48 | wire [15:0] andxy; 49 | wire [15:0] outzxnxzynyf; 50 | wire [15:0] notoutzxnxzynyf; 51 | wire [7:0] finalOutLow; 52 | wire [7:0] finalOutHigh; 53 | wire zr1; 54 | wire zr2; 55 | wire nzr; 56 | wire [15:0] sout; 57 | wire[15:0] out_temp; 58 | wire[15:0] ng_temp; 59 | 60 | Mux16 Mux16_0(x, 16'b0, zx, inzx); 61 | Not16 Not16_0(inzx, notx); 62 | Mux16 Mux16_1(inzx, notx, nx, inzxnx); 63 | 64 | Mux16 Mux16_2(y, 16'b0, zy, inzy); 65 | Not16 Not16_1(inzy, noty); 66 | Mux16 Mux16_3(inzy, noty, ny, inzyny); 67 | 68 | Add16 Add16_0(inzxnx, inzyny, addxy); 69 | And16 Add16_1(inzxnx, inzyny, andxy); 70 | 71 | Mux16 Mux16_4(andxy, addxy, f, outzxnxzynyf); 72 | 73 | Not16 Not16_2(outzxnxzynyf, notoutzxnxzynyf); 74 | Mux16 Mux16_5(outzxnxzynyf, notoutzxnxzynyf, no, sout); 75 | 76 | And16 And16_2(sout, 16'b1111111111111111, out_temp); 77 | assign finalOutLow = out_temp[7:0]; 78 | assign finalOutHigh = out_temp[15:8]; 79 | 80 | Or8Way Or8Way_0(finalOutLow, zr1); 81 | Or8Way Or8Way_1(finalOutHigh, zr2); 82 | Or Or_0(zr1, zr2, nzr); 83 | Not Not_0(nzr, zr); 84 | 85 | And16 And16_3(sout, 16'b1111111111111111, ng_temp); 86 | assign ng = ng_temp[15]; 87 | 88 | And16 And16_4(sout, 16'b1111111111111111, out); 89 | 90 | endmodule 91 | -------------------------------------------------------------------------------- /3-Hack/ALU.v: -------------------------------------------------------------------------------- 1 | /** 2 | * The ALU (Arithmetic Logic Unit). 3 | * Computes one of the following functions: 4 | * x+y, x-y, y-x, 0, 1, -1, x, y, -x, -y, !x, !y, 5 | * x+1, y+1, x-1, y-1, x&y, x|y on two 16-bit inputs, 6 | * according to 6 input bits denoted zx,nx,zy,ny,f,no. 7 | * In addition, the ALU computes two 1-bit outputs: 8 | * if the ALU output == 0, zr is set to 1; otherwise zr is set to 0; 9 | * if the ALU output < 0, ng is set to 1; otherwise ng is set to 0. 10 | */ 11 | 12 | // Implementation: the ALU logic manipulates the x and y inputs 13 | // and operates on the resulting values, as follows: 14 | // if (zx == 1) set x = 0 // 16-bit constant 15 | // if (nx == 1) set x = !x // bitwise not 16 | // if (zy == 1) set y = 0 // 16-bit constant 17 | // if (ny == 1) set y = !y // bitwise not 18 | // if (f == 1) set out = x + y // integer 2's complement addition 19 | // if (f == 0) set out = x & y // bitwise and 20 | // if (no == 1) set out = !out // bitwise not 21 | // if (out == 0) set zr = 1 22 | // if (out < 0) set ng = 1 23 | 24 | `default_nettype none 25 | module ALU( 26 | input wire [15:0] x, // input x (16 bit) 27 | input wire [15:0] y, // input y (16 bit) 28 | input wire zx, // zero the x input? 29 | input wire nx, // negate the x input? 30 | input wire zy, // zero the y input? 31 | input wire ny, // negate the y input? 32 | input wire f, // compute out = x + y (if 1) or x & y (if 0) 33 | input wire no, // negate the out output? 34 | output wire [15:0] out, // 16-bit output 35 | output wire zr, // 1 if (out == 0), 0 otherwise 36 | output wire ng // 1 if (out < 0), 0 otherwise 37 | ); 38 | 39 | // your implementation comes here: 40 | 41 | wire [15:0] inzx; 42 | wire [15:0] notx; 43 | wire [15:0] inzxnx; 44 | wire [15:0] inzy; 45 | wire [15:0] noty; 46 | wire [15:0] inzyny; 47 | wire [15:0] addxy; 48 | wire [15:0] andxy; 49 | wire [15:0] outzxnxzynyf; 50 | wire [15:0] notoutzxnxzynyf; 51 | wire [7:0] finalOutLow; 52 | wire [7:0] finalOutHigh; 53 | wire zr1; 54 | wire zr2; 55 | wire nzr; 56 | wire [15:0] sout; 57 | wire[15:0] out_temp; 58 | wire[15:0] ng_temp; 59 | 60 | Mux16 Mux16_0(x, 16'b0, zx, inzx); 61 | Not16 Not16_0(inzx, notx); 62 | Mux16 Mux16_1(inzx, notx, nx, inzxnx); 63 | 64 | Mux16 Mux16_2(y, 16'b0, zy, inzy); 65 | Not16 Not16_1(inzy, noty); 66 | Mux16 Mux16_3(inzy, noty, ny, inzyny); 67 | 68 | Add16 Add16_0(inzxnx, inzyny, addxy); 69 | And16 Add16_1(inzxnx, inzyny, andxy); 70 | 71 | Mux16 Mux16_4(andxy, addxy, f, outzxnxzynyf); 72 | 73 | Not16 Not16_2(outzxnxzynyf, notoutzxnxzynyf); 74 | Mux16 Mux16_5(outzxnxzynyf, notoutzxnxzynyf, no, sout); 75 | 76 | And16 And16_2(sout, 16'b1111111111111111, out_temp); 77 | assign finalOutLow = out_temp[7:0]; 78 | assign finalOutHigh = out_temp[15:8]; 79 | 80 | Or8Way Or8Way_0(finalOutLow, zr1); 81 | Or8Way Or8Way_1(finalOutHigh, zr2); 82 | Or Or_0(zr1, zr2, nzr); 83 | Not Not_0(nzr, zr); 84 | 85 | And16 And16_3(sout, 16'b1111111111111111, ng_temp); 86 | assign ng = ng_temp[15]; 87 | 88 | And16 And16_4(sout, 16'b1111111111111111, out); 89 | 90 | endmodule 91 | -------------------------------------------------------------------------------- /0-Xor/Readme.md: -------------------------------------------------------------------------------- 1 | 2 | # Step 0 - Xor 3 | 4 | To accomplish this part, try: 5 | 6 | ``` 7 | make test 8 | ``` 9 | 10 | you should see: 11 | 12 | ``` 13 | --- NAND PASS --- 14 | --- Not PASS --- 15 | --- AND PASS --- 16 | --- OR PASS --- 17 | --- XOR PASS --- 18 | ``` 19 | 20 | To make this happen, you need to implement several gates (around 5 lines of code each): 21 | 22 | - Nand.v 23 | - Not.v 24 | - And.v 25 | - Or.v 26 | - Xor.v 27 | 28 | And you can test them one by one to make sure every single step is OK: 29 | 30 | ``` 31 | make nand_test 32 | make not_test 33 | make and_test 34 | make or_test 35 | make xor_test 36 | ``` 37 | 38 | **When testing, be careful with the difference between LF (Linux) and CRLF (Windows).** 39 | 40 | ### File Structure 41 | 42 | ``` 43 | - Xor_tb.v // Test file to make sure Xor is well functioning, you don't need to change this 44 | - Xor.cmp // Xor output sample 45 | - Nand.v // Implement it! 46 | - Not.v // Implement it! 47 | - And.v // Implement it! 48 | - Or.v // Implement it! 49 | - Xor.v // Implement it! 50 | ``` 51 | 52 | ## Nand.v 53 | 54 | ``` 55 | /** 56 | * Nand gate: 57 | * out = 0 if (a == 1 and b == 1) 58 | * 1 otherwise 59 | * 60 | * This module is implemented using verilog primitives 61 | */ 62 | 63 | `default_nettype none 64 | 65 | module Nand( 66 | input a, 67 | input b, 68 | output out 69 | ); 70 | nand(out,a,b); 71 | endmodule 72 | ``` 73 | 74 | ### Not.v 75 | 76 | ``` 77 | /** 78 | * Not gate: 79 | * out = not in 80 | */ 81 | `default_nettype none 82 | 83 | module Not( 84 | input wire in, 85 | output wire out 86 | ); 87 | 88 | Nand Nand_1(in, in, out); 89 | 90 | endmodule 91 | ``` 92 | 93 | ## And.v 94 | 95 | ``` 96 | /** 97 | * And gate: 98 | * out = 1 if (a == 1 and b == 1) 99 | * 0 otherwise 100 | */ 101 | module And( 102 | input wire a, 103 | input wire b, 104 | output wire out 105 | ); 106 | 107 | // your implementation comes here: 108 | 109 | wire n_out; 110 | 111 | nand(n_out, a, b); 112 | nand(out, n_out, n_out); 113 | 114 | endmodule 115 | ``` 116 | 117 | ## Or.v 118 | 119 | ``` 120 | /** 121 | * Or gate: 122 | * out = 1 if (a == 1 or b == 1) 123 | * 0 otherwise 124 | */ 125 | `default_nettype none 126 | 127 | module Or( 128 | input wire a, 129 | input wire b, 130 | output wire out 131 | ); 132 | 133 | wire n_a, n_b; 134 | 135 | Not not_a(a, n_a); 136 | Not not_b(b, n_b); 137 | Nand Nand_1(n_a, n_b, out); 138 | 139 | endmodule 140 | ``` 141 | 142 | ## Xor.v 143 | 144 | ``` 145 | /** 146 | * Exclusive-or gate: 147 | * out = not (a == b) 148 | */ 149 | `default_nettype none 150 | 151 | module Xor( 152 | input wire a, 153 | input wire b, 154 | output wire out 155 | ); 156 | 157 | // assign out = a ^ b; 158 | 159 | wire n_a, n_b, n_a_b, n_b_a; 160 | 161 | Not not_a(a, n_a); 162 | Not not_b(b, n_b); 163 | And and_n_a_b(n_a, b, n_a_b); 164 | And and_n_b_a(a, n_b, n_b_a); 165 | Or or_o(n_a_b, n_b_a, out); 166 | 167 | endmodule 168 | ``` 169 | 170 | 171 | 172 | **Congratulations**, you are now familiar with the workflow, and successfully implemented Xor gate starting from a single Nand gate. 173 | -------------------------------------------------------------------------------- /1-ALU/tb/ALU.cmp: -------------------------------------------------------------------------------- 1 | | x | y |zx |nx |zy |ny | f |no | out |zr |ng | 2 | | 0000000000000000 | 1111111111111111 | 1 | 0 | 1 | 0 | 1 | 0 | 0000000000000000 | 1 | 0 | 3 | | 0000000000000000 | 1111111111111111 | 1 | 1 | 1 | 1 | 1 | 1 | 0000000000000001 | 0 | 0 | 4 | | 0000000000000000 | 1111111111111111 | 1 | 1 | 1 | 0 | 1 | 0 | 1111111111111111 | 0 | 1 | 5 | | 0000000000000000 | 1111111111111111 | 0 | 0 | 1 | 1 | 0 | 0 | 0000000000000000 | 1 | 0 | 6 | | 0000000000000000 | 1111111111111111 | 1 | 1 | 0 | 0 | 0 | 0 | 1111111111111111 | 0 | 1 | 7 | | 0000000000000000 | 1111111111111111 | 0 | 0 | 1 | 1 | 0 | 1 | 1111111111111111 | 0 | 1 | 8 | | 0000000000000000 | 1111111111111111 | 1 | 1 | 0 | 0 | 0 | 1 | 0000000000000000 | 1 | 0 | 9 | | 0000000000000000 | 1111111111111111 | 0 | 0 | 1 | 1 | 1 | 1 | 0000000000000000 | 1 | 0 | 10 | | 0000000000000000 | 1111111111111111 | 1 | 1 | 0 | 0 | 1 | 1 | 0000000000000001 | 0 | 0 | 11 | | 0000000000000000 | 1111111111111111 | 0 | 1 | 1 | 1 | 1 | 1 | 0000000000000001 | 0 | 0 | 12 | | 0000000000000000 | 1111111111111111 | 1 | 1 | 0 | 1 | 1 | 1 | 0000000000000000 | 1 | 0 | 13 | | 0000000000000000 | 1111111111111111 | 0 | 0 | 1 | 1 | 1 | 0 | 1111111111111111 | 0 | 1 | 14 | | 0000000000000000 | 1111111111111111 | 1 | 1 | 0 | 0 | 1 | 0 | 1111111111111110 | 0 | 1 | 15 | | 0000000000000000 | 1111111111111111 | 0 | 0 | 0 | 0 | 1 | 0 | 1111111111111111 | 0 | 1 | 16 | | 0000000000000000 | 1111111111111111 | 0 | 1 | 0 | 0 | 1 | 1 | 0000000000000001 | 0 | 0 | 17 | | 0000000000000000 | 1111111111111111 | 0 | 0 | 0 | 1 | 1 | 1 | 1111111111111111 | 0 | 1 | 18 | | 0000000000000000 | 1111111111111111 | 0 | 0 | 0 | 0 | 0 | 0 | 0000000000000000 | 1 | 0 | 19 | | 0000000000000000 | 1111111111111111 | 0 | 1 | 0 | 1 | 0 | 1 | 1111111111111111 | 0 | 1 | 20 | | 0000000000010001 | 0000000000000011 | 1 | 0 | 1 | 0 | 1 | 0 | 0000000000000000 | 1 | 0 | 21 | | 0000000000010001 | 0000000000000011 | 1 | 1 | 1 | 1 | 1 | 1 | 0000000000000001 | 0 | 0 | 22 | | 0000000000010001 | 0000000000000011 | 1 | 1 | 1 | 0 | 1 | 0 | 1111111111111111 | 0 | 1 | 23 | | 0000000000010001 | 0000000000000011 | 0 | 0 | 1 | 1 | 0 | 0 | 0000000000010001 | 0 | 0 | 24 | | 0000000000010001 | 0000000000000011 | 1 | 1 | 0 | 0 | 0 | 0 | 0000000000000011 | 0 | 0 | 25 | | 0000000000010001 | 0000000000000011 | 0 | 0 | 1 | 1 | 0 | 1 | 1111111111101110 | 0 | 1 | 26 | | 0000000000010001 | 0000000000000011 | 1 | 1 | 0 | 0 | 0 | 1 | 1111111111111100 | 0 | 1 | 27 | | 0000000000010001 | 0000000000000011 | 0 | 0 | 1 | 1 | 1 | 1 | 1111111111101111 | 0 | 1 | 28 | | 0000000000010001 | 0000000000000011 | 1 | 1 | 0 | 0 | 1 | 1 | 1111111111111101 | 0 | 1 | 29 | | 0000000000010001 | 0000000000000011 | 0 | 1 | 1 | 1 | 1 | 1 | 0000000000010010 | 0 | 0 | 30 | | 0000000000010001 | 0000000000000011 | 1 | 1 | 0 | 1 | 1 | 1 | 0000000000000100 | 0 | 0 | 31 | | 0000000000010001 | 0000000000000011 | 0 | 0 | 1 | 1 | 1 | 0 | 0000000000010000 | 0 | 0 | 32 | | 0000000000010001 | 0000000000000011 | 1 | 1 | 0 | 0 | 1 | 0 | 0000000000000010 | 0 | 0 | 33 | | 0000000000010001 | 0000000000000011 | 0 | 0 | 0 | 0 | 1 | 0 | 0000000000010100 | 0 | 0 | 34 | | 0000000000010001 | 0000000000000011 | 0 | 1 | 0 | 0 | 1 | 1 | 0000000000001110 | 0 | 0 | 35 | | 0000000000010001 | 0000000000000011 | 0 | 0 | 0 | 1 | 1 | 1 | 1111111111110010 | 0 | 1 | 36 | | 0000000000010001 | 0000000000000011 | 0 | 0 | 0 | 0 | 0 | 0 | 0000000000000001 | 0 | 0 | 37 | | 0000000000010001 | 0000000000000011 | 0 | 1 | 0 | 1 | 0 | 1 | 0000000000010011 | 0 | 0 | 38 | -------------------------------------------------------------------------------- /2-CPU/CPU.v: -------------------------------------------------------------------------------- 1 | /** 2 | * The Hack CPU (Central Processing unit), consisting of an ALU, 3 | * two registers named A and D, and a program counter named PC. 4 | * The CPU is designed to fetch and execute instructions written in 5 | * the Hack machine language. In particular, functions as follows: 6 | * Executes the inputted instruction according to the Hack machine 7 | * language specification. The D and A in the language specification 8 | * refer to CPU-resident registers, while M refers to the external 9 | * memory location addressed by A, i.e. to Memory[A]. The inM input 10 | * holds the value of this location. If the current instruction needs 11 | * to write a value to M, the value is placed in outM, the address 12 | * of the target location is placed in the addressM output, and the 13 | * writeM control bit is asserted. (When writeM==0, any value may 14 | * appear in outM). The outM and writeM outputs are combinational: 15 | * they are affected instantaneously by the execution of the current 16 | * instruction. The addressM and pc outputs are clocked: although they 17 | * are affected by the execution of the current instruction, they commit 18 | * to their new values only in the next time step. If reset==1 then the 19 | * CPU jumps to address 0 (i.e. pc is set to 0 in next time step) rather 20 | * than to the address resulting from executing the current instruction. 21 | */ 22 | 23 | module CPU( 24 | input wire clk, 25 | input wire [15:0] inM, // M value input (M = contents of RAM[A]) 26 | input wire [15:0] instruction, // Instruction for execution 27 | input wire reset, // Signals whether to re-start the current 28 | // program (rstn==1) or continue executing 29 | // the current program (rstn==0). 30 | 31 | output wire [15:0] outM, // M value output 32 | output wire loadM, // Write to M? 33 | output wire [15:0] addressM, // Address in data memory (of M) to read 34 | output reg [15:0] pc // address of next instruction 35 | ); 36 | 37 | // your implementation comes here: 38 | 39 | assign addressM = regA; 40 | wire loadI; 41 | wire loadA; 42 | wire loadD; 43 | assign outM = outALU; 44 | wire [15:0] am; 45 | assign am = (instruction[12]) ? inM : regA; 46 | wire lt; 47 | wire eq; 48 | wire jmp; 49 | wire inc; 50 | wire [15:0] outALU; 51 | 52 | reg [15:0] regA; 53 | reg [15:0] regD; 54 | ALU ALU_0( 55 | .x(regD), 56 | .y(am), 57 | .zx(instruction[11]), 58 | .nx(instruction[10]), 59 | .zy(instruction[9]), 60 | .ny(instruction[8]), 61 | .f(instruction[7]), 62 | .no(instruction[6]), 63 | .out(outALU), 64 | .zr(eq), 65 | .ng(lt) 66 | ); 67 | assign loadI = ~instruction[15]; 68 | assign loadA = instruction[15] & instruction[5]; 69 | assign loadD = instruction[15] & instruction[4]; 70 | assign loadM = instruction[15] & instruction[3]; 71 | assign jmp = instruction[15] & ((lt & instruction[2]) | (eq & instruction[1]) | ((!(lt|eq)) & instruction[0])); 72 | 73 | always @(posedge clk) 74 | if (reset) pc <= 0; 75 | else if (jmp) pc <= regA; 76 | else pc <= pc+1; 77 | 78 | always @(posedge clk) 79 | if (reset) regA <= 0; 80 | else if (loadI) regA <= instruction; 81 | else if (loadA) regA <= outALU; 82 | else regA <= regA; 83 | 84 | always @(posedge clk) 85 | if (reset) regD <= 0; 86 | else if (loadD) regD <= outALU; 87 | else regD <= regD; 88 | 89 | endmodule 90 | -------------------------------------------------------------------------------- /3-Hack/CPU.v: -------------------------------------------------------------------------------- 1 | /** 2 | * The Hack CPU (Central Processing unit), consisting of an ALU, 3 | * two registers named A and D, and a program counter named PC. 4 | * The CPU is designed to fetch and execute instructions written in 5 | * the Hack machine language. In particular, functions as follows: 6 | * Executes the inputted instruction according to the Hack machine 7 | * language specification. The D and A in the language specification 8 | * refer to CPU-resident registers, while M refers to the external 9 | * memory location addressed by A, i.e. to Memory[A]. The inM input 10 | * holds the value of this location. If the current instruction needs 11 | * to write a value to M, the value is placed in outM, the address 12 | * of the target location is placed in the addressM output, and the 13 | * writeM control bit is asserted. (When writeM==0, any value may 14 | * appear in outM). The outM and writeM outputs are combinational: 15 | * they are affected instantaneously by the execution of the current 16 | * instruction. The addressM and pc outputs are clocked: although they 17 | * are affected by the execution of the current instruction, they commit 18 | * to their new values only in the next time step. If reset==1 then the 19 | * CPU jumps to address 0 (i.e. pc is set to 0 in next time step) rather 20 | * than to the address resulting from executing the current instruction. 21 | */ 22 | 23 | module CPU( 24 | input wire clk, 25 | input wire [15:0] inM, // M value input (M = contents of RAM[A]) 26 | input wire [15:0] instruction, // Instruction for execution 27 | input wire reset, // Signals whether to re-start the current 28 | // program (rstn==1) or continue executing 29 | // the current program (rstn==0). 30 | 31 | output wire [15:0] outM, // M value output 32 | output wire loadM, // Write to M? 33 | output wire [15:0] addressM, // Address in data memory (of M) to read 34 | output reg [15:0] pc // address of next instruction 35 | ); 36 | 37 | // your implementation comes here: 38 | 39 | assign addressM = regA; 40 | wire loadI; 41 | wire loadA; 42 | wire loadD; 43 | assign outM = outALU; 44 | wire [15:0] am; 45 | assign am = (instruction[12]) ? inM : regA; 46 | wire lt; 47 | wire eq; 48 | wire jmp; 49 | wire inc; 50 | wire [15:0] outALU; 51 | 52 | reg [15:0] regA; 53 | reg [15:0] regD; 54 | ALU ALU_0( 55 | .x(regD), 56 | .y(am), 57 | .zx(instruction[11]), 58 | .nx(instruction[10]), 59 | .zy(instruction[9]), 60 | .ny(instruction[8]), 61 | .f(instruction[7]), 62 | .no(instruction[6]), 63 | .out(outALU), 64 | .zr(eq), 65 | .ng(lt) 66 | ); 67 | assign loadI = ~instruction[15]; 68 | assign loadA = instruction[15] & instruction[5]; 69 | assign loadD = instruction[15] & instruction[4]; 70 | assign loadM = instruction[15] & instruction[3]; 71 | assign jmp = instruction[15] & ((lt & instruction[2]) | (eq & instruction[1]) | ((!(lt|eq)) & instruction[0])); 72 | 73 | always @(posedge clk) 74 | if (reset) pc <= 0; 75 | else if (jmp) pc <= regA; 76 | else pc <= pc+1; 77 | 78 | always @(posedge clk) 79 | if (reset) regA <= 0; 80 | else if (loadI) regA <= instruction; 81 | else if (loadA) regA <= outALU; 82 | else regA <= regA; 83 | 84 | always @(posedge clk) 85 | if (reset) regD <= 0; 86 | else if (loadD) regD <= outALU; 87 | else regD <= regD; 88 | 89 | endmodule 90 | -------------------------------------------------------------------------------- /2-CPU/Readme.md: -------------------------------------------------------------------------------- 1 | ## Step 2 - CPU 2 | 3 | As always, try: 4 | 5 | ``` 6 | make test 7 | ``` 8 | 9 | And make sure you see: 10 | 11 | ``` 12 | --- CPU PASS --- 13 | 14 | --- ALL PASS --- 15 | ``` 16 | 17 | **When testing, be careful with the difference between LF (Linux) and CRLF (Windows).** 18 | 19 | There is only a single file you need to implement in this section: 20 | 21 | - CPU.v 22 | 23 | ### CPU.v 24 | 25 | ``` 26 | `default_nettype none 27 | module CPU( 28 | input wire clk, 29 | input wire [15:0] inM, // M value input (M = contents of RAM[A]) 30 | input wire [15:0] instruction, // Instruction for execution 31 | input wire reset, // Signals whether to re-start the current 32 | // program (reset==1) or continue executing 33 | // the current program (reset==0). 34 | 35 | output wire [15:0] outM, // M value output 36 | output wire loadM, // Write to M? 37 | output wire [15:0] addressM, // Address in data memory (of M) to read 38 | output reg [15:0] pc // address of next instruction 39 | ); 40 | 41 | // your implementation comes here: 42 | 43 | assign addressM = regA; 44 | wire loadI; 45 | wire loadA; 46 | wire loadD; 47 | assign outM = outALU; 48 | wire [15:0] am; 49 | assign am = (instruction[12]) ? inM : regA; 50 | wire lt; 51 | wire eq; 52 | wire jmp; 53 | wire inc; 54 | wire [15:0] outALU; 55 | 56 | ALU ALU_0( 57 | .x(regD), 58 | .y(am), 59 | .zx(instruction[11]), 60 | .nx(instruction[10]), 61 | .zy(instruction[9]), 62 | .ny(instruction[8]), 63 | .f(instruction[7]), 64 | .no(instruction[6]), 65 | .out(outALU), 66 | .zr(eq), 67 | .ng(lt) 68 | ); 69 | 70 | assign loadI = ~instruction[15]; 71 | assign loadA = instruction[15] & instruction[5]; 72 | assign loadD = instruction[15] & instruction[4]; 73 | assign loadM = instruction[15] & instruction[3]; 74 | assign jmp = instruction[15] & ((lt & instruction[2]) | (eq & instruction[1]) | ((!(lt|eq)) & instruction[0])); 75 | 76 | always @(posedge clk) 77 | if (reset) pc <= 0; 78 | else if (jmp) pc <= regA; 79 | else pc <= pc+1; 80 | 81 | reg [15:0] regA; 82 | always @(posedge clk) 83 | if (reset) regA <= 0; 84 | else if (loadI) regA <= instruction; 85 | else if (loadA) regA <= outALU; 86 | else regA <= regA; 87 | 88 | reg [15:0] regD; 89 | always @(posedge clk) 90 | if (reset) regD <= 0; 91 | else if (loadD) regD <= outALU; 92 | else regD <= regD; 93 | 94 | endmodule 95 | ``` 96 | 97 | 98 | 99 | ### What is CPU? 100 | 101 | ![](./img/CPU.png) 102 | 103 | 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. 104 | 105 | ---- 106 | 107 | **Congratulations**, let's move on to the last section of our journey. 108 | -------------------------------------------------------------------------------- /2-CPU/tb/CPU.cmp: -------------------------------------------------------------------------------- 1 | | pc | inM | instruction |rst| outM |wM | addressM | 2 | | 0000000000000000 | 0000000000000000 | 0000000000000000 | 1 | 0000000000000000 | 0 | 0000000000000000 | 3 | | 0000000000000001 | 0000000000000000 | 0000000000000000 | 0 | 0000000000000000 | 0 | 0000000000000000 | 4 | | 0000000000000010 | 0000000000000000 | 0011000000111001 | 0 | 0000000000000000 | 0 | 0000000000000000 | 5 | | 0000000000000100 | 0000000000000000 | 1110110000010000 | 0 | 1110110000010000 | 0 | 1110110000010000 | 6 | | 0000000000000101 | 0000000000000000 | 0101101110100000 | 0 | 1111111111111111 | 0 | 1110110000010000 | 7 | | 0000000000000111 | 0000000000000000 | 1110000111010000 | 0 | 1111010111000000 | 0 | 1110000111010000 | 8 | | 0000000000001000 | 0000000000000000 | 0000001111101000 | 0 | 0000101001000000 | 0 | 1110000111010000 | 9 | | 0000000000001010 | 0000000000000000 | 1110001100001000 | 0 | 1111010111000000 | 1 | 1110001100001000 | 10 | | 0000000000001011 | 0000000000000000 | 0000001111101001 | 0 | 0000101001000000 | 0 | 1110001100001000 | 11 | | 0000000000001101 | 0000000000000000 | 1110001110011000 | 0 | 1111010110111111 | 1 | 1110001110011000 | 12 | | 0000000000001110 | 0000000000000000 | 0000001111101000 | 0 | 0000101001000001 | 0 | 1110001110011000 | 13 | | 0000000000010001 | 0010101101100111 | 1111010011010000 | 0 | 1100101001011000 | 0 | 1111010011010000 | 14 | | 0000000000010010 | 0010101101100111 | 0000000000001110 | 0 | 1100000001010000 | 0 | 1111010011010000 | 15 | | 0000000000010100 | 0010101101100111 | 1110001100000100 | 0 | 1100101001011000 | 0 | 1110001100000100 | 16 | | 1110001100000100 | 0010101101100111 | 0000001111100111 | 0 | 0011010110101000 | 0 | 1110001100000100 | 17 | | 1110001100000110 | 0010101101100111 | 1110110111100000 | 0 | 1110110111100001 | 0 | 1110110111100000 | 18 | | 1110001100000111 | 0010101101100111 | 1110001100001000 | 0 | 1100101001011000 | 1 | 1110110111100001 | 19 | | 1110001100001001 | 0010101101100111 | 0000000000010101 | 0 | 1100100001000000 | 0 | 1110110111100001 | 20 | | 1110001100001010 | 0010101101100111 | 1110011111000010 | 0 | 1100101001011001 | 0 | 0000000000010101 | 21 | | 1110001100001100 | 0010101101100111 | 0000000000000010 | 0 | 0000000000010000 | 0 | 0000000000010101 | 22 | | 1110001100001101 | 0010101101100111 | 1110000010010000 | 0 | 1100101001011010 | 0 | 0000000000000010 | 23 | | 1110001100001111 | 0010101101100111 | 0000001111101000 | 0 | 0011010110100100 | 0 | 0000000000000010 | 24 | | 1110001100010000 | 0010101101100111 | 1110111010010000 | 0 | 1111111111111111 | 0 | 0000001111101000 | 25 | | 1110001100010010 | 0010101101100111 | 1110001100000001 | 0 | 1111111111111111 | 0 | 0000001111101000 | 26 | | 1110001100010011 | 0010101101100111 | 1110001100000010 | 0 | 1111111111111111 | 0 | 0000001111101000 | 27 | | 1110001100010101 | 0010101101100111 | 1110001100000011 | 0 | 1111111111111111 | 0 | 0000001111101000 | 28 | | 1110001100010110 | 0010101101100111 | 1110001100000100 | 0 | 1111111111111111 | 0 | 0000001111101000 | 29 | | 0000001111101000 | 0010101101100111 | 1110001100000101 | 0 | 1111111111111111 | 0 | 0000001111101000 | 30 | | 0000001111101000 | 0010101101100111 | 1110001100000110 | 0 | 1111111111111111 | 0 | 0000001111101000 | 31 | | 0000001111101000 | 0010101101100111 | 1110001100000111 | 0 | 1111111111111111 | 0 | 0000001111101000 | 32 | | 0000001111101000 | 0010101101100111 | 1110101010010000 | 0 | 0000000000000000 | 0 | 0000001111101000 | 33 | | 0000001111101010 | 0010101101100111 | 1110001100000001 | 0 | 0000000000000000 | 0 | 0000001111101000 | 34 | | 0000001111101011 | 0010101101100111 | 1110001100000010 | 0 | 0000000000000000 | 0 | 0000001111101000 | 35 | | 0000001111101000 | 0010101101100111 | 1110001100000011 | 0 | 0000000000000000 | 0 | 0000001111101000 | 36 | | 0000001111101000 | 0010101101100111 | 1110001100000100 | 0 | 0000000000000000 | 0 | 0000001111101000 | 37 | | 0000001111101010 | 0010101101100111 | 1110001100000101 | 0 | 0000000000000000 | 0 | 0000001111101000 | 38 | | 0000001111101011 | 0010101101100111 | 1110001100000110 | 0 | 0000000000000000 | 0 | 0000001111101000 | 39 | | 0000001111101000 | 0010101101100111 | 1110001100000111 | 0 | 0000000000000000 | 0 | 0000001111101000 | 40 | | 0000001111101000 | 0010101101100111 | 1110111111010000 | 0 | 0000000000000001 | 0 | 0000001111101000 | 41 | | 0000001111101010 | 0010101101100111 | 1110001100000001 | 0 | 0000000000000001 | 0 | 0000001111101000 | 42 | | 0000001111101000 | 0010101101100111 | 1110001100000010 | 0 | 0000000000000001 | 0 | 0000001111101000 | 43 | | 0000001111101010 | 0010101101100111 | 1110001100000011 | 0 | 0000000000000001 | 0 | 0000001111101000 | 44 | | 0000001111101000 | 0010101101100111 | 1110001100000100 | 0 | 0000000000000001 | 0 | 0000001111101000 | 45 | | 0000001111101010 | 0010101101100111 | 1110001100000101 | 0 | 0000000000000001 | 0 | 0000001111101000 | 46 | | 0000001111101000 | 0010101101100111 | 1110001100000110 | 0 | 0000000000000001 | 0 | 0000001111101000 | 47 | | 0000001111101010 | 0010101101100111 | 1110001100000111 | 0 | 0000000000000001 | 0 | 0000001111101000 | 48 | | 0000001111101000 | 0010101101100111 | 1110001100000111 | 1 | 0000000000000001 | 0 | 0000001111101000 | 49 | | 0000000000000001 | 0010101101100111 | 0111111111111111 | 0 | 0000000000000001 | 0 | 0111111111111111 | 50 | -------------------------------------------------------------------------------- /2-CPU/tb/CPU_tb.v: -------------------------------------------------------------------------------- 1 | `default_nettype none 2 | module CPU_tb(); 3 | 4 | integer file; 5 | reg clk=0; 6 | reg [15:0] inM=0; 7 | reg [15:0] instruction=0; 8 | reg reset=1; 9 | wire [15:0] outM; 10 | wire loadM; 11 | wire [15:0] addressM; 12 | wire [15:0] pc; 13 | CPU CPU( 14 | .clk(clk), 15 | .inM(inM), 16 | .instruction(instruction), 17 | .reset(reset), 18 | .outM(outM), 19 | .loadM(loadM), 20 | .addressM(addressM), 21 | .pc(pc) 22 | ); 23 | 24 | always #1 clk = ~clk; 25 | 26 | task display; 27 | #1 $fwrite(file, "| %16b | %16b | %16b | %1b | %16b | %1b | %16b |\n",pc,inM,instruction,reset,outM,loadM,addressM); 28 | endtask 29 | 30 | initial begin 31 | $dumpfile("CPU_tb.vcd"); 32 | $dumpvars(0, CPU_tb); 33 | file = $fopen("CPU.out","w"); 34 | $fwrite(file, "| pc | inM | instruction |rst| outM |wM | addressM |\n"); 35 | 36 | #1 reset = 1; 37 | display(); 38 | #1 reset = 0; 39 | display(); 40 | #2 instruction = 16'b0011000000111001; // @12345 41 | display(); 42 | 43 | #2 instruction = 16'b1110110000010000; // D=A 44 | display(); 45 | 46 | #2 instruction = 16'b0101101110100000; // @23456 47 | display(); 48 | 49 | #2 instruction = 16'b1110000111010000; // D=A-D 50 | display(); 51 | 52 | #2 instruction = 16'b0000001111101000; // @1000 53 | display(); 54 | 55 | #2 instruction = 16'b1110001100001000; // M=D 56 | display(); 57 | 58 | #2 instruction = 16'b0000001111101001; // @1001 59 | display(); 60 | 61 | #2 instruction = 16'b1110001110011000; // MD=D-1 62 | display(); 63 | 64 | #2 instruction = 16'b0000001111101000; // @1000 65 | display(); 66 | 67 | #2 instruction = 16'b1111010011010000; // D=D-M 68 | #2 inM=11111; 69 | display(); 70 | 71 | #2 instruction = 16'b0000000000001110; // @14 72 | display(); 73 | 74 | #2 instruction = 16'b1110001100000100; // D;jlt 75 | display(); 76 | 77 | #2 instruction = 16'b0000001111100111; // @999 78 | display(); 79 | 80 | #2 instruction = 16'b1110110111100000; // A=A+1 81 | display(); 82 | 83 | #2 instruction = 16'b1110001100001000; // M=D 84 | display(); 85 | 86 | #2 instruction = 16'b0000000000010101; // @21 87 | display(); 88 | 89 | #2 instruction = 16'b1110011111000010; // D+1;jeq 90 | display(); 91 | 92 | #2 instruction = 16'b0000000000000010; // @2 93 | display(); 94 | 95 | #2 instruction = 16'b1110000010010000; // D=D+A 96 | display(); 97 | 98 | #2 instruction = 16'b0000001111101000; // @1000 99 | display(); 100 | 101 | #2 instruction = 16'b1110111010010000; // D=-1 102 | display(); 103 | 104 | #2 instruction = 16'b1110001100000001; // D;JGT 105 | display(); 106 | 107 | #2 instruction = 16'b1110001100000010; // D;JEQ 108 | display(); 109 | 110 | #2 instruction = 16'b1110001100000011; // D;JGE 111 | display(); 112 | 113 | #2 instruction = 16'b1110001100000100; // D;JLT 114 | display(); 115 | 116 | #2 instruction = 16'b1110001100000101; // D;JNE 117 | display(); 118 | 119 | #2 instruction = 16'b1110001100000110; // D;JLE 120 | display(); 121 | 122 | #2 instruction = 16'b1110001100000111; // D;JMP 123 | display(); 124 | 125 | #2 instruction = 16'b1110101010010000; // D=0 126 | display(); 127 | 128 | #2 instruction = 16'b1110001100000001; // D;JGT 129 | display(); 130 | 131 | #2 instruction = 16'b1110001100000010; // D;JEQ 132 | display(); 133 | 134 | #2 instruction = 16'b1110001100000011; // D;JGE 135 | display(); 136 | 137 | #2 instruction = 16'b1110001100000100; // D;JLT 138 | display(); 139 | 140 | #2 instruction = 16'b1110001100000101; // D;JNE 141 | display(); 142 | 143 | #2 instruction = 16'b1110001100000110; // D;JLE 144 | display(); 145 | 146 | #2 instruction = 16'b1110001100000111; // D;JMP 147 | display(); 148 | 149 | #2 instruction = 16'b1110111111010000; // D=1 150 | display(); 151 | 152 | #2 instruction = 16'b1110001100000001; // D;JGT 153 | display(); 154 | 155 | #2 instruction = 16'b1110001100000010; // D;JEQ 156 | display(); 157 | 158 | #2 instruction = 16'b1110001100000011; // D;JGE 159 | display(); 160 | 161 | #2 instruction = 16'b1110001100000100; // D;JLT 162 | display(); 163 | 164 | #2 instruction = 16'b1110001100000101; // D;JNE 165 | display(); 166 | 167 | #2 instruction = 16'b1110001100000110; // D;JLE 168 | display(); 169 | 170 | #2 instruction = 16'b1110001100000111; // D;JMP 171 | display(); 172 | 173 | #2 reset=1; 174 | display(); 175 | 176 | #2 instruction = 16'b0111111111111111; // @32767 177 | #2 reset=0; 178 | display(); 179 | 180 | $finish; 181 | end 182 | 183 | endmodule 184 | -------------------------------------------------------------------------------- /3-Hack/Readme.md: -------------------------------------------------------------------------------- 1 | ## Step 3 - Computer 2 | Unfortunately, there is no test file in the last section, but you can test it on your real hardware. 3 | 4 | ### Reset.v 5 | 6 | ``` 7 | /** 8 | * The module rst delivers a reset signal at power up which 9 | * is clocked by clk. 10 | * 11 | * The timing diagram should be: 12 | * ------------------------------------------- 13 | * clk 0 | 1 | 0 | 1 | 0 | 1 | 0 | 1 ... 14 | * ------------------------------------------- 15 | * reset 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 ... 16 | * ------------------------------------------- 17 | */ 18 | 19 | module Reset( 20 | input wire clk, 21 | output wire reset 22 | ); 23 | 24 | // your implementation comes here: 25 | 26 | // remember that you did it 27 | reg done = 0; 28 | always @(posedge clk) 29 | done <= 1; 30 | 31 | // reset it on start 32 | reg reset_r = 0; 33 | always @(posedge clk) begin 34 | if (done==0) reset_r <=1; 35 | else reset_r <= 0; 36 | end 37 | 38 | assign reset = reset_r; 39 | 40 | endmodule 41 | ``` 42 | 43 | ### Rom.v 44 | 45 | ``` 46 | /** 47 | * The module rom provides access to the instruction memory 48 | * of hack. The instruction memory is read only (ROM) and 49 | * preloaded with 4Kx16bit of Hackcode. 50 | * 51 | * The signal data (16bit) provides the instruction at memory address 52 | * data = ROM[address] 53 | */ 54 | 55 | module ROM( 56 | input wire [15:0] address, 57 | output wire [15:0] data 58 | ); 59 | 60 | // your implementation comes here: 61 | 62 | // ROM file of hack 63 | parameter ROMFILE = "./blinky.hack"; 64 | 65 | reg [15:0] regROM [0:1023]; 66 | assign data = regROM[address]; 67 | initial begin 68 | $readmemb(ROMFILE,regROM); 69 | end 70 | 71 | endmodule 72 | ``` 73 | 74 | ### Memory.v 75 | 76 | ``` 77 | /* 78 | * The module mem provides access to memory RAM 79 | * and memory mapped IO 80 | * In our Minimal-Hack-Project we will use 4Kx16 Bit RAM 81 | * 82 | * address | memory 83 | * ---------------- 84 | * 0-4047 | RAM 85 | * 8192 | but 86 | * 8193 | led 87 | * 88 | * WRITE: 89 | * When load is set to 1, 16 bit dataW are stored to Memory address 90 | * at next clock cycle. M[address] <= dataW 91 | * READ: 92 | * dataR provides data stored in Memory at address. 93 | * dataR = M[address] 94 | * 95 | */ 96 | 97 | module Memory( 98 | input wire clk, 99 | input wire [15:0] address, 100 | input wire [15:0] dataW, 101 | output wire [15:0] dataR, 102 | input wire load, 103 | input wire [1:0] but, 104 | output wire [1:0] led 105 | ); 106 | 107 | // your implementation comes here: 108 | 109 | // Read Memory 110 | assign dataR = (address[13]==0)? regRAM[address[11:0]] : memGPIO; 111 | wire [15:0] memGPIO; 112 | assign memGPIO = (address[0]==0)? regLED : but; 113 | 114 | // Write to RAM 115 | reg [15:0] regRAM [0:8191]; 116 | always @(posedge clk) begin 117 | if (load & (address[13]==0)) regRAM[address[11:0]] <= dataW; 118 | end 119 | 120 | // leds 121 | assign led = regLED[1:0]; 122 | reg [15:0] regLED = 0; 123 | always @(posedge clk) begin 124 | if (load & (address==8192)) regLED <= dataW; 125 | else regLED <= regLED; 126 | end 127 | 128 | endmodule 129 | ``` 130 | 131 | The last file to accomplish. 132 | 133 | ### Hack.v 134 | 135 | ``` 136 | /** 137 | * The module hack is our top-level module 138 | * It connects the external pins of our fpga (hack.pcf) 139 | * to the internal components (cpu,mem,clk,rst,rom) 140 | * 141 | */ 142 | 143 | `default_nettype none 144 | module hack( // top level module 145 | input wire clk, 146 | input wire [1:0] but, // buttons (0 if pressed, 1 if released) 147 | output wire [1:0] led // leds (0 off, 1 on) 148 | ); 149 | 150 | // your implementation comes here: 151 | 152 | // reset logic 153 | wire reset; 154 | Reset Reset_0(.clk(clk),.reset(reset)); 155 | 156 | // hack cpu (nand2tetris) 157 | wire [15:0] pc; 158 | wire [15:0] instruction; 159 | wire [15:0] addressM; 160 | wire [15:0] inM; 161 | wire loadM; 162 | wire [15:0] outM; 163 | CPU CPU_0( 164 | .clk(clk), 165 | .inM(inM), // M value input (M = contents of RAM[A]) 166 | .instruction(instruction), // Instruction for execution 167 | .reset(reset), // Signals whether to re-start the current 168 | // program (rstn==0) or continue executing 169 | // the current program (rstn==1). 170 | .outM(outM), // M value output 171 | .loadM(loadM), // Write to M? 172 | .addressM(addressM), // Address in data memory to Read(of M) 173 | .pc(pc) // address of next instruction 174 | ); 175 | 176 | // rom stores hack code 177 | ROM ROM_0( 178 | .address(pc), 179 | .data(instruction) 180 | ); 181 | 182 | // mem gives access to ram and io 183 | Memory Memory_0( 184 | .clk(clk), 185 | .address(addressM), 186 | .dataR(inM), 187 | .dataW(outM), 188 | .load(loadM), 189 | .but(but), 190 | .led(led) 191 | ); 192 | 193 | endmodule 194 | ``` 195 | 196 | ### Hack Computer 197 | 198 | Hack1 is a minimal version of our hack computer consisting of six hardware modules (Clock, CPU, ROM, RAM, Memory, Register). The memory can address 2048 words of RAM plus two registers mapped to I/O, with which we can control button and leds on the board. ROM of 2048 words will be preloaded with small assembler programs to test the hardware. 199 | 200 | ![](./img/Hack1.png) 201 | 202 | ### Memory map 203 | |address | memory|R/W|function| 204 | |-|-|-|-| 205 | |0-2047 | RAM|R/W|R0--R15, static, stack, heap| 206 | | 8192 | but|R/W|0 = button pressed, 1 = button released| 207 | | 8193 | led|R/W|0 = led off, 1 = led on| 208 | 209 | --- 210 | 211 | **That's it**, not a long journey, right? Now you have a computer running at100 MHz (clk_in), with two buttons (but[1:0]) and two leds (led[1:0]). 212 | -------------------------------------------------------------------------------- /1-ALU/tb/ALU_tb.v: -------------------------------------------------------------------------------- 1 | `default_nettype none 2 | module ALU_tb(); 3 | 4 | integer file; 5 | 6 | reg [15:0] x; 7 | reg [15:0] y; 8 | reg zx; 9 | reg nx; 10 | reg zy; 11 | reg ny; 12 | reg f; 13 | reg no; 14 | wire [15:0] out; 15 | wire zr; 16 | wire ng; 17 | 18 | ALU ALU( 19 | .x(x), 20 | .y(y), 21 | .zx(zx), 22 | .nx(nx), 23 | .zy(zy), 24 | .ny(ny), 25 | .f(f), 26 | .no(no), 27 | .out(out), 28 | .zr(zr), 29 | .ng(ng) 30 | ); 31 | 32 | task display; 33 | #1 $fwrite(file, "| %16b | %16b | %1b | %1b | %1b | %1b | %1b | %1b | %16b | %1b | %1b |\n",x,y,zx,nx,zy,ny,f,no,out,zr,ng); 34 | endtask 35 | 36 | initial begin 37 | $dumpfile("ALU_tb.vcd"); 38 | $dumpvars(0, ALU_tb); 39 | file = $fopen("ALU.out","w"); 40 | $fwrite(file, "| x | y |zx |nx |zy |ny | f |no | out |zr |ng |\n"); 41 | 42 | x = 16'b0000000000000000; // x ==0 43 | y = 16'b1111111111111111; // y = -1 44 | 45 | // Compute=0 46 | zx = 1; 47 | nx =0; 48 | zy=1; 49 | ny=0; 50 | f =1; 51 | no=0; 52 | display(); 53 | 54 | // Compute 1 55 | zx=1; 56 | nx=1; 57 | zy=1; 58 | ny=1; 59 | f =1; 60 | no=1; 61 | 62 | display(); 63 | 64 | 65 | // Compute -1 66 | zx=1; 67 | nx=1; 68 | zy=1; 69 | ny=0; 70 | f =1; 71 | no=0; 72 | 73 | display(); 74 | 75 | // Compute x 76 | zx=0; 77 | nx=0; 78 | zy=1; 79 | ny=1; 80 | f =0; 81 | no=0; 82 | 83 | display(); 84 | 85 | // Compute y 86 | zx=1; 87 | nx=1; 88 | zy=0; 89 | ny=0; 90 | f =0; 91 | no=0; 92 | 93 | display(); 94 | 95 | // Compute !x 96 | zx=0; 97 | nx=0; 98 | zy=1; 99 | ny=1; 100 | f =0; 101 | no=1; 102 | 103 | display(); 104 | 105 | // Compute !y 106 | zx=1; 107 | nx=1; 108 | zy=0; 109 | ny=0; 110 | f =0; 111 | no=1; 112 | 113 | display(); 114 | 115 | // Compute -x 116 | zx=0; 117 | nx=0; 118 | zy=1; 119 | ny=1; 120 | f =1; 121 | no=1; 122 | 123 | display(); 124 | 125 | // Compute -y 126 | zx=1; 127 | nx=1; 128 | zy=0; 129 | ny=0; 130 | f =1; 131 | no=1; 132 | 133 | display(); 134 | 135 | // Compute x + 1 136 | zx=0; 137 | nx=1; 138 | zy=1; 139 | ny=1; 140 | f =1; 141 | no=1; 142 | 143 | display(); 144 | 145 | // Compute y + 1 146 | zx=1; 147 | nx=1; 148 | zy=0; 149 | ny=1; 150 | f =1; 151 | no=1; 152 | 153 | display(); 154 | 155 | // Compute x - 1 156 | zx=0; 157 | nx=0; 158 | zy=1; 159 | ny=1; 160 | f =1; 161 | no=0; 162 | 163 | display(); 164 | 165 | // Compute y - 1 166 | zx=1; 167 | nx=1; 168 | zy=0; 169 | ny=0; 170 | f =1; 171 | no=0; 172 | 173 | display(); 174 | 175 | 176 | // Compute x + y 177 | zx=0; 178 | nx=0; 179 | zy=0; 180 | ny=0; 181 | f =1; 182 | no=0; 183 | 184 | display(); 185 | 186 | 187 | // Compute x - y 188 | zx=0; 189 | nx=1; 190 | zy=0; 191 | ny=0; 192 | f =1; 193 | no=1; 194 | 195 | display(); 196 | 197 | // Compute y - x 198 | zx=0; 199 | nx=0; 200 | zy=0; 201 | ny=1; 202 | f =1; 203 | no=1; 204 | 205 | display(); 206 | 207 | // Compute x & y 208 | zx=0; 209 | nx=0; 210 | zy=0; 211 | ny=0; 212 | f =0; 213 | no=0; 214 | 215 | display(); 216 | 217 | // Compute x | y 218 | zx=0; 219 | nx=1; 220 | zy=0; 221 | ny=1; 222 | f =0; 223 | no=1; 224 | 225 | display(); 226 | 227 | x=16'b000000000010001; // x = 17 228 | y=16'b000000000000011; // y = 3 229 | 230 | // Compute=0 231 | zx=1; 232 | nx=0; 233 | zy=1; 234 | ny=0; 235 | f =1; 236 | no=0; 237 | 238 | display(); 239 | 240 | // Compute 1 241 | zx=1; 242 | nx=1; 243 | zy=1; 244 | ny=1; 245 | f =1; 246 | no=1; 247 | 248 | display(); 249 | 250 | // Compute -1 251 | zx=1; 252 | nx=1; 253 | zy=1; 254 | ny=0; 255 | f =1; 256 | no=0; 257 | 258 | display(); 259 | 260 | // Compute x 261 | zx=0; 262 | nx=0; 263 | zy=1; 264 | ny=1; 265 | f =0; 266 | no=0; 267 | 268 | display(); 269 | 270 | // Compute y 271 | zx=1; 272 | nx=1; 273 | zy=0; 274 | ny=0; 275 | f =0; 276 | no=0; 277 | 278 | display(); 279 | 280 | // Compute !x 281 | zx=0; 282 | nx=0; 283 | zy=1; 284 | ny=1; 285 | f =0; 286 | no=1; 287 | 288 | display(); 289 | 290 | // Compute !y 291 | zx=1; 292 | nx=1; 293 | zy=0; 294 | ny=0; 295 | f =0; 296 | no=1; 297 | 298 | display(); 299 | 300 | // Compute -x 301 | zx=0; 302 | nx=0; 303 | zy=1; 304 | ny=1; 305 | f =1; 306 | no=1; 307 | 308 | display(); 309 | 310 | // Compute -y 311 | zx=1; 312 | nx=1; 313 | zy=0; 314 | ny=0; 315 | f =1; 316 | no=1; 317 | 318 | display(); 319 | 320 | // Compute x + 1 321 | zx=0; 322 | nx=1; 323 | zy=1; 324 | ny=1; 325 | f =1; 326 | no=1; 327 | 328 | display(); 329 | 330 | // Compute y + 1 331 | zx=1; 332 | nx=1; 333 | zy=0; 334 | ny=1; 335 | f =1; 336 | no=1; 337 | 338 | display(); 339 | 340 | // Compute x - 1 341 | zx=0; 342 | nx=0; 343 | zy=1; 344 | ny=1; 345 | f =1; 346 | no=0; 347 | 348 | display(); 349 | 350 | // Compute y - 1 351 | zx=1; 352 | nx=1; 353 | zy=0; 354 | ny=0; 355 | f =1; 356 | no=0; 357 | 358 | display(); 359 | 360 | // Compute x + y 361 | zx=0; 362 | nx=0; 363 | zy=0; 364 | ny=0; 365 | f =1; 366 | no=0; 367 | 368 | display(); 369 | 370 | // Compute x - y 371 | zx=0; 372 | nx=1; 373 | zy=0; 374 | ny=0; 375 | f =1; 376 | no=1; 377 | 378 | display(); 379 | 380 | // Compute y - x 381 | zx=0; 382 | nx=0; 383 | zy=0; 384 | ny=1; 385 | f =1; 386 | no=1; 387 | 388 | display(); 389 | 390 | // Compute x & y 391 | zx=0; 392 | nx=0; 393 | zy=0; 394 | ny=0; 395 | f =0; 396 | no=0; 397 | 398 | display(); 399 | 400 | // Compute x | y 401 | zx=0; 402 | nx=1; 403 | zy=0; 404 | ny=1; 405 | f =0; 406 | no=1; 407 | 408 | display(); 409 | 410 | $finish; 411 | end 412 | 413 | endmodule 414 | --------------------------------------------------------------------------------