summaryrefslogtreecommitdiff
path: root/memory/dram.h
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--memory/dram.h50
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}