diff options
author | bd <bdunahu@operationnull.com> | 2025-03-09 23:49:29 -0400 |
---|---|---|
committer | bd <bdunahu@operationnull.com> | 2025-03-09 23:49:29 -0400 |
commit | 2669ab2cfccd9b0b3954e6a68af3de67bd951938 (patch) | |
tree | b5a53b6e85f59392267a8a26e631c00445c30e94 | |
parent | 95d90e454beca2e467613d0c0fbb035b02eada23 (diff) |
Properly set cache metadata when a value is loaded
-rw-r--r-- | src/storage/cache.cc | 15 | ||||
-rw-r--r-- | src/storage/dram.cc | 3 | ||||
-rw-r--r-- | tests/cache.cc | 169 |
3 files changed, 139 insertions, 48 deletions
diff --git a/src/storage/cache.cc b/src/storage/cache.cc index 52f13b9..2031367 100644 --- a/src/storage/cache.cc +++ b/src/storage/cache.cc @@ -34,6 +34,7 @@ Response Cache::write(Accessor accessor, signed int data, int address) int tag, index, offset; get_bit_fields(address, &tag, &index, &offset); this->data->at(index).at(offset) = data; + this->meta[index].at(1) = 1; r = OK; } } @@ -52,22 +53,24 @@ void Cache::fetch_resource(int expected) Response r = OK; int tag, index, offset; std::array<signed int, LINE_SIZE> actual; - std::array<int, 2> meta; + std::array<int, 2> *meta; get_bit_fields(expected, &tag, &index, &offset); - meta = this->meta.at(index); + meta = &this->meta.at(index); - if (this->meta[index][0] != tag) { + if (meta->at(0) != tag) { // address not in cache - if (this->meta[index][1] >= 0) { + if (meta->at(1) >= 0) { // occupant is dirty // TODO r = WAIT; } else { actual = this->data->at(index); r = this->lower->read(L1CACHE, expected, actual); - // clear dirty bit and set tag? - + if (r == OK) { + meta->at(0) = tag; + meta->at(1) = -1; + } } } diff --git a/src/storage/dram.cc b/src/storage/dram.cc index 9dab4ed..441f10b 100644 --- a/src/storage/dram.cc +++ b/src/storage/dram.cc @@ -57,13 +57,16 @@ Response Dram::read( Accessor accessor, int address, std::array<signed int, LINE_SIZE> &data) { Response r = WAIT; + if (this->requester == IDLE) this->requester = accessor; + if (this->requester == accessor) { if (this->wait_time == 0) { this->do_read(data, address); r = OK; } } + return r; } diff --git a/tests/cache.cc b/tests/cache.cc index 9e6521a..64819b6 100644 --- a/tests/cache.cc +++ b/tests/cache.cc @@ -42,45 +42,130 @@ TEST_CASE("no delay stores instantly", "[cache]") delete c; } -// TEST_CASE("cache takes \"forever\"", "[cache]") -// { -// int delay = 0; -// Dram *d = new Dram(MEM_SIZE, delay); -// Cache *c = new Cache(d, delay + 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 w = 0x11223344; - -// int i; -// Response r; -// for (i = 0; i < delay + 2; ++i) { -// r = c->write(MEM, w, 0x0000000000000); -// CHECK(r == WAIT); - -// // keep dram busy -// r = d->write(MEM, w, 0x0000000000101); -// CHECK(r == OK); - -// actual = c->view(0, 1)[0]; -// REQUIRE(expected == actual); -// c->resolve(); -// d->resolve(); -// } - -// r = c->write(MEM, w, 0x0000000000000); -// CHECK(r == OK); -// d->resolve(); - -// actual = d->view(0, 1)[0]; -// // we do NOT write back now! -// REQUIRE(expected == actual); - -// expected.at(1) = w; -// actual = c->view(0, 1)[0]; -// REQUIRE(expected == actual); - -// delete d; -// delete c; -// } +TEST_CASE("cache takes \"forever\"", "[cache]") +{ + int delay = 0; + Dram *d = new Dram(MEM_SIZE, delay); + Cache *c = new Cache(d, delay + 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 w = 0x11223344; + + int i; + Response r; + for (i = 0; i < delay + 2; ++i) { + r = c->write(MEM, w, 0x0000000000000); + CHECK(r == WAIT); // WAIT + + actual = c->view(0, 1)[0]; + REQUIRE(expected == actual); + c->resolve(); + d->resolve(); + } + + r = c->write(MEM, w, 0x0000000000000); + CHECK(r == OK); + d->resolve(); + + actual = d->view(0, 1)[0]; + // we do NOT write back now! + REQUIRE(expected == actual); + + expected.at(0) = w; + actual = c->view(0, 1)[0]; + REQUIRE(expected == actual); + + delete d; + delete c; +} + +TEST_CASE("dram takes \"forever\"", "[cache]") +{ + int delay = 0; + Dram *d = new Dram(MEM_SIZE, delay + 2); + Cache *c = new Cache(d, 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; + + int i; + Response r; + for (i = 0; i < delay + 2; ++i) { + r = c->write(MEM, w, 0x0000000000000); + CHECK(r == BLOCKED); // BLOCKED + + actual = c->view(0, 1)[0]; + REQUIRE(expected == actual); + c->resolve(); + d->resolve(); + } + + r = c->write(MEM, w, 0x0000000000000); + CHECK(r == OK); + d->resolve(); + + actual = d->view(0, 1)[0]; + // we do NOT write back now! + REQUIRE(expected == actual); + + expected.at(0) = w; + actual = c->view(0, 1)[0]; + REQUIRE(expected == actual); + + delete d; + delete c; +} + +TEST_CASE("dram and cache take \"forever\"", "[cache]") +{ + int delay = 2; + Dram *d = new Dram(MEM_SIZE, delay + 2); + Cache *c = new Cache(d, 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; + + int i; + Response r; + for (i = 0; i < delay + 2; ++i) { + r = c->write(MEM, w, 0x0000000000000); + CHECK(r == BLOCKED); // BLOCKED + + actual = c->view(0, 1)[0]; + REQUIRE(expected == actual); + c->resolve(); + d->resolve(); + } + + for (i = 0; i < delay; ++i) { + r = c->write(MEM, w, 0x0000000000000); + CHECK(r == WAIT); // WAIT + + actual = c->view(0, 1)[0]; + REQUIRE(expected == actual); + c->resolve(); + d->resolve(); + } + + r = c->write(MEM, w, 0x0000000000000); + CHECK(r == OK); + c->resolve(); + d->resolve(); + + actual = d->view(0, 1)[0]; + // we do NOT write back now! + REQUIRE(expected == actual); + + expected.at(0) = w; + actual = c->view(0, 1)[0]; + REQUIRE(expected == actual); + + delete d; + delete c; +} |