diff options
-rw-r--r-- | .clang-format | 3 | ||||
-rw-r--r-- | CMakeLists.txt | 33 | ||||
-rw-r--r-- | inc/definitions.h | 61 | ||||
-rw-r--r-- | inc/dram.h | 7 | ||||
-rw-r--r-- | inc/utils.h | 39 | ||||
-rw-r--r-- | src/cache.cc | 5 | ||||
-rw-r--r-- | src/dram.cc | 8 | ||||
-rw-r--r-- | src/utils.cc | 42 | ||||
-rw-r--r-- | tests/utils.cc | 65 |
9 files changed, 57 insertions, 206 deletions
diff --git a/.clang-format b/.clang-format index 39ed432..30fe2e7 100644 --- a/.clang-format +++ b/.clang-format @@ -1,11 +1,12 @@ --- Language: Cpp +AlwaysBreakAfterDefinitionReturnType: All AlignAfterOpenBracket: AlwaysBreak AllowAllParametersOfDeclarationOnNextLine: true BinPackParameters: false BreakBeforeBraces: Linux PointerAlignment: Right -ColumnLimit: 80 +ColumnLimit: 100 IndentWidth: 4 TabWidth: 4 UseTab: Always
\ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index f8ec7be..661e45c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,8 @@ cmake_minimum_required(VERSION 3.5) -set(CMAKE_CXX_COMPILER "g++") project(ram) +option(RAM_TESTS "Enable creation of a memory-subsystem test binary." ON) + set(CMAKE_EXPORT_COMPILE_COMMANDS ON) add_compile_options(-Wall -lstdc++ -g -O0) @@ -11,28 +12,26 @@ add_compile_options(-Wextra -Wpedantic) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) -# header files -include_directories( - ${PROJECT_SOURCE_DIR}/inc -) - # gather source files file(GLOB_RECURSE SRCS "src/*.cc") # binary executable add_library(${PROJECT_NAME}_lib ${SRCS}) -target_link_libraries(${PROJECT_NAME}_lib) +target_include_directories(${PROJECT_NAME}_lib PUBLIC ${PROJECT_SOURCE_DIR}/inc) -find_package(Catch2 REQUIRED) +if(RAM_TESTS) + find_package(Catch2 REQUIRED) -#gather test files -file(GLOB_RECURSE TESTS "tests/*.cc") + #gather test files + file(GLOB_RECURSE TESTS "tests/*.cc") -# test executable -add_executable(tests ${SRCS} ${TESTS}) -target_link_libraries(tests PRIVATE Catch2::Catch2WithMain PRIVATE) + # test executable + add_executable(tests ${SRCS} ${TESTS}) + target_include_directories(tests PUBLIC ${PROJECT_SOURCE_DIR}/inc) + target_link_libraries(tests PRIVATE Catch2::Catch2WithMain PRIVATE) -# test discovery -include(CTest) -include(Catch) -catch_discover_tests(tests) + # test discovery + include(CTest) + include(Catch) + catch_discover_tests(tests) +endif() diff --git a/inc/definitions.h b/inc/definitions.h index 6fa29ee..94414a4 100644 --- a/inc/definitions.h +++ b/inc/definitions.h @@ -31,8 +31,7 @@ * The total number of lines in l1 cache */ #define L1_CACHE_WORD_SPEC 7 -#define L1_CACHE_LINE_SPEC \ - static_cast<unsigned int>(L1_CACHE_WORD_SPEC - LINE_SPEC) +#define L1_CACHE_LINE_SPEC static_cast<unsigned int>(L1_CACHE_WORD_SPEC - LINE_SPEC) #define L1_CACHE_LINES static_cast<int>(pow(2, L1_CACHE_LINE_SPEC)) /** @@ -46,42 +45,6 @@ #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 @@ -98,4 +61,26 @@ */ #define GET_MID_BITS(k, m, n) GET_LS_BITS((k) >> (m), ((n) - (m))) +/** + * 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 + */ +// clang-format off +#define GET_FIELDS(a, t, i, o) \ + *(t) = GET_MID_BITS(a, L1_CACHE_LINE_SPEC + LINE_SPEC, MEM_WORD_SPEC); \ + *(i) = GET_MID_BITS(a, LINE_SPEC, L1_CACHE_LINE_SPEC + LINE_SPEC); \ + *(o) = GET_LS_BITS(a, LINE_SPEC); \ + +/** + * Ensures address is within the current memory size using a clean wrap. + * @param an address + */ +#define WRAP_ADDRESS(a) \ + ((a < 0) ? ((a % MEM_WORDS) + MEM_WORDS) % MEM_WORDS : a % MEM_WORDS) \ +// clang-format on + #endif /* DEFINITIONS_H_INCLUDED */ @@ -52,6 +52,13 @@ class Dram : public Storage */ int is_access_cleared(void *id); + /** + * 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 /* DRAM_H_INCLUDED */ 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 <string> - -/** - * 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/cache.cc b/src/cache.cc index bbb90b4..acbabcf 100644 --- a/src/cache.cc +++ b/src/cache.cc @@ -1,6 +1,5 @@ #include "cache.h" #include "definitions.h" -#include "utils.h" #include <bits/stdc++.h> #include <iterator> @@ -60,7 +59,7 @@ Cache::process(void *id, int address, std::function<void(int index, int offset)> r = this->is_access_cleared(id, address); if (r) { int tag, index, offset; - get_cache_fields(address, &tag, &index, &offset); + GET_FIELDS(address, &tag, &index, &offset); request_handler(index, offset); } return r; @@ -95,7 +94,7 @@ Cache::is_address_missing(int expected) std::array<signed int, LINE_SIZE> *actual; std::array<int, 2> *meta; - get_cache_fields(expected, &tag, &index, &offset); + GET_FIELDS(expected, &tag, &index, &offset); r = 0; meta = &this->meta.at(index); actual = &this->data->at(index); diff --git a/src/dram.cc b/src/dram.cc index d81e2d2..2fd8a91 100644 --- a/src/dram.cc +++ b/src/dram.cc @@ -4,7 +4,6 @@ #include <bits/stdc++.h> #include <bitset> #include <iterator> -#include <utils.h> Dram::Dram(int delay) : Storage(delay) { this->data->resize(MEM_LINES); } @@ -85,3 +84,10 @@ Dram::is_access_cleared(void *id) } return 0; } + +void +Dram::get_memory_index(int address, int &line, int &word) +{ + line = WRAP_ADDRESS(address) / LINE_SIZE; + word = address % LINE_SIZE; +} diff --git a/src/utils.cc b/src/utils.cc deleted file mode 100644 index e12a0e0..0000000 --- a/src/utils.cc +++ /dev/null @@ -1,42 +0,0 @@ -#include "utils.h" -#include "definitions.h" -#include <cstdarg> -#include <string> -#include <vector> - -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<char> 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 <catch2/catch_test_macros.hpp> - -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); -} |