diff options
author | bd <bdunahu@operationnull.com> | 2025-03-11 00:09:12 -0400 |
---|---|---|
committer | bd <bdunahu@operationnull.com> | 2025-03-11 00:09:12 -0400 |
commit | f34156105801c81677c54d1713104ac3d7c1c112 (patch) | |
tree | a37a0e14ec5cef442d979852876dd307c6d4bf22 | |
parent | 17dfdb2e00b609e3c7e975ce7a7c19da43318b79 (diff) |
cli display clock cycle, parse ';' delimited commands
-rw-r--r-- | CMakeLists.txt | 3 | ||||
-rw-r--r-- | inc/cli.h | 28 | ||||
-rw-r--r-- | inc/definitions.h | 6 | ||||
-rw-r--r-- | inc/utils.h | 9 | ||||
-rw-r--r-- | src/cli/cli.cc | 139 | ||||
-rw-r--r-- | src/main.cc | 5 | ||||
-rw-r--r-- | src/storage/cache.cc | 1 | ||||
-rw-r--r-- | src/storage/dram.cc | 1 | ||||
-rw-r--r-- | src/utils/utils.cc | 25 |
9 files changed, 139 insertions, 78 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 17ec29f..6a48922 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,6 +3,9 @@ project(risc_vector) set(CMAKE_EXPORT_COMPILE_COMMANDS ON) +add_compile_options(-Wall -lstdc++) +add_compile_options(-Wextra -Wpedantic) + # cpp standard set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) @@ -25,13 +25,14 @@ class Cli * @param memory_address address of the memory where data needs to be loaded * from */ - void load(int memory_address); + 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); @@ -43,15 +44,6 @@ class Cli void reset(); /** - * Updates the memory at the specified address with the given data. - * This function provides a side door modification interface to the memory - * system, allowing the user to modify the memory configuration directly. - * @param memory_address address of the memory to be updated - * @param data data value to be written to the memory - */ - void update(int memory_address, int data); - - /** * Advance the clock one cycle, refreshing the storage devices. */ void clock(); @@ -79,17 +71,27 @@ class Cli * 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< - std::string, - std::function<void(std::vector<std::string>)>> + 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 62ed0f6..f015ce9 100644 --- a/inc/definitions.h +++ b/inc/definitions.h @@ -10,7 +10,7 @@ /** * The total number of words in a line */ -#define LINE_SIZE (int)pow(2, 2) +#define LINE_SIZE static_cast<int>(pow(2, 2)) /** * The number of bits to specify a memory line @@ -20,7 +20,7 @@ /** * The total number of words in memory */ -#define MEM_SIZE (int)pow(2, MEM_SPEC) +#define MEM_SIZE static_cast<int>(pow(2, MEM_SPEC)) /** * The number of bits to specify a l1 cache line @@ -29,7 +29,7 @@ /** * The total number of words in l1 cache */ -#define L1_CACHE_SIZE (int)pow(2, L1_CACHE_SPEC) +#define L1_CACHE_SIZE static_cast<int>(pow(2, L1_CACHE_SPEC)) /** * The total number of cycles a memory access takes. diff --git a/inc/utils.h b/inc/utils.h index e258ed8..71e515b 100644 --- a/inc/utils.h +++ b/inc/utils.h @@ -1,5 +1,6 @@ #ifndef UTILS_H #define UTILS_H +#include <string> /** * Parse an address into a tag, index into the cache table, and a line @@ -11,4 +12,12 @@ */ void get_bit_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, ...); + #endif /* UTILS_H_INCLUDED */ diff --git a/src/cli/cli.cc b/src/cli/cli.cc index 272c246..033849e 100644 --- a/src/cli/cli.cc +++ b/src/cli/cli.cc @@ -3,17 +3,21 @@ #include "definitions.h" #include "dram.h" #include "response.h" -#include <stdio.h> +#include "utils.h" +#include <iostream> Cli::Cli() { this->cache = nullptr; + this->cycle = 0; this->initialize(); - commands["l"] = [this](std::vector<std::string> args) { - if (args.size() >= 1) { + commands['l'] = [this](std::vector<std::string> args) { + Accessor a; + if (args.size() >= 2) { try { - load(std::stoi(args[0])); + 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; } @@ -23,16 +27,11 @@ Cli::Cli() return; }; - commands["s"] = [this](std::vector<std::string> args) { + commands['s'] = [this](std::vector<std::string> args) { Accessor a; if (args.size() >= 3) { try { - if (tolower(args[0][0]) == 'f') - a = FETCH; - else if (tolower(args[0][0]) == 'm') - a = MEM; - else - throw std::invalid_argument(args[0]); + 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; @@ -43,12 +42,12 @@ Cli::Cli() return; }; - commands["r"] = [this](std::vector<std::string> args) { + commands['r'] = [this](std::vector<std::string> args) { reset(); return; }; - commands["p"] = [this](std::vector<std::string> args) { + commands['p'] = [this](std::vector<std::string> args) { if (args.size() >= 1) { try { peek(std::stoi(args[0])); @@ -61,12 +60,12 @@ Cli::Cli() return; }; - commands["c"] = [this](std::vector<std::string> args) { + commands['c'] = [this](std::vector<std::string> args) { clock(); return; }; - commands["h"] = [this](std::vector<std::string> args) { + commands['h'] = [this](std::vector<std::string> args) { help(); return; }; @@ -77,23 +76,29 @@ Cli::~Cli() { delete this->cache; } void Cli::help() { std::cout - << "Available commands:\n" - << " l <address> - Load data from memory at the specified " - "address\n" - << " s <accessor> <data> <address> - Stores data into memory at " - "specified address. Accessor must be one of: \"MEM\", \"FETCH\", " - "\"L1CACHE\".\n" - << " c - manually advances the clock\n" - << " f - advances the clock until one operation reports completion\n" - << " r - side door function that resets the memory configuration and " - "cycles\n" - << " p <storage-level> <base> <lines> - side door function that peeks " - "the current status of the entire memory subsystem\n" - << " h - Prints this help text\n" - << " q - Quits the program\n"; + << "Available commands:" << std::endl + << " [l]oad <address> - Load data from memory at the specified " + "address" + << std::endl + << " [s]tore <accessor> <data> <address> - Stores data into memory at " + "specified address. Acessor must be one of: [f]etch, [m]em" + << std::endl + << " [c]ycle - manually advances the clock" << std::endl + << " [f]orce - advances the clock until one operation reports " + "completion" + << std::endl + << " [r]eset - side door function that resets the memory " + "configuration and " + "cycles" + << std::endl + << " [p]eek <storage-level> <base> <lines> - side door function that " + "peeks the current status of the entire memory subsystem" + << std::endl + << " [h]elp - Prints this help text" << std::endl + << " [q]uit - Quits the program" << std::endl; } -void Cli::load(int memory_address) { ; } +void Cli::load(Accessor accessor, int address) { ; } void Cli::store(Accessor accessor, int data, int address) { @@ -101,12 +106,11 @@ void Cli::store(Accessor accessor, int data, int address) std::cout << r << " to " << accessor << " storing " << data << '\n'; } -void Cli::update(int memory_address, int data) +void Cli::clock() { - std::cout << "Resetting memory configuration and cycles.\n"; -}; - -void Cli::clock() { this->cache->resolve(); } + this->cache->resolve(); + ++this->cycle; +} void Cli::reset() { @@ -140,33 +144,42 @@ void Cli::run() "commands.\n"; std::string input; - while (true) { - std::cout << "> "; + bool run = true; + while (run) { + std::cout << this->cycle << "> "; std::getline(std::cin, input); - std::istringstream iss(input); - std::vector<std::string> tokens; + std::istringstream iss1(input); + std::vector<std::string> words; + std::string sentence; std::string word; - while (iss >> word) - tokens.push_back(word); - if (tokens.empty()) - continue; + while (std::getline(iss1, sentence, ';')) { + words.clear(); + std::istringstream iss2(sentence); - std::string command = tokens[0]; - tokens.erase(tokens.begin()); + while (iss2 >> word) { + words.push_back(word); + } + if (words.empty()) + continue; - if (command == "q") { - std::cout << "Exiting...\n"; - break; - } + std::string command = words[0]; + words.erase(words.begin()); - auto it = commands.find(command); - if (it != commands.end()) { - it->second(tokens); - } else { - std::cout << "Unknown command: '" << command - << "'. Type 'help' for available commands.\n"; + 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; + } } } } @@ -174,9 +187,23 @@ void Cli::run() void Cli::initialize() { Logger *global_log = Logger::getInstance(); - global_log->log(INFO, "Resetting memory configuration."); + + global_log->log(INFO, "Resetting memory configuration and cycle."); + if (this->cache != nullptr) delete this->cache; + Dram *d = new Dram(MEM_SIZE, MEM_DELAY); this->cache = new Cache(d, L1_CACHE_DELAY); + this->cycle = 1; +} + +Accessor 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/main.cc b/src/main.cc index f2f416d..1259729 100644 --- a/src/main.cc +++ b/src/main.cc @@ -21,7 +21,7 @@ static std::string banner = "_/ _/ _/ _/_/_/ _/ _/ _/ _/ _/_/_/ _/ \n" " _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ \n" " _/ _/ _/_/_/_/ _/_/_/ _/ _/_/ _/ _/ _/ \n" - " _/_/ _/_/ \n"; + " _/_/ _/_/ "; static void print_version_number() { std::cout << banner << version_number << '\n'; } static void err() @@ -79,5 +79,8 @@ int main(int argc, char **argv) } cli.run(); + + global_log->log(INFO, "Cleaning up..."); + global_log->log(INFO, "Goodbye!"); return EXIT_SUCCESS; } diff --git a/src/storage/cache.cc b/src/storage/cache.cc index 6dd0b8a..d382c3d 100644 --- a/src/storage/cache.cc +++ b/src/storage/cache.cc @@ -100,7 +100,6 @@ std::ostream &operator<<(std::ostream &os, const Cache &c) c.view(0, L1_CACHE_SIZE); std::array<std::array<int, 2>, L1_CACHE_SIZE> meta = c.get_meta(); - cout << data.capacity(); os << " " << std::setfill(' ') << std::setw(L1_CACHE_SPEC + 2) << "INDEX" << " | " << std::setfill(' ') << std::setw((8 + 3) * 4 - 1) << "DATA" << " | " << std::setfill(' ') diff --git a/src/storage/dram.cc b/src/storage/dram.cc index 5c6d719..7353bce 100644 --- a/src/storage/dram.cc +++ b/src/storage/dram.cc @@ -83,7 +83,6 @@ std::ostream &operator<<(std::ostream &os, const Dram &d) std::vector<std::array<signed int, LINE_SIZE>> data = d.view(0, MEM_SIZE); - cout << data.capacity(); os << " " << std::setfill(' ') << std::setw(MEM_SPEC + 2) << "INDEX" << " | " << std::setfill(' ') << std::setw((8 + 3) * 4 - 1) << "DATA" << '\n'; for (int i = 0; i < MEM_SIZE; ++i) { diff --git a/src/utils/utils.cc b/src/utils/utils.cc index dfeb2b3..5de8e89 100644 --- a/src/utils/utils.cc +++ b/src/utils/utils.cc @@ -1,11 +1,30 @@ #include "utils.h" #include "definitions.h" +#include <cstdarg> +#include <string> +#include <vector> 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); + *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); } + +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<char> zc(iLen + 1); + std::vsnprintf(zc.data(), zc.size(), zcFormat, vaArgs); + va_end(vaArgs); + return std::string(zc.data(), iLen); +} |