added v2.0

This commit is contained in:
Michael Schröder
2023-01-11 11:13:09 +01:00
parent 2a5a64ca91
commit 971b323822
584 changed files with 159319 additions and 0 deletions

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

View File

@@ -0,0 +1,48 @@
[*]
[*] GTKWave Analyzer v3.3.104 (w)1999-2020 BSI
[*] Fri Dec 23 09:59:16 2022
[*]
[dumpfile] "/home/micha/gitlab/nand2tetris/05_Computer_Architecture/01_CPU/CPU_tb.vcd"
[dumpfile_mtime] "Fri Dec 23 09:58:03 2022"
[dumpfile_size] 3204741
[savefile] "/home/micha/gitlab/nand2tetris/05_Computer_Architecture/01_CPU/CPU_tb.gtkw"
[timestart] 0
[size] 1866 600
[pos] -1 -1
*-3.000000 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
[treeopen] CPU_tb.
[sst_width] 281
[signals_width] 210
[sst_expanded] 1
[sst_vpaned_height] 132
@28
CPU_tb.clk
@200
-IN
@22
CPU_tb.inM[15:0]
CPU_tb.instruction[15:0]
@28
CPU_tb.reset
@200
-OUT
@22
CPU_tb.addressM[15:0]
CPU_tb.outM[15:0]
CPU_tb.pc[15:0]
@28
CPU_tb.writeM
@200
-CMP
@22
CPU_tb.addressM_cmp[15:0]
CPU_tb.out_cmp[15:0]
CPU_tb.pc_cmp[15:0]
@28
CPU_tb.writeM_cmp
@200
-Test
@28
CPU_tb.fail
[pattern_trace] 1
[pattern_trace] 0

View File

