summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSiddarth-Suresh <65844402+Siddarth-Suresh@users.noreply.github.com>2025-04-27 15:04:25 -0400
committerSiddarth-Suresh <65844402+Siddarth-Suresh@users.noreply.github.com>2025-04-27 15:04:25 -0400
commit7aaa516c0de444c956dff88342a57e9313a19e34 (patch)
tree011c07d24ec6e226ac703d50aab7dbf6089935d3
parent66dbfb6ee729e1ff8352c876e6c42aca2081f2e5 (diff)
WB and MEM changes for vectors
-rw-r--r--inc/instrDTO.h13
-rw-r--r--src/ex.cc39
-rw-r--r--src/id.cc12
-rw-r--r--src/mm.cc52
-rw-r--r--src/wb.cc11
5 files changed, 97 insertions, 30 deletions
diff --git a/inc/instrDTO.h b/inc/instrDTO.h
index b99ba20..f3d4597 100644
--- a/inc/instrDTO.h
+++ b/inc/instrDTO.h
@@ -33,6 +33,12 @@ struct V_TYPE {
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 {
/**
* If this instruction is squashed or not.
@@ -43,14 +49,10 @@ struct InstrDTO {
*/
signed int slot_A;
/**
- * Optional slot for holding PC / base address
+ * Optional slot for holding PC
*/
signed int slot_B;
/**
- * Optional slot to hold immediates
- */
- signed int slot_C;
- /**
* The mnemonic of the instruction.
*/
Mnemonic mnemonic;
@@ -61,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/src/ex.cc b/src/ex.cc
index 947407a..03a4e59 100644
--- a/src/ex.cc
+++ b/src/ex.cc
@@ -33,29 +33,26 @@ void EX::advance_helper()
Mnemonic m;
m = this->curr_instr->mnemonic;
+ pc = this->curr_instr->slot_B;
if(this->is_vector_type(m)) {
- v1 = this->curr_instr->operands.vector.slot_one;
- v2 = this->curr_instr->operands.vector.slot_two;
- v3 = this->curr_instr->operands.vector.slot_three;
- v_len = this->curr_instr->slot_A;
- if(this->curr_instr->slot_C){
- v_immediate = this->curr_instr->slot_C;
- }
- if(this->curr_instr->slot_B){
- v_base_addr = this->curr_instr->slot_B;
+ 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;
+ } else {
+ v_immediate = this->curr_instr->operands.load_store_vector.immediate;
+ v_base_addr = this->curr_instr->operands.load_store_vector.base_addr;
}
- /*if(v_len == 0){
- //clear vector reg
+ v_len = this->curr_instr->slot_A;
+ if(v_len == 0){
+ //clear destination vector reg
v1.fill(0);
- v2.fill(0);
- v3.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;
- pc = this->curr_instr->slot_B;
}
if(this->is_logical(m)) {
@@ -216,12 +213,18 @@ void EX::advance_helper()
}
break;
case CEV:
- bool equal = true;
- for(int i=0;i<v_len;i++){
+ int i;
+ for(i=0;i<v_len;i++){
if(v1[i] != v2[i]){
- equal = false;
+ 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;
diff --git a/src/id.cc b/src/id.cc
index 28a48a0..1f0e62b 100644
--- a/src/id.cc
+++ b/src/id.cc
@@ -213,30 +213,30 @@ void ID::decode_I_type(signed int &s1)
this->status = (r1 == OK && r2 == OK) ? OK : STALLED;
return;
case STOREV:
- this->curr_instr->slot_C = s3;
+ this->curr_instr->operands.load_store_vector.immediate = s3;
s2 = GET_MID_BITS(s1, s0b, s1b);
s1 = GET_LS_BITS(s1, s0b);
// base address
r1 = this->read_guard(s1);
- this->curr_instr->slot_B = s1;
+ this->curr_instr->operands.load_store_vector.base_addr = s1;
// vector value to be stored
- r2 = this->read_vec_guard(s2,this->curr_instr->operands.vector.slot_two);
+ r2 = this->read_vec_guard(s2,this->curr_instr->operands.load_store_vector.vector_register);
r3 = this->set_vlen();
this->status = (r1 == OK && r2 == OK && r3 == OK) ? OK : STALLED;
return;
case LOADV:
- this->curr_instr->slot_C = s3;
+ this->curr_instr->operands.load_store_vector.immediate = s3;
s2 = GET_LS_BITS(s1, s0b);
s1 = GET_MID_BITS(s1, s0b, s1b);
// base address
r1 = this->read_guard(s1);
- this->curr_instr->slot_B = s1;
+ this->curr_instr->operands.load_store_vector.base_addr = s1;
r3 = this->set_vlen();
if (r1 == OK && r3 == OK)
// vector destination
- this->write_vec_guard(s2, this->curr_instr->operands.vector.slot_two);
+ this->write_vec_guard(s2, this->curr_instr->operands.load_store_vector.vector_register);
this->status = (r1 == OK && r3 == OK) ? OK : STALLED;
return;
case LOAD:
diff --git a/src/mm.cc b/src/mm.cc
index ac77433..8134cf5 100644
--- a/src/mm.cc
+++ b/src/mm.cc
@@ -24,6 +24,7 @@ void MM::advance_helper()
{
signed int data;
int i;
+ int vector_delay = VECTOR_MEM_DELAY;
switch (this->curr_instr->mnemonic) {
case LOAD:
@@ -35,6 +36,32 @@ 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:
@@ -46,6 +73,31 @@ 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 79efe44..0dae5f2 100644
--- a/src/wb.cc
+++ b/src/wb.cc
@@ -51,7 +51,16 @@ void WB::write_handler()
this->checked_out.pop_front();
reg = this->curr_instr->checked_out;
- this->store_register<signed int>(reg, this->curr_instr->operands.integer.slot_one);
+
+ if(this->is_vector_type(this->curr_instr->mnemonic)) {
+ if(this->curr_instr->mnemonic != STOREV && this->curr_instr->mnemonic != LOADV) {
+ this->store_register<std::array<signed int, V_R_LIMIT>>(reg, this->curr_instr->operands.vector.slot_one);
+ } else {
+ this->store_register<std::array<signed int, V_R_LIMIT>>(reg, this->curr_instr->operands.load_store_vector.vector_register);
+ }
+ } else{
+ this->store_register<signed int>(reg, this->curr_instr->operands.integer.slot_one);
+ }
}
void WB::jump_handler()