summaryrefslogtreecommitdiff
path: root/infra/port.h
diff options
context:
space:
mode:
authorJulian Blake Kongslie2022-09-22 11:29:07 -0700
committerJulian Blake Kongslie2022-09-22 11:29:07 -0700
commiteb3fd68203fee7c63245c702914c2acd3332d65a (patch)
tree7796707c0372e7fbe4a8bac70aad95f619e8ba29 /infra/port.h
downloadprocmodel-eb3fd68203fee7c63245c702914c2acd3332d65a.tar.xz
Initial commit.
Diffstat (limited to 'infra/port.h')
-rw-r--r--infra/port.h45
1 files changed, 45 insertions, 0 deletions
diff --git a/infra/port.h b/infra/port.h
new file mode 100644
index 0000000..06a3aa5
--- /dev/null
+++ b/infra/port.h
@@ -0,0 +1,45 @@
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> struct port : public sim {
11 std::optional<T> consumer_side;
12 std::optional<T> producer_side;
13
14 bool can_read() { return consumer_side.has_value(); }
15 bool can_write() { return !producer_side.has_value(); }
16
17 T read() {
18 assert(can_read());
19 auto x = std::move(*consumer_side);
20 consumer_side.reset();
21 return x;
22 }
23
24 const T & peek() {
25 assert(can_read());
26 return *consumer_side;
27 }
28
29 void discard() {
30 consumer_side.reset();
31 }
32
33 void write(T &&x) {
34 assert(can_write());
35 producer_side = std::move(x);
36 }
37
38 void unclock() {
39 if (!consumer_side && producer_side) {
40 consumer_side = std::move(*producer_side);
41 producer_side.reset();
42 }
43 }
44 };
45}