summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSiddarth Suresh <155843085+SiddarthSuresh98@users.noreply.github.com>2025-03-22 11:00:14 -0400
committerGitHub <noreply@github.com>2025-03-22 11:00:14 -0400
commit4bad9ab29a5fa6c442a257974beb7daeaf91f046 (patch)
tree9386aa3ccd2302fceb9750858d74ab56f156b4e2
parent82096f8cea42d78505b49d9f8ba22573daa2cc12 (diff)
parente73294467108f914debda39db2204c1f1493f8bf (diff)
Merge pull request #29 from bdunahu/bdunahu
Small cleanups to up a lot of implementation details
-rw-r--r--inc/cache.h21
-rw-r--r--inc/dram.h29
-rw-r--r--inc/utils.h14
-rw-r--r--src/storage/cache.cc94
-rw-r--r--src/storage/dram.cc129
-rw-r--r--src/utils/utils.cc6
6 files changed, 133 insertions, 160 deletions
diff --git a/inc/cache.h b/inc/cache.h
index 3b16ca1..ef9c9e4 100644
--- a/inc/cache.h
+++ b/inc/cache.h
@@ -42,6 +42,27 @@ class Cache : public Storage
private:
/**
+ * Helper for all access methods.
+ * Calls `request_handler` when `accessor` is allowed to complete its
+ * request cycle.
+ * @param the source making the request
+ * @param the address to write to
+ * @param the function to call when an access should be completed
+ */
+ Response process(
+ Accessor accessor,
+ int address,
+ std::function<void(int index, int offset)> request_handler);
+ /**
+ * Returns OK if `accessor` is allowed to complete its request this cycle.
+ * Handles cache misses, wait times, and setting the current accessor this
+ * storage is serving.
+ * @param the accessor asking for a resource
+ * @return whether or not the access can be carried out this function call.
+ */
+ Response is_access_cleared(Accessor accessor, int address);
+ /**
+ * Helper for access_cleared.
* Fetches `address` from a lower level of storage if it is not already
* present. If it is not, temporarily sets the is_blocked attribute of this
* cache level to true, and the victim line is chosen/written back.
diff --git a/inc/dram.h b/inc/dram.h
index c7f927a..e6db633 100644
--- a/inc/dram.h
+++ b/inc/dram.h
@@ -32,22 +32,25 @@ class Dram : public Storage
private:
/**
- * Helper for `write` a word
+ * Helper for all access methods.
+ * Calls `request_handler` when `accessor` is allowed to complete its
+ * request cycle.
+ * @param the source making the request
+ * @param the address to write to
+ * @param the function to call when an access should be completed
*/
- void do_write(signed int, int);
- /**
- * Helper for writing a line.
- */
- void
- do_write_line(std::array<signed int, LINE_SIZE> data_line, int address);
- /**
- * Helper for `read` a line
- */
- void do_read(std::array<signed int, LINE_SIZE> &data_line, int address);
+ Response process(
+ Accessor accessor,
+ int address,
+ std::function<void(int line, int word)> request_handler);
/**
- * Helper for reading a word.
+ * Returns OK if `accessor` is allowed to complete its request this cycle.
+ * Handles wait times, side door, and setting the current accessor this
+ * storage is serving.
+ * @param the accessor asking for a resource
+ * @return whether or not the access can be carried out this function call.
*/
- void do_read_word(signed int &data, int address);
+ Response is_access_cleared(Accessor accessor);
};
std::ostream &operator<<(std::ostream &os, const Dram &d);
diff --git a/inc/utils.h b/inc/utils.h
index aa8831b..df8d374 100644
--- a/inc/utils.h
+++ b/inc/utils.h
@@ -20,6 +20,20 @@ void get_bit_fields(int address, int *tag, int *index, int *offset);
*/
const std::string string_format(const char *const zcFormat, ...);
+/**
+ * Given `address`, returns an address that is within the current memory size
+ * using a clean wrap.
+ * @param an address
+ * @return an address guaranteed to be within range.
+ */
int wrap_address(int address);
+/**
+ * Given `address`, returns the line and word it is in.
+ * @param an address
+ * @param the line (row) `address` is in
+ * @param the word (column) `address` corresponds to
+ */
+void get_memory_index(int address, int &line, int &word);
+
#endif /* UTILS_H_INCLUDED */
diff --git a/src/storage/cache.cc b/src/storage/cache.cc
index f15c919..8acdf08 100644
--- a/src/storage/cache.cc
+++ b/src/storage/cache.cc
@@ -27,51 +27,20 @@ Cache::~Cache()
Response Cache::write_word(Accessor accessor, signed int data, int address)
{
- Response r = WAIT;
-
- /* Do this first--then process the first cycle immediately. */
- if (this->requester == IDLE)
- this->requester = accessor;
-
- if (this->requester == accessor) {
- handle_miss(address);
- if (this->is_waiting)
- r = BLOCKED;
- else if (this->wait_time == 0) {
- int tag, index, offset;
- get_bit_fields(address, &tag, &index, &offset);
- this->data->at(index).at(offset) = data;
- this->meta[index].at(1) = 1;
- r = OK;
- }
- }
-
- return r;
+ return process(accessor, address, [&](int index, int offset) {
+ this->data->at(index).at(offset) = data;
+ this->meta[index].at(1) = 1;
+ });
}
Response Cache::write_line(
Accessor accessor, std::array<signed int, LINE_SIZE> data_line, int address)
{
- Response r = WAIT;
-
- /* Do this first--then process the first cycle immediately. */
- if (this->requester == IDLE)
- this->requester = accessor;
-
- if (this->requester == accessor) {
- handle_miss(address);
- if (this->is_waiting)
- r = BLOCKED;
- else if (this->wait_time == 0) {
- int tag, index, offset;
- get_bit_fields(address, &tag, &index, &offset);
- this->data->at(index) = data_line;
- this->meta[index].at(1) = 1;
- r = OK;
- }
- }
-
- return r;
+ return process(accessor, address, [&](int index, int offset) {
+ (void)offset;
+ this->data->at(index) = data_line;
+ this->meta[index].at(1) = 1;
+ });
}
// TODO: tests for multi level cache
@@ -80,26 +49,38 @@ Response Cache::read_line(
int address,
std::array<signed int, LINE_SIZE> &data_line)
{
- Response r = WAIT;
- if (this->requester == IDLE)
- this->requester = accessor;
- if (this->requester == accessor) {
- handle_miss(address);
- if (this->is_waiting)
- r = BLOCKED;
- else if (this->wait_time == 0) {
- int tag, index, offset;
- get_bit_fields(address, &tag, &index, &offset);
- data_line = this->data->at(index);
- r = OK;
- }
+ return process(accessor, address, [&](int index, int offset) {
+ (void)offset;
+ data_line = this->data->at(index);
+ });
+}
+
+Response Cache::read_word(Accessor accessor, int address, signed int &data)
+{
+ return process(accessor, address, [&](int index, int offset) {
+ data = this->data->at(index).at(offset);
+ });
+}
+
+Response Cache::process(
+ Accessor accessor,
+ int address,
+ std::function<void(int index, int offset)> request_handler)
+{
+ Response r = this->is_access_cleared(accessor, address);
+ if (r == OK) {
+ int tag, index, offset;
+ get_bit_fields(address, &tag, &index, &offset);
+ request_handler(index, offset);
}
return r;
}
-Response Cache::read_word(Accessor accessor, int address, signed int &data)
+Response Cache::is_access_cleared(Accessor accessor, int address)
{
- Response r = WAIT;
+ Response r;
+ r = WAIT;
+ /* Do this first--then process the first cycle immediately. */
if (this->requester == IDLE)
this->requester = accessor;
if (this->requester == accessor) {
@@ -107,9 +88,6 @@ Response Cache::read_word(Accessor accessor, int address, signed int &data)
if (this->is_waiting)
r = BLOCKED;
else if (this->wait_time == 0) {
- int tag, index, offset;
- get_bit_fields(address, &tag, &index, &offset);
- data = this->data->at(index).at(offset);
r = OK;
}
}
diff --git a/src/storage/dram.cc b/src/storage/dram.cc
index 20db47e..2c24b4b 100644
--- a/src/storage/dram.cc
+++ b/src/storage/dram.cc
@@ -21,118 +21,69 @@ Dram::Dram(int delay)
Dram::~Dram() { delete this->data; }
-void Dram::do_write(signed int data, int address)
+Response Dram::write_line(
+ Accessor accessor, std::array<signed int, LINE_SIZE> data_line, int address)
{
- address = wrap_address(address);
- int line = address / LINE_SIZE;
- int word = address % LINE_SIZE;
-
- this->data->at(line).at(word) = data;
+ return process(accessor, address, [&](int line, int word) {
+ (void)word;
+ this->data->at(line) = data_line;
+ });
}
-void Dram::do_write_line(
- std::array<signed int, LINE_SIZE> data_line, int address)
+Response Dram::write_word(Accessor accessor, signed int data, int address)
{
- address = wrap_address(address);
- int line = address / LINE_SIZE;
- this->data->at(line) = data_line;
+ return process(accessor, address, [&](int line, int word) {
+ this->data->at(line).at(word) = data;
+ });
}
-void Dram::do_read(std::array<signed int, LINE_SIZE> &data_line, int address)
+// TODO requires testing
+Response Dram::read_line(
+ Accessor accessor,
+ int address,
+ std::array<signed int, LINE_SIZE> &data_line)
{
- address = wrap_address(address);
- int line = address / LINE_SIZE;
- data_line = this->data->at(line);
+ return process(accessor, address, [&](int line, int word) {
+ (void)word;
+ data_line = this->data->at(line);
+ });
}
-void Dram::do_read_word(signed int &data, int address)
+Response Dram::read_word(Accessor accessor, int address, signed int &data)
{
- address = wrap_address(address);
- int line = address / LINE_SIZE;
- int word = address % LINE_SIZE;
- data = this->data->at(line).at(word);
+ return process(accessor, address, [&](int line, int word) {
+ data = this->data->at(line).at(word);
+ });
}
-Response Dram::write_line(
- Accessor accessor, std::array<signed int, LINE_SIZE> data_line, int address)
+Response Dram::process(
+ Accessor accessor,
+ int address,
+ std::function<void(int line, int word)> request_handler)
{
- Response r = WAIT;
-
- if (accessor == SIDE) {
- this->do_write_line(data_line, address);
- r = OK;
- } else {
- /* 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_line(data_line, address);
- r = OK;
- }
- }
+ Response r = this->is_access_cleared(accessor);
+ if (r == OK) {
+ int line, word;
+ get_memory_index(address, line, word);
+ request_handler(line, word);
}
return r;
}
-Response Dram::write_word(Accessor accessor, signed int data, int address)
+Response Dram::is_access_cleared(Accessor accessor)
{
- Response r = WAIT;
-
- if (accessor == SIDE) {
- this->do_write(data, address);
+ Response r;
+ r = WAIT;
+ /* Do this first--then process the first cycle immediately. */
+ if (accessor == SIDE)
r = OK;
- } else {
- /* Do this first--then process the first cycle immediately. */
+ else {
if (this->requester == IDLE)
this->requester = accessor;
-
- if (this->requester == accessor) {
- if (this->wait_time == 0) {
- this->do_write(data, address);
+ if (this->requester == accessor)
+ if (this->wait_time == 0)
r = OK;
- }
- }
}
-
- return r;
-}
-
-Response Dram::read_line(
- Accessor accessor,
- int address,
- std::array<signed int, LINE_SIZE> &data_line)
-{
- Response r = WAIT;
-
- if (this->requester == IDLE)
- this->requester = accessor;
-
- if (this->requester == accessor) {
- if (this->wait_time == 0) {
- this->do_read(data_line, address);
- r = OK;
- }
- }
-
- return r;
-}
-
-Response Dram::read_word(Accessor accessor, int address, signed int &data)
-{
- Response r = WAIT;
-
- if (this->requester == IDLE)
- this->requester = accessor;
-
- if (this->requester == accessor) {
- if (this->wait_time == 0) {
- this->do_read_word(data, address);
- r = OK;
- }
- }
-
return r;
}
diff --git a/src/utils/utils.cc b/src/utils/utils.cc
index ebbc1e9..3a11c2c 100644
--- a/src/utils/utils.cc
+++ b/src/utils/utils.cc
@@ -34,3 +34,9 @@ int wrap_address(int address) {
}
return address % MEM_WORDS;
}
+
+void get_memory_index(int address, int &line, int &word)
+{
+ line = wrap_address(address) / LINE_SIZE;
+ word = address % LINE_SIZE;
+}