summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--inc/storage.h9
-rw-r--r--src/storage/dram.cc31
-rw-r--r--src/storage/storage.cc9
-rw-r--r--tests/dram.cc39
4 files changed, 71 insertions, 17 deletions
diff --git a/inc/storage.h b/inc/storage.h
index f5659c5..841c531 100644
--- a/inc/storage.h
+++ b/inc/storage.h
@@ -11,6 +11,7 @@ enum Accessor {
FETCH,
L1CACHE,
IDLE,
+ SIDE,
};
class Storage
@@ -21,7 +22,7 @@ class Storage
* @param the source making the request.
* @param the data (hexadecimal) to write.
* @param the address to write to.
- * @return a status code reflecting the state of the storage level.
+ * @return a status code reflecting the state of the request.
*/
virtual Response *
write(Accessor accessor, signed int data, int address) = 0;
@@ -29,7 +30,7 @@ class Storage
* Get the data at `address`.
* @param the source making the request.
* @param the address being accessed.
- * @return a status code reflecting the state of the storage level, and the
+ * @return a status code reflecting the state of the request, and the
* data being returned.
*/
virtual Response *read(Accessor accessor, int address) = 0;
@@ -44,6 +45,10 @@ class Storage
protected:
/**
+ * Helper for `write`.
+ */
+ void do_write(signed int, int);
+ /**
* The data currently stored in this level of storage.
*/
std::vector<std::array<signed int, LINE_SIZE>> *data;
diff --git a/src/storage/dram.cc b/src/storage/dram.cc
index 3143a61..3eb0748 100644
--- a/src/storage/dram.cc
+++ b/src/storage/dram.cc
@@ -19,22 +19,23 @@ Response *Dram::write(Accessor accessor, signed int data, int address)
struct Response *r = new Response();
r->status = WAIT;
- /* Do this first--then process the first cycle immediately. */
- if (this->servicing == IDLE) {
- this->servicing = accessor;
- this->wait_time = delay;
- }
-
- if (this->servicing == accessor) {
- if (this->wait_time == 0) {
- int line = address / LINE_SIZE;
- int word = address % LINE_SIZE;
+ if (accessor == SIDE) {
+ this->do_write(data, address);
+ r->status = OK;
+ } else {
+ /* Do this first--then process the first cycle immediately. */
+ if (this->servicing == IDLE) {
+ this->servicing = accessor;
+ this->wait_time = delay;
+ }
- this->servicing = IDLE;
- this->data->at(line).at(word) = data;
- r->status = OK;
- } else {
- --this->wait_time;
+ if (this->servicing == accessor) {
+ if (this->wait_time == 0) {
+ this->do_write(data, address);
+ r->status = OK;
+ } else {
+ --this->wait_time;
+ }
}
}
diff --git a/src/storage/storage.cc b/src/storage/storage.cc
index a9a883a..024699b 100644
--- a/src/storage/storage.cc
+++ b/src/storage/storage.cc
@@ -12,3 +12,12 @@ Storage::view(int base, int lines)
ret.begin());
return ret;
}
+
+void Storage::do_write(signed data, int address)
+{
+ int line = address / LINE_SIZE;
+ int word = address % LINE_SIZE;
+
+ this->servicing = IDLE;
+ this->data->at(line).at(word) = data;
+}
diff --git a/tests/dram.cc b/tests/dram.cc
index 55d4d24..e98abc1 100644
--- a/tests/dram.cc
+++ b/tests/dram.cc
@@ -234,3 +234,42 @@ TEST_CASE(
delete d;
}
+
+TEST_CASE(
+ "Sidedoor bypasses delay",
+ "[dram]")
+{
+ Dram *d = new Dram(1, 3);
+ std::array<signed int, LINE_SIZE> expected = {0, 0, 0, 0};
+ std::array<signed int, LINE_SIZE> actual = d->view(0, 1)[0];
+ CHECK(expected == actual);
+
+ signed int w1 = 0x11223344;
+ signed int w2 = 0x55667788;
+
+ // MEMORY CYCLE 1
+ Response *r = d->write(MEMORY, w1, 0x00000000);
+ actual = d->view(0, 1)[0];
+ REQUIRE(expected == actual);
+ REQUIRE(r->status == WAIT);
+ delete r;
+
+ // MEMORY CYCLE 2
+ actual = d->view(0, 1)[0];
+ r = d->write(MEMORY, w1, 0x00000000);
+ actual = d->view(0, 1)[0];
+ REQUIRE(expected == actual);
+ REQUIRE(r->status == WAIT);
+ delete r;
+ // SIDE CYCLE 1
+ r = d->write(SIDE, w2, 0x00000001);
+ actual = d->view(0, 1)[0];
+ REQUIRE(r->status == OK);
+ delete r;
+
+ expected.at(1) = w2;
+ actual = d->view(0, 1)[0];
+ CHECK(expected == actual);
+
+ delete d;
+}