diff options
Diffstat (limited to 'inc')
-rw-r--r-- | inc/controller.h | 6 | ||||
-rw-r--r-- | inc/ex.h | 12 | ||||
-rw-r--r-- | inc/id.h | 14 | ||||
-rw-r--r-- | inc/instrDTO.h | 12 | ||||
-rw-r--r-- | inc/pipe_spec.h | 2 | ||||
-rw-r--r-- | inc/stage.h | 40 |
6 files changed, 67 insertions, 19 deletions
diff --git a/inc/controller.h b/inc/controller.h index b7fa835..cd59fc8 100644 --- a/inc/controller.h +++ b/inc/controller.h @@ -49,7 +49,11 @@ class Controller : public Stage /** * @return a copy of gprs. */ - std::array<int, GPR_NUM> get_gprs(); + std::array<signed int, GPR_NUM> get_gprs(); + /** + * @return a copy of vrs. + */ + std::array<std::array<signed int, V_R_LIMIT>, V_NUM> get_vrs(); /** * @return the pc. */ @@ -63,7 +63,7 @@ class EX : public Stage * @param The next stage in the pipeline. * @return A newly allocated EX object. */ - EX(Stage *next); + using Stage::Stage; using Stage::advance; private: @@ -76,16 +76,6 @@ class EX : public Stage * @param if the modulo operator should instead be used */ void handle_divide(signed int &s1, signed int s2, bool is_mod); - /** - * Maps each mnemonic to a function which carries out the instruction's base - * logic. - * All instructions store the result into s1. - */ - std::unordered_map< - Mnemonic, - std::function<void( - signed int &s1, signed int s2, signed int s3, unsigned int pc)>> - instr_map; }; #endif /* EX_H_INCLUDED */ @@ -50,6 +50,12 @@ class ID : public Stage */ void write_guard(signed int &r); + Response read_vec_guard(signed int r, std::array<signed int, V_R_LIMIT> &v); + + void write_vec_guard(signed int r, std::array<signed int, V_R_LIMIT> &v); + + Response set_vlen(); + private: /** * Helper for `get_instr_fields` @@ -76,10 +82,10 @@ class ID : public Stage * @param the resulting third field, which varies per type. * @param the resulting mnemonic. */ - void get_instr_fields(signed int &s1, signed int &s2, signed int &s3, Mnemonic &m); - void decode_R_type(signed int &s1, signed int &s2, signed int &s3, Mnemonic &m); - void decode_I_type(signed int &s1, signed int &s2, signed int &s3, Mnemonic &m); - void decode_J_type(signed int &s1, signed int &s2, signed int &s3, Mnemonic &m); + void get_instr_fields(signed int &s1); + void decode_R_type(signed int &s1); + void decode_I_type(signed int &s1); + void decode_J_type(signed int &s1); /** * Helper for `get_instr_fields`. * Given a raw instruction, returns the mnemonic and type. diff --git a/inc/instrDTO.h b/inc/instrDTO.h index 1402526..f3d4597 100644 --- a/inc/instrDTO.h +++ b/inc/instrDTO.h @@ -18,6 +18,8 @@ #ifndef INSTRDTO_H #define INSTRDTO_H #include "instr.h" +#include "pipe_spec.h" +#include<array> struct U_INT_TYPE { signed int slot_one; @@ -26,6 +28,15 @@ struct U_INT_TYPE { }; struct V_TYPE { + std::array<signed int, V_R_LIMIT> slot_one; + std::array<signed int, V_R_LIMIT> slot_two; + std::array<signed int, V_R_LIMIT> slot_three; +}; + +struct LOAD_STORE_V_TYPE{ + signed int base_addr; + signed int immediate; + std::array<signed int, V_R_LIMIT> vector_register; }; struct InstrDTO { @@ -52,6 +63,7 @@ struct InstrDTO { union { struct U_INT_TYPE integer; struct V_TYPE vector; + struct LOAD_STORE_V_TYPE load_store_vector; } operands; }; diff --git a/inc/pipe_spec.h b/inc/pipe_spec.h index 7d65637..d8153af 100644 --- a/inc/pipe_spec.h +++ b/inc/pipe_spec.h @@ -80,6 +80,8 @@ */ #define CACHE_DELAY 1 +#define VECTOR_MEM_DELAY 10 + /** * Return the N least-significant bits from integer K using a bit mask * @param the integer to be parsed diff --git a/inc/stage.h b/inc/stage.h index 16f1235..4e0c252 100644 --- a/inc/stage.h +++ b/inc/stage.h @@ -83,6 +83,10 @@ class Stage */ static std::deque<signed int> checked_out; + bool is_vector_type(Mnemonic m); + + bool is_logical(Mnemonic m); + protected: /** * The function expected to do the majority of the work. @@ -104,13 +108,43 @@ class Stage * @param the register number. * @param the value to store. */ - void store_register(signed int v, signed int d); + template <typename T> + void store_register(signed int v, T d) + { + if constexpr (std::is_same_v<T, signed int>) { + if (v < 0 || v >= GPR_NUM) { + throw std::out_of_range("Invalid GPR index for storing scalar"); + } + gprs[v] = d; + } + else if constexpr (std::is_same_v<T, std::array<signed int, V_R_LIMIT>>) { + if (v < GPR_NUM || v >= GPR_NUM + V_NUM) { + throw std::out_of_range("Invalid VR index for storing vector"); + } + vrs[v % GPR_NUM] = d; + } + } /** * Returns the value of the register corresponding to `v`. * @param the register number. * @return the value in the associated register. */ - signed int dereference_register(signed int v); + template <typename T> + T dereference_register(signed int v) + { + if constexpr (std::is_same_v<T, signed int>) { + if (v < 0 || v >= GPR_NUM) { + throw std::out_of_range("Invalid GPR index"); + } + return gprs[v]; + } + else if constexpr (std::is_same_v<T, std::array<signed int, V_R_LIMIT>>) { + if (v < GPR_NUM || v >= GPR_NUM + V_NUM) { + throw std::out_of_range("Invalid vector register index"); + } + return vrs[v % GPR_NUM]; + } + } /** * The shared pool of general-purpose integer registers. */ @@ -118,7 +152,7 @@ class Stage /** * The shared pool of general-purpose vector registers. */ - static std::array<signed int, V_NUM> vrs; + static std::array<std::array<signed int, V_R_LIMIT>, V_NUM> vrs; /** * The address of the currently executing instruction. */ |