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 /memory/dram.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 '')
| -rw-r--r-- | memory/dram.h | 50 |
1 files changed, 46 insertions, 4 deletions
diff --git a/memory/dram.h b/memory/dram.h index f59c7a6..31aea12 100644 --- a/memory/dram.h +++ b/memory/dram.h | |||
| @@ -21,6 +21,8 @@ namespace memory { | |||
| 21 | 21 | ||
| 22 | typedef std::array<line, PAGE_LINES> page; | 22 | typedef std::array<line, PAGE_LINES> page; |
| 23 | 23 | ||
| 24 | const unsigned int latency; | ||
| 25 | |||
| 24 | std::map<std::uint64_t, page> image; | 26 | std::map<std::uint64_t, page> image; |
| 25 | 27 | ||
| 26 | struct response { | 28 | struct response { |
| @@ -38,11 +40,26 @@ namespace memory { | |||
| 38 | infra::port<response> *responsep = nullptr; | 40 | infra::port<response> *responsep = nullptr; |
| 39 | }; | 41 | }; |
| 40 | 42 | ||
| 41 | infra::port<command> commandp; | 43 | infra::port<command> *commandp = nullptr; |
| 44 | |||
| 45 | unsigned int progress = 0; | ||
| 46 | std::optional<command> current_command; | ||
| 47 | |||
| 48 | dram(unsigned int latency=0) | ||
| 49 | : latency(latency) | ||
| 50 | { } | ||
| 42 | 51 | ||
| 43 | void clock() { | 52 | void clock() { |
| 44 | if (commandp.can_read()) { | 53 | if (!current_command.has_value() && commandp->can_read()) { |
| 45 | const auto &c = commandp.peek(); | 54 | current_command = commandp->read(); |
| 55 | progress = latency; | ||
| 56 | } | ||
| 57 | if (current_command.has_value()) { | ||
| 58 | if (progress) { | ||
| 59 | --progress; | ||
| 60 | return; | ||
| 61 | } | ||
| 62 | const auto &c = *current_command; | ||
| 46 | if (!c.responsep || c.responsep->can_write()) { | 63 | if (!c.responsep || c.responsep->can_write()) { |
| 47 | auto page_address = c.line_address >> PAGE_LINES_LOG2; | 64 | auto page_address = c.line_address >> PAGE_LINES_LOG2; |
| 48 | auto page_line = c.line_address & PAGE_LINE_OFFSET_MASK; | 65 | auto page_line = c.line_address & PAGE_LINE_OFFSET_MASK; |
| @@ -76,7 +93,7 @@ namespace memory { | |||
| 76 | c.responsep->write(std::move(r)); | 93 | c.responsep->write(std::move(r)); |
| 77 | } | 94 | } |
| 78 | } | 95 | } |
| 79 | commandp.discard(); | 96 | current_command.reset(); |
| 80 | } | 97 | } |
| 81 | } | 98 | } |
| 82 | } | 99 | } |
| @@ -92,5 +109,30 @@ namespace memory { | |||
| 92 | return; | 109 | return; |
| 93 | } | 110 | } |
| 94 | } | 111 | } |
| 112 | |||
| 113 | unsigned int fetch(std::uint64_t address) const { | ||
| 114 | auto page_address = address >> PAGE_LINES_LOG2; | ||
| 115 | if (auto i = image.find(page_address); i != image.end()) { | ||
| 116 | auto &page = i->second; | ||
| 117 | auto line_address = (address & PAGE_LINE_OFFSET_MASK) >> LINE_BYTES_LOG2; | ||
| 118 | auto &line = page[line_address]; | ||
| 119 | auto word_address = address & LINE_BYTE_OFFSET_MASK; | ||
| 120 | return line[word_address]; | ||
| 121 | } | ||
| 122 | return 0; | ||
| 123 | } | ||
| 124 | |||
| 125 | void store(std::uint64_t address, unsigned int value) { | ||
| 126 | auto page_address = address >> PAGE_LINES_LOG2; | ||
| 127 | auto [p, emplaced] = image.try_emplace(page_address); | ||
| 128 | auto &page = p->second; | ||
| 129 | if (emplaced) | ||
| 130 | for (unsigned int i = 0; i < PAGE_LINES; ++i) | ||
| 131 | page[i].fill(0); | ||
| 132 | auto line_address = (address & PAGE_LINE_OFFSET_MASK) >> LINE_BYTES_LOG2; | ||
| 133 | auto &line = page[line_address]; | ||
| 134 | auto word_address = address & LINE_BYTE_OFFSET_MASK; | ||
| 135 | line[word_address] = value; | ||
| 136 | } | ||
| 95 | }; | 137 | }; |
| 96 | } | 138 | } |
