summaryrefslogtreecommitdiff
path: root/infra/arbiter.h
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--infra/arbiter.h42
1 files changed, 42 insertions, 0 deletions
diff --git a/infra/arbiter.h b/infra/arbiter.h
new file mode 100644
index 0000000..5dd1647
--- /dev/null
+++ b/infra/arbiter.h
@@ -0,0 +1,42 @@
1#pragma once
2
3#include <cassert>
4#include <optional>
5#include <utility>
6
7#include "infra/sim.h"
8
9namespace infra {
10 template<typename T, unsigned int peers> struct priority_arbiter : public sim {
11 std::array<port<T>, peers> peerp;
12 port<T> *outp = nullptr;
13
14 void clock() {
15 for (unsigned int i = 0; i < peers; ++i) {
16 if (outp->can_write() && peerp[i].can_read())
17 outp->write(peerp[i].read());
18 }
19 }
20 };
21
22 template<typename T, unsigned int peers> struct round_robin_arbiter : public sim {
23 std::array<port<T>, peers> peerp;
24 port<T> *outp = nullptr;
25 unsigned int initial = 0;
26
27 void clock() {
28 bool initially_empty = outp->can_write();
29 for (unsigned int i = initial; i < peers; ++i) {
30 if (outp->can_write() && peerp[i].can_read())
31 outp->write(peerp[i].read());
32 }
33 for (unsigned int i = 0; i < initial; ++i) {
34 if (outp->can_write() && peerp[i].can_read())
35 outp->write(peerp[i].read());
36 }
37 if (initially_empty && !outp->can_write())
38 if (++initial == peers)
39 initial = 0;
40 }
41 };
42}