@@ -0,0 +1,86 @@
`default_nettype none
module CPU_tb();
// IN,OUT
reg clk=1;
reg [15:0] inM=0;
reg [15:0] instruction=0;
reg reset=1;
wire [15:0] outM;
wire writeM;
wire [15:0] addressM;
wire [15:0] pc;
// Part
CPU CPU(
.clk(clk),
.inM(inM),
.instruction(instruction),
.reset(reset),
.outM(outM),
.writeM(writeM),
.addressM(addressM),
.pc(pc)
);
// Simulation
always #1 clk=~clk;
always @(posedge clk) begin
inM <= $random;
reset <= (n<=10) || ((n>20) && (n<40));
instruction <= $random;
end
// Compare
reg [15:0] addressM_cmp=0;
reg [15:0] regD=0;
reg [15:0] pc_cmp=0;
reg zx,nx,zy,ny,f,no;
wire [15:0] out_cmp;
wire [15:0] x,y;
wire zr,ng;
assign x = instruction[10]?(instruction[11]?~0:~regD):(instruction[11]?0:regD);
assign y = instruction[8]?(instruction[9]?~0:~(instruction[12]?inM:addressM_cmp)):(instruction[9]?0:(instruction[12]?inM:addressM_cmp));
assign out_cmp = instruction[6]?(instruction[7]?~(x+y):~(x&y)):(instruction[7]?(x+y):(x&y));
wire comp;
wire jmp;
assign comp = instruction[15] && instruction[14] && instruction[13];
assign zr = (out_cmp==0);
assign ng = out_cmp[15];
assign jmp = comp && ((ng&&instruction[2])||(zr&&instruction[1])||(~(ng|zr)&&instruction[0]));
always @(posedge clk) begin
addressM_cmp <= comp?(instruction[5]?out_cmp:addressM_cmp) : instruction;
regD <= comp?(instruction[4]?out_cmp:regD) : regD;
pc_cmp <= reset?0 : (jmp?addressM_cmp:pc_cmp+1);
end
wire writeM_cmp;
assign writeM_cmp = comp?instruction[3]:0;
reg fail = 0;
reg [15:0] n = 0;
task check;
#1
if ((pc != pc_cmp) || (addressM != addressM_cmp) || (outM != out_cmp) || (writeM != writeM_cmp))
begin
$display("FAIL: clk=%1b, inM=%16b, instruction=%16b, reset=%1b, outM=%16b, writeM=%1b, addressM=%16b, pc=%16b",clk,inM,instruction,reset,outM,writeM,addressM,pc);
fail=1;
end
endtask
// Test
initial begin
$dumpfile("CPU_tb.vcd");
$dumpvars(0, CPU_tb);
$display("------------------------");
$display("Testbench: CPU");
for (n=0; n<1000;n=n+1)
check();
if (fail==0) $display("passed");
$display("------------------------");
$finish;
end
endmodule

View File

@@ -0,0 +1,33 @@
`include "../../01_Boolean_Logic/Nand.v"
`include "../../01_Boolean_Logic/Not.v"
`include "../../01_Boolean_Logic/Buffer.v"
`include "../../01_Boolean_Logic/And.v"
`include "../../01_Boolean_Logic/Or.v"
`include "../../01_Boolean_Logic/Xor.v"
`include "../../01_Boolean_Logic/Mux.v"
`include "../../01_Boolean_Logic/DMux.v"
`include "../../01_Boolean_Logic/Not16.v"
`include "../../01_Boolean_Logic/Buffer16.v"
`include "../../01_Boolean_Logic/And16.v"
`include "../../01_Boolean_Logic/Or16.v"
`include "../../01_Boolean_Logic/Mux16.v"
`include "../../01_Boolean_Logic/Or8Way.v"
`include "../../01_Boolean_Logic/Mux4Way16.v"
`include "../../01_Boolean_Logic/Mux8Way16.v"
`include "../../01_Boolean_Logic/DMux4Way.v"
`include "../../01_Boolean_Logic/DMux8Way.v"
`include "../../02_Boolean_Arithmetic/HalfAdder.v"
`include "../../02_Boolean_Arithmetic/FullAdder.v"
`include "../../02_Boolean_Arithmetic/Add16.v"
`include "../../02_Boolean_Arithmetic/Inc16.v"
`include "../../02_Boolean_Arithmetic/ALU.v"
`include "../../03_Sequential_Logic/DFF.v"
`include "../../03_Sequential_Logic/Bit.v"
`include "../../03_Sequential_Logic/Register.v"
`include "../../03_Sequential_Logic/PC.v"
`include "../../03_Sequential_Logic/BitShift9R.v"
`include "../../03_Sequential_Logic/BitShift8L.v"
`include "../../05_Computer_Architecture/CPU.v"

View File

@@ -0,0 +1,3 @@
[env]
board = iCE40-HX1K-EVB

View File

@@ -0,0 +1,34 @@
`include "../../01_Boolean_Logic/Nand.v"
`include "../../01_Boolean_Logic/Not.v"
`include "../../01_Boolean_Logic/Buffer.v"
`include "../../01_Boolean_Logic/And.v"
`include "../../01_Boolean_Logic/Or.v"
`include "../../01_Boolean_Logic/Xor.v"
`include "../../01_Boolean_Logic/Mux.v"
`include "../../01_Boolean_Logic/DMux.v"
`include "../../01_Boolean_Logic/Not16.v"
`include "../../01_Boolean_Logic/Buffer16.v"
`include "../../01_Boolean_Logic/And16.v"
`include "../../01_Boolean_Logic/Or16.v"
`include "../../01_Boolean_Logic/Mux16.v"
`include "../../01_Boolean_Logic/Or8Way.v"
`include "../../01_Boolean_Logic/Mux4Way16.v"
`include "../../01_Boolean_Logic/Mux8Way16.v"
`include "../../01_Boolean_Logic/DMux4Way.v"
`include "../../01_Boolean_Logic/DMux8Way.v"
`include "../../02_Boolean_Arithmetic/HalfAdder.v"
`include "../../02_Boolean_Arithmetic/FullAdder.v"
`include "../../02_Boolean_Arithmetic/Add16.v"
`include "../../02_Boolean_Arithmetic/Inc16.v"
`include "../../02_Boolean_Arithmetic/ALU.v"
`include "../../03_Sequential_Logic/DFF.v"
`include "../../03_Sequential_Logic/Bit.v"
`include "../../03_Sequential_Logic/Register.v"
`include "../../03_Sequential_Logic/PC.v"
`include "../../03_Sequential_Logic/BitShift9R.v"
`include "../../03_Sequential_Logic/BitShift8L.v"
`include "../../05_Computer_Architecture/CPU.v"
`include "../../05_Computer_Architecture/Memory.v"

View File

