summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbd <bdunahu@operationnull.com>2025-04-11 21:22:18 -0400
committerbd <bdunahu@operationnull.com>2025-04-11 21:22:18 -0400
commit1fb7a9bd5eb41e87871bcbb3423caaabdd8ce1d9 (patch)
tree08549aa6c7cbae114958df62f92c9e60eb5f114c
parent101f0facf8002907ca6e19faabfdcf472c0c3152 (diff)
First part of storage rework (see description)
- Removed response enum. - Removed messy ostream override, and cli.cc test class - Removed accessor enum, and instead used unique pointer to identify accessor. - Simplified storage by removing is_waiting variables. - Rewrote DRAM and Cache to use Storage constructor.
-rw-r--r--inc/accessor.h18
-rw-r--r--inc/cache.h55
-rw-r--r--inc/cli.h97
-rw-r--r--inc/definitions.h1
-rw-r--r--inc/dram.h47
-rw-r--r--inc/logger.h42
-rw-r--r--inc/response.h14
-rw-r--r--inc/storage.h58
-rw-r--r--src/accessor.cc10
-rw-r--r--src/cache.cc139
-rw-r--r--src/dram.cc113
-rw-r--r--src/logger.cc71
-rw-r--r--src/response.cc8
-rw-r--r--src/storage.cc14
-rw-r--r--tests/cache.cc116
-rw-r--r--tests/dram.cc223
16 files changed, 296 insertions, 730 deletions
diff --git a/inc/accessor.h b/inc/accessor.h
deleted file mode 100644
index eb56785..0000000
--- a/inc/accessor.h
+++ /dev/null
@@ -1,18 +0,0 @@
-#ifndef ACCESSOR_H
-#define ACCESSOR_H
-#include <iostream>
-
-enum Accessor {
- IDLE,
- WRITE,
- MEM,
- EXEC,
- DCDE,
- FETCH,
- L1CACHE,
- SIDE,
-};
-
-std::ostream &operator<<(std::ostream &os, Accessor a);
-
-#endif /* ACCESSOR_H_INCLUDED */
diff --git a/inc/cache.h b/inc/cache.h
index 88fd352..0f15536 100644
--- a/inc/cache.h
+++ b/inc/cache.h
@@ -3,8 +3,8 @@
#include "definitions.h"
#include "storage.h"
#include <array>
-#include <ostream>
#include <functional>
+#include <ostream>
class Cache : public Storage
{
@@ -21,55 +21,52 @@ class Cache : public Storage
Cache(Storage *lower, int delay);
~Cache();
- Response
- write_word(Accessor accessor, signed int data, int address) override;
- Response write_line(
- Accessor accessor,
- std::array<signed int, LINE_SIZE> data_line,
- int address) override;
- Response read_line(
- Accessor accessor,
- int address,
- std::array<signed int, LINE_SIZE> &data_line) override;
- Response
- read_word(Accessor accessor, int address, signed int &data) override;
+ int
+ write_word(void *, signed int, int) override;
+ int
+ write_line(void *, std::array<signed int, LINE_SIZE>, int) override;
+ int
+ read_line(void *, int, std::array<signed int, LINE_SIZE> &) override;
+ int
+ read_word(void *, int, signed int &) override;
/**
* Getter for the meta attribute.
* TODO this doesn't seem like good object-oriented practice.
* @return this->meta
*/
- std::array<std::array<int, 2>, L1_CACHE_LINES> get_meta() const;
+ std::array<std::array<int, 2>, L1_CACHE_LINES>
+ get_meta() const;
private:
/**
* Helper for all access methods.
- * Calls `request_handler` when `accessor` is allowed to complete its
+ * Calls `request_handler` when `id` 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);
+ int
+ process(void *id, 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
+ * Returns OK if `id` is allowed to complete its request this cycle.
+ * Handles cache misses, wait times, and setting the current id this
* storage is serving.
- * @param the accessor asking for a resource
- * @return whether or not the access can be carried out this function call.
+ * @param the id asking for a resource
+ * @return 1 if the access can be carried out this function call, 0 otherwise.
*/
- Response is_access_cleared(Accessor accessor, int address);
+ int
+ is_access_cleared(void *id, int address);
/**
- * Helper for access_cleared.
+ * Helper for is_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.
+ * present. The victim line is chosen/written back.
* @param the address that must be present in cache.
+ * @param 0 if the address is currently in cache, 1 if it is being fetched.
*/
- void handle_miss(int address);
+ int
+ is_address_missing(int address);
/**
* An array of metadata about elements in `data`.
* If the first value of an element is negative, the corresponding
@@ -79,6 +76,4 @@ class Cache : public Storage
std::array<std::array<int, 2>, L1_CACHE_LINES> meta;
};
-std::ostream &operator<<(std::ostream &os, const Cache &c);
-
#endif /* CACHE_H_INCLUDED */
diff --git a/inc/cli.h b/inc/cli.h
deleted file mode 100644
index a0c698a..0000000
--- a/inc/cli.h
+++ /dev/null
@@ -1,97 +0,0 @@
-#ifndef CLI_H
-#define CLI_H
-#include "cache.h"
-#include <functional>
-#include <string>
-#include <unordered_map>
-
-class Cli
-{
- public:
- /**
- * Constructor.
- * @return A newly allocated CLI object.
- */
- Cli();
- ~Cli();
-
- /**
- * Prints all available commands to the console.
- */
- void help();
-
- /**
- * Loads data from memory from the specified memory address.
- * @param memory_address address of the memory where data needs to be loaded
- * from
- */
- void load(Accessor accessor, int memory_address);
-
- /**
- * Stores data into memory at the specified address.
- * @param accessor the pipline stage that is making this request
- * @param data data value to be written to the memory
- * @param address address of the memory where data needs to be stored
- * @return the response from the storage device
- */
- void store(Accessor accessor, int data, int address);
-
- /**
- * Resets the memory configuration and cycles to their initial state.
- * This function provides a side door reset interface to the memory system,
- * allowing the user to reset the memory configuration directly.
- */
- void reset();
-
- /**
- * Advance the clock one cycle, refreshing the storage devices.
- */
- void clock();
-
- /**
- * Displays `lines` lines of the data in `level`, starting from `base`.
- *
- *
- * This function provides a side door view into the storage system, showing
- * its current state and configuration.
- * @param level the level specifying the storage device. The first level
- * one cache is level zero, with descending levels incrementing by a factor
- * of one.
- */
- void peek(int level);
-
- /**
- * Runs the command line interface
- * This function is the main entry point for the command line interface.
- */
- void run();
-
- private:
- /**
- * Initializes the cache object.
- */
- void initialize();
- /**
- * Attempts to match string to either fetch or mem, or throws
- * std::invalid_argument otherwise.
- * @param the string to be converted accessor
- * @return the corresponding accessor
- * @throws invalid_argument if the string is not fetch or mem
- */
- Accessor match_accessor_or_die(std::string s);
- /** Map of commands and their corresponding functions.
- * This map is used to store the commands and their corresponding functions.
- */
- std::unordered_map<char, std::function<void(std::vector<std::string>)>>
- commands;
- /**
- * The cache object to interface with.
- */
- Cache *cache;
- /**
- * The current cycle.
- */
- int cycle;
-};
-
-#endif /* CLI_H_INCLUDED */
diff --git a/inc/definitions.h b/inc/definitions.h
index c81c4e3..6fa29ee 100644
--- a/inc/definitions.h
+++ b/inc/definitions.h
@@ -1,6 +1,5 @@
#ifndef DEFINITIONS_H
#define DEFINITIONS_H
-#include "logger.h"
#include <cmath>
/**
diff --git a/inc/dram.h b/inc/dram.h
index 102ec0f..c6c3159 100644
--- a/inc/dram.h
+++ b/inc/dram.h
@@ -2,8 +2,8 @@
#define DRAM_H
#include "definitions.h"
#include "storage.h"
-#include <ostream>
#include <functional>
+#include <ostream>
class Dram : public Storage
{
@@ -16,47 +16,42 @@ class Dram : public Storage
Dram(int delay);
~Dram();
- Response
- write_word(Accessor accessor, signed int data, int address) override;
- Response read_line(
- Accessor accessor,
- int address,
- std::array<signed int, LINE_SIZE> &data_line) override;
- Response write_line(
- Accessor accessor,
- std::array<signed int, LINE_SIZE> data_line,
- int address) override;
- Response
- read_word(Accessor accessor, int address, signed int &data) override;
+ int
+ write_word(void *, signed int, int) override;
+ int
+ write_line(void *, std::array<signed int, LINE_SIZE>, int) override;
+ int
+ read_word(void *, int, signed int &) override;
+ int
+ read_line(void *, int, std::array<signed int, LINE_SIZE> &) override;
/**
* TODO This will accept a file at a later date.
*/
- void load(std::vector<signed int> program);
+ void
+ load(std::vector<signed int> program);
private:
/**
* Helper for all access methods.
- * Calls `request_handler` when `accessor` is allowed to complete its
+ * Calls `request_handler` when `id` 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
+ * @return 1 if the access completed successfully, 0 otherwise
*/
- Response process(
- Accessor accessor,
- int address,
- std::function<void(int line, int word)> request_handler);
+ int
+ process(void *id, int address, std::function<void(int line, int word)> request_handler);
/**
- * Returns OK if `accessor` is allowed to complete its request this cycle.
- * Handles wait times, side door, and setting the current accessor this
+ * Returns OK if `id` is allowed to complete its request this cycle.
+ * Handles wait times, side door, and setting the current id this
* storage is serving.
- * @param the accessor asking for a resource
- * @return whether or not the access can be carried out this function call.
+ * @param the source making the request
+ * @return 1 if the access can be completed this function call, 0 otherwise
*/
- Response is_access_cleared(Accessor accessor);
+ int
+ is_access_cleared(void *id);
};
-std::ostream &operator<<(std::ostream &os, const Dram &d);
-
#endif /* DRAM_H_INCLUDED */
diff --git a/inc/logger.h b/inc/logger.h
deleted file mode 100644
index 88f9e30..0000000
--- a/inc/logger.h
+++ /dev/null
@@ -1,42 +0,0 @@
-#ifndef LOGGER_H
-#define LOGGER_H
-#include <fstream>
-#include <sstream>
-using namespace std;
-
-enum LogLevel { DEBUG, INFO, WARNING, ERROR, CRITICAL };
-
-class Logger
-{
- public:
- static Logger* getInstance();
-
- ~Logger() = default;
-
- /**
- * Do not allow copies.
- */
- Logger(const Logger& obj) = delete;
-
- /**
- * Set the log level.
- * @param the log level to set to.
- */
- void setLevel(LogLevel);
- /**
- * Log a message at a certain log level.
- * @param The level to log this message. If the level is lower than the
- * level set by `setLevel`, then the message is not logged.
- * @param The message to log.
- */
- void log(LogLevel, const string &);
-
- private:
- Logger() = default;
- static Logger* logger_instance;
- static LogLevel level;
- static string level_to_string(LogLevel);
- static int level_to_int(LogLevel);
-};
-
-#endif /* LOGGER_H_INCLUDED */
diff --git a/inc/response.h b/inc/response.h
deleted file mode 100644
index 05e9352..0000000
--- a/inc/response.h
+++ /dev/null
@@ -1,14 +0,0 @@
-#ifndef RESPONSE_H
-#define RESPONSE_H
-#include <iostream>
-
-enum Response {
- OK,
- WAIT,
- BLOCKED,
- STALLED,
-};
-
-std::ostream &operator<<(std::ostream &os, Response r);
-
-#endif /* RESPONSE_H_INCLUDED */
diff --git a/inc/storage.h b/inc/storage.h
index d6fa094..81194da 100644
--- a/inc/storage.h
+++ b/inc/storage.h
@@ -1,8 +1,6 @@
#ifndef STORAGE_H
#define STORAGE_H
-#include "accessor.h"
#include "definitions.h"
-#include "response.h"
#include <algorithm>
#include <array>
#include <map>
@@ -11,6 +9,12 @@
class Storage
{
public:
+ /**
+ * Constructor.
+ * @param The time an access to this storage device takes.
+ * @return A newly allocated storage object.
+ */
+ Storage(int delay);
virtual ~Storage() = default;
/**
@@ -18,34 +22,26 @@ class Storage
* @param the source making the request.
* @param the data (hexadecimal) to write.
* @param the address to write to.
- * @return a status code reflecting the state of the request.
- */
- virtual Response write_word(Accessor accessor, signed int data, int address) = 0;
-
- /**
- * Write a data line to given address in this level of storage
+ * @return 1 if the request was completed, 0 otherwise.
*/
- virtual Response write_line(Accessor accessor, std::array<signed int, LINE_SIZE> data_line, int address) = 0;
+ virtual int
+ write_word(void *id, signed int data, int address) = 0;
+ virtual int
+ write_line(void *id, std::array<signed int, LINE_SIZE> data_line, int address) = 0;
-
/**
* Get the data line at `address`.
* @param the source making the request.
* @param the address being accessed.
- * @return a status code reflecting the state of the request, and the
- * data being returned.
+ * @param the data being returned
+ * @return 1 if the request was completed, 0 otherwise
*/
- virtual Response read_line(
- Accessor accessor,
- int address,
- std::array<signed int, LINE_SIZE> &data) = 0;
+ virtual int
+ read_line(void *id, int address, std::array<signed int, LINE_SIZE> &data) = 0;
+ virtual int
+ read_word(void *id, int address, signed int &data) = 0;
/**
- * Read a word from given address in this level of storage
- */
- virtual Response read_word(Accessor accessor, int address, signed int &data) = 0;
-
- /**
* Sidedoor view of `lines` of memory starting at `base`.
* @param The base line to start getting memory from.
* @param The amount of lines to fetch.
@@ -55,13 +51,6 @@ class Storage
std::vector<std::array<signed int, LINE_SIZE>>
view(int base, int lines) const;
- /**
- * Getter for lower attribute.
- * TODO this doesn't seem like good object-oriented practice.
- * @return this->lower
- */
- Storage *get_lower();
-
protected:
/**
* The data currently stored in this level of storage.
@@ -73,23 +62,18 @@ class Storage
*/
Storage *lower;
/**
+ * The id currently being serviced.
+ */
+ void *current_request;
+ /**
* The number of clock cycles this level of storage takes to complete
* requests.
*/
int delay;
/**
- * The accessor currently being serviced.
- */
- Accessor requester;
- /**
* The number of cycles until the current request is completed.
*/
int wait_time;
- /**
- * A flag indicating whether this level of storage is currently waiting for
- * a lower level.
- */
- int is_waiting;
};
#endif /* STORAGE_H_INCLUDED */
diff --git a/src/accessor.cc b/src/accessor.cc
deleted file mode 100644
index 99347ed..0000000
--- a/src/accessor.cc
+++ /dev/null
@@ -1,10 +0,0 @@
-#include "accessor.h"
-#include <iostream>
-
-std::ostream &operator<<(std::ostream &os, Accessor a)
-{
- const std::string nameA[] = {
- "IDLE", "WRITE", "MEM", "EXEC", "DCDE", "FETCH", "L1CACHE", "SIDE",
- };
- return os << nameA[a];
-}
diff --git a/src/cache.cc b/src/cache.cc
index 80f59ef..bbb90b4 100644
--- a/src/cache.cc
+++ b/src/cache.cc
@@ -1,21 +1,14 @@
#include "cache.h"
#include "definitions.h"
-#include "response.h"
#include "utils.h"
#include <bits/stdc++.h>
-#include <iostream>
#include <iterator>
-Cache::Cache(Storage *lower, int delay)
+Cache::Cache(Storage *lower, int delay) : Storage(delay)
{
- this->data = new std::vector<std::array<signed int, LINE_SIZE>>;
this->data->resize(L1_CACHE_LINES);
- this->delay = delay;
- this->is_waiting = false;
this->lower = lower;
this->meta.fill({-1, -1});
- this->requester = IDLE;
- this->wait_time = this->delay;
}
Cache::~Cache()
@@ -24,18 +17,19 @@ Cache::~Cache()
delete this->data;
}
-Response Cache::write_word(Accessor accessor, signed int data, int address)
+int
+Cache::write_word(void *id, signed int data, int address)
{
- return process(accessor, address, [&](int index, int offset) {
+ return process(id, 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)
+int
+Cache::write_line(void *id, std::array<signed int, LINE_SIZE> data_line, int address)
{
- return process(accessor, address, [&](int index, int offset) {
+ return process(id, address, [&](int index, int offset) {
(void)offset;
this->data->at(index) = data_line;
this->meta[index].at(1) = 1;
@@ -43,31 +37,28 @@ Response Cache::write_line(
}
// TODO: tests for multi level cache
-Response Cache::read_line(
- Accessor accessor,
- int address,
- std::array<signed int, LINE_SIZE> &data_line)
+int
+Cache::read_line(void *id, int address, std::array<signed int, LINE_SIZE> &data_line)
{
- return process(accessor, address, [&](int index, int offset) {
+ return process(id, address, [&](int index, int offset) {
(void)offset;
data_line = this->data->at(index);
});
}
-Response Cache::read_word(Accessor accessor, int address, signed int &data)
+int
+Cache::read_word(void *id, int address, signed int &data)
{
- return process(accessor, address, [&](int index, int offset) {
- data = this->data->at(index).at(offset);
- });
+ return process(
+ id, 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)
+int
+Cache::process(void *id, int address, std::function<void(int index, int offset)> request_handler)
{
- Response r = this->is_access_cleared(accessor, address);
- if (r == OK) {
+ 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);
@@ -75,106 +66,64 @@ Response Cache::process(
return r;
}
-Response Cache::is_access_cleared(Accessor accessor, int address)
+int
+Cache::is_access_cleared(void *id, int address)
{
- Response r;
- 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;
+ 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->requester = IDLE;
+ this->current_request = nullptr;
this->wait_time = delay;
- r = OK;
+ return 1;
} else {
--this->wait_time;
}
}
- return r;
+ return 0;
}
-void Cache::handle_miss(int expected)
+int
+Cache::is_address_missing(int expected)
{
- Response r, q;
- int tag, index, offset;
+ int r, q, tag, index, offset;
std::array<signed int, LINE_SIZE> *actual;
std::array<int, 2> *meta;
get_cache_fields(expected, &tag, &index, &offset);
- r = OK;
+ r = 0;
meta = &this->meta.at(index);
actual = &this->data->at(index);
if (meta->at(0) != tag) {
- r = WAIT;
- // address not in cache
+ r = 1;
if (meta->at(1) >= 0) {
- // occupant is dirty
- // writing line to DRam in case of dirty cache eviction
q = this->lower->write_line(
- L1CACHE, *actual,
- ((index << LINE_SPEC) +
- (meta->at(0) << (L1_CACHE_LINE_SPEC + LINE_SPEC))));
- if (q == OK) {
+ this, *actual,
+ ((index << LINE_SPEC) + (meta->at(0) << (L1_CACHE_LINE_SPEC + LINE_SPEC))));
+ if (q) {
meta->at(1) = -1;
}
} else {
- q = this->lower->read_line(L1CACHE, expected, *actual);
- if (q == OK) {
+ q = this->lower->read_line(this, expected, *actual);
+ if (q) {
meta->at(0) = tag;
}
}
}
- this->is_waiting = (r == OK) ? false : true;
+ return r;
}
-std::array<std::array<int, 2>, L1_CACHE_LINES> Cache::get_meta() const
+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;
}
-
-std::ostream &operator<<(std::ostream &os, const Cache &c)
-{
- const auto default_flags = std::cout.flags();
- const auto default_fill = std::cout.fill();
-
- std::vector<std::array<signed int, LINE_SIZE>> data =
- c.view(0, L1_CACHE_LINES);
- std::array<std::array<int, 2>, L1_CACHE_LINES> meta = c.get_meta();
-
- os << " " << std::setfill(' ') << std::setw(L1_CACHE_LINE_SPEC + 2)
- << "INDEX"
- << " | " << std::setfill(' ') << std::setw((8 + 3) * 4 - 1) << "DATA"
- << " | " << std::setfill(' ')
- << std::setw(MEM_LINE_SPEC - L1_CACHE_LINE_SPEC + 2) << "TAG"
- << " | D" << std::endl;
- for (int i = 0; i < L1_CACHE_LINES; ++i) {
- os << " 0b" << std::setw(L1_CACHE_LINE_SPEC)
- << std::bitset<L1_CACHE_LINE_SPEC>(i) << " | ";
- for (int j = 0; j < LINE_SIZE; ++j) {
- os << "0x" << std::setfill('0') << std::setw(8) << std::hex
- << data.at(i).at(j) << " ";
- }
- os << "| 0b" << std::setfill(' ');
-
- if (meta.at(i)[0] < 0)
- os << std::setfill('?')
- << std::setw(MEM_LINE_SPEC - L1_CACHE_LINE_SPEC) << "";
- else
- os << std::bitset<MEM_LINE_SPEC - L1_CACHE_LINE_SPEC>(
- meta.at(i)[0]);
-
- os << " | " << (int)(meta.at(i)[0] >= 0) << std::endl;
- }
-
- std::cout.flags(default_flags);
- std::cout.fill(default_fill);
- return os;
-}
diff --git a/src/dram.cc b/src/dram.cc
index f90f8db..d81e2d2 100644
--- a/src/dram.cc
+++ b/src/dram.cc
@@ -1,63 +1,50 @@
#include "dram.h"
#include "definitions.h"
-#include "response.h"
#include <algorithm>
#include <bits/stdc++.h>
#include <bitset>
-#include <iostream>
#include <iterator>
#include <utils.h>
-Dram::Dram(int delay)
-{
- this->data = new std::vector<std::array<signed int, LINE_SIZE>>;
- this->data->resize(MEM_LINES);
- this->delay = delay;
- this->is_waiting = false;
- this->lower = nullptr;
- this->requester = IDLE;
- this->wait_time = this->delay;
-}
+Dram::Dram(int delay) : Storage(delay) { this->data->resize(MEM_LINES); }
Dram::~Dram() { delete this->data; }
-Response Dram::write_line(
- Accessor accessor, std::array<signed int, LINE_SIZE> data_line, int address)
+int
+Dram::write_line(void *id, std::array<signed int, LINE_SIZE> data_line, int address)
{
- return process(accessor, address, [&](int line, int word) {
+ return process(id, address, [&](int line, int word) {
(void)word;
this->data->at(line) = data_line;
});
}
-Response Dram::write_word(Accessor accessor, signed int data, int address)
+int
+Dram::write_word(void *id, signed int data, int address)
{
- return process(accessor, address, [&](int line, int word) {
- this->data->at(line).at(word) = data;
- });
+ return process(id, address, [&](int line, int word) { this->data->at(line).at(word) = data; });
}
// TODO requires testing
-Response Dram::read_line(
- Accessor accessor,
- int address,
- std::array<signed int, LINE_SIZE> &data_line)
+int
+Dram::read_line(void *id, int address, std::array<signed int, LINE_SIZE> &data_line)
{
- return process(accessor, address, [&](int line, int word) {
+ return process(id, address, [&](int line, int word) {
(void)word;
data_line = this->data->at(line);
});
}
-Response Dram::read_word(Accessor accessor, int address, signed int &data)
+int
+Dram::read_word(void *id, int address, signed int &data)
{
- return process(accessor, address, [&](int line, int word) {
- data = this->data->at(line).at(word);
- });
+ return process(id, address, [&](int line, int word) { data = this->data->at(line).at(word); });
}
// TODO load a file instead and test this method
-void Dram::load(std::vector<signed int> program) {
+void
+Dram::load(std::vector<signed int> program)
+{
unsigned long i;
for (i = 0; i < program.size(); ++i) {
int line, word;
@@ -66,13 +53,12 @@ void Dram::load(std::vector<signed int> program) {
}
}
-Response Dram::process(
- Accessor accessor,
- int address,
- std::function<void(int line, int word)> request_handler)
+int
+Dram::process(void *id, int address, std::function<void(int line, int word)> request_handler)
{
- Response r = this->is_access_cleared(accessor);
- if (r == OK) {
+ int r;
+ r = this->is_access_cleared(id);
+ if (r) {
int line, word;
get_memory_index(address, line, word);
request_handler(line, word);
@@ -80,51 +66,22 @@ Response Dram::process(
return r;
}
-Response Dram::is_access_cleared(Accessor accessor)
+int
+Dram::is_access_cleared(void *id)
{
- Response r;
- r = WAIT;
/* Do this first--then process the first cycle immediately. */
- if (accessor == SIDE)
- r = OK;
- else {
- if (this->requester == IDLE)
- this->requester = accessor;
- if (this->requester == accessor) {
- if (this->wait_time == 0) {
- this->requester = IDLE;
- this->wait_time = delay;
- r = OK;
- } else {
- --this->wait_time;
- }
- }
- }
- return r;
-}
-
-std::ostream &operator<<(std::ostream &os, const Dram &d)
-{
- const auto default_flags = std::cout.flags();
- const auto default_fill = std::cout.fill();
-
- std::vector<std::array<signed int, LINE_SIZE>> data = d.view(0, MEM_LINES);
-
- os << " " << std::setfill(' ') << std::setw(MEM_LINE_SPEC + 2 + LINE_SPEC)
- << "ADDRESS"
- << " | " << std::setfill(' ') << std::setw((8 + 3) * 4 - 1) << "DATA"
- << std::endl;
- for (int i = 0; i < MEM_LINES; ++i) {
- os << " 0b" << std::setw(MEM_LINE_SPEC + LINE_SPEC) << left
- << std::bitset<MEM_LINE_SPEC>(i) << " | ";
- for (int j = 0; j < LINE_SIZE; ++j) {
- os << "0x" << std::setfill('0') << std::setw(8) << std::hex
- << data.at(i).at(j) << ' ';
+ 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;
}
- os << std::endl;
}
-
- std::cout.flags(default_flags);
- std::cout.fill(default_fill);
- return os;
+ return 0;
}
diff --git a/src/logger.cc b/src/logger.cc
deleted file mode 100644
index b07e66f..0000000
--- a/src/logger.cc
+++ /dev/null
@@ -1,71 +0,0 @@
-#include "logger.h"
-#include <ctime>
-#include <fstream>
-#include <iostream>
-#include <sstream>
-using namespace std;
-
-LogLevel Logger::level = INFO;
-Logger *Logger::logger_instance;
-
-void Logger::setLevel(LogLevel level) { this->level = level; }
-
-void Logger::log(LogLevel level, const string &message)
-{
- if (level_to_int(level) > level_to_int(this->level)) {
- return;
- }
-
- time_t now = time(0);
- tm *timeinfo = localtime(&now);
- char timestamp[20];
- strftime(timestamp, sizeof(timestamp), "%Y-%m-%d %H:%M:%S", timeinfo);
-
- ostringstream logEntry;
- logEntry << "[" << timestamp << "] " << level_to_string(level) << ": "
- << message << endl;
-
- cout << logEntry.str();
-}
-
-Logger *Logger::getInstance()
-{
- if (logger_instance == nullptr) {
- logger_instance = new Logger();
- }
- return logger_instance;
-}
-
-string Logger::level_to_string(LogLevel level)
-{
- switch (level) {
- case DEBUG:
- return "DEBUG";
- case INFO:
- return "INFO";
- case WARNING:
- return "WARNING";
- case ERROR:
- return "ERROR";
- case CRITICAL:
- return "CRITICAL";
- default:
- return "UNKNOWN";
- }
-}
-
-int Logger::level_to_int(LogLevel level)
-{
- switch (level) {
- case DEBUG:
- return 5;
- case INFO:
- return 4;
- case WARNING:
- return 3;
- case ERROR:
- return 2;
- default:
- return 1;
- }
-}
diff --git a/src/response.cc b/src/response.cc
deleted file mode 100644
index 3d6e439..0000000
--- a/src/response.cc
+++ /dev/null
@@ -1,8 +0,0 @@
-#include "response.h"
-#include <iostream>
-
-std::ostream &operator<<(std::ostream &os, Response r)
-{
- const std::string nameR[] = {"OK", "WAIT", "BLOCKED", "STALLED"};
- return os << nameR[r];
-}
diff --git a/src/storage.cc b/src/storage.cc
index fed607b..4ad916b 100644
--- a/src/storage.cc
+++ b/src/storage.cc
@@ -2,15 +2,19 @@
#include "definitions.h"
#include <algorithm>
+Storage::Storage(int delay) {
+ this->data = new std::vector<std::array<signed int, LINE_SIZE>>;
+ this->delay = delay;
+ this->lower = nullptr;
+ this->current_request = nullptr;
+ this->wait_time = this->delay;
+}
+
std::vector<std::array<signed int, LINE_SIZE>>
Storage::view(int base, int lines) const
{
base = (base / LINE_SIZE) * LINE_SIZE;
std::vector<std::array<signed int, LINE_SIZE>> ret(lines + 1);
- std::copy(
- this->data->begin() + base, this->data->begin() + base + lines,
- ret.begin());
+ std::copy(this->data->begin() + base, this->data->begin() + base + lines, ret.begin());
return ret;
}
-
-Storage *Storage::get_lower() { return this->lower; }
diff --git a/tests/cache.cc b/tests/cache.cc
index 0b04bce..313f93f 100644
--- a/tests/cache.cc
+++ b/tests/cache.cc
@@ -11,21 +11,28 @@ class CacheFixture
this->c_delay = 2;
this->d = new Dram(this->m_delay);
this->c = new Cache(this->d, this->c_delay);
+ this->mem = new int;
+ this->fetch = new int;
this->expected = {0, 0, 0, 0};
this->actual = this->c->view(0, 1)[0];
}
- ~CacheFixture() { delete this->c; }
+ ~CacheFixture()
+ {
+ delete this->c;
+ delete this->mem;
+ delete this->fetch;
+ }
/**
* An operation that is done a lot.
*/
void
- wait_for_storage(int delay, Response expected, std::function<Response()> f)
+ wait_for_storage(int delay, int expected, std::function<int()> f)
{
for (int i = 0; i < delay; ++i) {
- Response r = f();
-
+ int r = f();
+
// check response
CHECK(r == expected);
// check for early modifications
@@ -38,29 +45,27 @@ class CacheFixture
int c_delay;
Cache *c;
Dram *d;
+ int *mem;
+ int *fetch;
std::array<signed int, LINE_SIZE> expected;
std::array<signed int, LINE_SIZE> actual;
};
TEST_CASE_METHOD(CacheFixture, "store 0th element in DELAY cycles", "[dram]")
{
- Response r;
+ int r;
signed int w;
CHECK(expected == actual);
w = 0x11223344;
// delay + 1 due to internal logic, when mem
// finishes handle_miss still returns 'blocked'
- this->wait_for_storage(this->m_delay + 1, BLOCKED, [this, w]() {
- return this->c->write_word(MEM, w, 0b0);
- });
-
- this->wait_for_storage(this->c_delay, WAIT, [this, w]() {
- return this->c->write_word(MEM, w, 0b0);
+ this->wait_for_storage(this->m_delay + this->c_delay + 1, 0, [this, w]() {
+ return this->c->write_word(this->mem, w, 0b0);
});
- r = c->write_word(MEM, w, 0b0);
- CHECK(r == OK);
+ r = c->write_word(this->mem, w, 0b0);
+ CHECK(r);
actual = this->d->view(0, 1)[0];
// we do NOT write back now!
@@ -71,43 +76,28 @@ TEST_CASE_METHOD(CacheFixture, "store 0th element in DELAY cycles", "[dram]")
REQUIRE(expected == actual);
}
-TEST_CASE_METHOD(
- CacheFixture,
- "store 0th, 1st element in DELAY cycles, with conflict",
- "[cache]")
+TEST_CASE_METHOD(CacheFixture, "store 0th, 1st element in DELAY cycles, with conflict", "[cache]")
{
- Response r;
signed int w;
- int i;
+ int r, i;
CHECK(expected == actual);
w = 0x11223344;
// delay + 1 due to internal logic, when mem
// finishes handle_miss still returns 'blocked'
- for (i = 0; i < this->m_delay + 1; ++i) {
- r = c->write_word(MEM, w, 0b0);
- CHECK(r == BLOCKED);
- r = c->write_word(FETCH, w, 0b1);
- CHECK(r == WAIT);
-
- // check for early modifications
- actual = c->view(0, 1)[0];
- REQUIRE(this->expected == this->actual);
- }
+ for (i = 0; i < this->m_delay + this->c_delay + 1; ++i) {
+ r = c->write_word(this->mem, w, 0b0);
+ CHECK(!r);
+ r = c->write_word(this->fetch, w, 0b1);
+ CHECK(!r);
- for (i = 0; i < this->c_delay; ++i) {
- r = c->write_word(MEM, w, 0b0);
- CHECK(r == WAIT);
- r = c->write_word(FETCH, w, 0b1);
- CHECK(r == WAIT);
-
// check for early modifications
actual = c->view(0, 1)[0];
REQUIRE(this->expected == this->actual);
}
- r = c->write_word(MEM, w, 0b0);
- CHECK(r == OK);
+ r = c->write_word(this->mem, w, 0b0);
+ CHECK(r);
actual = d->view(0, 1)[0];
// we do NOT write back now!
@@ -118,69 +108,57 @@ TEST_CASE_METHOD(
REQUIRE(expected == actual);
// this should have been loaded already!
- this->wait_for_storage(this->c_delay, WAIT, [this, w]() {
- return this->c->write_word(FETCH, w, 0b1);
- });
+ this->wait_for_storage(
+ this->c_delay, 0, [this, w]() { return this->c->write_word(this->fetch, w, 0b1); });
+
+ r = c->write_word(this->fetch, w, 0b1);
+ CHECK(r);
- r = c->write_word(FETCH, w, 0b1);
- CHECK(r == OK);
-
expected.at(1) = w;
actual = c->view(0, 1)[0];
REQUIRE(expected == actual);
}
TEST_CASE_METHOD(
- CacheFixture,
- "store 0th, 1st element different tags, in DELAY cycles, no conflict",
- "[cache]")
+ CacheFixture, "store 0th, 1st element different tags, in DELAY cycles, no conflict", "[cache]")
{
- Response r;
+ int r;
signed int w;
CHECK(expected == actual);
w = 0x11223344;
// delay + 1 due to internal logic, when mem
// finishes handle_miss still returns 'blocked'
- this->wait_for_storage(this->m_delay + 1, BLOCKED, [this, w]() {
- return this->c->write_word(MEM, w, 0b0);
+ this->wait_for_storage(this->m_delay + this->c_delay + 1, 0, [this, w]() {
+ return this->c->write_word(this->mem, w, 0b0);
});
- this->wait_for_storage(this->c_delay, WAIT, [this, w]() {
- return this->c->write_word(MEM, w, 0b0);
- });
+ r = c->write_word(this->mem, w, 0b0);
+ CHECK(r);
- r = c->write_word(MEM, w, 0b0);
- CHECK(r == OK);
-
expected.at(0) = w;
actual = c->view(0, 1)[0];
REQUIRE(expected == actual);
// write back to memory
- this->wait_for_storage(this->m_delay + 1, BLOCKED, [this, w]() {
- return this->c->write_word(FETCH, w, 0b10000001);
- });
-
// fetch new address (don't run the completion cycle yet)
- this->wait_for_storage(this->m_delay, BLOCKED, [this, w]() {
- return this->c->write_word(FETCH, w, 0b10000001);
+ this->wait_for_storage(this->m_delay + this->m_delay + 1, 0, [this, w]() {
+ return this->c->write_word(this->fetch, w, 0b10000001);
});
// after the fetch, this cache line should be empty
- this->c->write_word(FETCH, w, 0b10000001);
- CHECK(r == OK);
-
+ this->c->write_word(this->fetch, w, 0b10000001);
+ CHECK(r);
+
expected.at(0) = 0;
actual = c->view(0, 1)[0];
CHECK(expected == actual);
- this->wait_for_storage(this->c_delay, WAIT, [this, w]() {
- return this->c->write_word(FETCH, w, 0b10000001);
- });
+ this->wait_for_storage(
+ this->c_delay, 0, [this, w]() { return this->c->write_word(this->fetch, w, 0b10000001); });
- r = c->write_word(FETCH, w, 0b10000001);
- CHECK(r == OK);
+ r = c->write_word(this->fetch, w, 0b10000001);
+ CHECK(r);
expected.at(0) = 0;
expected.at(1) = w;
diff --git a/tests/dram.cc b/tests/dram.cc
index 0e97e81..086ca4a 100644
--- a/tests/dram.cc
+++ b/tests/dram.cc
@@ -9,23 +9,27 @@ class DramFixture
{
this->delay = 3;
this->d = new Dram(this->delay);
+ this->mem = new int;
+ this->fetch = new int;
this->expected = {0, 0, 0, 0};
this->actual = this->d->view(0, 1)[0];
}
- ~DramFixture() { delete this->d; }
+ ~DramFixture()
+ {
+ delete this->d;
+ delete this->mem;
+ delete this->fetch;
+ }
- /**
- * An operation that is done a lot.
- */
void
- wait_for_storage(int delay, Response expected, std::function<Response()> f)
+ wait_for_storage(int delay, std::function<int()> f)
{
for (int i = 0; i < delay; ++i) {
- Response r = f();
+ int r = f();
// check response
- CHECK(r == expected);
+ CHECK(!r);
// check for early modifications
actual = d->view(0, 1)[0];
REQUIRE(this->expected == this->actual);
@@ -34,95 +38,84 @@ class DramFixture
int delay;
Dram *d;
+ int *mem;
+ int *fetch;
std::array<signed int, LINE_SIZE> expected;
std::array<signed int, LINE_SIZE> actual;
};
TEST_CASE_METHOD(DramFixture, "store 0th element in DELAY cycles", "[dram]")
{
- Response r;
+ int r;
signed int w;
CHECK(expected == actual);
w = 0x11223344;
- this->wait_for_storage(this->delay, WAIT, [this, w]() {
- return this->d->write_word(MEM, w, 0x0);
- });
+ this->wait_for_storage(this->delay, [this, w]() { return this->d->write_word(this->mem, w, 0x0); });
- r = this->d->write_word(MEM, w, 0x0);
+ r = this->d->write_word(this->mem, w, 0x0);
- CHECK(r == OK);
+ CHECK(r);
expected.at(0) = w;
actual = this->d->view(0, 1)[0];
REQUIRE(expected == actual);
}
-TEST_CASE_METHOD(
- DramFixture,
- "store 0th, 1st element in DELAY cycles, no conflict",
- "[dram]")
+TEST_CASE_METHOD(DramFixture, "store 0th, 1st element in DELAY cycles, no conflict", "[dram]")
{
- Response r;
+ int r;
signed int w;
CHECK(expected == actual);
w = 0x11223344;
- this->wait_for_storage(this->delay, WAIT, [this, w]() {
- return this->d->write_word(MEM, w, 0x0);
- });
+ this->wait_for_storage(this->delay, [this, w]() { return this->d->write_word(this->mem, w, 0x0); });
- r = d->write_word(MEM, w, 0x0);
- REQUIRE(r == OK);
+ r = d->write_word(this->mem, w, 0x0);
+ REQUIRE(r);
expected.at(0) = w;
actual = d->view(0, 1)[0];
REQUIRE(expected == actual);
- this->wait_for_storage(this->delay, WAIT, [this, w]() {
- return this->d->write_word(FETCH, w, 0x1);
- });
+ this->wait_for_storage(this->delay, [this, w]() { return this->d->write_word(this->fetch, w, 0x1); });
- r = d->write_word(FETCH, w, 0x1);
- CHECK(r == OK);
+ r = d->write_word(this->fetch, w, 0x1);
+ CHECK(r);
actual = d->view(0, 1)[0];
expected.at(1) = w;
REQUIRE(expected == actual);
}
-TEST_CASE_METHOD(
- DramFixture, "store 0th element in DELAY cycles with conflict", "[dram]")
+TEST_CASE_METHOD(DramFixture, "store 0th element in DELAY cycles with conflict", "[dram]")
{
- Response r;
+ int r, i;
signed int w;
- int i;
CHECK(expected == actual);
w = 0x11223344;
for (i = 0; i < this->delay; ++i) {
- r = this->d->write_word(MEM, w, 0x0);
- CHECK(r == WAIT);
- r = this->d->write_word(FETCH, w, 0x1);
- CHECK(r == WAIT);
+ r = this->d->write_word(this->mem, w, 0x0);
+ CHECK(!r);
+ r = this->d->write_word(this->fetch, w, 0x1);
+ CHECK(!r);
// check for early modifications
actual = d->view(0, 1)[0];
REQUIRE(expected == actual);
}
- r = d->write_word(MEM, w, 0x0);
- REQUIRE(r == OK);
+ r = d->write_word(this->mem, w, 0x0);
+ REQUIRE(r);
expected.at(0) = w;
actual = d->view(0, 1)[0];
REQUIRE(expected == actual);
- this->wait_for_storage(this->delay, WAIT, [this, w]() {
- return this->d->write_word(FETCH, w, 0x1);
- });
+ this->wait_for_storage(this->delay, [this, w]() { return this->d->write_word(this->fetch, w, 0x1); });
- r = d->write_word(FETCH, w, 0x1);
- CHECK(r == OK);
+ r = d->write_word(this->fetch, w, 0x1);
+ CHECK(r);
actual = d->view(0, 1)[0];
expected.at(1) = w;
@@ -131,95 +124,88 @@ TEST_CASE_METHOD(
TEST_CASE_METHOD(DramFixture, "store line in DELAY cycles", "[dram]")
{
- Response r;
+ int r;
signed int w;
std::array<signed int, LINE_SIZE> buffer;
CHECK(expected == actual);
w = 0x11223344;
buffer = {w, w + 1, w + 2, w + 3};
- this->wait_for_storage(this->delay, WAIT, [this, w, buffer]() {
- return this->d->write_line(MEM, buffer, 0x0);
- });
+ this->wait_for_storage(
+ this->delay, [this, w, buffer]() { return this->d->write_line(this->mem, buffer, 0x0); });
- r = d->write_line(MEM, buffer, 0x0);
- CHECK(r == OK);
+ r = d->write_line(this->mem, buffer, 0x0);
+ CHECK(r);
actual = d->view(0, 1)[0];
expected = buffer;
REQUIRE(expected == actual);
}
-TEST_CASE_METHOD(
- DramFixture, "store line in DELAY cycles no conflict", "[dram]")
+TEST_CASE_METHOD(DramFixture, "store line in DELAY cycles no conflict", "[dram]")
{
- Response r;
+ int r;
signed int w;
std::array<signed int, LINE_SIZE> buffer;
CHECK(expected == actual);
w = 0x11223344;
buffer = {w, w + 1, w + 2, w + 3};
- this->wait_for_storage(this->delay, WAIT, [this, w, buffer]() {
- return this->d->write_line(MEM, buffer, 0x0);
- });
+ this->wait_for_storage(
+ this->delay, [this, w, buffer]() { return this->d->write_line(this->mem, buffer, 0x0); });
- r = this->d->write_line(MEM, buffer, 0x0);
- REQUIRE(r == OK);
+ r = this->d->write_line(this->mem, buffer, 0x0);
+ REQUIRE(r);
expected = buffer;
actual = d->view(0, 1)[0];
REQUIRE(expected == actual);
buffer = {w + 4, w + 5, w + 6, w + 7};
- this->wait_for_storage(this->delay, WAIT, [this, w, buffer]() {
- return this->d->write_line(FETCH, buffer, 0x1);
- });
+ this->wait_for_storage(
+ this->delay, [this, w, buffer]() { return this->d->write_line(this->fetch, buffer, 0x1); });
- r = this->d->write_line(FETCH, buffer, 0x1);
- CHECK(r == OK);
+ r = this->d->write_line(this->fetch, buffer, 0x1);
+ CHECK(r);
expected = buffer;
actual = d->view(0, 1)[0];
REQUIRE(expected == actual);
}
-TEST_CASE_METHOD(
- DramFixture, "store line in DELAY cycles with conflict", "[dram]")
+TEST_CASE_METHOD(DramFixture, "store line in DELAY cycles with conflict", "[dram]")
{
- Response r;
+ int r, i;
signed int w;
- int i;
std::array<signed int, LINE_SIZE> buffer;
CHECK(expected == actual);
w = 0x11223344;
buffer = {w, w + 1, w + 2, w + 3};
for (i = 0; i < this->delay; ++i) {
- r = this->d->write_line(MEM, buffer, 0x0);
- CHECK(r == WAIT);
- r = d->write_line(FETCH, buffer, 0x1);
- CHECK(r == WAIT);
+ r = this->d->write_line(this->mem, buffer, 0x0);
+ CHECK(!r);
+ r = d->write_line(this->fetch, buffer, 0x1);
+ CHECK(!r);
// check for early modifications
actual = d->view(0, 1)[0];
REQUIRE(expected == actual);
}
- r = d->write_line(MEM, buffer, 0x0);
- CHECK(r == OK);
+ r = d->write_line(this->mem, buffer, 0x0);
+ CHECK(r);
actual = d->view(0, 1)[0];
expected = buffer;
REQUIRE(expected == actual);
buffer = {w + 4, w + 5, w + 6, w + 7};
- this->wait_for_storage(this->delay, WAIT, [this, w, buffer]() {
- return this->d->write_line(FETCH, buffer, 0x1);
- });
+ this->wait_for_storage(
+ this->delay, [this, w, buffer]() { return this->d->write_line(this->fetch, buffer, 0x1); });
- r = this->d->write_line(FETCH, buffer, 0x1);
- CHECK(r == OK);
+ r = this->d->write_line(this->fetch, buffer, 0x1);
+ CHECK(r);
expected = buffer;
actual = d->view(0, 1)[0];
@@ -227,71 +213,65 @@ TEST_CASE_METHOD(
}
TEST_CASE_METHOD(
- DramFixture,
- "store line in DELAY cycles, read in DELAY cycles, no conflict",
- "[dram]")
+ DramFixture, "store line in DELAY cycles, read in DELAY cycles, no conflict", "[dram]")
{
- Response r;
+ int r, i, addr;
signed int w;
- int i, addr;
CHECK(expected == actual);
w = 0x11223311;
addr = 0x0;
expected = {w, w + 1, w + 2, w + 3};
for (i = 0; i < this->delay; ++i) {
- r = d->write_line(MEM, expected, addr);
- CHECK(r == WAIT);
+ r = d->write_line(this->mem, expected, addr);
+ CHECK(!r);
}
- r = d->write_line(MEM, expected, addr);
- CHECK(r == OK);
+ r = d->write_line(this->mem, expected, addr);
+ CHECK(r);
for (i = 0; i < this->delay; ++i) {
- r = d->read_line(MEM, addr, actual);
+ r = d->read_line(this->mem, addr, actual);
- CHECK(r == WAIT);
+ CHECK(!r);
REQUIRE(expected != actual);
}
- r = d->read_line(MEM, addr, actual);
+ r = d->read_line(this->mem, addr, actual);
- CHECK(r == OK);
+ CHECK(r);
REQUIRE(expected == actual);
}
TEST_CASE_METHOD(
- DramFixture,
- "store line in DELAY cycles, read in DELAY cycles with conflict",
- "[dram]")
+ DramFixture, "store line in DELAY cycles, read in DELAY cycles with conflict", "[dram]")
{
- Response r;
+ int r, i, addr;
signed int w;
- int i, addr;
CHECK(expected == actual);
w = 0x11223311;
addr = 0x0;
expected = {w, w + 1, w + 2, w + 3};
for (i = 0; i < delay; ++i) {
- r = d->write_line(MEM, expected, addr);
- CHECK(r == WAIT);
+ r = d->write_line(this->mem, expected, addr);
+ CHECK(!r);
- r = d->read_line(FETCH, addr, actual);
- CHECK(r == WAIT);
+ r = d->read_line(this->fetch, addr, actual);
+ CHECK(!r);
}
- r = d->write_line(MEM, expected, addr);
- CHECK(r == OK);
+ r = d->write_line(this->mem, expected, addr);
+ CHECK(r);
for (i = 0; i < this->delay; ++i) {
- r = d->read_line(MEM, addr, actual);
+ r = d->read_line(this->mem, addr, actual);
- CHECK(r == WAIT);
+ CHECK(!r);
REQUIRE(expected != actual);
}
- r = d->read_line(MEM, addr, actual);
+ r = d->read_line(this->mem, addr, actual);
- CHECK(r == OK);
+ CHECK(r);
REQUIRE(expected == actual);
}
@@ -301,7 +281,7 @@ TEST_CASE_METHOD(
"with conflict",
"[dram]")
{
- Response r;
+ int r;
signed int w, a;
int i, j, addr;
CHECK(expected == actual);
@@ -311,41 +291,26 @@ TEST_CASE_METHOD(
addr = 0x0;
expected = {w, w + 1, w + 2, w + 3};
for (i = 0; i < this->delay; ++i) {
- r = d->write_line(MEM, expected, addr);
- CHECK(r == WAIT);
+ r = d->write_line(this->mem, expected, addr);
+ CHECK(!r);
}
- r = d->write_line(MEM, expected, addr);
- CHECK(r == OK);
+ r = d->write_line(this->mem, expected, addr);
+ CHECK(r);
actual = d->view(0, 1)[0];
REQUIRE(expected == actual);
for (i = 0; i < LINE_SIZE; ++i) {
for (j = 0; j < this->delay; ++j) {
- r = d->read_word(MEM, addr, a);
+ r = d->read_word(this->mem, addr, a);
- CHECK(r == WAIT);
+ CHECK(!r);
REQUIRE(0x0 == a);
}
- r = d->read_word(MEM, addr++, a);
- CHECK(r == OK);
+ r = d->read_word(this->mem, addr++, a);
+ CHECK(r);
REQUIRE(w++ == a);
a = 0;
}
}
-
-TEST_CASE_METHOD(DramFixture, "Sidedoor bypasses delay", "[dram]")
-{
- Response r;
- signed int w;
- CHECK(expected == actual);
-
- w = 0x11223344;
- r = this->d->write_word(SIDE, w, 0x0);
- CHECK(r == OK);
-
- expected.at(0) = w;
- actual = d->view(0, 1)[0];
- REQUIRE(expected == actual);
-}