-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtb_top.sv
More file actions
131 lines (112 loc) · 3.45 KB
/
tb_top.sv
File metadata and controls
131 lines (112 loc) · 3.45 KB
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
125
126
127
128
129
130
131
`timescale 1ns / 1ps `default_nettype none
module tb_top;
// Clock and reset
logic CLK = 0;
always #5 CLK = ~CLK; // 100 MHz clock -> period 10ns
// Buttons / reset
logic BTN_N = 0; // active-low reset
logic BTN1 = 0;
logic BTN2 = 0;
logic BTN3 = 0;
// Observables
logic LED1, LED2, LED3, LED4, LED5;
logic P1A1, P1A2, P1A3, P1A4, P1A7, P1A8, P1A9, P1A10;
// Instantiate DUT (named port mapping)
top uut (
.CLK (CLK),
.BTN_N(BTN_N),
.BTN1 (BTN1),
.BTN2 (BTN2),
.BTN3 (BTN3),
.LED1 (LED1),
.LED2 (LED2),
.LED3 (LED3),
.LED4 (LED4),
.LED5 (LED5),
.P1A1 (P1A1),
.P1A2 (P1A2),
.P1A3 (P1A3),
.P1A4 (P1A4),
.P1A7 (P1A7),
.P1A8 (P1A8),
.P1A9 (P1A9),
.P1A10(P1A10)
);
// Dump waveforms
initial begin
$dumpfile("tb_top.vcd");
$dumpvars(0, tb_top);
end
// Print a header once
initial begin
$display("=== SIM START ===");
$display("Note: watch CLK, BTN_N, uut.core.resetn (if present), uut.core.state_id");
$display("Time CLK BTN_N BTN3 db_btn3 btn3_pulse core.resetn core.state_id core.iptr");
end
// Periodic debug print every 10 cycles
always @(posedge CLK) begin
// Print every 1us (100 cycles) to reduce spam; but show first 50 cycles every edge
if ($time < 1000 || ($time % 1000 == 0)) begin
// Safe access to nested signals: use hierarchical names that exist in your design.
$display("%6t %b %b %b %b %b %0d %0d", $time, CLK, BTN_N,
BTN3, uut.db_btn3, // top-level signal
uut.btn3_pulse, // top-level pulse (we made it direct in top)
uut.core.resetn, // core reset input (if present)
uut.core.state_id, uut.core.iptr);
// $display("");
end
end
// Clean, simple button press (no force/release)
task press_button_simple(input integer cycles);
begin
BTN3 = 1;
repeat (cycles) @(posedge CLK);
BTN3 = 0;
// hold a bit
repeat (10) @(posedge CLK);
end
endtask
task press_button_start(input integer cycles);
begin
BTN1 = 1;
repeat (cycles) @(posedge CLK);
BTN1 = 0;
repeat (10) @(posedge CLK);
end
endtask
integer timeout;
initial begin
// INITIAL VALUES
BTN_N = 0;
BTN1 = 0;
BTN2 = 0;
BTN3 = 0;
// let some clocks run (use posedge to guarantee time advances)
repeat (10) @(posedge CLK);
// Release reset (BTN_N is active low)
$display("[%0t] Releasing reset (BTN_N <= 1)", $time);
BTN_N = 1;
repeat (20) @(posedge CLK);
// Quick sanity prints
$display("[%0t] BTN_N=%b, CLK=%b", $time, BTN_N, CLK);
// Press load button
$display("[%0t] pressing load (BTN3) for 20 cycles", $time);
press_button_simple(20);
// Wait for core.loaded or timeout
timeout = 0;
while (uut.core.loaded !== 1 && timeout < 20000) begin
@(posedge CLK);
timeout = timeout + 1;
end
if (uut.core.loaded === 1) $display("[%0t] core.loaded detected", $time);
else $display("[%0t] TIMEOUT waiting for core.loaded", $time);
// Press start/run
$display("[%0t] pressing start (BTN1) for 20 cycles", $time);
press_button_start(20);
// Run for a while and then finish
repeat (50000) @(posedge CLK);
$display("[%0t] Final: core.state_id=%0d core.display=%02h", $time, uut.core.state_id,
uut.core.display);
$finish;
end
endmodule