generated from kivikakk/chryse-template
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathSimThread.cc
89 lines (73 loc) · 1.69 KB
/
SimThread.cc
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
#include <fstream>
#include <tuple>
#include "SimThread.h"
static int simmain(void *vsim) {
return static_cast<SimThread *>(vsim)->main();
}
SimThread::SimThread(const std::optional<std::string> &vcd_out)
: _top(), _vcd_out(vcd_out), _vcd_time(0), _vcd(), _running(true) {
if (_vcd_out) {
debug_items di;
_top.debug_info(&di, nullptr, "top ");
_vcd.add(di);
}
_mutex = SDL_CreateMutex();
}
SimThread::~SimThread() { SDL_DestroyMutex(_mutex); }
SimThread *SimThread::start(const std::optional<std::string> &vcd_out) {
auto sim = new SimThread(vcd_out);
sim->_thread = SDL_CreateThread(simmain, "simmain", sim);
return sim;
}
int SimThread::main() {
lock();
sync_reset();
unlock();
while (lock_if_running()) {
cycle();
unlock();
}
return write_vcd();
}
bool SimThread::lock_if_running() {
lock();
if (!_running) {
unlock();
return false;
}
return true;
}
void SimThread::lock() { SDL_LockMutex(_mutex); }
void SimThread::unlock() { SDL_UnlockMutex(_mutex); }
int SimThread::wait() {
int rc = 0;
SDL_WaitThread(_thread, &rc);
return rc;
}
uint64_t SimThread::cycle_number() { return _vcd_time >> 1; }
void SimThread::halt() { _running = false; }
void SimThread::sync_reset() {
_top.p_reset.set(true);
cycle();
_top.p_reset.set(false);
}
void SimThread::cycle() {
_top.p_clock.set(false);
_top.step();
_vcd.sample(_vcd_time++);
_top.p_clock.set(true);
_top.step();
_vcd.sample(_vcd_time++);
}
int SimThread::write_vcd() {
if (_vcd_out) {
std::ofstream of(*_vcd_out);
of << _vcd.buffer;
of.close();
if (!of) {
std::cerr << "error while writing vcd" << std::endl;
return 1;
}
}
return 0;
}