summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorbd <bdunahu@operationnull.com>2025-03-08 12:51:01 -0500
committerbd <bdunahu@operationnull.com>2025-03-08 12:51:01 -0500
commit2c424d29fd813b1fbef3b07595713611a1684903 (patch)
treefc5e0f85af22003dce16abd06a131cac7c1d8b5c /tests
parentc5f26a0bfdaafc8d49c88d2016df1724b64e5271 (diff)
enforce single unit per clock cycle, order to serve storage requests
Diffstat (limited to 'tests')
-rw-r--r--tests/dram.cc256
1 files changed, 140 insertions, 116 deletions
diff --git a/tests/dram.cc b/tests/dram.cc
index ba81508..e0189c7 100644
--- a/tests/dram.cc
+++ b/tests/dram.cc
@@ -23,7 +23,7 @@ TEST_CASE(
signed int w = 0x11223344;
Response r = d->write(MEM, w, 0x00000000);
- REQUIRE(r == OK);
+ CHECK(r == OK);
expected.at(0) = w;
actual = d->view(0, 1)[0];
@@ -35,34 +35,28 @@ TEST_CASE(
TEST_CASE(
"Construct singleton dram, store 0th element in three cycles", "[dram]")
{
- Dram *d = new Dram(1, 3);
+ int delay = 3;
+ Dram *d = new Dram(1, delay);
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 w = 0x11223344;
- // MEMORY CYCLE 1
- Response r = d->write(MEM, w, 0x00000000);
- actual = d->view(0, 1)[0];
- REQUIRE(expected == actual);
- REQUIRE(r == WAIT);
+ int i;
+ Response r;
+ for (i = 0; i < delay; ++i) {
+ r = d->write(MEM, w, 0x00000000);
+ CHECK(r == WAIT);
- // MEMORY CYCLE 2
- r = d->write(MEM, w, 0x00000000);
- actual = d->view(0, 1)[0];
- REQUIRE(expected == actual);
- REQUIRE(r == WAIT);
+ actual = d->view(0, 1)[0];
+ REQUIRE(expected == actual);
+ d->resolve();
+ }
- // MEMORY CYCLE 3
r = d->write(MEM, w, 0x00000000);
- actual = d->view(0, 1)[0];
- REQUIRE(expected == actual);
- REQUIRE(r == WAIT);
-
- // MEMORY CYCLE 4
- r = d->write(MEM, w, 0x00000000);
- REQUIRE(r == OK);
+ CHECK(r == OK);
+ d->resolve();
expected.at(0) = w;
actual = d->view(0, 1)[0];
@@ -76,66 +70,58 @@ TEST_CASE(
"conflict",
"[dram]")
{
- Dram *d = new Dram(1, 3);
+ int delay = 3;
+ Dram *d = new Dram(1, delay);
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;
+ signed int w = 0x11223344;
- // MEMORY CYCLE 1
- Response r = d->write(MEM, w1, 0x00000000);
- actual = d->view(0, 1)[0];
- REQUIRE(expected == actual);
- REQUIRE(r == WAIT);
+ int i;
+ Response r;
+ for (i = 0; i < delay; ++i) {
+ r = d->write(MEM, w, 0x00000000);
+ CHECK(r == WAIT);
- // MEMORY CYCLE 2
- actual = d->view(0, 1)[0];
- r = d->write(MEM, w1, 0x00000000);
- actual = d->view(0, 1)[0];
- REQUIRE(expected == actual);
- REQUIRE(r == WAIT);
+ actual = d->view(0, 1)[0];
+ CHECK(r == WAIT);
- // MEMORY CYCLE 3
- r = d->write(MEM, w1, 0x00000000);
- actual = d->view(0, 1)[0];
- REQUIRE(expected == actual);
- REQUIRE(r == WAIT);
+ REQUIRE(expected == actual);
+ d->resolve();
+ }
- // MEMORY CYCLE 4
- r = d->write(MEM, w1, 0x00000000);
+ r = d->write(MEM, w, 0x00000000);
REQUIRE(r == OK);
- // NOTE: servicing on the same clock cycle should probably not be allowed
- // FETCH CYCLE 1
- r = d->write(FETCH, w2, 0x00000001);
- actual = d->view(0, 1)[0];
- REQUIRE(r == WAIT);
+ // clock cycle did NOT resolve yet!
+ // this fetch should not make progress
+ r = d->write(FETCH, w, 0x00000001);
+ CHECK(r == WAIT);
- expected.at(0) = w1;
actual = d->view(0, 1)[0];
- CHECK(expected == actual);
+ CHECK(r == WAIT);
+ d->resolve();
- // FETCH CYCLE 2
- r = d->write(FETCH, w2, 0x00000001);
+ expected.at(0) = w;
actual = d->view(0, 1)[0];
REQUIRE(expected == actual);
- REQUIRE(r == WAIT);
- // FETCH CYCLE 3
- r = d->write(FETCH, w2, 0x00000001);
- actual = d->view(0, 1)[0];
- REQUIRE(expected == actual);
- REQUIRE(r == WAIT);
+ for (i = 0; i < delay; ++i) {
+ r = d->write(FETCH, w, 0x00000001);
+ CHECK(r == WAIT);
- // FETCH CYCLE 4
- r = d->write(FETCH, w2, 0x00000001);
+ actual = d->view(0, 1)[0];
+ REQUIRE(expected == actual);
+ d->resolve();
+ }
+
+ r = d->write(FETCH, w, 0x00000001);
actual = d->view(0, 1)[0];
- REQUIRE(r == OK);
+ CHECK(r == OK);
- expected.at(1) = w2;
+ expected.at(1) = w;
actual = d->view(0, 1)[0];
- CHECK(expected == actual);
+ REQUIRE(expected == actual);
delete d;
}
@@ -145,103 +131,141 @@ TEST_CASE(
"conflict",
"[dram]")
{
- Dram *d = new Dram(1, 3);
+ int delay = 2;
+ Dram *d = new Dram(1, 2);
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;
+ signed int w = 0x11223344;
- // MEMORY CYCLE 1
- Response r = d->write(MEM, w1, 0x00000000);
- actual = d->view(0, 1)[0];
- REQUIRE(expected == actual);
- REQUIRE(r == WAIT);
+ int i;
+ Response r;
+ for (i = 0; i < delay; ++i) {
+ r = d->write(MEM, w, 0x00000000);
+ CHECK(r == WAIT);
+
+ r = d->write(FETCH, w, 0x00000001);
+ CHECK(r == WAIT);
+
+ actual = d->view(0, 1)[0];
+ REQUIRE(expected == actual);
+ d->resolve();
+ }
+
+ r = d->write(MEM, w, 0x00000000);
+ CHECK(r == OK);
+ r = d->write(FETCH, w, 0x00000001);
+ CHECK(r == WAIT);
+ d->resolve();
- // MEMORY CYCLE 2
- actual = d->view(0, 1)[0];
- r = d->write(MEM, w1, 0x00000000);
actual = d->view(0, 1)[0];
+ expected.at(0) = w;
REQUIRE(expected == actual);
- REQUIRE(r == WAIT);
- // FETCH CYCLE 1
- r = d->write(FETCH, w2, 0x00000001);
+
+ for (i = 0; i < delay; ++i) {
+ r = d->write(FETCH, w, 0x00000001);
+ CHECK(r == WAIT);
+
+ r = d->write(MEM, w, 0x00000003);
+ CHECK(r == WAIT);
+
+ actual = d->view(0, 1)[0];
+ REQUIRE(expected == actual);
+ d->resolve();
+ }
+
+ r = d->write(FETCH, w, 0x00000001);
actual = d->view(0, 1)[0];
- REQUIRE(r == WAIT);
+ CHECK(r == OK);
+ r = d->write(MEM, w, 0x00000003);
+ CHECK(r == WAIT);
- r = d->write(MEM, w1, 0x00000000);
+ expected.at(1) = w;
actual = d->view(0, 1)[0];
REQUIRE(expected == actual);
- REQUIRE(r == WAIT);
- // FETCH CYCLE 1
- r = d->write(FETCH, w2, 0x00000001);
- actual = d->view(0, 1)[0];
- REQUIRE(r == WAIT);
- r = d->write(MEM, w1, 0x00000000);
- REQUIRE(r == OK);
- // NOTE: servicing on the same clock cycle should probably not be allowed
- // FETCH CYCLE 1
- r = d->write(FETCH, w2, 0x00000001);
- actual = d->view(0, 1)[0];
- REQUIRE(r == WAIT);
+ delete d;
+}
- expected.at(0) = w1;
- actual = d->view(0, 1)[0];
+TEST_CASE("Many conflicting requests first-come first serve", "[dram]")
+{
+ int delay = 1;
+ Dram *d = new Dram(1, delay);
+ 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);
- r = d->write(FETCH, w2, 0x00000001);
+ signed int w = 0x11223344;
+
+ Response r;
+ r = d->write(FETCH, w, 0x00000000);
+ r = d->write(MEM, w, 0x00000001);
+
actual = d->view(0, 1)[0];
REQUIRE(expected == actual);
- REQUIRE(r == WAIT);
+ d->resolve();
- r = d->write(FETCH, w2, 0x00000001);
+ r = d->write(FETCH, w, 0x00000000);
+ r = d->write(L1CACHE, w, 0x00000002);
+ // call mem after cache
+ r = d->write(MEM, w, 0x00000001);
+
+ expected.at(0) = w;
actual = d->view(0, 1)[0];
REQUIRE(expected == actual);
- REQUIRE(r == WAIT);
+ d->resolve();
+
+ r = d->write(MEM, w, 0x00000001);
+ r = d->write(L1CACHE, w, 0x00000002);
- r = d->write(FETCH, w2, 0x00000001);
actual = d->view(0, 1)[0];
- REQUIRE(r == OK);
+ REQUIRE(expected == actual);
+ d->resolve();
- expected.at(1) = w2;
+ r = d->write(MEM, w, 0x00000001);
+ r = d->write(L1CACHE, w, 0x00000002);
+
+ expected.at(1) = w;
actual = d->view(0, 1)[0];
- CHECK(expected == actual);
+ REQUIRE(expected == actual);
delete d;
}
TEST_CASE("Sidedoor bypasses delay", "[dram]")
{
- Dram *d = new Dram(1, 3);
+ int delay = 3;
+ Dram *d = new Dram(1, delay);
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;
+ signed int w = 0x11223344;
+
+ int i;
+ Response r;
+ for (i = 0; i < delay - 1; ++i) {
+ r = d->write(MEM, w, 0x00000000);
+ CHECK(r == WAIT);
- // MEMORY CYCLE 1
- Response r = d->write(MEM, w1, 0x00000000);
- actual = d->view(0, 1)[0];
- REQUIRE(expected == actual);
- REQUIRE(r == WAIT);
+ actual = d->view(0, 1)[0];
+ REQUIRE(expected == actual);
+ d->resolve();
+ }
- // MEMORY CYCLE 2
- actual = d->view(0, 1)[0];
- r = d->write(MEM, w1, 0x00000000);
+ r = d->write(MEM, w, 0x00000000);
+ CHECK(r == WAIT);
actual = d->view(0, 1)[0];
REQUIRE(expected == actual);
- REQUIRE(r == WAIT);
- // SIDE CYCLE 1
- r = d->write(SIDE, w2, 0x00000001);
+
+ r = d->write(SIDE, w, 0x00000001);
actual = d->view(0, 1)[0];
- REQUIRE(r == OK);
+ CHECK(r == OK);
- expected.at(1) = w2;
+ expected.at(1) = w;
actual = d->view(0, 1)[0];
- CHECK(expected == actual);
+ REQUIRE(expected == actual);
delete d;
}