-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathVerilatorTbFst.h
136 lines (114 loc) · 2.73 KB
/
VerilatorTbFst.h
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
132
133
134
135
136
// Header file to be used in verilator C++ testbenches.
// SPDX-FileCopyrightText: © 2022 Aadi Desai <21363892+supleed2@users.noreply.github.com>
// SPDX-License-Identifier: Apache-2.0
//
// Intended usage / order:
// - VerilatorTbFst<Vtest_DUT> *tb = new VerilatorTbFst<Vtest_DUT>();
// - tb->setClockPeriodPS(clock_period_in_picoseconds);
// - This value can be taken from within the SystemVerilog Testbench
// - tb->opentrace("output/test_DUT.verilator.fst");
// - tb->m_trace->dump(0);
// - Followed by arst/rst and signals matching the intended testbench flow.
#ifndef _VERILATORTBFST_H
#define _VERILATORTBFST_H
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <svdpi.h>
#include <verilated_fst_c.h>
typedef enum {
ERROR,
WARN,
NOTE
} TbPrintLevel;
template <class VA>
class VerilatorTbFst {
public:
VA *m_dut;
VerilatedFstC *m_trace;
uint64_t m_tickcount;
uint64_t m_clockperiod;
bool m_dodump;
VerilatorTbFst(void) : m_trace(NULL), m_tickcount(0l) {
m_dut = new VA;
Verilated::traceEverOn(true);
m_dut->i_clk = 0;
m_dut->i_rst = 1;
m_dodump = true;
eval(); // Get our initial values set properly.
}
virtual ~VerilatorTbFst(void) {
closetrace();
delete m_dut;
m_dut = NULL;
}
virtual void setClockPeriodPS(const uint64_t ps) {
m_clockperiod = ps;
}
virtual void opentrace(const char *fstname) {
opentrace(fstname, 99);
}
virtual void opentrace(const char *fstname, int tracedepth) {
if (!m_trace) {
m_trace = new VerilatedFstC;
m_dut->trace(m_trace, tracedepth);
m_trace->open(fstname);
}
}
virtual void closetrace(void) {
if (m_trace) {
m_trace->close();
delete m_trace;
m_trace = NULL;
}
}
virtual void eval(void) {
m_dut->eval();
}
// Call from loop {check, drive, tick}
virtual void tick(void) {
// check
// drive
// rise eval dump
// fall eval dump
m_dut->i_clk = 1;
eval();
if (m_dodump && m_trace) {
m_trace->dump((uint64_t)(m_clockperiod * m_tickcount));
}
m_dut->i_clk = 0;
eval();
if (m_dodump && m_trace) {
m_trace->dump((uint64_t)(m_clockperiod * m_tickcount + (m_clockperiod / 2)));
m_trace->flush();
}
m_tickcount++;
}
virtual void ticks(int numTicks) {
for (int i = 0; i < numTicks; i++)
tick();
}
virtual void areset(void) {
m_dut->i_arst = 0;
tick();
m_dut->i_arst = 1;
ticks(4);
m_dut->i_arst = 0;
}
virtual void reset(void) {
m_dut->i_rst = 1;
ticks(5);
m_dut->i_rst = 0;
}
unsigned long tickcount(void) {
return m_tickcount;
}
virtual bool done(void) {
return Verilated::gotFinish();
}
virtual void setScope(const char *scopeName) {
char fullScopeName[1024];
svSetScope(svGetScopeFromName(strcat(strcpy(fullScopeName, "TOP."), scopeName)));
}
};
#endif // _VERILATORTBFST_H