From 7c226db9f04de7061596b98763dc408d601d74e1 Mon Sep 17 00:00:00 2001 From: bd Date: Tue, 11 Mar 2025 11:54:21 -0400 Subject: Clarify size of mem and cache in definitions, CLI print invalid tags --- inc/cache.h | 4 ++-- inc/definitions.h | 23 +++++++++++------------ src/cli/cli.cc | 4 ++-- src/storage/cache.cc | 29 +++++++++++++++++------------ src/storage/dram.cc | 8 ++++---- src/utils/utils.cc | 6 +++--- tests/cache.cc | 12 ++++++------ 7 files changed, 45 insertions(+), 41 deletions(-) diff --git a/inc/cache.h b/inc/cache.h index 04f6181..a566f24 100644 --- a/inc/cache.h +++ b/inc/cache.h @@ -31,7 +31,7 @@ class Cache : public Storage * TODO this doesn't seem like good object-oriented practice. * @return this->meta */ - std::array, L1_CACHE_SIZE> get_meta() const; + std::array, L1_CACHE_LINES> get_meta() const; private: /** @@ -47,7 +47,7 @@ class Cache : public Storage * element in `data` is invalid. If the most second value of an element * is nonzero, the corresponding element in `data` is dirty. */ - std::array, L1_CACHE_SIZE> meta; + std::array, L1_CACHE_LINES> meta; }; std::ostream &operator<<(std::ostream &os, const Cache &c); diff --git a/inc/definitions.h b/inc/definitions.h index f015ce9..1d68a60 100644 --- a/inc/definitions.h +++ b/inc/definitions.h @@ -13,28 +13,27 @@ #define LINE_SIZE static_cast(pow(2, 2)) /** + * The number of bits to specify a memory word * The number of bits to specify a memory line - * calculated as: (/ (expt 2 15) 4) + * The total number of lines in memory */ -#define MEM_SPEC 8 -/** - * The total number of words in memory - */ -#define MEM_SIZE static_cast(pow(2, MEM_SPEC)) +#define MEM_WORD_SPEC 10 +#define MEM_LINE_SPEC static_cast(MEM_WORD_SPEC - LINE_SPEC) +#define MEM_LINES static_cast(pow(2, MEM_LINE_SPEC)) /** + * The number of bits to specify a l1 cache word * The number of bits to specify a l1 cache line + * The total number of lines in l1 cache */ -#define L1_CACHE_SPEC 5 -/** - * The total number of words in l1 cache - */ -#define L1_CACHE_SIZE static_cast(pow(2, L1_CACHE_SPEC)) +#define L1_CACHE_WORD_SPEC 7 +#define L1_CACHE_LINE_SPEC static_cast(L1_CACHE_WORD_SPEC - LINE_SPEC) +#define L1_CACHE_LINES static_cast(pow(2, L1_CACHE_LINE_SPEC)) /** * The total number of cycles a memory access takes. */ -#define MEM_DELAY 4 +#define MEM_DELAY 3 /** * The total number of cycles a level one cache access takes diff --git a/src/cli/cli.cc b/src/cli/cli.cc index 0729e00..c9f83e9 100644 --- a/src/cli/cli.cc +++ b/src/cli/cli.cc @@ -116,7 +116,7 @@ void Cli::load(Accessor accessor, int address) void Cli::store(Accessor accessor, int data, int address) { Response r = this->cache->write(accessor, data, address); - std::cout << r << " to " << accessor << " storing " << data << " in" + std::cout << r << " to " << accessor << " storing " << data << " in " << address << std::endl; } @@ -209,7 +209,7 @@ void Cli::initialize() if (this->cache != nullptr) delete this->cache; - Dram *d = new Dram(MEM_SIZE, MEM_DELAY); + Dram *d = new Dram(MEM_LINES, MEM_DELAY); this->cache = new Cache(d, L1_CACHE_DELAY); this->cycle = 1; } diff --git a/src/storage/cache.cc b/src/storage/cache.cc index 1a8a10b..ddab551 100644 --- a/src/storage/cache.cc +++ b/src/storage/cache.cc @@ -10,7 +10,7 @@ Cache::Cache(Storage *lower, int delay) { this->data = new std::vector>; - this->data->resize(L1_CACHE_SIZE); + this->data->resize(L1_CACHE_LINES); this->delay = delay; this->is_waiting = false; this->lower = lower; @@ -84,9 +84,9 @@ void Cache::fetch_resource(int expected) this->is_waiting = (r == OK) ? false : true; } -std::array, L1_CACHE_SIZE> Cache::get_meta() const +std::array, L1_CACHE_LINES> Cache::get_meta() const { - std::array, L1_CACHE_SIZE> ret; + std::array, L1_CACHE_LINES> ret; std::copy(std::begin(this->meta), std::end(this->meta), std::begin(ret)); return ret; } @@ -97,24 +97,29 @@ std::ostream &operator<<(std::ostream &os, const Cache &c) const auto default_fill = std::cout.fill(); std::vector> data = - c.view(0, L1_CACHE_SIZE); - std::array, L1_CACHE_SIZE> meta = c.get_meta(); + c.view(0, L1_CACHE_LINES); + std::array, L1_CACHE_LINES> meta = c.get_meta(); - os << " " << std::setfill(' ') << std::setw(L1_CACHE_SPEC + 2) << "INDEX" + os << " " << std::setfill(' ') << std::setw(L1_CACHE_LINE_SPEC + 2) << "INDEX" << " | " << std::setfill(' ') << std::setw((8 + 3) * 4 - 1) << "DATA" << " | " << std::setfill(' ') - << std::setw(MEM_SPEC - LINE_SPEC - L1_CACHE_SPEC + 2) << "TAG" + << std::setw(MEM_LINE_SPEC - LINE_SPEC - L1_CACHE_LINE_SPEC + 2) << "TAG" << " | D" << std::endl; - for (int i = 0; i < L1_CACHE_SIZE; ++i) { - os << " 0b" << std::setw(L1_CACHE_SPEC) << std::bitset(i) + for (int i = 0; i < L1_CACHE_LINES; ++i) { + os << " 0b" << std::setw(L1_CACHE_LINE_SPEC) << std::bitset(i) << " | "; for (int j = 0; j < LINE_SIZE; ++j) { os << "0x" << std::setfill('0') << std::setw(8) << std::hex << data.at(i).at(j) << " "; } - os << "| 0x" << std::setfill(' ') - << std::bitset(meta.at(i)[0]) - << " | " << (int)(meta.at(i)[0] >= 0) << std::endl; + os << "| 0x" << std::setfill(' '); + + if (meta.at(i)[0] < 0) + os << "?"; + else + os << std::bitset(meta.at(i)[0]); + + os << " | " << (int)(meta.at(i)[0] >= 0) << std::endl; } std::cout.flags(default_flags); diff --git a/src/storage/dram.cc b/src/storage/dram.cc index e755c2a..d239cb1 100644 --- a/src/storage/dram.cc +++ b/src/storage/dram.cc @@ -80,13 +80,13 @@ std::ostream &operator<<(std::ostream &os, const Dram &d) const auto default_flags = std::cout.flags(); const auto default_fill = std::cout.fill(); - std::vector> data = d.view(0, MEM_SIZE); + std::vector> data = d.view(0, MEM_LINES); - os << " " << std::setfill(' ') << std::setw(MEM_SPEC + 2) << "INDEX" + os << " " << std::setfill(' ') << std::setw(MEM_LINE_SPEC + 2) << "INDEX" << " | " << std::setfill(' ') << std::setw((8 + 3) * 4 - 1) << "DATA" << std::endl; - for (int i = 0; i < MEM_SIZE; ++i) { - os << " 0b" << std::setw(MEM_SPEC) << std::bitset(i) << " | "; + for (int i = 0; i < MEM_LINES; ++i) { + os << " 0b" << std::setw(MEM_LINE_SPEC) << std::bitset(i) << " | "; for (int j = 0; j < LINE_SIZE; ++j) { os << "0x" << std::setfill('0') << std::setw(8) << std::hex << data.at(i).at(j) << ' '; diff --git a/src/utils/utils.cc b/src/utils/utils.cc index 5de8e89..3a99cec 100644 --- a/src/utils/utils.cc +++ b/src/utils/utils.cc @@ -7,9 +7,9 @@ void get_bit_fields(int address, int *tag, int *index, int *offset) { *tag = GET_MID_BITS( - address, LINE_SPEC + L1_CACHE_SPEC, - MEM_SPEC + LINE_SPEC + L1_CACHE_SPEC); - *index = GET_MID_BITS(address, LINE_SPEC, L1_CACHE_SPEC + LINE_SPEC); + address, LINE_SPEC + L1_CACHE_LINE_SPEC, + MEM_LINE_SPEC + LINE_SPEC + L1_CACHE_LINE_SPEC); + *index = GET_MID_BITS(address, LINE_SPEC, L1_CACHE_LINE_SPEC + LINE_SPEC); *offset = GET_LS_BITS(address, LINE_SPEC); } diff --git a/tests/cache.cc b/tests/cache.cc index e8a257f..d463fc9 100644 --- a/tests/cache.cc +++ b/tests/cache.cc @@ -15,7 +15,7 @@ TEST_CASE("Constructor singleton cache", "[cache]") TEST_CASE("no delay stores instantly", "[cache]") { int delay = 0; - Dram *d = new Dram(MEM_SIZE, delay); + 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]; @@ -43,7 +43,7 @@ TEST_CASE("no delay stores instantly", "[cache]") TEST_CASE("cache takes \"forever\"", "[cache]") { int delay = 0; - Dram *d = new Dram(MEM_SIZE, delay); + 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]; @@ -79,7 +79,7 @@ TEST_CASE("cache takes \"forever\"", "[cache]") TEST_CASE("dram takes \"forever\"", "[cache]") { int delay = 0; - Dram *d = new Dram(MEM_SIZE, 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]; @@ -115,7 +115,7 @@ TEST_CASE("dram takes \"forever\"", "[cache]") TEST_CASE("dram and cache take \"forever\"", "[cache]") { int delay = 2; - Dram *d = new Dram(MEM_SIZE, 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]; @@ -162,7 +162,7 @@ TEST_CASE( "dram takes \"forever\", two concurrent requests same index", "[cache]") { int delay = 0; - Dram *d = new Dram(MEM_SIZE, 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]; @@ -217,7 +217,7 @@ TEST_CASE( "[cache]") { int delay = 0; - Dram *d = new Dram(MEM_SIZE, 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]; -- cgit v1.2.3 From 97173af3651138db50cc42df25b474af2b6ece43 Mon Sep 17 00:00:00 2001 From: bd Date: Tue, 11 Mar 2025 12:00:09 -0400 Subject: Pad memory address output with trailing zeros --- src/storage/dram.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/storage/dram.cc b/src/storage/dram.cc index d239cb1..8513147 100644 --- a/src/storage/dram.cc +++ b/src/storage/dram.cc @@ -82,11 +82,11 @@ std::ostream &operator<<(std::ostream &os, const Dram &d) std::vector> data = d.view(0, MEM_LINES); - os << " " << std::setfill(' ') << std::setw(MEM_LINE_SPEC + 2) << "INDEX" + os << " " << std::setfill(' ') << std::setw(MEM_LINE_SPEC + 2 + LINE_SPEC) << "ADDRESS" << " | " << std::setfill(' ') << std::setw((8 + 3) * 4 - 1) << "DATA" << std::endl; for (int i = 0; i < MEM_LINES; ++i) { - os << " 0b" << std::setw(MEM_LINE_SPEC) << std::bitset(i) << " | "; + os << " 0b" << std::setw(MEM_LINE_SPEC+LINE_SPEC) << left << std::bitset(i) << " | "; for (int j = 0; j < LINE_SIZE; ++j) { os << "0x" << std::setfill('0') << std::setw(8) << std::hex << data.at(i).at(j) << ' '; -- cgit v1.2.3 From 256fd73b42ae7d10fe0190984d032f839a2127bd Mon Sep 17 00:00:00 2001 From: bd Date: Tue, 11 Mar 2025 17:24:49 -0400 Subject: clarify macro names, implement load in CLI, fix many display issues --- src/cli/cli.cc | 8 ++++---- src/storage/cache.cc | 2 +- src/utils/utils.cc | 4 ++-- tests/utils.cc | 16 ++++++++-------- 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/cli/cli.cc b/src/cli/cli.cc index d90edef..8dc7e2e 100644 --- a/src/cli/cli.cc +++ b/src/cli/cli.cc @@ -104,10 +104,10 @@ void Cli::load(Accessor accessor, int address) const auto default_fill = std::cout.fill(); signed int data; - // Response r = this->cache->read_word(accessor, address, data); - // std::cout << r << " to " << accessor << " reading " << address << std::endl; - // if (r == OK) - // std::cout << "\tGot:" << std::hex << data; + Response r = this->cache->read_word(accessor, address, data); + std::cout << r << " to " << accessor << " reading " << address << std::endl; + if (r == OK) + std::cout << " Got:" << std::hex << data << std::endl; std::cout.flags(default_flags); std::cout.fill(default_fill); diff --git a/src/storage/cache.cc b/src/storage/cache.cc index a73390b..14a6e61 100644 --- a/src/storage/cache.cc +++ b/src/storage/cache.cc @@ -135,7 +135,7 @@ void Cache::fetch_resource(int expected) r = this->lower->write_line( L1CACHE, actual, ((index << LINE_SPEC) + - (meta->at(0) << (L1_CACHE_SPEC + LINE_SPEC)))); + (meta->at(0) << (L1_CACHE_LINE_SPEC + LINE_SPEC)))); if (r == OK) { meta->at(1) = -1; } diff --git a/src/utils/utils.cc b/src/utils/utils.cc index b5a4d55..87ce488 100644 --- a/src/utils/utils.cc +++ b/src/utils/utils.cc @@ -31,7 +31,7 @@ const std::string string_format(const char *const zcFormat, ...) int wrap_address(int address) { if (address < 0){ - return ((address % MEM_SIZE) + MEM_SIZE) % MEM_SIZE; + return ((address % MEM_LINES) + MEM_LINES) % MEM_LINES; } - return address % MEM_SIZE; + return address % MEM_LINES; } diff --git a/tests/utils.cc b/tests/utils.cc index f0e4c24..900db1a 100644 --- a/tests/utils.cc +++ b/tests/utils.cc @@ -24,21 +24,21 @@ TEST_CASE("Parse arbitrary fields # two", "[cache]") TEST_CASE("wrap address outside upper bound", "[utils]") { - int address = MEM_SIZE + 25; + int address = MEM_LINES + 25; int wrapped = wrap_address(address); REQUIRE(wrapped == 25); } TEST_CASE("wrap address inside upper bound", "[utils]") { - int address = MEM_SIZE - 25; + int address = MEM_LINES - 25; int wrapped = wrap_address(address); - REQUIRE(wrapped == MEM_SIZE - 25); + REQUIRE(wrapped == MEM_LINES - 25); } TEST_CASE("wrap address at upper bound", "[utils]") { - int address = MEM_SIZE; + int address = MEM_LINES; int wrapped = wrap_address(address); REQUIRE(wrapped == 0); } @@ -47,14 +47,14 @@ TEST_CASE("wrap address lower than 0 with magnitude lesser than mem size", "[uti { int address = -10; int wrapped = wrap_address(address); - REQUIRE(wrapped == MEM_SIZE - 10); + REQUIRE(wrapped == MEM_LINES - 10); } TEST_CASE("wrap address lower than 0 but with magnitude greater than mem size", "[utils]") { - int address = -(MEM_SIZE + 10); + int address = -(MEM_LINES + 10); int wrapped = wrap_address(address); - REQUIRE(wrapped == MEM_SIZE - 10); + REQUIRE(wrapped == MEM_LINES - 10); } TEST_CASE("wrap address at 0", "[utils]") @@ -62,4 +62,4 @@ TEST_CASE("wrap address at 0", "[utils]") int address = 0; int wrapped = wrap_address(address); REQUIRE(wrapped == 0); -} \ No newline at end of file +} -- cgit v1.2.3 From df803d2ccc6a3e1e112cc88feb6c8b84743073b6 Mon Sep 17 00:00:00 2001 From: bd Date: Tue, 11 Mar 2025 17:33:27 -0400 Subject: Call memory wrapping functions properly --- src/cli/cli.cc | 4 +++- src/storage/dram.cc | 5 +++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/cli/cli.cc b/src/cli/cli.cc index 8dc7e2e..41ac57c 100644 --- a/src/cli/cli.cc +++ b/src/cli/cli.cc @@ -100,6 +100,7 @@ void Cli::help() void Cli::load(Accessor accessor, int address) { + address = wrap_address(address); const auto default_flags = std::cout.flags(); const auto default_fill = std::cout.fill(); @@ -107,7 +108,7 @@ void Cli::load(Accessor accessor, int address) Response r = this->cache->read_word(accessor, address, data); std::cout << r << " to " << accessor << " reading " << address << std::endl; if (r == OK) - std::cout << " Got:" << std::hex << data << std::endl; + std::cout << " Got: " << std::hex << data << std::endl; std::cout.flags(default_flags); std::cout.fill(default_fill); @@ -115,6 +116,7 @@ void Cli::load(Accessor accessor, int address) void Cli::store(Accessor accessor, int data, int address) { + address = wrap_address(address); Response r = this->cache->write_word(accessor, data, address); std::cout << r << " to " << accessor << " storing " << data << " in " << address << std::endl; diff --git a/src/storage/dram.cc b/src/storage/dram.cc index c244da5..60b4ae5 100644 --- a/src/storage/dram.cc +++ b/src/storage/dram.cc @@ -6,6 +6,7 @@ #include #include #include +#include Dram::Dram(int lines, int delay) { @@ -22,6 +23,7 @@ Dram::~Dram() { delete this->data; } void Dram::do_write(signed int data, int address) { + address = wrap_address(address); int line = address / LINE_SIZE; int word = address % LINE_SIZE; @@ -31,18 +33,21 @@ void Dram::do_write(signed int data, int address) void Dram::do_write_line( std::array data_line, int address) { + address = wrap_address(address); int line = address / LINE_SIZE; this->data->at(line) = data_line; } void Dram::do_read(std::array &data_line, int address) { + address = wrap_address(address); int line = address / LINE_SIZE; data_line = this->data->at(line); } void Dram::do_read_word(signed int &data, int address) { + address = wrap_address(address); int line = address / LINE_SIZE; int word = address % LINE_SIZE; data = this->data->at(line).at(word); -- cgit v1.2.3 From fb7735049f571ac45a193481e962f497b4759fa4 Mon Sep 17 00:00:00 2001 From: bd Date: Tue, 11 Mar 2025 19:02:55 -0400 Subject: fix lots of bugs --- inc/definitions.h | 1 + src/storage/cache.cc | 10 ++++++---- src/utils/utils.cc | 7 +++---- tests/utils.cc | 22 +++++++++++----------- 4 files changed, 21 insertions(+), 19 deletions(-) diff --git a/inc/definitions.h b/inc/definitions.h index 1d68a60..80fccbe 100644 --- a/inc/definitions.h +++ b/inc/definitions.h @@ -19,6 +19,7 @@ */ #define MEM_WORD_SPEC 10 #define MEM_LINE_SPEC static_cast(MEM_WORD_SPEC - LINE_SPEC) +#define MEM_WORDS static_cast(pow(2, MEM_WORD_SPEC)) #define MEM_LINES static_cast(pow(2, MEM_LINE_SPEC)) /** diff --git a/src/storage/cache.cc b/src/storage/cache.cc index 14a6e61..ea90f50 100644 --- a/src/storage/cache.cc +++ b/src/storage/cache.cc @@ -138,6 +138,7 @@ void Cache::fetch_resource(int expected) (meta->at(0) << (L1_CACHE_LINE_SPEC + LINE_SPEC)))); if (r == OK) { meta->at(1) = -1; + r = WAIT; } } else { r = this->lower->read_line(L1CACHE, expected, actual); @@ -165,11 +166,12 @@ std::ostream &operator<<(std::ostream &os, const Cache &c) std::vector> data = c.view(0, L1_CACHE_LINES); std::array, L1_CACHE_LINES> meta = c.get_meta(); + std::cout << "FOO " << meta.at(31)[0]; os << " " << std::setfill(' ') << std::setw(L1_CACHE_LINE_SPEC + 2) << "INDEX" << " | " << std::setfill(' ') << std::setw((8 + 3) * 4 - 1) << "DATA" << " | " << std::setfill(' ') - << std::setw(MEM_LINE_SPEC - LINE_SPEC - L1_CACHE_LINE_SPEC + 2) << "TAG" + << std::setw(MEM_LINE_SPEC - L1_CACHE_LINE_SPEC + 2) << "TAG" << " | D" << std::endl; for (int i = 0; i < L1_CACHE_LINES; ++i) { os << " 0b" << std::setw(L1_CACHE_LINE_SPEC) << std::bitset(i) @@ -178,12 +180,12 @@ std::ostream &operator<<(std::ostream &os, const Cache &c) os << "0x" << std::setfill('0') << std::setw(8) << std::hex << data.at(i).at(j) << " "; } - os << "| 0x" << std::setfill(' '); + os << "| 0b" << std::setfill(' '); if (meta.at(i)[0] < 0) - os << "?"; + os << std::setfill('?') << std::setw(MEM_LINE_SPEC - L1_CACHE_LINE_SPEC) << ""; else - os << std::bitset(meta.at(i)[0]); + os << std::bitset(meta.at(i)[0]); os << " | " << (int)(meta.at(i)[0] >= 0) << std::endl; } diff --git a/src/utils/utils.cc b/src/utils/utils.cc index 87ce488..ebbc1e9 100644 --- a/src/utils/utils.cc +++ b/src/utils/utils.cc @@ -7,8 +7,7 @@ void get_bit_fields(int address, int *tag, int *index, int *offset) { *tag = GET_MID_BITS( - address, LINE_SPEC + L1_CACHE_LINE_SPEC, - MEM_LINE_SPEC + LINE_SPEC + L1_CACHE_LINE_SPEC); + address, L1_CACHE_LINE_SPEC + LINE_SPEC, MEM_WORD_SPEC); *index = GET_MID_BITS(address, LINE_SPEC, L1_CACHE_LINE_SPEC + LINE_SPEC); *offset = GET_LS_BITS(address, LINE_SPEC); } @@ -31,7 +30,7 @@ const std::string string_format(const char *const zcFormat, ...) int wrap_address(int address) { if (address < 0){ - return ((address % MEM_LINES) + MEM_LINES) % MEM_LINES; + return ((address % MEM_WORDS) + MEM_WORDS) % MEM_WORDS; } - return address % MEM_LINES; + return address % MEM_WORDS; } diff --git a/tests/utils.cc b/tests/utils.cc index 900db1a..ea1a1ed 100644 --- a/tests/utils.cc +++ b/tests/utils.cc @@ -5,9 +5,9 @@ TEST_CASE("Parse arbitrary fields # one", "[cache]") { int tag, index, offset; - int address = 0b111110001010101; + int address = 0b0001010101; get_bit_fields(address, &tag, &index, &offset); - CHECK(tag == 0b11111000); + CHECK(tag == 0b000); CHECK(index == 0b10101); CHECK(offset == 0b01); } @@ -15,30 +15,30 @@ TEST_CASE("Parse arbitrary fields # one", "[cache]") TEST_CASE("Parse arbitrary fields # two", "[cache]") { int tag, index, offset; - int address = 0b000110100111011; + int address = 0b0100111011; get_bit_fields(address, &tag, &index, &offset); - CHECK(tag == 0b00011010); + CHECK(tag == 0b010); CHECK(index == 0b01110); CHECK(offset == 0b11); } TEST_CASE("wrap address outside upper bound", "[utils]") { - int address = MEM_LINES + 25; + int address = MEM_WORDS + 25; int wrapped = wrap_address(address); REQUIRE(wrapped == 25); } TEST_CASE("wrap address inside upper bound", "[utils]") { - int address = MEM_LINES - 25; + int address = MEM_WORDS - 25; int wrapped = wrap_address(address); - REQUIRE(wrapped == MEM_LINES - 25); + REQUIRE(wrapped == MEM_WORDS - 25); } TEST_CASE("wrap address at upper bound", "[utils]") { - int address = MEM_LINES; + int address = MEM_WORDS; int wrapped = wrap_address(address); REQUIRE(wrapped == 0); } @@ -47,14 +47,14 @@ TEST_CASE("wrap address lower than 0 with magnitude lesser than mem size", "[uti { int address = -10; int wrapped = wrap_address(address); - REQUIRE(wrapped == MEM_LINES - 10); + REQUIRE(wrapped == MEM_WORDS - 10); } TEST_CASE("wrap address lower than 0 but with magnitude greater than mem size", "[utils]") { - int address = -(MEM_LINES + 10); + int address = -(MEM_WORDS + 10); int wrapped = wrap_address(address); - REQUIRE(wrapped == MEM_LINES - 10); + REQUIRE(wrapped == MEM_WORDS - 10); } TEST_CASE("wrap address at 0", "[utils]") -- cgit v1.2.3 From 1400c65a1d19f96fff8b4a0e98fcd9ed792f4883 Mon Sep 17 00:00:00 2001 From: bd Date: Tue, 11 Mar 2025 19:52:30 -0400 Subject: Fix issue where fetch_resource did not update cache data --- src/storage/cache.cc | 22 ++++++++++++---------- src/storage/dram.cc | 6 ++++-- 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/src/storage/cache.cc b/src/storage/cache.cc index ea90f50..4842ed5 100644 --- a/src/storage/cache.cc +++ b/src/storage/cache.cc @@ -120,12 +120,12 @@ void Cache::fetch_resource(int expected) { Response r = OK; int tag, index, offset; - std::array actual; + std::array *actual; std::array *meta; get_bit_fields(expected, &tag, &index, &offset); meta = &this->meta.at(index); - actual = this->data->at(index); + actual = &this->data->at(index); if (meta->at(0) != tag) { // address not in cache @@ -133,7 +133,7 @@ void Cache::fetch_resource(int expected) // occupant is dirty // writing line to DRam in case of dirty cache eviction r = this->lower->write_line( - L1CACHE, actual, + L1CACHE, *actual, ((index << LINE_SPEC) + (meta->at(0) << (L1_CACHE_LINE_SPEC + LINE_SPEC)))); if (r == OK) { @@ -141,7 +141,7 @@ void Cache::fetch_resource(int expected) r = WAIT; } } else { - r = this->lower->read_line(L1CACHE, expected, actual); + r = this->lower->read_line(L1CACHE, expected, *actual); if (r == OK) { meta->at(0) = tag; } @@ -166,16 +166,16 @@ std::ostream &operator<<(std::ostream &os, const Cache &c) std::vector> data = c.view(0, L1_CACHE_LINES); std::array, L1_CACHE_LINES> meta = c.get_meta(); - std::cout << "FOO " << meta.at(31)[0]; - os << " " << std::setfill(' ') << std::setw(L1_CACHE_LINE_SPEC + 2) << "INDEX" + os << " " << std::setfill(' ') << std::setw(L1_CACHE_LINE_SPEC + 2) + << "INDEX" << " | " << std::setfill(' ') << std::setw((8 + 3) * 4 - 1) << "DATA" << " | " << std::setfill(' ') << std::setw(MEM_LINE_SPEC - L1_CACHE_LINE_SPEC + 2) << "TAG" << " | D" << std::endl; for (int i = 0; i < L1_CACHE_LINES; ++i) { - os << " 0b" << std::setw(L1_CACHE_LINE_SPEC) << std::bitset(i) - << " | "; + os << " 0b" << std::setw(L1_CACHE_LINE_SPEC) + << std::bitset(i) << " | "; for (int j = 0; j < LINE_SIZE; ++j) { os << "0x" << std::setfill('0') << std::setw(8) << std::hex << data.at(i).at(j) << " "; @@ -183,9 +183,11 @@ std::ostream &operator<<(std::ostream &os, const Cache &c) os << "| 0b" << std::setfill(' '); if (meta.at(i)[0] < 0) - os << std::setfill('?') << std::setw(MEM_LINE_SPEC - L1_CACHE_LINE_SPEC) << ""; + os << std::setfill('?') + << std::setw(MEM_LINE_SPEC - L1_CACHE_LINE_SPEC) << ""; else - os << std::bitset(meta.at(i)[0]); + os << std::bitset( + meta.at(i)[0]); os << " | " << (int)(meta.at(i)[0] >= 0) << std::endl; } diff --git a/src/storage/dram.cc b/src/storage/dram.cc index 60b4ae5..56eec47 100644 --- a/src/storage/dram.cc +++ b/src/storage/dram.cc @@ -143,11 +143,13 @@ std::ostream &operator<<(std::ostream &os, const Dram &d) std::vector> data = d.view(0, MEM_LINES); - os << " " << std::setfill(' ') << std::setw(MEM_LINE_SPEC + 2 + LINE_SPEC) << "ADDRESS" + os << " " << std::setfill(' ') << std::setw(MEM_LINE_SPEC + 2 + LINE_SPEC) + << "ADDRESS" << " | " << std::setfill(' ') << std::setw((8 + 3) * 4 - 1) << "DATA" << std::endl; for (int i = 0; i < MEM_LINES; ++i) { - os << " 0b" << std::setw(MEM_LINE_SPEC+LINE_SPEC) << left << std::bitset(i) << " | "; + os << " 0b" << std::setw(MEM_LINE_SPEC + LINE_SPEC) << left + << std::bitset(i) << " | "; for (int j = 0; j < LINE_SIZE; ++j) { os << "0x" << std::setfill('0') << std::setw(8) << std::hex << data.at(i).at(j) << ' '; -- cgit v1.2.3 From c55104f8e99ea6ccb0c66a5e0d3cfc81dbbc19ab Mon Sep 17 00:00:00 2001 From: bd Date: Tue, 11 Mar 2025 20:26:59 -0400 Subject: Fix small issue in fetch_resource wih off by one cycle count --- inc/definitions.h | 2 +- src/storage/cache.cc | 11 ++++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/inc/definitions.h b/inc/definitions.h index 80fccbe..eced554 100644 --- a/inc/definitions.h +++ b/inc/definitions.h @@ -39,7 +39,7 @@ /** * The total number of cycles a level one cache access takes */ -#define L1_CACHE_DELAY 1 +#define L1_CACHE_DELAY 0 /** * Return the N least-significant bits from integer K using a bit mask diff --git a/src/storage/cache.cc b/src/storage/cache.cc index 4842ed5..3e2a5e0 100644 --- a/src/storage/cache.cc +++ b/src/storage/cache.cc @@ -119,6 +119,7 @@ Response Cache::read_word(Accessor accessor, int address, signed int &data) void Cache::fetch_resource(int expected) { Response r = OK; + Response q; int tag, index, offset; std::array *actual; std::array *meta; @@ -128,21 +129,21 @@ void Cache::fetch_resource(int expected) actual = &this->data->at(index); if (meta->at(0) != tag) { + r = WAIT; // address not in cache if (meta->at(1) >= 0) { // occupant is dirty // writing line to DRam in case of dirty cache eviction - r = this->lower->write_line( + q = this->lower->write_line( L1CACHE, *actual, ((index << LINE_SPEC) + (meta->at(0) << (L1_CACHE_LINE_SPEC + LINE_SPEC)))); - if (r == OK) { + if (q == OK) { meta->at(1) = -1; - r = WAIT; } } else { - r = this->lower->read_line(L1CACHE, expected, *actual); - if (r == OK) { + q = this->lower->read_line(L1CACHE, expected, *actual); + if (q == OK) { meta->at(0) = tag; } } -- cgit v1.2.3