-
Notifications
You must be signed in to change notification settings - Fork 1
/
test_top.sv
124 lines (102 loc) · 3.07 KB
/
test_top.sv
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
//--------------------------------------------------------------
// Testbench for the top level design
//--------------------------------------------------------------
`include "z80.svh"
`include "Z80_MMU.v"
module test_bench_top(z80_if.tb z);
assign clk = z.CLK;
initial begin : init
$display("Test: Start of test at %d", $time);
z.nWAIT <= `CLR;
z.nINT <= `CLR;
z.nNMI <= `CLR;
z.nBUSRQ <= `CLR;
z.nRESET <= `SET;
#2 repeat (3) @(posedge clk);
z.nRESET <= `CLR;
end : init
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Testbench for interrupt testing
// Enable one or more interrupt generators and run them with the
// 'hello world' code
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Infuse a NMI at a certain clock
initial begin : nmi_once
repeat (500) @(posedge clk);
// z.nNMI <= `SET;
repeat (1) @(posedge clk);
z.nNMI <= `CLR;
end : nmi_once
// Test sending a *periodic* NMI
always begin : nmi_rep
repeat (3000) @(posedge clk);
// z.nNMI <= `SET;
repeat (1) @(posedge clk);
z.nNMI <= `CLR;
end : nmi_rep
// Infuse an INT at a certain clock
initial begin : int_once
repeat (1000) @(posedge clk);
// z.nINT <= `SET;
repeat (300) @(posedge clk);
z.nINT <= `CLR;
end : int_once
// Test sending a *periodic* INT
always begin : int_rep
repeat (5000) @(posedge clk);
// z.nINT <= `SET;
repeat (300) @(posedge clk);
z.nINT <= `CLR;
end : int_rep
// Test WAIT.. inject at will
initial begin : wait_once
repeat (1008) @(posedge clk);
// z.nWAIT <= `SET;
repeat (2) @(posedge clk);
z.nWAIT <= `CLR;
end : wait_once
// Test BUSRQ / BUSACK
initial begin : busrq_once
repeat (10) @(posedge clk);
// z.nBUSRQ <= `SET;
repeat (10) @(posedge clk);
z.nBUSRQ <= `CLR;
end : busrq_once
// Test special RESET
initial begin : spc_reset
repeat (40) @(posedge clk);
// z.nRESET <= `SET;
repeat (1) @(posedge clk);
z.nRESET <= `CLR;
end : spc_reset
endmodule
module test_top();
// Although the clock is going forever, we will stop simulation at some point
bit clk = 1;
initial forever #1 clk = ~clk;
// Stop after printing "Hello, World!"
initial begin : stopme
#70000 $stop();
end : stopme
z80_if z80(clk); // Instantiate the Z80 bus interface
z80_top_ifc_n dut(z80); // Create an instance of our Z80 design
test_bench_top tb(z80); // Create an instance of the test bench
// TODO MMU
// wire [19:0] physical_addr;
// reg [19:0] pa_z80;
// assign physical_addr = pa_z80;
wire [7:0] mmu_data;
wire [19:0] mmu_address;
Z80_MMU mmu(
.nMREQ (z80.nMREQ),
.nRD (z80.nRD),
.nWR (z80.nWR),
.ram_data (mmu_data),
.cpu_data (z80.D),
.cpu_addr (z80.A),
.ram_addr (mmu_address)
);
ram ram( .Address(mmu_address[15:0]), .Data(mmu_data), .CS(mmu.nMREQ), .WE(mmu.nWR), .OE(mmu.nRD) );
io io( .Address(z80.A), .Data(z80.D), .CS(z80.nIORQ), .WE(z80.nWR), .OE(z80.nRD) );
iorq iorq( .Data(z80.D), .M1(z80.nM1), .IORQ(z80.nIORQ) );
endmodule