#include "cache.h" #include "definitions.h" #include "dram.h" #include TEST_CASE("Constructor singleton cache", "[cache]") { Cache *c = new Cache(nullptr, 0); std::array expected = {0, 0, 0, 0}; std::array actual = c->view(0, 1)[0]; REQUIRE(expected == actual); delete c; } TEST_CASE("no delay stores instantly", "[cache]") { int delay = 0; Dram *d = new Dram(MEM_LINES, delay); Cache *c = new Cache(d, delay); std::array expected = {0, 0, 0, 0}; std::array actual = d->view(0, 1)[0]; CHECK(expected == actual); signed int w = 0x11223344; Response r; r = c->write(MEM, w, 0b0); CHECK(r == OK); c->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 c; } TEST_CASE("cache takes \"forever\"", "[cache]") { int delay = 0; Dram *d = new Dram(MEM_LINES, delay); Cache *c = new Cache(d, delay + 2); std::array expected = {0, 0, 0, 0}; std::array 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, 0b0); CHECK(r == WAIT); // WAIT actual = c->view(0, 1)[0]; REQUIRE(expected == actual); c->resolve(); } r = c->write(MEM, w, 0b0); CHECK(r == OK); 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 c; } TEST_CASE("dram takes \"forever\"", "[cache]") { int delay = 0; Dram *d = new Dram(MEM_LINES, delay + 2); Cache *c = new Cache(d, delay); std::array expected = {0, 0, 0, 0}; std::array 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, 0b0); CHECK(r == BLOCKED); // BLOCKED actual = c->view(0, 1)[0]; REQUIRE(expected == actual); c->resolve(); } r = c->write(MEM, w, 0b0); CHECK(r == OK); 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 c; } TEST_CASE("dram and cache take \"forever\"", "[cache]") { int delay = 2; Dram *d = new Dram(MEM_LINES, delay + 2); Cache *c = new Cache(d, delay); std::array expected = {0, 0, 0, 0}; std::array 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, 0b0); CHECK(r == BLOCKED); // BLOCKED actual = c->view(0, 1)[0]; REQUIRE(expected == actual); c->resolve(); } for (i = 0; i < delay; ++i) { r = c->write(MEM, w, 0b0); CHECK(r == WAIT); // WAIT actual = c->view(0, 1)[0]; REQUIRE(expected == actual); c->resolve(); } r = c->write(MEM, w, 0b0); CHECK(r == OK); c->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 c; } TEST_CASE( "dram takes \"forever\", two concurrent requests same index", "[cache]") { int delay = 0; Dram *d = new Dram(MEM_LINES, delay + 2); Cache *c = new Cache(d, delay); std::array expected = {0, 0, 0, 0}; std::array 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, 0b0); CHECK(r == BLOCKED); // BLOCKED r = c->write(FETCH, w, 0b1); CHECK(r == WAIT); // WAIT actual = c->view(0, 1)[0]; REQUIRE(expected == actual); c->resolve(); } r = c->write(MEM, w, 0b0); CHECK(r == OK); r = c->write(FETCH, w, 0b1); CHECK(r == WAIT); c->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); r = c->write(FETCH, w, 0b1); // this should have been loaded already! CHECK(r == OK); c->resolve(); expected.at(1) = w; actual = c->view(0, 1)[0]; REQUIRE(expected == actual); delete c; } TEST_CASE( "dram takes \"forever\", two concurrent requests different index", "[cache]") { int delay = 0; Dram *d = new Dram(MEM_LINES, delay + 2); Cache *c = new Cache(d, delay); std::array expected = {0, 0, 0, 0}; std::array 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, 0b0); CHECK(r == BLOCKED); // BLOCKED r = c->write(FETCH, w, 0b100); CHECK(r == WAIT); // WAIT actual = c->view(0, 1)[0]; REQUIRE(expected == actual); c->resolve(); } r = c->write(MEM, w, 0b0); CHECK(r == OK); r = c->write(FETCH, w, 0b1); CHECK(r == WAIT); c->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); for (i = 0; i < delay + 2; ++i) { r = c->write(FETCH, w, 0b100); CHECK(r == BLOCKED); // BLOCKED actual = c->view(0, 1)[0]; REQUIRE(expected == actual); c->resolve(); } r = c->write(FETCH, w, 0b1); CHECK(r == OK); c->resolve(); expected.at(1) = w; actual = c->view(0, 1)[0]; REQUIRE(expected == actual); delete c; } TEST_CASE( "dram takes \"forever\", two concurrent requests different tag", "[cache]") { // TODO }