summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--inc/cache.h14
-rw-r--r--inc/definitions.h44
-rw-r--r--inc/utils.h14
-rw-r--r--src/storage/cache.cc20
-rw-r--r--src/utils/utils.cc11
-rw-r--r--tests/utils.cc23
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);
+}