@@ -0,0 +1,67 @@
[*]
[*] GTKWave Analyzer v3.3.104 (w)1999-2020 BSI
[*] Tue Nov 22 10:53:14 2022
[*]
[dumpfile] "/home/micha/gitlab/nand2tetris/05_Computer_Architecture/02_Memory/Memory_tb.vcd"
[dumpfile_mtime] "Tue Nov 22 10:50:29 2022"
[dumpfile_size] 15133403
[savefile] "/home/micha/gitlab/nand2tetris/05_Computer_Architecture/02_Memory/Memory_tb.gtkw"
[timestart] 0
[size] 1920 963
[pos] -1 -1
*0.000000 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
[sst_width] 281
[signals_width] 160
[sst_expanded] 1
[sst_vpaned_height] 258
@200
-IN
@22
Memory_tb.address[15:0]
Memory_tb.inRAM[15:0]
Memory_tb.inIO0[15:0]
Memory_tb.inIO1[15:0]
Memory_tb.inIO2[15:0]
Memory_tb.inIO3[15:0]
Memory_tb.inIO4[15:0]
Memory_tb.inIO5[15:0]
Memory_tb.inIO6[15:0]
Memory_tb.inIO7[15:0]
Memory_tb.inIO8[15:0]
Memory_tb.inIO9[15:0]
Memory_tb.inIOA[15:0]
Memory_tb.inIOB[15:0]
Memory_tb.inIOC[15:0]
Memory_tb.inIOD[15:0]
Memory_tb.inIOE[15:0]
Memory_tb.inIOF[15:0]
@28
Memory_tb.load
@200
-OUT
@22
Memory_tb.out[15:0]
@28
Memory_tb.loadRAM
Memory_tb.loadIO0
Memory_tb.loadIO1
Memory_tb.loadIO2
Memory_tb.loadIO3
Memory_tb.loadIO4
Memory_tb.loadIO5
Memory_tb.loadIO6
Memory_tb.loadIO7
Memory_tb.loadIO8
Memory_tb.loadIO9
Memory_tb.loadIOA
Memory_tb.loadIOB
Memory_tb.loadIOC
Memory_tb.loadIOD
Memory_tb.loadIOE
Memory_tb.loadIOF
@200
-Test
@29
Memory_tb.fail
[pattern_trace] 1
[pattern_trace] 0

View File

