diff options
| -rw-r--r-- | inc/cache.h | 14 | ||||
| -rw-r--r-- | inc/definitions.h | 44 | ||||
| -rw-r--r-- | inc/utils.h | 14 | ||||
| -rw-r--r-- | src/storage/cache.cc | 20 | ||||
| -rw-r--r-- | src/utils/utils.cc | 11 | ||||
| -rw-r--r-- | tests/utils.cc | 23 | 
6 files changed, 120 insertions, 6 deletions
| diff --git a/inc/cache.h b/inc/cache.h index d470e6c..d9d8ba7 100644 --- a/inc/cache.h +++ b/inc/cache.h @@ -1,6 +1,9 @@  #ifndef CACHE_H  #define CACHE_H -#include <storage.h> +#include "definitions.h" +#include "storage.h" +#include <array> +#include <bitset>  class Cache : public Storage  { @@ -19,6 +22,15 @@ class Cache : public Storage  	Response write(Accessor accessor, signed int data, int address) override;  	Response read(Accessor accessor, int address, std::array<signed int, LINE_SIZE>& data) override; + +  private: +	/** +	 * An array of paired bits. +	 * If the least significant bit of an element is set, the corresponding +	 * element in `data` is invalid. If the most significant bit of an element +	 * is set, the corresponding element in `data` is dirty. +	 */ +	std::array<std::bitset<2>, L1_CACHE_SIZE> stat;  };  #endif /* CACHE_H_INCLUDED */ diff --git a/inc/definitions.h b/inc/definitions.h index 1593162..877065e 100644 --- a/inc/definitions.h +++ b/inc/definitions.h @@ -1,10 +1,50 @@  #ifndef DEFINITIONS_H  #define DEFINITIONS_H +#include <cmath>  /** - * Defines common macros. + * 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 (int)pow(2, 2) + +/** + * The number of bits to specify a memory line + * calculated as: (/ (expt 2 15) 4) + */ +#define MEM_SPEC 13 +/** + * The total number of words in memory + */ +#define MEM_SIZE (int)pow(2, MEM_SPEC) + +/** + * The number of bits to specify a l1 cache line + */ +#define L1_CACHE_SPEC 5 +/** + * The total number of words in l1 cache + */ +#define L1_CACHE_SIZE (int)pow(2, L1_CACHE_SPEC) -#define LINE_SIZE 4 +/** + * 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/utils.h b/inc/utils.h new file mode 100644 index 0000000..e258ed8 --- /dev/null +++ b/inc/utils.h @@ -0,0 +1,14 @@ +#ifndef UTILS_H +#define UTILS_H + +/** + * 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_bit_fields(int address, int *tag, int *index, int *offset); + +#endif /* UTILS_H_INCLUDED */ diff --git a/src/storage/cache.cc b/src/storage/cache.cc index 67cedda..cf954b0 100644 --- a/src/storage/cache.cc +++ b/src/storage/cache.cc @@ -6,17 +6,31 @@  Cache::Cache(int lines, Storage *lower, int delay)  {  	this->data = new std::vector<std::array<signed int, LINE_SIZE>>; -	this->data->resize(lines); +	this->data->resize(L1_CACHE_SIZE);  	this->lower = lower;  	this->delay = delay; -	this->lower = nullptr; +	for (int i = 0; i < L1_CACHE_SIZE; ++i) +		this->stat[i] = 0b01;  }  Cache::~Cache() { delete this->data; }  Response Cache::write(Accessor accessor, signed int data, int address)  { -	return WAIT; +	Response r = WAIT; + +	/* Do this first--then process the first cycle immediately. */ +	if (this->requester == IDLE) +		this->requester = accessor; + +	if (this->requester == accessor) { +		if (this->wait_time == 0) { +			this->do_write(data, address); +			r = OK; +		} +	} + +	return r;  }  Response Cache::read(Accessor accessor, int address, std::array<signed int, LINE_SIZE>& data) { return WAIT; } diff --git a/src/utils/utils.cc b/src/utils/utils.cc new file mode 100644 index 0000000..dfeb2b3 --- /dev/null +++ b/src/utils/utils.cc @@ -0,0 +1,11 @@ +#include "utils.h" +#include "definitions.h" + +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); +	*index = GET_MID_BITS(address, LINE_SPEC, L1_CACHE_SPEC + LINE_SPEC); +	*offset = GET_LS_BITS(address, LINE_SPEC); +} diff --git a/tests/utils.cc b/tests/utils.cc new file mode 100644 index 0000000..5368204 --- /dev/null +++ b/tests/utils.cc @@ -0,0 +1,23 @@ +#include "utils.h" +#include "definitions.h" +#include <catch2/catch_test_macros.hpp> + +TEST_CASE("Parse arbitrary fields # one", "[cache]") +{ +	int tag, index, offset; +	int address = 0b111110001010101; +	get_bit_fields(address, &tag, &index, &offset); +	CHECK(tag == 0b11111000); +	CHECK(index == 0b10101); +	CHECK(offset == 0b01); +} + +TEST_CASE("Parse arbitrary fields # two", "[cache]") +{ +	int tag, index, offset; +	int address = 0b000110100111011; +	get_bit_fields(address, &tag, &index, &offset); +	CHECK(tag == 0b00011010); +	CHECK(index == 0b01110); +	CHECK(offset == 0b11); +} | 
