diff options
| author | Julian Blake Kongslie | 2022-11-11 16:28:55 -0800 |
|---|---|---|
| committer | Julian Blake Kongslie | 2022-11-11 16:28:55 -0800 |
| commit | db82579d3c023c441c895d26d32de3fa039eafa4 (patch) | |
| tree | e42ee62e50a5910dac54f6b57489876303b3d516 /infra/arbiter.h | |
| parent | Slightly more ergonomic support for events without data (diff) | |
| download | nanosim-db82579d3c023c441c895d26d32de3fa039eafa4.tar.xz | |
Starting to write a real memory subsystem for biggolf.
Diffstat (limited to 'infra/arbiter.h')
| -rw-r--r-- | infra/arbiter.h | 31 |
1 files changed, 9 insertions, 22 deletions
diff --git a/infra/arbiter.h b/infra/arbiter.h index 79a9920..63ddbd6 100644 --- a/infra/arbiter.h +++ b/infra/arbiter.h | |||
| @@ -3,53 +3,40 @@ | |||
| 3 | #include <array> | 3 | #include <array> |
| 4 | #include <cassert> | 4 | #include <cassert> |
| 5 | 5 | ||
| 6 | #include "infra/port.h" | ||
| 6 | #include "infra/sim.h" | 7 | #include "infra/sim.h" |
| 7 | 8 | ||
| 8 | namespace infra { | 9 | namespace infra { |
| 9 | template<typename T, unsigned int peers> struct priority_arbiter : public sim { | 10 | template<typename T, unsigned int peers> struct priority_arbiter : public sim { |
| 10 | std::array<port<T>, peers> peerp; | 11 | std::array<port<T> *, peers> peerp; |
| 11 | port<T> *outp = nullptr; | 12 | port<T> *outp = nullptr; |
| 12 | 13 | ||
| 13 | void clock() { | 14 | void clock() { |
| 14 | for (unsigned int i = 0; i < peers; ++i) { | 15 | for (unsigned int i = 0; i < peers; ++i) { |
| 15 | if (outp->can_write() && peerp[i].can_read()) | 16 | if (outp->can_write() && peerp[i]->can_read()) |
| 16 | outp->write(peerp[i].read()); | 17 | outp->write(peerp[i]->read()); |
| 17 | } | 18 | } |
| 18 | } | 19 | } |
| 19 | }; | 20 | }; |
| 20 | 21 | ||
| 21 | template<typename T, unsigned int peers> struct round_robin_arbiter : public sim { | 22 | template<typename T, unsigned int peers> struct round_robin_arbiter : public sim { |
| 22 | std::array<port<T>, peers> peerp; | 23 | std::array<port<T> *, peers> peerp; |
| 23 | port<T> *outp = nullptr; | 24 | port<T> *outp = nullptr; |
| 24 | unsigned int initial = 0; | 25 | unsigned int initial = 0; |
| 25 | 26 | ||
| 26 | void clock() { | 27 | void clock() { |
| 27 | bool initially_empty = outp->can_write(); | 28 | bool initially_empty = outp->can_write(); |
| 28 | for (unsigned int i = initial; i < peers; ++i) { | 29 | for (unsigned int i = initial; i < peers; ++i) { |
| 29 | if (outp->can_write() && peerp[i].can_read()) | 30 | if (outp->can_write() && peerp[i]->can_read()) |
| 30 | outp->write(peerp[i].read()); | 31 | outp->write(peerp[i]->read()); |
| 31 | } | 32 | } |
| 32 | for (unsigned int i = 0; i < initial; ++i) { | 33 | for (unsigned int i = 0; i < initial; ++i) { |
| 33 | if (outp->can_write() && peerp[i].can_read()) | 34 | if (outp->can_write() && peerp[i]->can_read()) |
| 34 | outp->write(peerp[i].read()); | 35 | outp->write(peerp[i]->read()); |
| 35 | } | 36 | } |
| 36 | if (initially_empty && !outp->can_write()) | 37 | if (initially_empty && !outp->can_write()) |
| 37 | if (++initial == peers) | 38 | if (++initial == peers) |
| 38 | initial = 0; | 39 | initial = 0; |
| 39 | } | 40 | } |
| 40 | }; | 41 | }; |
| 41 | |||
| 42 | template<typename T, unsigned int peers> struct shared_bus : public sim { | ||
| 43 | std::array<port<T>, peers> peerp; | ||
| 44 | port<T> *outp = nullptr; | ||
| 45 | |||
| 46 | void clock() { | ||
| 47 | for (unsigned int i = 0; i < peers; ++i) { | ||
| 48 | if (peerp[i].can_read()) { | ||
| 49 | assert(outp->can_write()); | ||
| 50 | outp->write(peerp[i].read()); | ||
| 51 | } | ||
| 52 | } | ||
| 53 | } | ||
| 54 | }; | ||
| 55 | } | 42 | } |