@@ -0,0 +1,180 @@
`default_nettype none
module Memory_tb();
// IN,OUT
reg [15:0] address;
reg load;
wire [15:0] out;
wire loadRAM;
wire loadIO0;
wire loadIO1;
wire loadIO2;
wire loadIO3;
wire loadIO4;
wire loadIO5;
wire loadIO6;
wire loadIO7;
wire loadIO8;
wire loadIO9;
wire loadIOA;
wire loadIOB;
wire loadIOC;
wire loadIOD;
wire loadIOE;
wire loadIOF;
reg [15:0] inRAM;
reg [15:0] inIO0;
reg [15:0] inIO1;
reg [15:0] inIO2;
reg [15:0] inIO3;
reg [15:0] inIO4;
reg [15:0] inIO5;
reg [15:0] inIO6;
reg [15:0] inIO7;
reg [15:0] inIO8;
reg [15:0] inIO9;
reg [15:0] inIOA;
reg [15:0] inIOB;
reg [15:0] inIOC;
reg [15:0] inIOD;
reg [15:0] inIOE;
reg [15:0] inIOF;
// Part
Memory MEMORY(
.address(address),
.load(load),
.out(out),
.loadRAM(loadRAM),
.loadIO0(loadIO0),
.loadIO1(loadIO1),
.loadIO2(loadIO2),
.loadIO3(loadIO3),
.loadIO4(loadIO4),
.loadIO5(loadIO5),
.loadIO6(loadIO6),
.loadIO7(loadIO7),
.loadIO8(loadIO8),
.loadIO9(loadIO9),
.loadIOA(loadIOA),
.loadIOB(loadIOB),
.loadIOC(loadIOC),
.loadIOD(loadIOD),
.loadIOE(loadIOE),
.loadIOF(loadIOF),
.inRAM(inRAM),
.inIO0(inIO0),
.inIO1(inIO1),
.inIO2(inIO2),
.inIO3(inIO3),
.inIO4(inIO4),
.inIO5(inIO5),
.inIO6(inIO6),
.inIO7(inIO7),
.inIO8(inIO8),
.inIO9(inIO9),
.inIOA(inIOA),
.inIOB(inIOB),
.inIOC(inIOC),
.inIOD(inIOD),
.inIOE(inIOE),
.inIOF(inIOF)
);
// Compare
reg fail = 0;
wire [15:0] out_cmp;
assign out_cmp = ((address==4096)?inIO0:
(address==4097)?inIO1:
(address==4098)?inIO2:
(address==4099)?inIO3:
(address==4100)?inIO4:
(address==4101)?inIO5:
(address==4102)?inIO6:
(address==4103)?inIO7:
(address==4104)?inIO8:
(address==4105)?inIO9:
(address==4106)?inIOA:
(address==4107)?inIOB:
(address==4108)?inIOC:
(address==4109)?inIOD:
(address==4110)?inIOE:
(address==4111)?inIOF:
inRAM);
wire loadRAM_cmp,loadIO0_cmp,loadIO1_cmp,loadIO2_cmp,loadIO3_cmp,loadIO4_cmp,loadIO5_cmp,loadIO6_cmp,loadIO7_cmp,
loadIO8_cmp,loadIO9_cmp,loadIOA_cmp,loadIOB_cmp,loadIOC_cmp,loadIOD_cmp,loadIOE_cmp,loadIOF_cmp;
assign loadRAM_cmp = (address<=3839)?load:0;
assign loadIO0_cmp = (address==4096)?load:0;
assign loadIO1_cmp = (address==4097)?load:0;
assign loadIO2_cmp = (address==4098)?load:0;
assign loadIO3_cmp = (address==4099)?load:0;
assign loadIO4_cmp = (address==4100)?load:0;
assign loadIO5_cmp = (address==4101)?load:0;
assign loadIO6_cmp = (address==4102)?load:0;
assign loadIO7_cmp = (address==4103)?load:0;
assign loadIO8_cmp = (address==4104)?load:0;
assign loadIO9_cmp = (address==4105)?load:0;
assign loadIOA_cmp = (address==4106)?load:0;
assign loadIOB_cmp = (address==4107)?load:0;
assign loadIOC_cmp = (address==4108)?load:0;
assign loadIOD_cmp = (address==4109)?load:0;
assign loadIOE_cmp = (address==4110)?load:0;
assign loadIOF_cmp = (address==4111)?load:0;
task check;
#1
if ((out!=out_cmp)||(loadRAM!=loadRAM_cmp)||
(loadIO0!=loadIO0_cmp)||(loadIO1!=loadIO1_cmp)||(loadIO2!=loadIO2_cmp)||(loadIO3!=loadIO3_cmp)||
(loadIO4!=loadIO4_cmp)||(loadIO5!=loadIO5_cmp)||(loadIO6!=loadIO6_cmp)||(loadIO7!=loadIO7_cmp)||
(loadIO8!=loadIO8_cmp)||(loadIO9!=loadIO9_cmp)||(loadIOA!=loadIOA_cmp)||(loadIOB!=loadIOB_cmp)||
(loadIOC!=loadIOC_cmp)||(loadIOD!=loadIOD_cmp)||(loadIOE!=loadIOE_cmp)||(loadIOF!=loadIOF_cmp))
begin
$display("FAIL: address=%16b, load=%1b, out=%16b, loadRAM=%1b, loadIO0=%1b, loadIO1=%1b, ... ",address,load,out,loadRAM,loadIO0,loadIO1);
fail=1;
end
endtask
// Test
initial begin
$dumpfile("Memory_tb.vcd");
$dumpvars(0, Memory_tb);
$display("------------------------");
$display("Testbench: Memory");
inRAM=$random;
inIO0=$random;
inIO1=$random;
inIO2=$random;
inIO3=$random;
inIO4=$random;
inIO5=$random;
inIO6=$random;
inIO7=$random;
inIO8=$random;
inIO9=$random;
inIOA=$random;
inIOB=$random;
inIOC=$random;
inIOD=$random;
inIOE=$random;
inIOF=$random;
for (address=4096; address<4112;address=address+1)
begin
load=0;check();
load=1;check();
end
for (address=0; address<3840;address=address+1)
begin
inRAM=$random;
load=0;check();
load=1;check();
end
if (fail==0) $display("passed");
$display("------------------------");
$finish;
end
endmodule

View File

@@ -0,0 +1,3 @@
[env]
board = iCE40-HX1K-EVB

View File

@@ -0,0 +1,23 @@
[*]
[*] GTKWave Analyzer v3.3.104 (w)1999-2020 BSI
[*] Thu Dec 29 21:52:20 2022
[*]
[dumpfile] "/home/micha/gitlab/nand2tetris-fpga/05_Computer_Architecture/03_Clock_Reset/Clock25_Reset20_tb.vcd"
[dumpfile_mtime] "Thu Dec 29 21:51:50 2022"
[dumpfile_size] 2320447
[savefile] "/home/micha/gitlab/nand2tetris-fpga/05_Computer_Architecture/03_Clock_Reset/Clock25_Reset20_tb.gtkw"
[timestart] 0
[size] 1636 438
[pos] -1 -1
*-17.000000 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
[sst_width] 281
[signals_width] 80
[sst_expanded] 1
[sst_vpaned_height] 76
@28
Clock25_Reset20_tb.CLK
Clock25_Reset20_tb.clk
@29
Clock25_Reset20_tb.reset
[pattern_trace] 1
[pattern_trace] 0

View File

@@ -0,0 +1,32 @@
`timescale 10ns/1ns
`default_nettype none
module Clock25_Reset20_tb();
// IN,OUT
reg CLK=1;
wire clk;
wire reset;
// Part
Clock25_Reset20 CLOCK25_RESET20(
.CLK(CLK),
.clk(clk),
.reset(reset)
);
// Simulation
always #0.5 CLK=~CLK;
// Test
initial begin
$dumpfile("Clock25_Reset20_tb.vcd");
$dumpvars(0, Clock25_Reset20_tb);
$display("------------------------");
$display("Testbench: Clock25_Reset10");
#4000
$finish;
end
endmodule

View File

@@ -0,0 +1,33 @@
`include "../../01_Boolean_Logic/Nand.v"
`include "../../01_Boolean_Logic/Not.v"
`include "../../01_Boolean_Logic/Buffer.v"
`include "../../01_Boolean_Logic/And.v"
`include "../../01_Boolean_Logic/Or.v"
`include "../../01_Boolean_Logic/Xor.v"
`include "../../01_Boolean_Logic/Mux.v"
`include "../../01_Boolean_Logic/DMux.v"
`include "../../01_Boolean_Logic/Not16.v"
`include "../../01_Boolean_Logic/Buffer16.v"
`include "../../01_Boolean_Logic/And16.v"
`include "../../01_Boolean_Logic/Or16.v"
`include "../../01_Boolean_Logic/Mux16.v"
`include "../../01_Boolean_Logic/Or8Way.v"
`include "../../01_Boolean_Logic/Mux4Way16.v"
`include "../../01_Boolean_Logic/Mux8Way16.v"
`include "../../01_Boolean_Logic/DMux4Way.v"
`include "../../01_Boolean_Logic/DMux8Way.v"
`include "../../02_Boolean_Arithmetic/HalfAdder.v"
`include "../../02_Boolean_Arithmetic/FullAdder.v"
`include "../../02_Boolean_Arithmetic/Add16.v"
`include "../../02_Boolean_Arithmetic/Inc16.v"
`include "../../02_Boolean_Arithmetic/ALU.v"
`include "../../03_Sequential_Logic/DFF.v"
`include "../../03_Sequential_Logic/Bit.v"
`include "../../03_Sequential_Logic/Register.v"
`include "../../03_Sequential_Logic/PC.v"
`include "../../03_Sequential_Logic/BitShift9R.v"
`include "../../03_Sequential_Logic/BitShift8L.v"
`include "../../05_Computer_Architecture/Clock25_Reset20.v"

View File

@@ -0,0 +1,3 @@
[env]
board = iCE40-HX1K-EVB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

View File

@@ -0,0 +1,42 @@
[*]
[*] GTKWave Analyzer v3.3.104 (w)1999-2020 BSI
[*] Mon Dec 12 16:41:42 2022
[*]
[dumpfile] "/home/micha/gitlab/nand2tetris/05_Computer_Architecture/04_HACK/HACK_tb.vcd"
[dumpfile_mtime] "Mon Dec 12 16:41:24 2022"
[dumpfile_size] 5432004
[savefile] "/home/micha/gitlab/nand2tetris/05_Computer_Architecture/04_HACK/HACK_tb.gtkw"
[timestart] 0
[size] 1673 487
[pos] 118 133
*-23.000000 50 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
[treeopen] HACK_tb.
[sst_width] 281
[signals_width] 180
[sst_expanded] 1
[sst_vpaned_height] 98
@200
-IN
@28
HACK_tb.CLK
HACK_tb.BUT[1:0]
@200
-OUT
@28
HACK_tb.LED[1:0]
@200
-DEBUG
@28
HACK_tb.HACK.loadDEBUG0
@24
HACK_tb.HACK.outDEBUG0[15:0]
@28
HACK_tb.HACK.loadDEBUG1
@24
HACK_tb.HACK.outDEBUG1[15:0]
@28
HACK_tb.HACK.loadDEBUG2
@24
HACK_tb.HACK.outDEBUG2[15:0]
[pattern_trace] 1
[pattern_trace] 0

View File

@@ -0,0 +1,30 @@
`timescale 10ns/1ns
`default_nettype none
module HACK_tb();
// IN,OUT
reg CLK = 1;
reg [1:0] BUT = 0;
wire [1:0] LED;
// Part
HACK HACK(
.CLK(CLK),
.BUT(BUT),
.LED(LED)
);
// Simulate
always #500 BUT <= BUT+1;
// Test
always #0.5 CLK = ~CLK;
initial begin
$dumpfile("HACK_tb.vcd");
$dumpvars(0, HACK_tb);
#4000
$finish;
end
endmodule

View File

@@ -0,0 +1,68 @@
[*]
[*] GTKWave Analyzer v3.3.104 (w)1999-2020 BSI
[*] Mon Nov 28 10:58:53 2022
[*]
[dumpfile] "/home/micha/gitlab/nand2tetris/05_Computer_Architecture/03_HACK/Hack_tb.vcd"
[dumpfile_mtime] "Mon Nov 28 10:58:25 2022"
[dumpfile_size] 3140780
[savefile] "/home/micha/gitlab/nand2tetris/05_Computer_Architecture/03_HACK/Hack_tb.gtkw"
[timestart] 0
[size] 1920 963
[pos] -1 -1
*-8.420643 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
[treeopen] Hack_tb.
[treeopen] Hack_tb.HACK.
[sst_width] 281
[signals_width] 200
[sst_expanded] 1
[sst_vpaned_height] 261
@28
Hack_tb.HACK.clk
@200
-IN
@28
Hack_tb.RST
Hack_tb.BUT
@200
-CPU
@22
Hack_tb.HACK.pc[15:0]
Hack_tb.HACK.instruction[15:0]
Hack_tb.HACK.CPU.regA[15:0]
Hack_tb.HACK.CPU.regD[15:0]
@200
-MEM
@22
Hack_tb.HACK.MEMORY.address[15:0]
@28
Hack_tb.HACK.MEMORY.load
@22
Hack_tb.HACK.MEMORY.out[15:0]
@200
-OUT
@28
Hack_tb.LED[1:0]
@200
-DEBUG
@28
Hack_tb.HACK.loadDEBUG0
@24
Hack_tb.HACK.outDEBUG0[15:0]
@28
Hack_tb.HACK.loadDEBUG1
@24
Hack_tb.HACK.outDEBUG1[15:0]
@28
Hack_tb.HACK.loadDEBUG2
@25
Hack_tb.HACK.outDEBUG2[15:0]
@28
Hack_tb.HACK.loadDEBUG3
@22
Hack_tb.HACK.outDEBUG3[15:0]
@28
Hack_tb.HACK.loadDEBUG4
@22
Hack_tb.HACK.outDEBUG4[15:0]
[pattern_trace] 1
[pattern_trace] 0

View File

@@ -0,0 +1,40 @@
`include "../../01_Boolean_Logic/Nand.v"
`include "../../01_Boolean_Logic/Not.v"
`include "../../01_Boolean_Logic/Buffer.v"
`include "../../01_Boolean_Logic/And.v"
`include "../../01_Boolean_Logic/Or.v"
`include "../../01_Boolean_Logic/Xor.v"
`include "../../01_Boolean_Logic/Mux.v"
`include "../../01_Boolean_Logic/DMux.v"
`include "../../01_Boolean_Logic/Not16.v"
`include "../../01_Boolean_Logic/Buffer16.v"
`include "../../01_Boolean_Logic/And16.v"
`include "../../01_Boolean_Logic/Or16.v"
`include "../../01_Boolean_Logic/Mux16.v"
`include "../../01_Boolean_Logic/Or8Way.v"
`include "../../01_Boolean_Logic/Mux4Way16.v"
`include "../../01_Boolean_Logic/Mux8Way16.v"
`include "../../01_Boolean_Logic/DMux4Way.v"
`include "../../01_Boolean_Logic/DMux8Way.v"
`include "../../02_Boolean_Arithmetic/HalfAdder.v"
`include "../../02_Boolean_Arithmetic/FullAdder.v"
`include "../../02_Boolean_Arithmetic/Add16.v"
`include "../../02_Boolean_Arithmetic/Inc16.v"
`include "../../02_Boolean_Arithmetic/ALU.v"
`include "../../03_Sequential_Logic/DFF.v"
`include "../../03_Sequential_Logic/Bit.v"
`include "../../03_Sequential_Logic/Register.v"
`include "../../03_Sequential_Logic/PC.v"
`include "../../03_Sequential_Logic/RAM256.v"
`include "../../03_Sequential_Logic/RAM512.v"
`include "../../03_Sequential_Logic/RAM3840.v"
`include "../../03_Sequential_Logic/BitShift9R.v"
`include "../../03_Sequential_Logic/BitShift8L.v"
`include "../../05_Computer_Architecture/CPU.v"
`include "../../05_Computer_Architecture/Memory.v"
`include "../../05_Computer_Architecture/ROM.v"
`include "../../05_Computer_Architecture/Clock25_Reset20.v"
`include "../../05_Computer_Architecture/HACK.v"

