From df580c5352528a4837b996a838f486d3838050a4 Mon Sep 17 00:00:00 2001 From: bd Date: Fri, 11 Apr 2025 23:09:49 -0400 Subject: Move storage to a separate git repository. --- src/cli/cli.cc | 214 ------------------------------------------------- src/sim/if.cc | 4 +- src/sim/mm.cc | 10 ++- src/storage/cache.cc | 180 ----------------------------------------- src/storage/dram.cc | 130 ------------------------------ src/storage/storage.cc | 16 ---- 6 files changed, 9 insertions(+), 545 deletions(-) delete mode 100644 src/cli/cli.cc delete mode 100644 src/storage/cache.cc delete mode 100644 src/storage/dram.cc delete mode 100644 src/storage/storage.cc (limited to 'src') diff --git a/src/cli/cli.cc b/src/cli/cli.cc deleted file mode 100644 index 58575cb..0000000 --- a/src/cli/cli.cc +++ /dev/null @@ -1,214 +0,0 @@ -#include "cli.h" -#include "cache.h" -#include "definitions.h" -#include "dram.h" -#include "response.h" -#include "accessor.h" -#include "utils.h" -#include - -Cli::Cli() -{ - this->cache = nullptr; - this->cycle = 0; - this->initialize(); - - commands['l'] = [this](std::vector args) { - Accessor a; - if (args.size() >= 2) { - try { - a = match_accessor_or_die(args[0]); - load(a, std::stoi(args[1])); - } catch (const std::invalid_argument &e) { - std::cerr << "Invalid input: " << e.what() << std::endl; - } - } else { - std::cout << "Usage: l \n"; - } - return; - }; - - commands['s'] = [this](std::vector args) { - Accessor a; - if (args.size() >= 3) { - try { - a = match_accessor_or_die(args[0]); - store(a, std::stoi(args[1]), std::stoi(args[2])); - } catch (const std::invalid_argument &e) { - std::cerr << "Invalid input: " << e.what() << std::endl; - } - } else { - std::cout << "Usage: s \n"; - } - return; - }; - - commands['r'] = [this](std::vector args) { - (void)args; - reset(); - return; - }; - - commands['p'] = [this](std::vector args) { - if (args.size() >= 1) { - try { - peek(std::stoi(args[0])); - } catch (const std::invalid_argument &e) { - std::cerr << "Invalid input: " << e.what() << std::endl; - } - } else { - std::cout << "Usage: v \n"; - } - return; - }; - - commands['h'] = [this](std::vector args) { - (void)args; - help(); - return; - }; -} - -Cli::~Cli() { delete this->cache; } - -void Cli::help() -{ - std::cout - << "Available commands:" << std::endl - << " [l]oad
- Load data from memory at the specified " - "address" - << std::endl - << " [s]tore
- Stores data into memory at " - "specified address. Acessor must be one of: [f]etch, [m]em" - << " [p]eek - side door function that " - "peeks the current status of the entire memory subsystem" - << std::endl - << " [r]eset - side door function that resets the memory " - "configuration and " - "cycles" - << std::endl - << " [h]elp - prints this help text" << std::endl - << " [q]uit - quits the program" << std::endl; -} - -void Cli::load(Accessor accessor, int address) -{ - address = wrap_address(address); - const auto default_flags = std::cout.flags(); - const auto default_fill = std::cout.fill(); - - signed int data; - Response r = this->cache->read_word(accessor, address, data); - std::cout << r << " to " << accessor << " reading " << address << std::endl; - if (r == OK) - std::cout << " Got: " << std::hex << data << std::endl; - - std::cout.flags(default_flags); - std::cout.fill(default_fill); -} - -void Cli::store(Accessor accessor, int data, int address) -{ - address = wrap_address(address); - Response r = this->cache->write_word(accessor, data, address); - std::cout << r << " to " << accessor << " storing " << data << " in " - << address << std::endl; -} - -void Cli::reset() -{ - this->initialize(); - std::cout << "Done." << std::endl; -} - -void Cli::peek(int level) -{ - Storage *curr = this->cache; - for (int i = 0; i < level; ++i) { - if (!curr) { - std::cerr << "Level " << level << " of storage does not exist." - << std::endl; - return; - } - curr = curr->get_lower(); - } - - Cache *c = dynamic_cast(curr); - if (c) { - std::cout << *c << std::endl; - } else { - std::cout << *dynamic_cast(curr) << std::endl; - ; - } -} - -void Cli::run() -{ - std::cout << "Memory Command Processor Started. Type 'h' for a list of " - "commands." - << std::endl; - std::string input; - - bool run = true; - while (run) { - std::cout << this->cycle << "> "; - std::getline(std::cin, input); - - std::istringstream iss1(input); - std::vector words; - std::string sentence; - std::string word; - - while (std::getline(iss1, sentence, ';')) { - words.clear(); - std::istringstream iss2(sentence); - - while (iss2 >> word) { - words.push_back(word); - } - if (words.empty()) - continue; - - std::string command = words[0]; - words.erase(words.begin()); - - if (command == "q") { - run = false; - break; - } - - auto it = commands.find(tolower(command[0])); - if (it != commands.end()) { - it->second(words); - } else { - std::cout << "Unknown command: '" << command - << "'. Type 'help' for available commands." - << std::endl; - } - } - } -} - -void Cli::initialize() -{ - Logger *global_log = Logger::getInstance(); - - global_log->log(INFO, "Resetting memory configuration and cycle."); - - if (this->cache != nullptr) - delete this->cache; - - Dram *d = new Dram(MEM_DELAY); - this->cache = new Cache(d, L1_CACHE_DELAY); - this->cycle = 1; -} - -Accessor Cli::match_accessor_or_die(std::string s) -{ - if (tolower(s[0]) == 'f') - return FETCH; - else if (tolower(s[0]) == 'm') - return MEM; - else - throw std::invalid_argument(s); -} diff --git a/src/sim/if.cc b/src/sim/if.cc index 85fb27f..4ab7f3e 100644 --- a/src/sim/if.cc +++ b/src/sim/if.cc @@ -26,10 +26,12 @@ InstrDTO *IF::advance(Response p) void IF::advance_helper() { Response r; + int i; signed int bits; if (this->curr_instr == nullptr) { - r = this->storage->read_word(this->id, this->pc, bits); + i = this->storage->read_word(this, this->pc, bits); + r = i ? OK : STALLED; if (r == OK) { this->curr_instr = new InstrDTO(); this->curr_instr->set_instr_bits(bits); diff --git a/src/sim/mm.cc b/src/sim/mm.cc index 07a362b..a9a60c2 100644 --- a/src/sim/mm.cc +++ b/src/sim/mm.cc @@ -9,11 +9,12 @@ MM::MM(Stage *stage) : Stage(stage) { this->id = MEM; } void MM::advance_helper() { signed int data; + int i; switch (this->curr_instr->get_mnemonic()) { case LOAD: - this->status = this->storage->read_word( - this->id, this->curr_instr->get_s1(), data); + i = this->storage->read_word(this, this->curr_instr->get_s1(), data); + this->status = i ? OK : STALLED; if (this->status == OK) { this->curr_instr->set_s1(data); } else @@ -22,8 +23,9 @@ void MM::advance_helper() case STORE: // TODO signed issues, we aren't wrapping addresses - this->status = this->storage->write_word( - this->id, this->curr_instr->get_s2(), this->curr_instr->get_s1()); + i = this->storage->write_word( + this, this->curr_instr->get_s2(), this->curr_instr->get_s1()); + this->status = i ? OK : STALLED; if (this->status != OK) { this->status = STALLED; } diff --git a/src/storage/cache.cc b/src/storage/cache.cc deleted file mode 100644 index 80f59ef..0000000 --- a/src/storage/cache.cc +++ /dev/null @@ -1,180 +0,0 @@ -#include "cache.h" -#include "definitions.h" -#include "response.h" -#include "utils.h" -#include -#include -#include - -Cache::Cache(Storage *lower, int delay) -{ - this->data = new std::vector>; - 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() -{ - delete this->lower; - delete this->data; -} - -Response Cache::write_word(Accessor accessor, signed int data, int address) -{ - 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 data_line, int address) -{ - 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 -Response Cache::read_line( - Accessor accessor, - int address, - std::array &data_line) -{ - 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 request_handler) -{ - Response r = this->is_access_cleared(accessor, address); - if (r == OK) { - int tag, index, offset; - get_cache_fields(address, &tag, &index, &offset); - request_handler(index, offset); - } - return r; -} - -Response Cache::is_access_cleared(Accessor accessor, 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; - else if (this->wait_time == 0) { - this->requester = IDLE; - this->wait_time = delay; - r = OK; - } else { - --this->wait_time; - } - } - return r; -} - -void Cache::handle_miss(int expected) -{ - Response r, q; - int tag, index, offset; - std::array *actual; - std::array *meta; - - get_cache_fields(expected, &tag, &index, &offset); - r = OK; - meta = &this->meta.at(index); - actual = &this->data->at(index); - - if (meta->at(0) != tag) { - r = WAIT; - // address not in cache - 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) { - meta->at(1) = -1; - } - } else { - q = this->lower->read_line(L1CACHE, expected, *actual); - if (q == OK) { - meta->at(0) = tag; - } - } - } - - this->is_waiting = (r == OK) ? false : true; -} - -std::array, L1_CACHE_LINES> Cache::get_meta() const -{ - std::array, 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> data = - c.view(0, L1_CACHE_LINES); - std::array, 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(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( - 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/storage/dram.cc b/src/storage/dram.cc deleted file mode 100644 index f90f8db..0000000 --- a/src/storage/dram.cc +++ /dev/null @@ -1,130 +0,0 @@ -#include "dram.h" -#include "definitions.h" -#include "response.h" -#include -#include -#include -#include -#include -#include - -Dram::Dram(int delay) -{ - this->data = new std::vector>; - 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() { delete this->data; } - -Response Dram::write_line( - Accessor accessor, std::array data_line, int address) -{ - return process(accessor, address, [&](int line, int word) { - (void)word; - this->data->at(line) = data_line; - }); -} - -Response Dram::write_word(Accessor accessor, signed int data, int address) -{ - return process(accessor, 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 &data_line) -{ - return process(accessor, address, [&](int line, int word) { - (void)word; - data_line = this->data->at(line); - }); -} - -Response Dram::read_word(Accessor accessor, int address, signed int &data) -{ - return process(accessor, 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 program) { - unsigned long i; - for (i = 0; i < program.size(); ++i) { - int line, word; - get_memory_index(i, line, word); - this->data->at(line).at(word) = program[i]; - } -} - -Response Dram::process( - Accessor accessor, - int address, - std::function request_handler) -{ - 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::is_access_cleared(Accessor accessor) -{ - 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> 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(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 << std::endl; - } - - std::cout.flags(default_flags); - std::cout.fill(default_fill); - return os; -} diff --git a/src/storage/storage.cc b/src/storage/storage.cc deleted file mode 100644 index fed607b..0000000 --- a/src/storage/storage.cc +++ /dev/null @@ -1,16 +0,0 @@ -#include "storage.h" -#include "definitions.h" -#include - -std::vector> -Storage::view(int base, int lines) const -{ - base = (base / LINE_SIZE) * LINE_SIZE; - std::vector> ret(lines + 1); - std::copy( - this->data->begin() + base, this->data->begin() + base + lines, - ret.begin()); - return ret; -} - -Storage *Storage::get_lower() { return this->lower; } -- cgit v1.2.3 From 249e5bc94ef86307ecf68f8a07c65b2672ebb21c Mon Sep 17 00:00:00 2001 From: bd Date: Sat, 12 Apr 2025 00:10:52 -0400 Subject: Delete some more storage-only files --- CMakeLists.txt | 7 ++-- gui/CMakeLists.txt | 3 +- gui/main.cc | 2 +- inc/definitions.h | 102 ----------------------------------------------------- inc/stage.h | 2 +- inc/utils.h | 39 -------------------- src/sim/ex.cc | 2 +- src/utils/utils.cc | 42 ---------------------- tests/utils.cc | 65 ---------------------------------- 9 files changed, 7 insertions(+), 257 deletions(-) delete mode 100644 inc/definitions.h delete mode 100644 inc/utils.h delete mode 100644 src/utils/utils.cc delete mode 100644 tests/utils.cc (limited to 'src') diff --git a/CMakeLists.txt b/CMakeLists.txt index c7918b5..cb614b1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -26,11 +26,6 @@ set(RAM ram) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) -# header files -include_directories( - ${PROJECT_SOURCE_DIR}/inc -) - # don't build RAM's tests set(RAM_TESTS OF CACHE BOOL "" FORCE) @@ -47,6 +42,7 @@ qt_standard_project_setup() # binary executable add_library(${PROJECT_NAME}_lib ${SRCS}) +target_include_directories(${PROJECT_NAME}_lib PRIVATE ${PROJECT_SOURCE_DIR}/inc) target_link_libraries(${PROJECT_NAME}_lib ${RAM}_lib) find_package(Catch2 REQUIRED) @@ -56,6 +52,7 @@ file(GLOB_RECURSE TESTS "tests/*.cc") # test executable add_executable(test_rv ${SRCS} ${TESTS}) +target_include_directories(test_rv PRIVATE ${PROJECT_SOURCE_DIR}/inc) target_link_libraries(test_rv PRIVATE Catch2::Catch2WithMain PRIVATE ${RAM}_lib) # test discovery diff --git a/gui/CMakeLists.txt b/gui/CMakeLists.txt index 5b177d2..0d73527 100644 --- a/gui/CMakeLists.txt +++ b/gui/CMakeLists.txt @@ -21,7 +21,8 @@ file(GLOB SRCS qt_add_resources(GUI_RESOURCES "resources.qrc") add_executable(risc_vector ${SRCS} ${GUI_RESOURCES}) -target_link_libraries(${PROJECT_NAME} PRIVATE ${PROJECT_NAME}_lib ram_lib Qt6::Widgets) +target_include_directories(${PROJECT_NAME} PRIVATE ${PROJECT_SOURCE_DIR}/inc) +target_link_libraries(${PROJECT_NAME} PRIVATE ${PROJECT_NAME}_lib ram_lib Qt6::Widgets) set_target_properties(risc_vector PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}" diff --git a/gui/main.cc b/gui/main.cc index e873d1c..5e45465 100644 --- a/gui/main.cc +++ b/gui/main.cc @@ -1,4 +1,4 @@ -#include "definitions.h" +#include "pipe_spec.h" #include "gui.h" #include "logger.h" #include diff --git a/inc/definitions.h b/inc/definitions.h deleted file mode 100644 index c81c4e3..0000000 --- a/inc/definitions.h +++ /dev/null @@ -1,102 +0,0 @@ -#ifndef DEFINITIONS_H -#define DEFINITIONS_H -#include "logger.h" -#include - -/** - * 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 static_cast(pow(2, 2)) -/** - * Number of bits in a word - */ -#define WORD_SPEC 32 - -/** - * The number of bits to specify a memory word - * The number of bits to specify a memory line - * The total number of lines in memory - */ -#define MEM_WORD_SPEC 10 -#define MEM_LINE_SPEC static_cast(MEM_WORD_SPEC - LINE_SPEC) -#define MEM_WORDS static_cast(pow(2, MEM_WORD_SPEC)) -#define MEM_LINES static_cast(pow(2, MEM_LINE_SPEC)) - -/** - * The number of bits to specify a l1 cache word - * The number of bits to specify a l1 cache line - * The total number of lines in l1 cache - */ -#define L1_CACHE_WORD_SPEC 7 -#define L1_CACHE_LINE_SPEC \ - static_cast(L1_CACHE_WORD_SPEC - LINE_SPEC) -#define L1_CACHE_LINES static_cast(pow(2, L1_CACHE_LINE_SPEC)) - -/** - * The total number of cycles a memory access takes - */ -#define MEM_DELAY 3 - -/** - * The total number of cycles a level one cache access takes - */ -#define L1_CACHE_DELAY 0 - -/** - * The number of general purpose registers - */ -#define GPR_NUM 16 - -/** - * The number of vector registers - */ -#define V_NUM 8 - -/** - * The number of bits to specify an instruction type - */ -#define TYPE_SIZE 2 - -/** - * The number of bits to specify a register - */ -#define REG_SIZE 5 - -/** - * The number of bits to specify an R-Type opcode. - */ -#define R_OPCODE_SIZE 5 - -/** - * The number of bits to specify an opcode. - */ -#define OPCODE_SIZE 4 - -/** - * The maximum value an integer can hold. - * The minimum is always this number plus one negated. - */ -#define MAX_INT 2147483647 - -/** - * 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/stage.h b/inc/stage.h index 51ab667..da33075 100644 --- a/inc/stage.h +++ b/inc/stage.h @@ -1,8 +1,8 @@ #ifndef STAGE_H #define STAGE_H #include "accessor.h" -#include "definitions.h" #include "instrDTO.h" +#include "pipe_spec.h" #include "response.h" #include "storage.h" #include diff --git a/inc/utils.h b/inc/utils.h deleted file mode 100644 index a375b68..0000000 --- a/inc/utils.h +++ /dev/null @@ -1,39 +0,0 @@ -#ifndef UTILS_H -#define UTILS_H -#include - -/** - * 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_cache_fields(int address, int *tag, int *index, int *offset); - -/** - * Formats a string using snprintf. - * @param an object that represents the format string - * @param arguments to be formatted - * @return a string object holding the formatted result - */ -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/sim/ex.cc b/src/sim/ex.cc index b6f8a1d..50f00a8 100644 --- a/src/sim/ex.cc +++ b/src/sim/ex.cc @@ -1,6 +1,6 @@ #include "ex.h" #include "accessor.h" -#include "definitions.h" +#include "pipe_spec.h" #include "instrDTO.h" #include "response.h" #include "stage.h" diff --git a/src/utils/utils.cc b/src/utils/utils.cc deleted file mode 100644 index e12a0e0..0000000 --- a/src/utils/utils.cc +++ /dev/null @@ -1,42 +0,0 @@ -#include "utils.h" -#include "definitions.h" -#include -#include -#include - -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 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; -} diff --git a/tests/utils.cc b/tests/utils.cc deleted file mode 100644 index 2e0e934..0000000 --- a/tests/utils.cc +++ /dev/null @@ -1,65 +0,0 @@ -#include "utils.h" -#include "definitions.h" -#include - -TEST_CASE("Parse arbitrary fields # one", "[utils]") -{ - int tag, index, offset; - int address = 0b0001010101; - get_cache_fields(address, &tag, &index, &offset); - CHECK(tag == 0b000); - CHECK(index == 0b10101); - CHECK(offset == 0b01); -} - -TEST_CASE("Parse arbitrary fields # two", "[utils]") -{ - int tag, index, offset; - int address = 0b0100111011; - get_cache_fields(address, &tag, &index, &offset); - CHECK(tag == 0b010); - CHECK(index == 0b01110); - CHECK(offset == 0b11); -} - -TEST_CASE("wrap address outside upper bound", "[utils]") -{ - int address = MEM_WORDS + 25; - int wrapped = wrap_address(address); - REQUIRE(wrapped == 25); -} - -TEST_CASE("wrap address inside upper bound", "[utils]") -{ - int address = MEM_WORDS - 25; - int wrapped = wrap_address(address); - REQUIRE(wrapped == MEM_WORDS - 25); -} - -TEST_CASE("wrap address at upper bound", "[utils]") -{ - int address = MEM_WORDS; - int wrapped = wrap_address(address); - REQUIRE(wrapped == 0); -} - -TEST_CASE("wrap address lower than 0 with magnitude lesser than mem size", "[utils]") -{ - int address = -10; - int wrapped = wrap_address(address); - REQUIRE(wrapped == MEM_WORDS - 10); -} - -TEST_CASE("wrap address lower than 0 but with magnitude greater than mem size", "[utils]") -{ - int address = -(MEM_WORDS + 10); - int wrapped = wrap_address(address); - REQUIRE(wrapped == MEM_WORDS - 10); -} - -TEST_CASE("wrap address at 0", "[utils]") -{ - int address = 0; - int wrapped = wrap_address(address); - REQUIRE(wrapped == 0); -} -- cgit v1.2.3