-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathconsole.cpp
81 lines (67 loc) · 1.46 KB
/
console.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
#include <iostream>
#include <queue>
#include <thread>
#include <mutex>
#include "console.h"
#include "ingress.h"
#include "egress.h"
#include "tickable.h"
using namespace chdl;
using namespace std;
template <typename T, unsigned N>
void sim_val(T &o, const bvec<N> &x, cdomain_handle_t cd = 0)
{
unsigned i;
for (i = 0, o = 0; i < N; ++i) {
o <<= 1;
o |= (nodes[nodeid_t(x[N - i - 1])]->eval(cd) ? 1 : 0);
}
}
void chdl::ConsoleOut(node valid, bvec<8> x, std::ostream &out) {
gtap(x);
cdomain_handle_t cd(cur_clock_domain());
EgressFunc([x, cd, &out](bool v) {
if (v) {
char c;
sim_val(c, x, cd);
out << c;
}
}, valid);
}
struct console_t : public tickable {
console_t(node v, bvec<8> x, istream &in): c(0), valid(false), in(in)
{
x = IngressInt<8>(c);
v = Ingress(valid);
t = new thread([this, &in]{
char c;
while (in.get(c)) {
m.lock(); {
q.push(c);
} m.unlock();
}
});
}
void tick(cdomain_handle_t cd) {
m.lock(); {
valid = !q.empty();
if (valid) {
c = q.front();
q.pop();
} else {
c = 0;
}
} m.unlock();
}
char c;
bool valid;
queue<char> q;
mutex m;
thread *t;
std::istream ∈
static vector<console_t*> console_ts;
};
vector<console_t*> console_t::console_ts;
void chdl::ConsoleIn(const node &valid, const bvec<8> &x, std::istream &in) {
console_t *c = new console_t(valid, x, in);
}