View File

@@ -0,0 +1,3 @@
[env]
board = iCE40-HX1K-EVB

View File

@@ -0,0 +1,11 @@
# physical constrain file
# assign io-pins to pin numbering of iCE40-HX1K on olimex board iCE40-HX1K-EVB
# compare to the schematic of the board and the datasheet of fpga
set_io CLK 15
set_io BUT[0] 41
set_io BUT[1] 42
set_io LED[0] 40
set_io LED[1] 51

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB

View File

@@ -0,0 +1,40 @@
/**
* 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.
*/
`default_nettype none
module CPU(
input clk,
input [15:0] inM, // M value input (M = contents of RAM[A])
input [15:0] instruction, // Instruction for execution
input reset, // Signals whether to re-start the current
// program (reset==1) or continue executing
// the current program (reset==0).
output [15:0] outM, // M value output
output writeM, // Write to M?
output [15:0] addressM, // Address in data memory (of M) to read
output [15:0] pc // address of next instruction
);
// Put your code here:
endmodule

View File

@@ -0,0 +1,15 @@
/**
* Uses CLK of 100MHz to generate:
* internal clock signal clk with 25MHz and
* a reset signal of approx. 20us length
*/
`default_nettype none
module Clock25_Reset20(
input CLK, // external clock 100 MHz
output clk, // internal clock 25 Mhz
output reset // reset signal approx. 20us
);
// Put your code here:
endmodule

