diff options
-rw-r--r-- | inc/cache.h | 14 | ||||
-rw-r--r-- | inc/definitions.h | 44 | ||||
-rw-r--r-- | inc/utils.h | 14 | ||||
-rw-r--r-- | src/storage/cache.cc | 20 | ||||
-rw-r--r-- | src/utils/utils.cc | 11 | ||||
-rw-r--r-- | tests/utils.cc | 23 |
6 files changed, 120 insertions, 6 deletions
diff --git a/inc/cache.h b/inc/cache.h index d470e6c..d9d8ba7 100644 --- a/inc/cache.h +++ b/inc/cache.h @@ -1,6 +1,9 @@ #ifndef CACHE_H #define CACHE_H -#include <storage.h> +#include "definitions.h" +#include "storage.h" +#include <array> +#include <bitset> class Cache : public Storage { @@ -19,6 +22,15 @@ class Cache : public Storage Response write(Accessor accessor, signed int data, int address) override; Response read(Accessor accessor, int address, std::array<signed int, LINE_SIZE>& data) override; + + private: + /** + * An array of paired bits. + * If the least significant bit of an element is set, the corresponding + * element in `data` is invalid. If the most significant bit of an element + * is set, the corresponding element in `data` is dirty. + */ + std::array<std::bitset<2>, L1_CACHE_SIZE> stat; }; #endif /* CACHE_H_INCLUDED */ diff --git a/inc/definitions.h b/inc/definitions.h index 1593162..877065e 100644 --- a/inc/definitions.h +++ b/inc/definitions.h @@ -1,10 +1,50 @@ #ifndef DEFINITIONS_H #define DEFINITIONS_H +#include <cmath> /** - * Defines common macros. + * The number of bits to specify a word in a line */ +#define LINE_SPEC 2 +/** + * The total number of words in a line + */ +#define LINE_SIZE (int)pow(2, 2) + +/** + * The number of bits to specify a memory line + * calculated as: (/ (expt 2 15) 4) + */ +#define MEM_SPEC 13 +/** + * The total number of words in memory + */ +#define MEM_SIZE (int)pow(2, MEM_SPEC) + +/** + * The number of bits to specify a l1 cache line + */ +#define L1_CACHE_SPEC 5 +/** + * The total number of words in l1 cache + */ +#define L1_CACHE_SIZE (int)pow(2, L1_CACHE_SPEC) -#define LINE_SIZE 4 +/** + * Return the N least-significant bits from integer K using a bit mask + * @param the integer to be parsed + * @param the number of bits to be parsed + * @return the N least-significant bits from K + */ +#define GET_LS_BITS(k, n) ((k) & ((1 << (n)) - 1)) +/** + * Return the bits from integer K starting at N and ending at M using a bit + * mask + * @param the integer to be parsed + * @param the index of the starting bit to be parsed + * @param the index of the ending bit to be parsed + * @return a section of bits from K + */ +#define GET_MID_BITS(k, m, n) GET_LS_BITS((k) >> (m), ((n) - (m))) #endif /* DEFINITIONS_H_INCLUDED */ diff --git a/inc/utils.h b/inc/utils.h new file mode 100644 index 0000000..e258ed8 --- /dev/null +++ b/inc/utils.h @@ -0,0 +1,14 @@ +#ifndef UTILS_H +#define UTILS_H + +/** + * Parse an address into a tag, index into the cache table, and a line + * offset. + * @param the address to be parsed + * @param the resulting tag + * @param the resulting index + * @param the resulting offset + */ +void get_bit_fields(int address, int *tag, int *index, int *offset); + +#endif /* UTILS_H_INCLUDED */ diff --git a/src/storage/cache.cc b/src/storage/cache.cc index 67cedda..cf954b0 100644 --- a/src/storage/cache.cc +++ b/src/storage/cache.cc @@ -6,17 +6,31 @@ Cache::Cache(int lines, Storage *lower, int delay) { this->data = new std::vector<std::array<signed int, LINE_SIZE>>; - this->data->resize(lines); + this->data->resize(L1_CACHE_SIZE); this->lower = lower; this->delay = delay; - this->lower = nullptr; + for (int i = 0; i < L1_CACHE_SIZE; ++i) + this->stat[i] = 0b01; } Cache::~Cache() { delete this->data; } Response Cache::write(Accessor accessor, signed int data, int address) { - return WAIT; + Response r = WAIT; + + /* Do this first--then process the first cycle immediately. */ + if (this->requester == IDLE) + this->requester = accessor; + + if (this->requester == accessor) { + if (this->wait_time == 0) { + this->do_write(data, address); + r = OK; + } + } + + return r; } Response Cache::read(Accessor accessor, int address, std::array<signed int, LINE_SIZE>& data) { return WAIT; } diff --git a/src/utils/utils.cc b/src/utils/utils.cc new file mode 100644 index 0000000..dfeb2b3 --- /dev/null +++ b/src/utils/utils.cc @@ -0,0 +1,11 @@ +#include "utils.h" +#include "definitions.h" + +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); + *offset = GET_LS_BITS(address, LINE_SPEC); +} diff --git a/tests/utils.cc b/tests/utils.cc new file mode 100644 index 0000000..5368204 --- /dev/null +++ b/tests/utils.cc @@ -0,0 +1,23 @@ +#include "utils.h" +#include "definitions.h" +#include <catch2/catch_test_macros.hpp> + +TEST_CASE("Parse arbitrary fields # one", "[cache]") +{ + int tag, index, offset; + int address = 0b111110001010101; + get_bit_fields(address, &tag, &index, &offset); + CHECK(tag == 0b11111000); + CHECK(index == 0b10101); + CHECK(offset == 0b01); +} + +TEST_CASE("Parse arbitrary fields # two", "[cache]") +{ + int tag, index, offset; + int address = 0b000110100111011; + get_bit_fields(address, &tag, &index, &offset); + CHECK(tag == 0b00011010); + CHECK(index == 0b01110); + CHECK(offset == 0b11); +} |