diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/cache.cc | 76 | ||||
-rw-r--r-- | src/dram.cc | 38 | ||||
-rw-r--r-- | src/storage.cc | 33 | ||||
-rw-r--r-- | src/utils.cc | 42 |
4 files changed, 73 insertions, 116 deletions
diff --git a/src/cache.cc b/src/cache.cc index bbb90b4..08545fd 100644 --- a/src/cache.cc +++ b/src/cache.cc @@ -1,14 +1,20 @@ #include "cache.h" #include "definitions.h" -#include "utils.h" -#include <bits/stdc++.h> +#include <iostream> #include <iterator> -Cache::Cache(Storage *lower, int delay) : Storage(delay) +Cache::Cache(Storage *lower, unsigned int size, unsigned int ways, int delay) : Storage(delay) { - this->data->resize(L1_CACHE_LINES); + int true_size; + + true_size = 1 << size; + this->data->resize(true_size); + this->meta = std::vector<std::array<signed int, 3>>(true_size, {-1, -1, -1}); this->lower = lower; - this->meta.fill({-1, -1}); + + this->size = size; + // store the number of bits which are moved into the tag field + this->ways = ways; } Cache::~Cache() @@ -36,7 +42,6 @@ Cache::write_line(void *id, std::array<signed int, LINE_SIZE> data_line, int add }); } -// TODO: tests for multi level cache int Cache::read_line(void *id, int address, std::array<signed int, LINE_SIZE> &data_line) { @@ -56,36 +61,14 @@ Cache::read_word(void *id, int address, signed int &data) int Cache::process(void *id, int address, std::function<void(int index, int offset)> request_handler) { - int r; - r = this->is_access_cleared(id, address); - if (r) { - int tag, index, offset; - get_cache_fields(address, &tag, &index, &offset); - request_handler(index, offset); - } - return r; -} + if (!preprocess(id) || is_address_missing(address) || !this->is_data_ready()) + return 0; -int -Cache::is_access_cleared(void *id, int address) -{ - /* Do this first--then process the first cycle immediately. */ - if (id == nullptr) - throw std::invalid_argument("Accessor cannot be nullptr."); - if (this->current_request == nullptr) - this->current_request = id; - if (this->current_request == id) { - if (is_address_missing(address)) - return 0; - else if (this->wait_time == 0) { - this->current_request = nullptr; - this->wait_time = delay; - return 1; - } else { - --this->wait_time; - } - } - return 0; + int tag, index, offset; + GET_FIELDS(address, &tag, &index, &offset); + request_handler(index, offset); + + return 1; } int @@ -93,9 +76,9 @@ Cache::is_address_missing(int expected) { int r, q, tag, index, offset; std::array<signed int, LINE_SIZE> *actual; - std::array<int, 2> *meta; + std::array<int, 3> *meta; - get_cache_fields(expected, &tag, &index, &offset); + GET_FIELDS(expected, &tag, &index, &offset); r = 0; meta = &this->meta.at(index); actual = &this->data->at(index); @@ -104,8 +87,7 @@ Cache::is_address_missing(int expected) r = 1; if (meta->at(1) >= 0) { q = this->lower->write_line( - this, *actual, - ((index << LINE_SPEC) + (meta->at(0) << (L1_CACHE_LINE_SPEC + LINE_SPEC)))); + this, *actual, ((index << LINE_SPEC) + (meta->at(0) << (this->size + LINE_SPEC)))); if (q) { meta->at(1) = -1; } @@ -120,10 +102,12 @@ Cache::is_address_missing(int expected) return r; } -std::array<std::array<int, 2>, L1_CACHE_LINES> -Cache::get_meta() const -{ - std::array<std::array<int, 2>, L1_CACHE_LINES> ret; - std::copy(std::begin(this->meta), std::end(this->meta), std::begin(ret)); - return ret; -} +// unsigned int +// Cache::get_true_index(unsigned int index) +// { +// } + +// unsigned int +// Cache::get_replacement_index(unsigned int index) +// { +// } diff --git a/src/dram.cc b/src/dram.cc index d81e2d2..53db16b 100644 --- a/src/dram.cc +++ b/src/dram.cc @@ -4,7 +4,6 @@ #include <bits/stdc++.h> #include <bitset> #include <iterator> -#include <utils.h> Dram::Dram(int delay) : Storage(delay) { this->data->resize(MEM_LINES); } @@ -25,7 +24,6 @@ Dram::write_word(void *id, signed int data, int address) return process(id, address, [&](int line, int word) { this->data->at(line).at(word) = data; }); } -// TODO requires testing int Dram::read_line(void *id, int address, std::array<signed int, LINE_SIZE> &data_line) { @@ -56,32 +54,18 @@ Dram::load(std::vector<signed int> program) int Dram::process(void *id, int address, std::function<void(int line, int word)> request_handler) { - int r; - r = this->is_access_cleared(id); - if (r) { - int line, word; - get_memory_index(address, line, word); - request_handler(line, word); - } - return r; + if (!preprocess(id) || !this->is_data_ready()) + return 0; + + int line, word; + get_memory_index(address, line, word); + request_handler(line, word); + return 1; } -int -Dram::is_access_cleared(void *id) +void +Dram::get_memory_index(int address, int &line, int &word) { - /* Do this first--then process the first cycle immediately. */ - if (id == nullptr) - throw std::invalid_argument("Accessor cannot be nullptr."); - if (this->current_request == nullptr) - this->current_request = id; - if (this->current_request == id) { - if (this->wait_time == 0) { - this->current_request = nullptr; - this->wait_time = delay; - return 1; - } else { - --this->wait_time; - } - } - return 0; + line = WRAP_ADDRESS(address) / LINE_SIZE; + word = address % LINE_SIZE; } diff --git a/src/storage.cc b/src/storage.cc index 4ad916b..ee2e7e7 100644 --- a/src/storage.cc +++ b/src/storage.cc @@ -1,8 +1,10 @@ #include "storage.h" #include "definitions.h" #include <algorithm> +#include <stdexcept> -Storage::Storage(int delay) { +Storage::Storage(int delay) +{ this->data = new std::vector<std::array<signed int, LINE_SIZE>>; this->delay = delay; this->lower = nullptr; @@ -18,3 +20,32 @@ Storage::view(int base, int lines) const std::copy(this->data->begin() + base, this->data->begin() + base + lines, ret.begin()); return ret; } + +int +Storage::preprocess(void *id) +{ + if (id == nullptr) + throw std::invalid_argument("Accessor cannot be nullptr."); + + if (this->current_request == nullptr) + this->current_request = id; + + return this->current_request == id; +} + +int +Storage::is_data_ready() +{ + int r; + + r = 0; + if (this->wait_time == 0) { + this->current_request = nullptr; + this->wait_time = delay; + r = 1; + } else { + --this->wait_time; + } + + return r; +} diff --git a/src/utils.cc b/src/utils.cc deleted file mode 100644 index e12a0e0..0000000 --- a/src/utils.cc +++ /dev/null @@ -1,42 +0,0 @@ -#include "utils.h" -#include "definitions.h" -#include <cstdarg> -#include <string> -#include <vector> - -void get_cache_fields(int address, int *tag, int *index, int *offset) -{ - *tag = GET_MID_BITS(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); -} - -const std::string string_format(const char *const zcFormat, ...) -{ - va_list vaArgs; - va_start(vaArgs, zcFormat); - - va_list vaArgsCopy; - va_copy(vaArgsCopy, vaArgs); - const int iLen = std::vsnprintf(NULL, 0, zcFormat, vaArgsCopy); - va_end(vaArgsCopy); - - std::vector<char> zc(iLen + 1); - std::vsnprintf(zc.data(), zc.size(), zcFormat, vaArgs); - va_end(vaArgs); - return std::string(zc.data(), iLen); -} - -int wrap_address(int address) -{ - if (address < 0) { - return ((address % MEM_WORDS) + MEM_WORDS) % MEM_WORDS; - } - return address % MEM_WORDS; -} - -void get_memory_index(int address, int &line, int &word) -{ - line = wrap_address(address) / LINE_SIZE; - word = address % LINE_SIZE; -} |