View File

@@ -0,0 +1,19 @@
/**
* The HACK computer, including CPU, ROM, RAM and the generator for
* reset and clk (25MHz) signal. For approx. 20us HACK CPU resets.
* From this point onward the user is at the mercy of the software.
* In particular, depending on the program's code, the LED may show
* some output and the user may be able to interact with the computer
* via the BUT.
*/
`default_nettype none
module HACK(
input CLK, // external clock 100 MHz
input [1:0] BUT, // user button (0 if pressed, 1 if released)
output [1:0] LED // leds (0 off, 1 on)
);
// Put your code here:
endmodule

View File

@@ -0,0 +1,60 @@
/**
* The complete address space of the Hack computer's memory,
* including RAM and memory-mapped I/O.
* The chip facilitates read and write operations, as follows:
* Read: out(t) = Memory[address(t)](t)
* Write: if load(t-1) then Memory[address(t-1)](t) = in(t-1)
* In words: the chip always outputs the value stored at the memory
* location specified by address. If load==1, the in value is loaded
* into the memory location specified by address. This value becomes
* available through the out output from the next time step onward.
* Address space rules:
* RAM 0x0000 - 0x0EFF (3840 words)
* IO 0x1000 - 0x100F (maps to 16 different devices)
* The behavior of IO addresses is described in 06_IO-Devices
*/
`default_nettype none
module Memory(
input [15:0] address,
input load,
output [15:0] out,
output loadRAM,
output loadIO0,
output loadIO1,
output loadIO2,
output loadIO3,
output loadIO4,
output loadIO5,
output loadIO6,
output loadIO7,
output loadIO8,
output loadIO9,
output loadIOA,
output loadIOB,
output loadIOC,
output loadIOD,
output loadIOE,
output loadIOF,
input [15:0] inRAM,
input [15:0] inIO0,
input [15:0] inIO1,
input [15:0] inIO2,
input [15:0] inIO3,
input [15:0] inIO4,
input [15:0] inIO5,
input [15:0] inIO6,
input [15:0] inIO7,
input [15:0] inIO8,
input [15:0] inIO9,
input [15:0] inIOA,
input [15:0] inIOB,
input [15:0] inIOC,
input [15:0] inIOD,
input [15:0] inIOE,
input [15:0] inIOF
);
// Put your code here:
endmodule

