From 41f612789f652654b5f2fa8c3fee4e348e2081b1 Mon Sep 17 00:00:00 2001 From: Siddarth-Suresh <65844402+Siddarth-Suresh@users.noreply.github.com> Date: Sat, 26 Apr 2025 20:21:02 -0400 Subject: Initial vector extension changes --- inc/stage.h | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 57 insertions(+), 3 deletions(-) (limited to 'inc/stage.h') diff --git a/inc/stage.h b/inc/stage.h index 7dcb7b4..ae01723 100644 --- a/inc/stage.h +++ b/inc/stage.h @@ -82,6 +82,10 @@ class Stage */ static std::deque checked_out; + bool is_vector_type(Mnemonic m); + + bool is_logical(Mnemonic m); + protected: /** * The function expected to do the majority of the work. @@ -103,13 +107,63 @@ class Stage * @param the register number. * @param the value to store. */ - void store_register(signed int v, signed int d); + template + void store_register(signed int v, T d) + { + // if (v < 0 || v >= GPR_NUM + V_NUM) { + // throw std::out_of_range( + // "instruction tried to access register which does not exist"); + // } + + // if (v >= GPR_NUM) + // this->vrs[v % GPR_NUM] = d; + // else + // this->gprs[v] = d; + + if constexpr (std::is_same_v) { + 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>) { + 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 + T dereference_register(signed int v) + { + // signed int r; + + // if (v < 0 || v >= GPR_NUM + V_NUM) { + // throw std::out_of_range( + // "instruction tried to access register which does not exist"); + // } + + // r = (v >= GPR_NUM) ? this->vrs[v % GPR_NUM] : this->gprs[v]; + // return r; + + if constexpr (std::is_same_v) { + if (v < 0 || v >= GPR_NUM) { + throw std::out_of_range("Invalid GPR index"); + } + return gprs[v]; + } + else if constexpr (std::is_same_v>) { + 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. */ @@ -117,7 +171,7 @@ class Stage /** * The shared pool of general-purpose vector registers. */ - static std::array vrs; + static std::array, V_NUM> vrs; /** * The address of the currently executing instruction. */ -- cgit v1.2.3 From bd4714ae53898337a02cfcec17628eeff9d77a9c Mon Sep 17 00:00:00 2001 From: Siddarth-Suresh <65844402+Siddarth-Suresh@users.noreply.github.com> Date: Sat, 26 Apr 2025 23:57:02 -0400 Subject: Fix for load and store vector --- inc/ex.h | 5 ----- inc/instrDTO.h | 6 +++++- inc/stage.h | 20 -------------------- src/id.cc | 12 ++++++++++-- 4 files changed, 15 insertions(+), 28 deletions(-) (limited to 'inc/stage.h') diff --git a/inc/ex.h b/inc/ex.h index 58237ab..5a5c046 100644 --- a/inc/ex.h +++ b/inc/ex.h @@ -76,11 +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. - */ }; #endif /* EX_H_INCLUDED */ diff --git a/inc/instrDTO.h b/inc/instrDTO.h index 8f8e28e..b99ba20 100644 --- a/inc/instrDTO.h +++ b/inc/instrDTO.h @@ -43,9 +43,13 @@ struct InstrDTO { */ signed int slot_A; /** - * Optional slot for holding PC + * Optional slot for holding PC / base address */ signed int slot_B; + /** + * Optional slot to hold immediates + */ + signed int slot_C; /** * The mnemonic of the instruction. */ diff --git a/inc/stage.h b/inc/stage.h index ae01723..dde103b 100644 --- a/inc/stage.h +++ b/inc/stage.h @@ -110,16 +110,6 @@ class Stage template void store_register(signed int v, T d) { - // if (v < 0 || v >= GPR_NUM + V_NUM) { - // throw std::out_of_range( - // "instruction tried to access register which does not exist"); - // } - - // if (v >= GPR_NUM) - // this->vrs[v % GPR_NUM] = d; - // else - // this->gprs[v] = d; - if constexpr (std::is_same_v) { if (v < 0 || v >= GPR_NUM) { throw std::out_of_range("Invalid GPR index for storing scalar"); @@ -141,16 +131,6 @@ class Stage template T dereference_register(signed int v) { - // signed int r; - - // if (v < 0 || v >= GPR_NUM + V_NUM) { - // throw std::out_of_range( - // "instruction tried to access register which does not exist"); - // } - - // r = (v >= GPR_NUM) ? this->vrs[v % GPR_NUM] : this->gprs[v]; - // return r; - if constexpr (std::is_same_v) { if (v < 0 || v >= GPR_NUM) { throw std::out_of_range("Invalid GPR index"); diff --git a/src/id.cc b/src/id.cc index b976ef0..d51c70c 100644 --- a/src/id.cc +++ b/src/id.cc @@ -194,26 +194,33 @@ 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 = GET_BITS_SIGN_EXTEND(s1, s1b, s2b); switch (this->curr_instr->mnemonic) { case STORE: + this->curr_instr->operands.integer.slot_three = s3; s2 = GET_MID_BITS(s1, s0b, s1b); s1 = GET_LS_BITS(s1, s0b); // both operands are read values + // s1 is base address r1 = this->read_guard(s1); this->curr_instr->operands.integer.slot_one = s1; + // s2 is value to be stored r2 = this->read_guard(s2); this->curr_instr->operands.integer.slot_two = s2; this->status = (r1 == OK && r2 == OK) ? OK : STALLED; return; case STOREV: + this->curr_instr->slot_C = s3; s2 = GET_MID_BITS(s1, s0b, s1b); s1 = GET_LS_BITS(s1, s0b); - // both operands are read values - r1 = this->read_vec_guard(s1,this->curr_instr->operands.vector.slot_one); + // base address + r1 = this->read_guard(s1); + this->curr_instr->slot_B = s1; + // vector value to be stored r2 = this->read_vec_guard(s2,this->curr_instr->operands.vector.slot_two); r3 = this->set_vlen(); @@ -229,6 +236,7 @@ void ID::decode_I_type(signed int &s1) this->status = (r1 == OK && r3 == OK) ? OK : STALLED; return; case LOAD: + this->curr_instr->operands.integer.slot_three = s3; s2 = GET_LS_BITS(s1, s0b); s1 = GET_MID_BITS(s1, s0b, s1b); break; -- cgit v1.2.3 From b50cb7048275f5b9255dea7f3ac1362aaa09fe83 Mon Sep 17 00:00:00 2001 From: Siddarth-Suresh <65844402+Siddarth-Suresh@users.noreply.github.com> Date: Sun, 27 Apr 2025 21:09:27 -0400 Subject: Bug fixes --- inc/stage.h | 4 +++- src/ex.cc | 24 ++++++++++++++---------- src/id.cc | 7 ++++++- 3 files changed, 23 insertions(+), 12 deletions(-) (limited to 'inc/stage.h') diff --git a/inc/stage.h b/inc/stage.h index 4e0c252..a5d7fe6 100644 --- a/inc/stage.h +++ b/inc/stage.h @@ -136,6 +136,8 @@ class Stage if (v < 0 || v >= GPR_NUM) { throw std::out_of_range("Invalid GPR index"); } + cout << "dereference_register: " << v << endl; + cout << "gprs[v]: " << gprs[v] << endl; return gprs[v]; } else if constexpr (std::is_same_v>) { @@ -188,4 +190,4 @@ class Stage Response status; }; -#endif /* STAGE_H_INCLUDED */ +#endif /* STAGE_H_INCLUDED */ \ No newline at end of file diff --git a/src/ex.cc b/src/ex.cc index 03a4e59..6dfe44f 100644 --- a/src/ex.cc +++ b/src/ex.cc @@ -183,14 +183,10 @@ void EX::advance_helper() break; case ADDV: - if(v_len ==0){ - - } else { - for(int i=0;iset_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(int i=0;iset_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]; } break; case SUBV: @@ -234,8 +230,16 @@ void EX::advance_helper() case NOP: break; - } - + } + if(this->is_vector_type(m)) { + if(this->curr_instr->mnemonic != LOADV && this->curr_instr->mnemonic != STOREV){ + this->curr_instr->operands.vector.slot_one = v1; + } else { + this->curr_instr->operands.load_store_vector.base_addr = v_base_addr; + } + } else{ + this->curr_instr->operands.integer.slot_one = s1; + } this->status = OK; } diff --git a/src/id.cc b/src/id.cc index 7db67c4..4358150 100644 --- a/src/id.cc +++ b/src/id.cc @@ -253,6 +253,7 @@ void ID::decode_I_type(signed int &s1) s1 = GET_MID_BITS(s1, s0b, s1b); break; default: + this->curr_instr->operands.integer.slot_three = s3; s2 = GET_MID_BITS(s1, s0b, s1b); s1 = GET_LS_BITS(s1, s0b); } @@ -312,6 +313,10 @@ void ID::decode_J_type(signed int &s1) [[fallthrough]]; default: this->status = this->read_guard(s1); - this->curr_instr->operands.integer.slot_one = s1; + if(this->status == OK){ + this->curr_instr->operands.integer.slot_one = s1; + this->curr_instr->operands.integer.slot_two = s2; + this->curr_instr->operands.integer.slot_three = s3; + } } } -- cgit v1.2.3 From a5366c56469bdec480c7eb463f9f71d7a3e3b2d2 Mon Sep 17 00:00:00 2001 From: bd Date: Sun, 27 Apr 2025 23:26:40 -0400 Subject: Fix push/pop instruction --- inc/stage.h | 4 +- src/controller.cc | 1 + src/ex.cc | 374 +++++++++++++++++++++++++++--------------------------- src/id.cc | 4 +- 4 files changed, 194 insertions(+), 189 deletions(-) (limited to 'inc/stage.h') diff --git a/inc/stage.h b/inc/stage.h index a5d7fe6..4e0c252 100644 --- a/inc/stage.h +++ b/inc/stage.h @@ -136,8 +136,6 @@ class Stage if (v < 0 || v >= GPR_NUM) { throw std::out_of_range("Invalid GPR index"); } - cout << "dereference_register: " << v << endl; - cout << "gprs[v]: " << gprs[v] << endl; return gprs[v]; } else if constexpr (std::is_same_v>) { @@ -190,4 +188,4 @@ class Stage Response status; }; -#endif /* STAGE_H_INCLUDED */ \ No newline at end of file +#endif /* STAGE_H_INCLUDED */ diff --git a/src/controller.cc b/src/controller.cc index a84126d..a5c6691 100644 --- a/src/controller.cc +++ b/src/controller.cc @@ -31,6 +31,7 @@ Controller::Controller(Stage *stage, Storage *storage, bool is_pipelined) this->pc = 0x0; this->checked_out = {}; this->gprs = {0}; + this->vrs.fill({0}); this->gprs.at(2) = MEM_WORDS; // set the stack pointer } diff --git a/src/ex.cc b/src/ex.cc index 6dfe44f..3f86ad4 100644 --- a/src/ex.cc +++ b/src/ex.cc @@ -22,7 +22,6 @@ #include "stage.h" #include - // Switch statements for each instruction void EX::advance_helper() { @@ -32,212 +31,217 @@ void EX::advance_helper() unsigned int pc; Mnemonic m; + s1 = 0, s2 = 0, s3 = 0; m = this->curr_instr->mnemonic; pc = this->curr_instr->slot_B; - if(this->is_vector_type(m)) { - if(this->curr_instr->mnemonic != LOADV && this->curr_instr->mnemonic != STOREV){ + if (this->is_vector_type(m)) { + if (this->curr_instr->mnemonic != LOADV && + this->curr_instr->mnemonic != STOREV) { v1 = this->curr_instr->operands.vector.slot_one; v2 = this->curr_instr->operands.vector.slot_two; - v3 = this->curr_instr->operands.vector.slot_three; + v3 = this->curr_instr->operands.vector.slot_three; } else { - v_immediate = this->curr_instr->operands.load_store_vector.immediate; - v_base_addr = this->curr_instr->operands.load_store_vector.base_addr; + v_immediate = + this->curr_instr->operands.load_store_vector.immediate; + v_base_addr = + this->curr_instr->operands.load_store_vector.base_addr; } v_len = this->curr_instr->slot_A; - if(v_len == 0){ - //clear destination vector reg + if (v_len == 0) { + // clear destination vector reg v1.fill(0); - } - } else{ + } + } 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; } - if(this->is_logical(m)) { + if (this->is_logical(m)) { this->set_condition(OF, false); this->set_condition(UF, false); } - switch(m) { - case ADD: - this->set_condition(OF, ADDITION_OF_GUARD(s1, s2)); - this->set_condition(UF, ADDITION_UF_GUARD(s1, s2)); - s1 = s1 + s2; - break; - - case SUB: - this->set_condition(OF, SUBTRACTION_OF_GUARD(s1, s2)); - this->set_condition(UF, SUBTRACTION_UF_GUARD(s1, s2)); - s1 = s1 - s2; - break; - - case MUL: - this->set_condition(OF, MULTIPLICATION_OF_GUARD(s1, s2)); - this->set_condition(UF, MULTIPLICATION_UF_GUARD(s1, s2)); - s1 = s1 * s2; - break; - - case QUOT: - this->handle_divide(s1, s2, false); - break; - - case REM: - this->handle_divide(s1, s2, true); - break; - - case SFTR: - s1 = s1 >> s2; - break; - - case SFTL: - s1 = s1 << s2; - break; - - case AND: - s1 = s1 & s2; - break; - - case OR: - s1 = s1 | s2; - break; - - case XOR: - s1 = s1 ^ s2; - break; - - case NOT: - s1 = ~s1; - break; - - case CMP: - (s1 > s2) ? this->set_condition(GT, true) - : this->set_condition(GT, false); - (s1 == s2) ? this->set_condition(EQ, true) - : this->set_condition(EQ, false); + switch (m) { + case ADD: + this->set_condition(OF, ADDITION_OF_GUARD(s1, s2)); + this->set_condition(UF, ADDITION_UF_GUARD(s1, s2)); + s1 = s1 + s2; + break; + + case SUB: + this->set_condition(OF, SUBTRACTION_OF_GUARD(s1, s2)); + this->set_condition(UF, SUBTRACTION_UF_GUARD(s1, s2)); + s1 = s1 - s2; + break; + + case MUL: + this->set_condition(OF, MULTIPLICATION_OF_GUARD(s1, s2)); + this->set_condition(UF, MULTIPLICATION_UF_GUARD(s1, s2)); + s1 = s1 * s2; + break; + + case QUOT: + this->handle_divide(s1, s2, false); + break; + + case REM: + this->handle_divide(s1, s2, true); + break; + + case SFTR: + s1 = s1 >> s2; + break; + + case SFTL: + s1 = s1 << s2; + break; + + case AND: + s1 = s1 & s2; + break; + + case OR: + s1 = s1 | s2; + break; + + case XOR: + s1 = s1 ^ s2; + break; + + case NOT: + s1 = ~s1; + break; + + case CMP: + (s1 > s2) ? this->set_condition(GT, true) + : this->set_condition(GT, false); + (s1 == s2) ? this->set_condition(EQ, true) + : this->set_condition(EQ, false); + break; + + case ADDI: + this->set_condition(OF, ADDITION_OF_GUARD(s1, s3)); + this->set_condition(UF, ADDITION_UF_GUARD(s1, s3)); + s1 = s1 + s3; + break; + + case SUBI: + this->set_condition(OF, SUBTRACTION_OF_GUARD(s1, s3)); + this->set_condition(UF, SUBTRACTION_UF_GUARD(s1, s3)); + s1 = s1 - s3; + break; + + case SFTRI: + s1 = s1 >> s3; + break; + + case SFTLI: + s1 = s1 << s3; + break; + + case ANDI: + s1 = s1 & s3; + break; + + case ORI: + s1 = s1 | s3; + break; + + case XORI: + s1 = s1 ^ s3; + break; + + case LOAD: + case STORE: + case PUSH: + case POP: + s1 = s1 + s3; + break; + + case JMP: + case JAL: + s1 = s1 + s2; + break; + + case JRL: + s1 = pc + s2; + break; + + case BEQ: + (this->get_condition(EQ)) ? s1 = pc + s2 : s1 = -1; + break; + + case BGT: + (this->get_condition(GT)) ? s1 = pc + s2 : s1 = -1; + break; + + case BUF: + (this->get_condition(UF)) ? s1 = pc + s2 : s1 = -1; + break; + + case BOF: + (this->get_condition(OF)) ? s1 = pc + s2 : s1 = -1; + break; + + 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]; + } + 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]; + } + 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]; + } + break; + case DIVV: + for (int i = 0; i < v_len; i++) { + this->handle_divide(v1[i], v2[i], false); + } + break; + case CEV: + int i; + for (i = 0; i < v_len; i++) { + if (v1[i] != v2[i]) { break; - - case ADDI: - this->set_condition(OF, ADDITION_OF_GUARD(s1, s3)); - this->set_condition(UF, ADDITION_UF_GUARD(s1, s3)); - s1 = s1 + s3; - break; - - case SUBI: - this->set_condition(OF, SUBTRACTION_OF_GUARD(s1, s3)); - this->set_condition(UF, SUBTRACTION_UF_GUARD(s1, s3)); - s1 = s1 - s3; - break; - - case SFTRI: - s1 = s1 >> s3; - break; - - case SFTLI: - s1 = s1 << s3; - break; - - case ANDI: - s1 = s1 & s3; - break; - - case ORI: - s1 = s1 | s3; - break; - - case XORI: - s1 = s1 ^ s3; - break; - - case LOAD: - case STORE: - case PUSH: - case POP: - s1 = s1 + s3; - break; - - case JMP: - case JAL: - s1 = s1 + s2; - break; - - case JRL: - s1 = pc + s2; - break; - - case BEQ: - (this->get_condition(EQ)) ? s1 = pc + s2 : s1 = -1; - break; - - case BGT: - (this->get_condition(GT)) ? s1 = pc + s2 : s1 = -1; - break; - - case BUF: - (this->get_condition(UF)) ? s1 = pc + s2 : s1 = -1; - break; - - case BOF: - (this->get_condition(OF)) ? s1 = pc + s2 : s1 = -1; - break; - - case ADDV: - for(int i=0;iset_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]; } - break; - case SUBV: - for(int i=0;iset_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]; - } - break; - case MULV: - for(int i=0;iset_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]; - } - break; - case DIVV: - for(int i=0;ihandle_divide(v1[i],v2[i],false); - } - break; - case CEV: - int i; - for(i=0;iset_condition(EQ, true); - } else { - this->set_condition(EQ, false); - } - break; - case LOADV: - case STOREV: - v_base_addr = v_base_addr + v_immediate; - break; - - case RET: - case NOP: - break; - + } + if (i == v_len) { + this->set_condition(EQ, true); + } else { + this->set_condition(EQ, false); + } + break; + case LOADV: + case STOREV: + v_base_addr = v_base_addr + v_immediate; + break; + + case RET: + case NOP: + break; } - if(this->is_vector_type(m)) { - if(this->curr_instr->mnemonic != LOADV && this->curr_instr->mnemonic != STOREV){ - this->curr_instr->operands.vector.slot_one = v1; + if (this->is_vector_type(m)) { + if (this->curr_instr->mnemonic != LOADV && + this->curr_instr->mnemonic != STOREV) { + this->curr_instr->operands.vector.slot_one = v1; } else { - this->curr_instr->operands.load_store_vector.base_addr = v_base_addr; - } - } else{ + this->curr_instr->operands.load_store_vector.base_addr = + v_base_addr; + } + } else { this->curr_instr->operands.integer.slot_one = s1; } this->status = OK; diff --git a/src/id.cc b/src/id.cc index 4358150..e4790ef 100644 --- a/src/id.cc +++ b/src/id.cc @@ -285,6 +285,7 @@ void ID::decode_J_type(signed int &s1) s3 = 2; // stack pointer s1 = -1; // increment amount r1 = this->read_guard(s2); + this->curr_instr->operands.integer.slot_one = s1; this->curr_instr->operands.integer.slot_two = s2; r2 = (this->is_checked_out(s3)) ? STALLED : OK; // we read the stack pointer @@ -298,6 +299,7 @@ void ID::decode_J_type(signed int &s1) s2 = s1; // destination s3 = 2; // stack pointer s1 = 1; // increment amount + this->curr_instr->operands.integer.slot_one = s1; r1 = (this->is_checked_out(s3)) ? STALLED : OK; // we read the stack pointer if (r1 == OK) { @@ -316,7 +318,7 @@ void ID::decode_J_type(signed int &s1) if(this->status == OK){ this->curr_instr->operands.integer.slot_one = s1; this->curr_instr->operands.integer.slot_two = s2; - this->curr_instr->operands.integer.slot_three = s3; + this->curr_instr->operands.integer.slot_three = s3; } } } -- cgit v1.2.3