-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathsim.cpp
89 lines (69 loc) · 2.12 KB
/
sim.cpp
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 <iostream>
#include <functional>
#include <vector>
#include "sim.h"
#include "tickable.h"
#include "tap.h"
#include "reset.h"
#include "cdomain.h"
#include "nodeimpl.h"
using namespace chdl;
using namespace std;
vector<cycle_t> chdl::now{0};
static void reset_now() { now = vector<cycle_t>{0}; }
CHDL_REGISTER_RESET(reset_now);
cycle_t chdl::sim_time(cdomain_handle_t cd) { return now[cd]; }
cycle_t chdl::advance(unsigned /* threads */, cdomain_handle_t cd) {
for (auto &t : tickables()[cd]) t->pre_tick(cd);
for (auto &t : tickables()[cd]) t->tick(cd);
for (auto &t : tickables()[cd]) t->tock(cd);
for (auto &t : tickables()[cd]) t->post_tock(cd);
now[cd]++;
return now[cd];
}
void chdl::reset_sim() {
for (unsigned i = 0; i < nodes.size(); ++i)
nodes[i]->reset();
for (unsigned cd = 0; cd < clock_domains(); ++cd)
now[cd] = 0;
}
void chdl::print_time(ostream &out) {
out << '#' << now[0] << endl;
}
void chdl::run(ostream &vcdout, function<bool()> end_condition,
unsigned threads)
{
using namespace std;
using namespace chdl;
vector<unsigned> &ti(tick_intervals());
vector<bool> cache(nodes.size());
print_vcd_header(vcdout);
print_time(vcdout);
print_taps(vcdout, 0, cache, true);
do {
print_taps(vcdout, 0, cache, false);
for (unsigned j = 0; j < ti.size(); ++j)
if (sim_time()%ti[j] == 0) advance(threads, j);
print_time(vcdout);
} while (!end_condition());
call_final_funcs();
}
void chdl::run(ostream &vcdout, cycle_t time, unsigned threads) {
run(vcdout, [time](){ return now[0] == time; }, threads);
}
void chdl::run(ostream &vcdout, bool &stop, unsigned threads) {
run(vcdout, [&stop](){ return stop; }, threads);
}
void chdl::run(ostream &vcdout, bool &stop, cycle_t tmax, unsigned threads) {
run(vcdout, [&stop, tmax](){ return now[0] == tmax || stop; }, threads);
}
vector<function<void()> > &final_funcs() {
static vector<function<void()> > &ff(*(new vector<function<void()> >()));
return ff;
}
void chdl::finally(function<void()> f) {
final_funcs().push_back(f);
}
void chdl::call_final_funcs() {
for (auto f : final_funcs()) f();
}