View File

@@ -0,0 +1,26 @@
/**
* instruction memory at boot time
* The instruction memory is read only (ROM) and
* preloaded with 256 x 16bit of Hackcode holding the bootloader.
*
* instruction = ROM[pc]
*/
`default_nettype none
module ROM(
input [15:0] pc,
output [15:0] instruction
);
// No need to implement this chip
// The file ROM.BIN holds the hack code
parameter ROMFILE = "ROM.hack";
reg [15:0] mem [0:255];
assign instruction = mem[pc[7:0]];
initial begin
$readmemb(ROMFILE,mem);
end
endmodule

View File

@@ -0,0 +1,122 @@
# 05 Computer Architecture
Build the `HACK` computer system consisting of the chips `CPU`, `Memory`, `Clock25_Reset20`, `RAM` and `ROM`. `ROM` uses a block ram structure (256 words) of iCE40HX1K and can be considered primitive. It can be preloaded with the instructions of the assembler programs implemented in `04_Machine_Language` .
### 01 CPU
The `CPU` corresponds to the proposed implementation of nand2tetris course.
![](01_CPU/CPU.png)**Attention:** In the original specification of HACK all C instruction have the binary form: 111xxxxxxxxxxxxx and A instruction have the form 0xxxxxxxxxxxxxxx. In order to use HACK with instruction memory ROM >32K (to play tetris), we will also interpret the machine language instructions starting with 000-110 as A-instructions, allowing the following jumps for all labels up to 56K!
```
@label
0;JMP
```
### 02 Memory
The chip `Memory.v` maps all addresses 0 - 0x0FFF to RAM and the addresses 0x1000-0x100F to the 16 special function registers used for memory mapped IO-Devices and debugging.
### 03 Clock25_Reset20
The 100 MHz (CLK) of the clock generator on the iCE40HX1K-EVB is to fast to drive our HACK design. Therefore we must scale down the external clock (CLK) of 100 MHz to the internal clock (clk) of 25Mhz using a counter `PC` .
HACK CPU needs a reset signal to have a proper start of the complete computer system. The fpga chip nees some time delay to preload the ROM with ROM.hack code. Therefore the reset signal at startup should have a minimal length of approximately 20us.
### 04 HACK
The chip `HACK.v` is the top level module, that connects to the outer world.
![](04_HACK/HACK.png)
The signals wires `CLK`, `RST`, `BUT[1:0]` and `LED[1:0]` (by convention written in capital letters) connect to the outer pins of the fpga chip iCE40HX1K according to the file `iCE40HX1K.pcf`. The board iCE40-HX1K-EVB comes with a clock generator of 100 MHz, two buttons and two leds connected to FPGA (refer to [datasheets/iCE40HX1K-EVB](../datasheets/iCE40HX1K-EVB_Rev_B.pdf)).
| wire | iCE40HX1K (FPGA) | board iCE40HX1K-EVB |
| ------ | ---------------- | ----------------------- |
| CLK | 15 | 100 Mhz clock generator |
| BUT[0] | 41 | BUT1 |
| BUT[1] | 42 | BUT2 |
| LED[0] | 40 | LED1 |
| LED[1] | 51 | LED2 |
To add IO capability we add 7 more special function registers mapped to the following addresses:
| address | I/O dev | function |
| ----------- | ------- | ---------------------------------------------------- |
| 0 - 3839 | RAM | |
| 4096 | LED | 0 = led off, 1 = led on |
| 4097 | BUT | 0 = button pressed "down", 1 = button released |
| 4098 - 4106 | | reserved for IO devices (see. project 06_IO_Devices) |
| 4107 - 4111 | DEBUG | used for debugging |
The HACK simulation needs a valid file `ROM.hack` (created in project `04_Machine_Language`) with the machine language instructions to perform.
The test bench of `04_HACK` will:
1. occasionally press the user buttons BUT1/2
2. show the result of LED1/2
3. show the content of DEBUG0-DEBUG5
***
### Project
- Implement the chips `CPU` , `Memory` and `Clock25__Reset20` and simulate with the corresponding test benches:
```
$ cd 0X_<chipname>
$ apio clean
$ apio sim
```
- Check the frequency of the internal clk signal to be 25MHz. So one clock cylce takes 40us.
![](03_Clock25_Reset20/clock.png)
- Check the reset signal of HACK. You should see a reset signal of approximately 20 us.
![](03_Clock25_Reset20/reset.png)
* Implement `HACK` and test with `leds.asm`:
```
$ cd ../04_Machine_Language
$ make leds
$ cd ../05_Computer_Architecture/04_HACK
$ apio clean
$ apio sim
```
* Check, if LEDs change state accoring to BUT:
![](04_HACK/leds.png)
* Test `HACK` with `mult.asm`.
```
$ cd ../04_Machine_Language
$ make mult
$ cd ../05_Computer_Architecture/04_HACK
$ apio clean
$ apio sim
```
* You should see the result 715 of the multiplication 13*55 in the debug register `DEBUG2`! You can change the number format to decimal.
![](04_HACK/mult.png)
* finally upload the complete HACK design with `leds.asm` preloaded into instruction ROM and run in real hardware!
```
$ cd ../04_Machine_Language/01_leds
$ make
$ cd ../05_Computer_Architecture/04_HACK
$ apio clean
$ apio build
$ apio upload
```
* press the user buttons BUT1/BUT2 and see if the LED change pattern accordingly.
* Repeat the test with the second machine language programm `mult.asm`.
**Attention:** remember to run `apio clean`, after changing the file `ROM.hack`!