From 7a94defa477d5dd0a5f7c77a7c64d46aa4266e6a Mon Sep 17 00:00:00 2001 From: bd Date: Wed, 16 Apr 2025 14:45:07 -0400 Subject: Add untested support for configurable ways --- inc/cache.h | 26 +++++++++++++++++++++- src/cache.cc | 70 ++++++++++++++++++++++++++++++++++++++---------------------- 2 files changed, 70 insertions(+), 26 deletions(-) diff --git a/inc/cache.h b/inc/cache.h index 6f06466..4b2521a 100644 --- a/inc/cache.h +++ b/inc/cache.h @@ -55,7 +55,31 @@ nn * Constructor. * @param the address that must be present in cache. * @param 0 if the address is currently in cache, 1 if it is being fetched. */ - int is_address_missing(int address); + int priming_address(int address); + /** + * Walks the ways in this set of ways. If none of the tags match, returns -1. Otherwise, returns + * the index the matching data is located. + * @param an index aligned to the set of ways in `this->data' + * @param the tag to be matched + * @return -1 if the tag is not present in this set of ways (not in cache), or the true index if + * the tag is present. + */ + unsigned int is_address_missing(unsigned int true_index, unsigned int tag); + /** + * Converts an index into a set of ways into an index into `this->data', which is a + * 1D array. The next `this->ways' entries after the returned index represent the ways in the + * set for this index. + * @param an index to a set of ways + * @param an index aligned to the set of ways in `this->data' + */ + unsigned int get_true_index(unsigned int index); + /** + * Selects an index into the `data' and `meta' tables for write back using a random replacement + * policy. + * @param an index aligned to the set of ways in `this->data' + * @return an index aligned to the data line selected for eviction + */ + unsigned int get_replacement_index(unsigned int index); /** * The number of bits required to specify a line in this level of cache. */ diff --git a/src/cache.cc b/src/cache.cc index 08545fd..7092bc5 100644 --- a/src/cache.cc +++ b/src/cache.cc @@ -1,5 +1,6 @@ #include "cache.h" #include "definitions.h" +#include #include #include @@ -61,53 +62,72 @@ Cache::read_word(void *id, int address, signed int &data) int Cache::process(void *id, int address, std::function request_handler) { - if (!preprocess(id) || is_address_missing(address) || !this->is_data_ready()) + if (!preprocess(id) || priming_address(address) || !this->is_data_ready()) return 0; int tag, index, offset; GET_FIELDS(address, &tag, &index, &offset); + index = this->get_true_index(index); request_handler(index, offset); return 1; } int -Cache::is_address_missing(int expected) +Cache::priming_address(int address) { - int r, q, tag, index, offset; - std::array *actual; + unsigned int tag, index, offset; + int r1, r2; + std::array *evict; std::array *meta; - GET_FIELDS(expected, &tag, &index, &offset); - r = 0; - meta = &this->meta.at(index); - actual = &this->data->at(index); + r1 = 0; + GET_FIELDS(address, &tag, &index, &offset); + index = this->get_true_index(index); + + if (this->is_address_missing(index, tag)) { + r1 = 1; + + index = this->get_replacement_index(index); + meta = &this->meta.at(index); + evict = &this->data->at(index); - if (meta->at(0) != tag) { - r = 1; + // handle eviction of dirty cache lines if (meta->at(1) >= 0) { - q = this->lower->write_line( - this, *actual, ((index << LINE_SPEC) + (meta->at(0) << (this->size + LINE_SPEC)))); - if (q) { + r2 = this->lower->write_line( + this, *evict, ((index << LINE_SPEC) + (meta->at(0) << (this->size + LINE_SPEC)))); + if (r2) meta->at(1) = -1; - } } else { - q = this->lower->read_line(this, expected, *actual); - if (q) { + r2 = this->lower->read_line(this, address, *evict); + if (r2) { meta->at(0) = tag; } } } - return r; + return r1; +} + +unsigned int +Cache::is_address_missing(unsigned int index, unsigned int tag) +{ + int i; + + for (i = 0; i < (1 << this->ways); ++i) + if (this->meta.at(index + i).at(0) == tag) + return i; + return -1; } -// unsigned int -// Cache::get_true_index(unsigned int index) -// { -// } +unsigned int +Cache::get_true_index(unsigned int index) +{ + return index * (1 << this->ways); +} -// unsigned int -// Cache::get_replacement_index(unsigned int index) -// { -// } +unsigned int +Cache::get_replacement_index(unsigned int index) +{ + return index + (rand() % (1 << this->ways)); +} -- cgit v1.2.3 From 0041cc424b5711559302bd77a534922a9dbca8ae Mon Sep 17 00:00:00 2001 From: bd Date: Wed, 16 Apr 2025 15:06:04 -0400 Subject: Use signed integers for cache eviction --- inc/cache.h | 6 +++--- src/cache.cc | 14 +++++++------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/inc/cache.h b/inc/cache.h index 4b2521a..8075d1a 100644 --- a/inc/cache.h +++ b/inc/cache.h @@ -64,7 +64,7 @@ nn * Constructor. * @return -1 if the tag is not present in this set of ways (not in cache), or the true index if * the tag is present. */ - unsigned int is_address_missing(unsigned int true_index, unsigned int tag); + int is_address_missing(int true_index, int tag); /** * Converts an index into a set of ways into an index into `this->data', which is a * 1D array. The next `this->ways' entries after the returned index represent the ways in the @@ -72,14 +72,14 @@ nn * Constructor. * @param an index to a set of ways * @param an index aligned to the set of ways in `this->data' */ - unsigned int get_true_index(unsigned int index); + int get_true_index(int index); /** * Selects an index into the `data' and `meta' tables for write back using a random replacement * policy. * @param an index aligned to the set of ways in `this->data' * @return an index aligned to the data line selected for eviction */ - unsigned int get_replacement_index(unsigned int index); + int get_replacement_index(int index); /** * The number of bits required to specify a line in this level of cache. */ diff --git a/src/cache.cc b/src/cache.cc index 7092bc5..a2d4525 100644 --- a/src/cache.cc +++ b/src/cache.cc @@ -76,7 +76,7 @@ Cache::process(void *id, int address, std::function int Cache::priming_address(int address) { - unsigned int tag, index, offset; + int tag, index, offset; int r1, r2; std::array *evict; std::array *meta; @@ -109,8 +109,8 @@ Cache::priming_address(int address) return r1; } -unsigned int -Cache::is_address_missing(unsigned int index, unsigned int tag) +int +Cache::is_address_missing(int index, int tag) { int i; @@ -120,14 +120,14 @@ Cache::is_address_missing(unsigned int index, unsigned int tag) return -1; } -unsigned int -Cache::get_true_index(unsigned int index) +int +Cache::get_true_index(int index) { return index * (1 << this->ways); } -unsigned int -Cache::get_replacement_index(unsigned int index) +int +Cache::get_replacement_index(int index) { return index + (rand() % (1 << this->ways)); } -- cgit v1.2.3 From 24fd3ac34fe955818542a8eaa7f76f87644f10bf Mon Sep 17 00:00:00 2001 From: bd Date: Wed, 16 Apr 2025 15:13:37 -0400 Subject: Update README --- README.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/README.md b/README.md index dfde60f..ad0f4fb 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,6 @@ # RAM - RAM Acts Magically -## - -This is a cache and memory simulator for a custom ISA nicknamed "RISC V[ECTOR]". It uses a writeback and write allocate on a miss scheme, and supports a configurable number of cache levels and ways, with a least-recently used replacement policy. +This is a cache and memory simulator for a custom ISA nicknamed "RISC V[ECTOR]". It uses a writeback and write allocate on a miss scheme. It also supports a configurable number of cache levels and ways (allowing creation of a direct mapped or fully associative cache). Additionally, it uses a least-recently used replacement policy. ## Dependencies -- cgit v1.2.3