From f4a5db14436ddbb2820c0abefcb34e5482105a12 Mon Sep 17 00:00:00 2001 From: bd Date: Thu, 8 May 2025 19:44:23 -0400 Subject: Move is_logical_type and is_vector_type to instr.h --- src/wb.cc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src/wb.cc') diff --git a/src/wb.cc b/src/wb.cc index 0dae5f2..12f4edf 100644 --- a/src/wb.cc +++ b/src/wb.cc @@ -18,6 +18,7 @@ #include "wb.h" #include "instrDTO.h" #include "response.h" +#include "instr.h" #include "stage.h" #include #include @@ -51,8 +52,8 @@ void WB::write_handler() this->checked_out.pop_front(); reg = this->curr_instr->checked_out; - - if(this->is_vector_type(this->curr_instr->mnemonic)) { + + if(instr::is_vector_type(this->curr_instr->mnemonic)) { if(this->curr_instr->mnemonic != STOREV && this->curr_instr->mnemonic != LOADV) { this->store_register>(reg, this->curr_instr->operands.vector.slot_one); } else { -- cgit v1.2.3 From ebb2a3d33d4536bcace34e9ba95198067ae19522 Mon Sep 17 00:00:00 2001 From: bd Date: Sat, 10 May 2025 18:25:23 -0400 Subject: Add type field to InstrDTO, required for next refactor --- inc/instr.h | 13 +++++++++++-- inc/instrDTO.h | 4 ++++ src/ex.cc | 28 ++++++++++++++++++---------- src/id.cc | 13 +++++++------ src/instr.cc | 20 ++++++++------------ src/wb.cc | 2 +- 6 files changed, 49 insertions(+), 31 deletions(-) (limited to 'src/wb.cc') diff --git a/inc/instr.h b/inc/instr.h index c4f5e37..0c49a79 100644 --- a/inc/instr.h +++ b/inc/instr.h @@ -61,11 +61,20 @@ enum Mnemonic { NOP, }; +enum FieldType { + SI_INT, + R_VECT, + I_VECT, +}; + namespace instr { extern const std::unordered_map mnemonic_map; -bool is_vector_type(Mnemonic m); -bool is_logical_type(Mnemonic m); +/** + * @param a mnemonic + * @return an enum representing the types of the decoded instruction fields. + */ +FieldType get_field_types(Mnemonic m); } // namespace instr #endif /* INSTR_H_INCLUDED */ diff --git a/inc/instrDTO.h b/inc/instrDTO.h index f4ef416..98247a3 100644 --- a/inc/instrDTO.h +++ b/inc/instrDTO.h @@ -60,6 +60,10 @@ struct InstrDTO { * The register this instruction checks out. */ signed int checked_out; + /** + * The currently active union member. + */ + FieldType type; union { struct U_INT_TYPE integer; struct V_TYPE vector; diff --git a/src/ex.cc b/src/ex.cc index 73ed615..45a018a 100644 --- a/src/ex.cc +++ b/src/ex.cc @@ -36,11 +36,11 @@ void EX::advance_helper() v1 = {0}, v2 = {0}, v3 = {0}; v_len = 0, v_immediate = 0, v_base_addr = 0; m = this->curr_instr->mnemonic; + v_len = this->curr_instr->slot_B; pc = this->curr_instr->slot_B; - if (instr::is_vector_type(m)) { - if (this->curr_instr->mnemonic != LOADV && - this->curr_instr->mnemonic != STOREV) { + if (this->curr_instr->type != SI_INT) { + if (this->curr_instr->type == R_VECT) { v1 = this->curr_instr->operands.vector.slot_one; v2 = this->curr_instr->operands.vector.slot_two; v3 = this->curr_instr->operands.vector.slot_three; @@ -50,7 +50,6 @@ void EX::advance_helper() v_base_addr = this->curr_instr->operands.load_store_vector.base_addr; } - v_len = this->curr_instr->slot_B; if (v_len == 0) { // clear destination vector reg v1.fill(0); @@ -61,11 +60,6 @@ void EX::advance_helper() s3 = this->curr_instr->operands.integer.slot_three; } - if (instr::is_logical_type(m)) { - this->set_condition(OF, false); - this->set_condition(UF, false); - } - switch (m) { case ADD: this->set_condition(OF, ADDITION_OF_GUARD(s1, s2)); @@ -102,18 +96,26 @@ void EX::advance_helper() break; case AND: + this->set_condition(OF, false); + this->set_condition(UF, false); s1 = s1 & s2; break; case OR: + this->set_condition(OF, false); + this->set_condition(UF, false); s1 = s1 | s2; break; case XOR: + this->set_condition(OF, false); + this->set_condition(UF, false); s1 = s1 ^ s2; break; case NOT: + this->set_condition(OF, false); + this->set_condition(UF, false); s1 = ~s1; break; @@ -145,14 +147,20 @@ void EX::advance_helper() break; case ANDI: + this->set_condition(OF, false); + this->set_condition(UF, false); s1 = s1 & s3; break; case ORI: + this->set_condition(OF, false); + this->set_condition(UF, false); s1 = s1 | s3; break; case XORI: + this->set_condition(OF, false); + this->set_condition(UF, false); s1 = s1 ^ s3; break; @@ -236,7 +244,7 @@ void EX::advance_helper() case NOP: break; } - if (instr::is_vector_type(m)) { + if (this->curr_instr->type != SI_INT) { if (this->curr_instr->mnemonic != LOADV && this->curr_instr->mnemonic != STOREV) { this->curr_instr->operands.vector.slot_one = v1; diff --git a/src/id.cc b/src/id.cc index 490b03a..d24497a 100644 --- a/src/id.cc +++ b/src/id.cc @@ -38,6 +38,7 @@ void ID::get_instr_fields(signed int instr_bits) Mnemonic m; this->split_instr(instr_bits, type, m); this->curr_instr->mnemonic = m; + this->curr_instr->type = instr::get_field_types(m); switch (type) { case 0b00: this->decode_R_type(instr_bits); @@ -100,17 +101,17 @@ void ID::decode_R_type(signed int &s1) s2 = GET_MID_BITS(s1, s0b, s1b); s1 = GET_LS_BITS(s1, s0b); - if (instr::is_vector_type(this->curr_instr->mnemonic)) { + if (this->curr_instr->type == SI_INT) { + r1 = this->read_guard(s1, s1); + this->curr_instr->operands.integer.slot_one = s1; + r2 = this->read_guard(s2, s2); + this->curr_instr->operands.integer.slot_two = s2; + } else { r1 = this->read_guard>( s1, this->curr_instr->operands.vector.slot_one); r2 = this->read_guard>( s2, this->curr_instr->operands.vector.slot_two); r3 = this->set_vlen(); - } else { - r1 = this->read_guard(s1, s1); - this->curr_instr->operands.integer.slot_one = s1; - r2 = this->read_guard(s2, s2); - this->curr_instr->operands.integer.slot_two = s2; } this->status = (r1 == OK && r2 == OK && r3 == OK) ? OK : STALLED; diff --git a/src/instr.cc b/src/instr.cc index 0282be3..ee2d37f 100644 --- a/src/instr.cc +++ b/src/instr.cc @@ -38,18 +38,14 @@ const std::unordered_map mnemonic_map = { {0b0100110, POP}, {0b0101010, RET}, }; -bool is_vector_type(Mnemonic m) +FieldType get_field_types(Mnemonic m) { - return ( - m == ADDV || m == SUBV || m == MULV || m == DIVV || m == CEV || - m == LOADV || m == STOREV); + if (m == ADDV || m == SUBV || m == MULV || m == DIVV || m == CEV) { + return R_VECT; + } else if (m == STOREV || m == LOADV) { + return I_VECT; + } else { + return SI_INT; + } } - -bool is_logical_type(Mnemonic m) -{ - return ( - m == ANDI || m == ORI || m == XORI || m == AND || m == OR || m == XOR || - m == NOT); -} - } // namespace instr diff --git a/src/wb.cc b/src/wb.cc index 12f4edf..1c364b0 100644 --- a/src/wb.cc +++ b/src/wb.cc @@ -53,7 +53,7 @@ void WB::write_handler() this->checked_out.pop_front(); reg = this->curr_instr->checked_out; - if(instr::is_vector_type(this->curr_instr->mnemonic)) { + if(this->curr_instr->type != SI_INT) { if(this->curr_instr->mnemonic != STOREV && this->curr_instr->mnemonic != LOADV) { this->store_register>(reg, this->curr_instr->operands.vector.slot_one); } else { -- cgit v1.2.3 From c5e989bbf1adf6cb0ea63f5d215db7c90518c607 Mon Sep 17 00:00:00 2001 From: bd Date: Sat, 10 May 2025 18:52:04 -0400 Subject: Rename load/store vector to i_vector --- inc/instrDTO.h | 4 ++-- src/ex.cc | 8 ++++---- src/id.cc | 12 ++++++------ src/wb.cc | 2 +- 4 files changed, 13 insertions(+), 13 deletions(-) (limited to 'src/wb.cc') diff --git a/inc/instrDTO.h b/inc/instrDTO.h index 98247a3..12c72d9 100644 --- a/inc/instrDTO.h +++ b/inc/instrDTO.h @@ -33,7 +33,7 @@ struct V_TYPE { std::array slot_three; }; -struct LOAD_STORE_V_TYPE { +struct VI_TYPE { signed int base_addr; signed int immediate; std::array vector_register; @@ -67,7 +67,7 @@ struct InstrDTO { union { struct U_INT_TYPE integer; struct V_TYPE vector; - struct LOAD_STORE_V_TYPE load_store_vector; + struct VI_TYPE i_vector; } operands; }; diff --git a/src/ex.cc b/src/ex.cc index 45a018a..3c9632b 100644 --- a/src/ex.cc +++ b/src/ex.cc @@ -16,11 +16,11 @@ // along with this program. If not, see . #include "ex.h" +#include "instr.h" #include "instrDTO.h" #include "pipe_spec.h" #include "response.h" #include "stage.h" -#include "instr.h" #include // Switch statements for each instruction @@ -46,9 +46,9 @@ void EX::advance_helper() v3 = this->curr_instr->operands.vector.slot_three; } else { v_immediate = - this->curr_instr->operands.load_store_vector.immediate; + this->curr_instr->operands.i_vector.immediate; v_base_addr = - this->curr_instr->operands.load_store_vector.base_addr; + this->curr_instr->operands.i_vector.base_addr; } if (v_len == 0) { // clear destination vector reg @@ -249,7 +249,7 @@ void EX::advance_helper() this->curr_instr->mnemonic != STOREV) { this->curr_instr->operands.vector.slot_one = v1; } else { - this->curr_instr->operands.load_store_vector.base_addr = + this->curr_instr->operands.i_vector.base_addr = v_base_addr; } } else { diff --git a/src/id.cc b/src/id.cc index d24497a..81527db 100644 --- a/src/id.cc +++ b/src/id.cc @@ -166,31 +166,31 @@ void ID::decode_I_type(signed int &s1) this->status = (r1 == OK && r2 == OK) ? OK : STALLED; return; case STOREV: - this->curr_instr->operands.load_store_vector.immediate = s3; + this->curr_instr->operands.i_vector.immediate = s3; s2 = GET_MID_BITS(s1, s0b, s1b); s1 = GET_LS_BITS(s1, s0b); // base address r1 = this->read_guard(s1, s1); - this->curr_instr->operands.load_store_vector.base_addr = s1; + this->curr_instr->operands.i_vector.base_addr = s1; // vector value to be stored r2 = this->read_guard>( - s2, this->curr_instr->operands.load_store_vector.vector_register); + s2, this->curr_instr->operands.i_vector.vector_register); r3 = this->set_vlen(); this->status = (r1 == OK && r2 == OK && r3 == OK) ? OK : STALLED; return; case LOADV: - this->curr_instr->operands.load_store_vector.immediate = s3; + this->curr_instr->operands.i_vector.immediate = s3; s2 = GET_LS_BITS(s1, s0b); s1 = GET_MID_BITS(s1, s0b, s1b); // base address r1 = this->read_guard(s1, s1); - this->curr_instr->operands.load_store_vector.base_addr = s1; + this->curr_instr->operands.i_vector.base_addr = s1; r3 = this->set_vlen(); if (r1 == OK && r3 == OK) // vector destination - this->curr_instr->operands.load_store_vector.vector_register = + this->curr_instr->operands.i_vector.vector_register = this->write_guard>(s2); this->status = (r1 == OK && r3 == OK) ? OK : STALLED; return; diff --git a/src/wb.cc b/src/wb.cc index 1c364b0..455c7ad 100644 --- a/src/wb.cc +++ b/src/wb.cc @@ -57,7 +57,7 @@ void WB::write_handler() if(this->curr_instr->mnemonic != STOREV && this->curr_instr->mnemonic != LOADV) { this->store_register>(reg, this->curr_instr->operands.vector.slot_one); } else { - this->store_register>(reg, this->curr_instr->operands.load_store_vector.vector_register); + this->store_register>(reg, this->curr_instr->operands.i_vector.vector_register); } } else{ this->store_register(reg, this->curr_instr->operands.integer.slot_one); -- cgit v1.2.3 From 727afe4ffac0f193696c99234a2ade3a02f73157 Mon Sep 17 00:00:00 2001 From: bd Date: Sat, 10 May 2025 20:35:18 -0400 Subject: Separate ex advance into methods handling different field types --- inc/ex.h | 73 +++++++++++++++++++++--------- inc/instrDTO.h | 7 +-- src/ex.cc | 137 +++++++++++++++++++++++++++++++-------------------------- src/id.cc | 14 +++--- src/mm.cc | 52 ---------------------- src/wb.cc | 2 +- 6 files changed, 138 insertions(+), 147 deletions(-) (limited to 'src/wb.cc') diff --git a/inc/ex.h b/inc/ex.h index 5a5c046..0e235cb 100644 --- a/inc/ex.h +++ b/inc/ex.h @@ -23,36 +23,28 @@ #include #include -#define ADDITION_OF_GUARD(a, b) \ - (b >= 0) && (a > MAX_INT - b) +#define ADDITION_OF_GUARD(a, b) (b >= 0) && (a > MAX_INT - b) -#define ADDITION_UF_GUARD(a, b) \ - (b < 0) && (a < (-(MAX_INT)-1) - b) +#define ADDITION_UF_GUARD(a, b) (b < 0) && (a < (-(MAX_INT)-1) - b) -#define SUBTRACTION_OF_GUARD(a, b) \ - (b < 0) && (a > MAX_INT + b) +#define SUBTRACTION_OF_GUARD(a, b) (b < 0) && (a > MAX_INT + b) -#define SUBTRACTION_UF_GUARD(a, b) \ - (b >= 0) && (a < (-(MAX_INT)-1) + b) +#define SUBTRACTION_UF_GUARD(a, b) (b >= 0) && (a < (-(MAX_INT)-1) + b) -#define MULTIPLICATION_OF_GUARD(a, b) \ - (b != 0) && \ - (((b > 0) && (a > 0) && (a > MAX_INT / b)) || \ - ((b < 0) && (a < 0) && (a < MAX_INT / b))) +#define MULTIPLICATION_OF_GUARD(a, b) \ + (b != 0) && (((b > 0) && (a > 0) && (a > MAX_INT / b)) || \ + ((b < 0) && (a < 0) && (a < MAX_INT / b))) -#define MULTIPLICATION_UF_GUARD(a, b) \ - (b != 0) && (b != -1) && \ - (((b > 0) && (a < 0) && (a < (-(MAX_INT)-1) / b)) || \ - ((b < 0) && (a > 0) && (a > (-(MAX_INT)-1) / b))) +#define MULTIPLICATION_UF_GUARD(a, b) \ + (b != 0) && (b != -1) && \ + (((b > 0) && (a < 0) && (a < (-(MAX_INT)-1) / b)) || \ + ((b < 0) && (a > 0) && (a > (-(MAX_INT)-1) / b))) -#define DIVISION_OF_GUARD(a, b) \ - ((a == -(MAX_INT) - 1) && (b == -1)) || (b == 0) +#define DIVISION_OF_GUARD(a, b) ((a == -(MAX_INT)-1) && (b == -1)) || (b == 0) class HaltException : public std::exception { - const char *what() const noexcept override { - return ""; - } + const char *what() const noexcept override { return ""; } }; class EX : public Stage @@ -63,11 +55,48 @@ class EX : public Stage * @param The next stage in the pipeline. * @return A newly allocated EX object. */ - using Stage::Stage; using Stage::advance; + using Stage::Stage; private: void advance_helper(); + /** + * Handles operations involving three ints. + * @param slot 1, and later, the result of the mnemonic operation. + * @param slot 2 + * @param slot 3 + * @param the mnemonic + * @param the program counter + */ + void handle_int_operations( + signed int &s1, + signed int s2, + signed int s3, + Mnemonic m, + unsigned int pc); + /** + * Handles operations involving three vector registers. + * @param slot 1, and later, the result of the mnemonic operation. + * @param slot 2 + * @param slot 3 + * @param the mnemonic + * @param the vector length register + */ + void handle_vector_operations( + std::array &s1, + std::array s2, + Mnemonic m, + unsigned int v_len); + + /** + * Handles operations involving a single vector register. + * Currently, this is LOADV and STOREV + * @param slot 1, and later, the result of the mnemonic operation. + * @param slot 2 + * @param the mnemonic + * @param the vector length register + */ + void handle_i_vector_operations(signed int &s1, signed int s2, Mnemonic m); /** * Wrapper for division functions, which detects HALT instructinos (division * by 0). diff --git a/inc/instrDTO.h b/inc/instrDTO.h index 12c72d9..ccc6ed9 100644 --- a/inc/instrDTO.h +++ b/inc/instrDTO.h @@ -21,6 +21,7 @@ #include "pipe_spec.h" #include + struct U_INT_TYPE { signed int slot_one; signed int slot_two; @@ -34,9 +35,9 @@ struct V_TYPE { }; struct VI_TYPE { - signed int base_addr; - signed int immediate; - std::array vector_register; + signed int slot_one; + signed int slot_two; + std::array slot_three; }; struct InstrDTO { diff --git a/src/ex.cc b/src/ex.cc index 3c9632b..810461f 100644 --- a/src/ex.cc +++ b/src/ex.cc @@ -21,45 +21,12 @@ #include "pipe_spec.h" #include "response.h" #include "stage.h" +#include #include -// Switch statements for each instruction -void EX::advance_helper() +void EX::handle_int_operations( + signed int &s1, signed int s2, signed int s3, Mnemonic m, unsigned int pc) { - signed int s1, s2, s3; - std::array v1, v2, v3; - signed int v_len, v_immediate, v_base_addr; - unsigned int pc; - Mnemonic m; - - s1 = 0, s2 = 0, s3 = 0; - v1 = {0}, v2 = {0}, v3 = {0}; - v_len = 0, v_immediate = 0, v_base_addr = 0; - m = this->curr_instr->mnemonic; - v_len = this->curr_instr->slot_B; - pc = this->curr_instr->slot_B; - - if (this->curr_instr->type != SI_INT) { - if (this->curr_instr->type == R_VECT) { - v1 = this->curr_instr->operands.vector.slot_one; - v2 = this->curr_instr->operands.vector.slot_two; - v3 = this->curr_instr->operands.vector.slot_three; - } else { - v_immediate = - this->curr_instr->operands.i_vector.immediate; - v_base_addr = - this->curr_instr->operands.i_vector.base_addr; - } - if (v_len == 0) { - // clear destination vector reg - v1.fill(0); - } - } else { - s1 = this->curr_instr->operands.integer.slot_one; - s2 = this->curr_instr->operands.integer.slot_two; - s3 = this->curr_instr->operands.integer.slot_three; - } - switch (m) { case ADD: this->set_condition(OF, ADDITION_OF_GUARD(s1, s2)); @@ -196,36 +163,55 @@ void EX::advance_helper() (this->get_condition(OF)) ? s1 = pc + s2 : s1 = -1; break; + case RET: + case NOP: + break; + + default: + throw std::invalid_argument( + "handle_int_operations received a vector operation!"); + } +} + +void EX::handle_vector_operations( + std::array &s1, + std::array s2, + Mnemonic m, + unsigned int v_len) +{ + unsigned int i; + + switch (m) { case ADDV: - for (int i = 0; i < v_len; i++) { - this->set_condition(OF, ADDITION_OF_GUARD(v1[i], v2[i])); - this->set_condition(UF, ADDITION_UF_GUARD(v1[i], v2[i])); - v1[i] = v1[i] + v2[i]; + for (i = 0; i < v_len; i++) { + this->set_condition(OF, ADDITION_OF_GUARD(s1[i], s2[i])); + this->set_condition(UF, ADDITION_UF_GUARD(s1[i], s2[i])); + s1[i] = s1[i] + s2[i]; } break; case SUBV: - for (int i = 0; i < v_len; i++) { - this->set_condition(OF, SUBTRACTION_OF_GUARD(v1[i], v2[i])); - this->set_condition(UF, SUBTRACTION_UF_GUARD(v1[i], v2[i])); - v1[i] = v1[i] - v2[i]; + for (i = 0; i < v_len; i++) { + this->set_condition(OF, SUBTRACTION_OF_GUARD(s1[i], s2[i])); + this->set_condition(UF, SUBTRACTION_UF_GUARD(s1[i], s2[i])); + s1[i] = s1[i] - s2[i]; } break; case MULV: - for (int i = 0; i < v_len; i++) { - this->set_condition(OF, MULTIPLICATION_OF_GUARD(v1[i], v2[i])); - this->set_condition(UF, MULTIPLICATION_UF_GUARD(v1[i], v2[i])); - v1[i] = v1[i] * v2[i]; + for (i = 0; i < v_len; i++) { + this->set_condition(OF, MULTIPLICATION_OF_GUARD(s1[i], s2[i])); + this->set_condition(UF, MULTIPLICATION_UF_GUARD(s1[i], s2[i])); + s1[i] = s1[i] * s2[i]; } break; case DIVV: - for (int i = 0; i < v_len; i++) { - this->handle_divide(v1[i], v2[i], false); + for (i = 0; i < v_len; i++) { + this->handle_divide(s1[i], s2[i], false); } break; case CEV: - int i; + for (i = 0; i < v_len; i++) { - if (v1[i] != v2[i]) { + if (s1[i] != s2[i]) { break; } } @@ -235,26 +221,53 @@ void EX::advance_helper() this->set_condition(EQ, false); } break; + + default: + throw std::invalid_argument( + "handle_vector_operations received an integer operation!"); + } +} + +void EX::handle_i_vector_operations(signed int &s1, signed int s2, Mnemonic m) +{ + switch (m) { case LOADV: case STOREV: - v_base_addr = v_base_addr + v_immediate; + s1 = s1 + s2; break; case RET: case NOP: break; + + default: + throw std::invalid_argument("handle_i_vector_operations did not " + "receive a LOADV or STOREV operation!"); } - if (this->curr_instr->type != SI_INT) { - if (this->curr_instr->mnemonic != LOADV && - this->curr_instr->mnemonic != STOREV) { - this->curr_instr->operands.vector.slot_one = v1; - } else { - this->curr_instr->operands.i_vector.base_addr = - v_base_addr; - } +} + +void EX::advance_helper() +{ + unsigned int v_len_or_pc; + Mnemonic m; + m = this->curr_instr->mnemonic; + v_len_or_pc = this->curr_instr->slot_B; + + if (this->curr_instr->type == FieldType::SI_INT) { + handle_int_operations( + this->curr_instr->operands.integer.slot_one, + this->curr_instr->operands.integer.slot_two, + this->curr_instr->operands.integer.slot_three, m, v_len_or_pc); + } else if (this->curr_instr->type == FieldType::R_VECT) { + handle_vector_operations( + this->curr_instr->operands.vector.slot_one, + this->curr_instr->operands.vector.slot_two, m, v_len_or_pc); } else { - this->curr_instr->operands.integer.slot_one = s1; + handle_i_vector_operations( + this->curr_instr->operands.i_vector.slot_one, + this->curr_instr->operands.i_vector.slot_two, m); } + this->status = OK; } diff --git a/src/id.cc b/src/id.cc index 81527db..2645aeb 100644 --- a/src/id.cc +++ b/src/id.cc @@ -147,7 +147,7 @@ void ID::decode_I_type(signed int &s1) s0b = REG_SIZE; s1b = s0b + REG_SIZE; s2b = WORD_SPEC - LINE_SPEC - OPCODE_SIZE; - // s3 is immediate + // s3 is slot_two s3 = GET_BITS_SIGN_EXTEND(s1, s1b, s2b); switch (this->curr_instr->mnemonic) { @@ -166,31 +166,31 @@ void ID::decode_I_type(signed int &s1) this->status = (r1 == OK && r2 == OK) ? OK : STALLED; return; case STOREV: - this->curr_instr->operands.i_vector.immediate = s3; + this->curr_instr->operands.i_vector.slot_two = s3; s2 = GET_MID_BITS(s1, s0b, s1b); s1 = GET_LS_BITS(s1, s0b); // base address r1 = this->read_guard(s1, s1); - this->curr_instr->operands.i_vector.base_addr = s1; + this->curr_instr->operands.i_vector.slot_one = s1; // vector value to be stored r2 = this->read_guard>( - s2, this->curr_instr->operands.i_vector.vector_register); + s2, this->curr_instr->operands.i_vector.slot_three); r3 = this->set_vlen(); this->status = (r1 == OK && r2 == OK && r3 == OK) ? OK : STALLED; return; case LOADV: - this->curr_instr->operands.i_vector.immediate = s3; + this->curr_instr->operands.i_vector.slot_two = s3; s2 = GET_LS_BITS(s1, s0b); s1 = GET_MID_BITS(s1, s0b, s1b); // base address r1 = this->read_guard(s1, s1); - this->curr_instr->operands.i_vector.base_addr = s1; + this->curr_instr->operands.i_vector.slot_one = s1; r3 = this->set_vlen(); if (r1 == OK && r3 == OK) // vector destination - this->curr_instr->operands.i_vector.vector_register = + this->curr_instr->operands.i_vector.slot_three = this->write_guard>(s2); this->status = (r1 == OK && r3 == OK) ? OK : STALLED; return; diff --git a/src/mm.cc b/src/mm.cc index 8134cf5..ac77433 100644 --- a/src/mm.cc +++ b/src/mm.cc @@ -24,7 +24,6 @@ void MM::advance_helper() { signed int data; int i; - int vector_delay = VECTOR_MEM_DELAY; switch (this->curr_instr->mnemonic) { case LOAD: @@ -36,32 +35,6 @@ void MM::advance_helper() } else this->status = STALLED; break; - case LOADV: - if (vector_delay == 0){ - signed int word_address = this->curr_instr->operands.load_store_vector.base_addr; - int j = 0; - while(j < this->curr_instr->slot_A){ - i = this->storage->read_word(this, word_address, data); - this->status = i ? OK : STALLED; - if (this->status == OK) { - this->curr_instr->operands.load_store_vector.vector_register[j] = data; - // +1 or +4? - word_address += 1; - j++; - } else { - break; - } - } - if(this->status == OK){ - // if vector is loaded, reset delay - vector_delay = VECTOR_MEM_DELAY; - } else { - this->status = STALLED; - } - } else { - vector_delay--; - } - break; case PUSH: case STORE: @@ -73,31 +46,6 @@ void MM::advance_helper() this->status = STALLED; } break; - case STOREV: - if (vector_delay == 0){ - signed int word_address = this->curr_instr->operands.load_store_vector.base_addr; - int j = 0; - while(j < this->curr_instr->slot_A){ - this->storage->write_word( - this, this->curr_instr->operands.load_store_vector.vector_register[j], word_address); - this->status = i ? OK : STALLED; - if (this->status != OK) { - break; - } else { - word_address += 1; - j++; - } - } - if(this->status == OK){ - // if vector is stored , reset delay - vector_delay = VECTOR_MEM_DELAY; - } else { - this->status = STALLED; - } - } else { - vector_delay--; - } - break; case POP: i = this->storage->read_word(this, this->curr_instr->operands.integer.slot_three, data); diff --git a/src/wb.cc b/src/wb.cc index 455c7ad..e174157 100644 --- a/src/wb.cc +++ b/src/wb.cc @@ -57,7 +57,7 @@ void WB::write_handler() if(this->curr_instr->mnemonic != STOREV && this->curr_instr->mnemonic != LOADV) { this->store_register>(reg, this->curr_instr->operands.vector.slot_one); } else { - this->store_register>(reg, this->curr_instr->operands.i_vector.vector_register); + this->store_register>(reg, this->curr_instr->operands.i_vector.slot_three); } } else{ this->store_register(reg, this->curr_instr->operands.integer.slot_one); -- cgit v1.2.3 From 6f4e9e0b914c3e68691a5d884cbad0b5813fcf18 Mon Sep 17 00:00:00 2001 From: bd Date: Sat, 10 May 2025 22:28:01 -0400 Subject: Fix bug where too many vector elements were written back --- inc/wb.h | 9 ++++++++- src/ex.cc | 1 - src/wb.cc | 37 +++++++++++++++++++++++++++---------- 3 files changed, 35 insertions(+), 12 deletions(-) (limited to 'src/wb.cc') diff --git a/inc/wb.h b/inc/wb.h index d3a1b93..35c9240 100644 --- a/inc/wb.h +++ b/inc/wb.h @@ -24,8 +24,8 @@ class WB : public Stage { public: - using Stage::Stage; using Stage::advance; + using Stage::Stage; private: void advance_helper() override; @@ -47,6 +47,13 @@ class WB : public Stage * STORE. */ bool should_jump(); + /** + * @return the vector register to be stored, obtained by copying the + * unfilled elements in the destination register to the source. This is + * required to ensure what is written back only changes VECTOR_LENGTH number + * of elements. + */ + std::array copy_extra_vector_elements(); }; #endif /* WB_H_INCLUDED */ diff --git a/src/ex.cc b/src/ex.cc index 066f584..56a59d7 100644 --- a/src/ex.cc +++ b/src/ex.cc @@ -231,7 +231,6 @@ void EX::handle_vector_operations( } this->set_condition(EQ, eq); break; - default: throw std::invalid_argument( "handle_vector_operations received an integer operation!"); diff --git a/src/wb.cc b/src/wb.cc index e174157..bfdbc3a 100644 --- a/src/wb.cc +++ b/src/wb.cc @@ -16,9 +16,9 @@ // along with this program. If not, see . #include "wb.h" +#include "instr.h" #include "instrDTO.h" #include "response.h" -#include "instr.h" #include "stage.h" #include #include @@ -53,14 +53,20 @@ void WB::write_handler() this->checked_out.pop_front(); reg = this->curr_instr->checked_out; - if(this->curr_instr->type != SI_INT) { - if(this->curr_instr->mnemonic != STOREV && this->curr_instr->mnemonic != LOADV) { - this->store_register>(reg, this->curr_instr->operands.vector.slot_one); - } else { - this->store_register>(reg, this->curr_instr->operands.i_vector.slot_three); - } - } else{ - this->store_register(reg, this->curr_instr->operands.integer.slot_one); + switch (this->curr_instr->type) { + case SI_INT: + this->store_register( + reg, this->curr_instr->operands.integer.slot_one); + break; + case R_VECT: + this->store_register>( + reg, this->copy_extra_vector_elements()); + break; + case I_VECT: + this->store_register>( + reg, this->curr_instr->operands.i_vector.slot_three); + // todo, use copy_extra_vector_elements + break; } } @@ -69,7 +75,6 @@ void WB::jump_handler() if (this->curr_instr->operands.integer.slot_one > 0) { if (this->curr_instr->mnemonic == JAL) this->gprs[1] = this->curr_instr->slot_B + 1; - ; this->pc = this->curr_instr->operands.integer.slot_one; this->checked_out = {}; this->next->squash(); @@ -86,3 +91,15 @@ bool WB::should_jump() else return false; } + +std::array WB::copy_extra_vector_elements() +{ + int i; + std::array v; + + v = this->curr_instr->operands.vector.slot_one; + for (i = V_R_LIMIT - 1; i >= this->curr_instr->slot_B; --i) { + v[i] = this->curr_instr->operands.vector.slot_three[i]; + } + return v; +} -- cgit v1.2.3