forked from pdaxrom/pyldin2012
-
Notifications
You must be signed in to change notification settings - Fork 0
/
testb.h
130 lines (117 loc) · 3.09 KB
/
testb.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
////////////////////////////////////////////////////////////////////////////////
//
// Filename: testb.h
//
// Project: Verilog Tutorial Example file
//
// Purpose: A wrapper providing a common interface to a clocked FPGA core
// being exercised by Verilator.
//
// Creator: Dan Gisselquist, Ph.D.
// Gisselquist Technology, LLC
//
////////////////////////////////////////////////////////////////////////////////
//
// Written and distributed by Gisselquist Technology, LLC
//
// This program is hereby granted to the public domain.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
////////////////////////////////////////////////////////////////////////////////
//
//
#ifndef TESTB_H
#define TESTB_H
#include <stdio.h>
#include <stdint.h>
#include <verilated_vcd_c.h>
#define TBASSERT(TB,A) do { if (!(A)) { (TB).closetrace(); } assert(A); } while(0);
template <class VA> class TESTB {
public:
VA *m_core;
VerilatedVcdC* m_trace;
uint64_t m_tickcount;
TESTB(void) : m_trace(NULL), m_tickcount(0l) {
m_core = new VA;
Verilated::traceEverOn(true);
m_core->clk_25mhz = 0;
m_core->rst = 0;
eval(); // Get our initial values set properly.
}
virtual ~TESTB(void) {
closetrace();
delete m_core;
m_core = NULL;
}
virtual void reset(void) {
m_core->rst = 1;
tick();
m_core->rst = 0;
}
virtual void opentrace(const char *vcdname) {
if (!m_trace) {
m_trace = new VerilatedVcdC;
m_core->trace(m_trace, 99);
m_trace->open(vcdname);
}
}
virtual void closetrace(void) {
if (m_trace) {
m_trace->close();
delete m_trace;
m_trace = NULL;
}
}
virtual void eval(void) {
m_core->eval();
}
virtual void tick(void) {
m_tickcount++;
// Make sure we have our evaluations straight before the top
// of the clock. This is necessary since some of the
// connection modules may have made changes, for which some
// logic depends. This forces that logic to be recalculated
// before the top of the clock.
eval();
if (m_trace) m_trace->dump((vluint64_t)(10*m_tickcount-2));
m_core->clk_25mhz = 1;
eval();
if (m_trace) m_trace->dump((vluint64_t)(10*m_tickcount));
m_core->clk_25mhz = 0;
eval();
if (m_trace) {
m_trace->dump((vluint64_t)(10*m_tickcount+5));
m_trace->flush();
}
}
void delay_cycles(uint64_t cycles) {
while (cycles > 0) {
m_tickcount++;
eval();
if (m_trace) m_trace->dump((vluint64_t)(10*m_tickcount-2));
m_core->clk_25mhz = 1;
eval();
if (m_trace) m_trace->dump((vluint64_t)(10*m_tickcount));
m_core->clk_25mhz = 0;
eval();
if (m_trace) {
m_trace->dump((vluint64_t)(10*m_tickcount+5));
m_trace->flush();
}
cycles--;
}
}
void ps2_clk(int val) {
m_core->esp32_ps2clk = val;
}
void ps2_data(int val) {
m_core->esp32_ps2data = val;
}
unsigned long tickcount(void) {
return m_tickcount;
}
};
#endif