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 --- src/id.cc | 178 +++++++++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 131 insertions(+), 47 deletions(-) (limited to 'src/id.cc') diff --git a/src/id.cc b/src/id.cc index 0135c21..b976ef0 100644 --- a/src/id.cc +++ b/src/id.cc @@ -22,30 +22,26 @@ #include "response.h" #include "stage.h" -void ID::split_instr(signed int &raw, unsigned int &type, Mnemonic &m) +Response ID::read_guard(signed int &v) { - unsigned int opcode, opcode_size; - - type = GET_LS_BITS(raw, TYPE_SIZE); - opcode_size = (type == 0b0) ? R_OPCODE_SIZE : OPCODE_SIZE; - opcode = GET_MID_BITS(raw, TYPE_SIZE, TYPE_SIZE + opcode_size); - try { - m = instr::mnemonic_map.at((opcode << TYPE_SIZE) + type); - } catch (std::out_of_range const &) { - m = NOP; + Response r; + if (this->is_checked_out(v)) + r = STALLED; + else { + r = OK; + v = this->dereference_register(v); } - - raw = (unsigned int)raw >> (TYPE_SIZE + opcode_size); + return r; } -Response ID::read_guard(signed int &v) +Response ID::read_vec_guard(signed int v, std::array &vrs) { Response r; if (this->is_checked_out(v)) r = STALLED; else { r = OK; - v = this->dereference_register(v); + vrs = this->dereference_register>(v); } return r; } @@ -59,54 +55,95 @@ void ID::write_guard(signed int &v) this->checked_out.push_back(v); this->curr_instr->checked_out = v; } - v = this->dereference_register(v); + v = this->dereference_register(v); +} + +void ID::write_vec_guard(signed int v, std::array &vrs){ + + // zero register shouldn't be written. + if (v != 0) { + // keep track in the instrDTO for displaying to user and writeback + // keep track in checked_out so we can still access this information! + this->checked_out.push_back(v); + this->curr_instr->checked_out = v; + } + vrs = this->dereference_register>(v); } void ID::advance_helper() { - signed int s1, s2, s3; - Mnemonic m; + signed int s1; - if (curr_instr->mnemonic == NOP) + if (this->curr_instr->mnemonic == NOP) this->status = OK; else { - s1 = curr_instr->slot_A; - get_instr_fields(s1, s2, s3, m); - if (this->status == OK) { - curr_instr->operands.integer.slot_one = s1; - curr_instr->operands.integer.slot_two = s2; - curr_instr->operands.integer.slot_three = s3; - curr_instr->mnemonic = m; - } + // instuction in bits in s1 + s1 = this->curr_instr->slot_A; + get_instr_fields(s1); } } -void ID::get_instr_fields( - signed int &s1, signed int &s2, signed int &s3, Mnemonic &m) +void ID::get_instr_fields(signed int &s1) { unsigned int type; + Mnemonic m; this->split_instr(s1, type, m); - + this->curr_instr->mnemonic = m; switch (type) { case 0b00: - this->decode_R_type(s1, s2, s3, m); + this->decode_R_type(s1); break; case 0b01: - this->decode_I_type(s1, s2, s3, m); + this->decode_I_type(s1); break; case 0b10: - this->decode_J_type(s1, s2, s3, m); + this->decode_J_type(s1); break; case 0b11: + // not defined, m = NOP this->status = OK; } } -void ID::decode_R_type( - signed int &s1, signed int &s2, signed int &s3, Mnemonic &m) +void ID::split_instr(signed int &raw, unsigned int &type, Mnemonic &m) +{ + unsigned int opcode, opcode_size; + + type = GET_LS_BITS(raw, TYPE_SIZE); + opcode_size = (type == 0b0) ? R_OPCODE_SIZE : OPCODE_SIZE; + opcode = GET_MID_BITS(raw, TYPE_SIZE, TYPE_SIZE + opcode_size); + try { + m = instr::mnemonic_map.at((opcode << TYPE_SIZE) + type); + } catch (std::out_of_range const &) { + m = NOP; + } + + raw = (unsigned int)raw >> (TYPE_SIZE + opcode_size); +} + +Response ID::set_vlen(){ + signed int vlen_reg = 4; + Response r; + r = this->read_guard(vlen_reg); + vlen_reg = vlen_reg & 0xf; + if (r == OK){ + if (vlen_reg > V_R_LIMIT){ + this->curr_instr->slot_A = V_R_LIMIT; + } else { + this->curr_instr->slot_A = vlen_reg; + } + } + return r; +} + + + +void ID::decode_R_type(signed int &s1) { unsigned int s0b, s1b, s2b; + signed int s2, s3; Response r1, r2; + Response r3 = OK; s0b = REG_SIZE; s1b = s0b + REG_SIZE; @@ -115,44 +152,83 @@ void ID::decode_R_type( s2 = GET_MID_BITS(s1, s0b, s1b); s1 = GET_LS_BITS(s1, s0b); - r1 = this->read_guard(s1); - r2 = this->read_guard(s2); - this->status = (r1 == OK && r2 == OK) ? OK : STALLED; + if(this->is_vector_type(this->curr_instr->mnemonic)){ + r1 = this->read_vec_guard(s1, this->curr_instr->operands.vector.slot_one); + r2 = this->read_vec_guard(s2, this->curr_instr->operands.vector.slot_two); + r3 = this->set_vlen(); + } else { + r1 = this->read_guard(s1); + this->curr_instr->operands.integer.slot_one = s1; + r2 = this->read_guard(s2); + this->curr_instr->operands.integer.slot_two = s2; + } - switch (m) { + this->status = (r1 == OK && r2 == OK && r3 == OK) ? OK : STALLED; + + switch (this->curr_instr->mnemonic) { case CMP: case CEV: break; + case ADDV: + case SUBV: + case MULV: + case DIVV: + if(this->status == OK){ + this->write_vec_guard(s3, this->curr_instr->operands.vector.slot_three); + } + break; default: if (this->status == OK) this->write_guard(s3); + this->curr_instr->operands.integer.slot_three = s3; } } -void ID::decode_I_type( - signed int &s1, signed int &s2, signed int &s3, Mnemonic &m) +void ID::decode_I_type(signed int &s1) { unsigned int s0b, s1b, s2b; + signed int s2, s3; Response r1, r2; + Response r3 = OK; s0b = REG_SIZE; s1b = s0b + REG_SIZE; s2b = WORD_SPEC - LINE_SPEC - OPCODE_SIZE; s3 = GET_BITS_SIGN_EXTEND(s1, s1b, s2b); - switch (m) { + switch (this->curr_instr->mnemonic) { case STORE: - case STOREV: s2 = GET_MID_BITS(s1, s0b, s1b); s1 = GET_LS_BITS(s1, s0b); // both operands are read values r1 = this->read_guard(s1); + this->curr_instr->operands.integer.slot_one = s1; r2 = this->read_guard(s2); + this->curr_instr->operands.integer.slot_two = s2; this->status = (r1 == OK && r2 == OK) ? OK : STALLED; return; - case LOAD: + case STOREV: + 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); + r2 = this->read_vec_guard(s2,this->curr_instr->operands.vector.slot_two); + r3 = this->set_vlen(); + + this->status = (r1 == OK && r2 == OK && r3 == OK) ? OK : STALLED; + return; case LOADV: + s2 = GET_LS_BITS(s1, s0b); + s1 = GET_MID_BITS(s1, s0b, s1b); + r1 = this->read_vec_guard(s1, this->curr_instr->operands.vector.slot_one); + r3 = this->set_vlen(); + if (r1 == OK && r3 == OK) + this->write_vec_guard(s2, this->curr_instr->operands.vector.slot_two); + this->status = (r1 == OK && r3 == OK) ? OK : STALLED; + return; + case LOAD: s2 = GET_LS_BITS(s1, s0b); s1 = GET_MID_BITS(s1, s0b, s1b); break; @@ -162,15 +238,18 @@ void ID::decode_I_type( } r1 = this->read_guard(s1); - if (r1 == OK) + this->curr_instr->operands.integer.slot_one = s1; + if (r1 == OK){ this->write_guard(s2); + this->curr_instr->operands.integer.slot_two = s2; + } this->status = r1; } -void ID::decode_J_type( - signed int &s1, signed int &s2, signed int &s3, Mnemonic &m) +void ID::decode_J_type(signed int &s1) { Response r1, r2; + signed int s2,s3; unsigned int s0b, s1b; s0b = REG_SIZE; @@ -179,15 +258,17 @@ void ID::decode_J_type( s2 = GET_BITS_SIGN_EXTEND(s1, s0b, s1b); s1 = GET_LS_BITS(s1, s0b); - switch (m) { + switch (this->curr_instr->mnemonic) { case PUSH: s2 = s1; // source s3 = 2; // stack pointer s1 = -1; // increment amount r1 = this->read_guard(s2); + this->curr_instr->operands.integer.slot_two = s2; r2 = (this->is_checked_out(s3)) ? STALLED : OK; // we read the stack pointer if (r1 == OK && r2 == OK) { this->write_guard(s3); // we write the stack pointer + this->curr_instr->operands.integer.slot_three = s3; } this->status = (r1 == OK && r2 == OK) ? OK : STALLED; break; @@ -198,7 +279,9 @@ void ID::decode_J_type( r1 = (this->is_checked_out(s3)) ? STALLED : OK; // we read the stack pointer if (r1 == OK) { this->write_guard(s2); + this->curr_instr->operands.integer.slot_two = s2; this->write_guard(s3); // we write the stack pointer + this->curr_instr->operands.integer.slot_three = s3; } this->status = r1; break; @@ -207,6 +290,7 @@ void ID::decode_J_type( [[fallthrough]]; default: this->status = this->read_guard(s1); + this->curr_instr->operands.integer.slot_one = s1; } } -- 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 'src/id.cc') 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 ee4af301dfd61b21e8aa3ce04e7a77b716d65f24 Mon Sep 17 00:00:00 2001 From: Siddarth-Suresh <65844402+Siddarth-Suresh@users.noreply.github.com> Date: Sun, 27 Apr 2025 00:04:53 -0400 Subject: LOADV Changes --- src/id.cc | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src/id.cc') diff --git a/src/id.cc b/src/id.cc index d51c70c..28a48a0 100644 --- a/src/id.cc +++ b/src/id.cc @@ -227,11 +227,15 @@ void ID::decode_I_type(signed int &s1) this->status = (r1 == OK && r2 == OK && r3 == OK) ? OK : STALLED; return; case LOADV: + this->curr_instr->slot_C = s3; s2 = GET_LS_BITS(s1, s0b); s1 = GET_MID_BITS(s1, s0b, s1b); - 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; r3 = this->set_vlen(); if (r1 == OK && r3 == OK) + // vector destination this->write_vec_guard(s2, this->curr_instr->operands.vector.slot_two); this->status = (r1 == OK && r3 == OK) ? OK : STALLED; return; -- cgit v1.2.3 From 7aaa516c0de444c956dff88342a57e9313a19e34 Mon Sep 17 00:00:00 2001 From: Siddarth-Suresh <65844402+Siddarth-Suresh@users.noreply.github.com> Date: Sun, 27 Apr 2025 15:04:25 -0400 Subject: WB and MEM changes for vectors --- inc/instrDTO.h | 13 ++++++++----- src/ex.cc | 39 +++++++++++++++++++++------------------ src/id.cc | 12 ++++++------ src/mm.cc | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++ src/wb.cc | 11 ++++++++++- 5 files changed, 97 insertions(+), 30 deletions(-) (limited to 'src/id.cc') 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 slot_three; }; +struct LOAD_STORE_V_TYPE{ + signed int base_addr; + signed int immediate; + std::array vector_register; +}; + struct InstrDTO { /** * If this instruction is squashed or not. @@ -43,13 +49,9 @@ 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. */ @@ -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;iset_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(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>(reg, this->curr_instr->operands.vector.slot_one); + } else { + this->store_register>(reg, this->curr_instr->operands.load_store_vector.vector_register); + } + } else{ + this->store_register(reg, this->curr_instr->operands.integer.slot_one); + } } void WB::jump_handler() -- cgit v1.2.3 From 07c618096daec422c42ee1a379200101d0d349cc Mon Sep 17 00:00:00 2001 From: bd Date: Sun, 27 Apr 2025 16:00:06 -0400 Subject: Add files for new RegisterView class --- gui/gui.cc | 6 ++++-- gui/registerview.cc | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++ gui/registerview.h | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ gui/storageview.cc | 5 +++-- gui/storageview.h | 12 ++++++++---- src/id.cc | 2 -- 6 files changed, 116 insertions(+), 10 deletions(-) create mode 100644 gui/registerview.cc create mode 100644 gui/registerview.h (limited to 'src/id.cc') diff --git a/gui/gui.cc b/gui/gui.cc index b4feda6..4d558d4 100644 --- a/gui/gui.cc +++ b/gui/gui.cc @@ -21,6 +21,7 @@ #include "dynamicwaysentry.h" #include "messages.h" #include "storageview.h" +#include "registerview.h" #include "util.h" #include #include @@ -355,14 +356,15 @@ void GUI::make_tabs(int num) for (i = 0; i < num; ++i) { if (i == 0) { n = "Registers"; - e = new StorageView(0, this); + e = new RegisterView(GPR_NUM+V_NUM, V_R_LIMIT, this); } else if (i == num - 1) { n = "DRAM"; - e = new StorageView(MEM_LINES, this); + e = new StorageView(MEM_LINES, LINE_SIZE, this); } else { n = QString("L%1").arg(i); e = new StorageView( (1 << cache_size_mapper(this->curr_cache_levels - 1, i - 1)), + LINE_SIZE, this); } diff --git a/gui/registerview.cc b/gui/registerview.cc new file mode 100644 index 0000000..5320afa --- /dev/null +++ b/gui/registerview.cc @@ -0,0 +1,53 @@ +// Simulator for the RISC-V[ECTOR] mini-ISA +// Copyright (C) 2025 Siddarth Suresh +// Copyright (C) 2025 bdunahu + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include "registerview.h" +#include "definitions.h" +#include "util.h" +#include +#include + +QVariant RegisterView::data(const QModelIndex &i, int role) const +{ + Qt::Alignment a; + + if (role == Qt::TextAlignmentRole) { + a = Qt::AlignRight | Qt::AlignVCenter; + return QVariant(static_cast(a)); + } + if (!i.isValid() || role != Qt::DisplayRole) + return QVariant(); + return this->d[i.row()][i.column()]; +} + +QVariant RegisterView::headerData(int section, Qt::Orientation o, int role) const +{ + Qt::Alignment a; + + if (role == Qt::TextAlignmentRole) { + a = Qt::AlignRight | Qt::AlignVCenter; + return QVariant(static_cast(a)); + } + + if (role != Qt::DisplayRole) + return QVariant(); + + if (o == Qt::Vertical) { + return format_toggled_value(section * 4, this->is_hex); + } + return QVariant(); +} diff --git a/gui/registerview.h b/gui/registerview.h new file mode 100644 index 0000000..e4cb940 --- /dev/null +++ b/gui/registerview.h @@ -0,0 +1,48 @@ +// Simulator for the RISC-V[ECTOR] mini-ISA +// Copyright (C) 2025 Siddarth Suresh +// Copyright (C) 2025 bdunahu + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#ifndef REGISTERVIEW_H +#define REGISTERVIEW_H + +#include +#include "storageview.h" +#include + +// see https://doc.qt.io/qt-6/qabstracttablemodel.html +class RegisterView : public StorageView +{ + Q_OBJECT + public: + using StorageView::StorageView; + + /** + * Returns a properly formatted cell, including alignment.This function is + * specific to the implementation details of QAbstractTableModel. + */ + QVariant + data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + + /** + * Adds custom formatting options for row and column headers. + */ + QVariant headerData( + int section, + Qt::Orientation o, + int role = Qt::DisplayRole) const override; +}; + +#endif // REGISTERVIEW_H diff --git a/gui/storageview.cc b/gui/storageview.cc index 2f444a9..60391f9 100644 --- a/gui/storageview.cc +++ b/gui/storageview.cc @@ -21,10 +21,11 @@ #include #include -StorageView::StorageView(int rows, QObject *parent) +StorageView::StorageView(int rows, int columns, QObject *parent) : QAbstractTableModel(parent) { this->r = rows; + this->c = columns; this->d.resize(rows); for (auto &row : this->d) row.resize(LINE_SIZE, 0); @@ -32,7 +33,7 @@ StorageView::StorageView(int rows, QObject *parent) int StorageView::rowCount(const QModelIndex &) const { return this->r; } -int StorageView::columnCount(const QModelIndex &) const { return LINE_SIZE; } +int StorageView::columnCount(const QModelIndex &) const { return this->c; } QVariant StorageView::data(const QModelIndex &i, int role) const { diff --git a/gui/storageview.h b/gui/storageview.h index 0518d8f..e8f3473 100644 --- a/gui/storageview.h +++ b/gui/storageview.h @@ -31,7 +31,7 @@ class StorageView : public QAbstractTableModel * `rows' rows. * @param the number of rows */ - StorageView(int rows, QObject *parent = nullptr); + StorageView(int rows, int columns, QObject *parent = nullptr); /** * Returns the number of rows in this table. @@ -51,13 +51,13 @@ class StorageView : public QAbstractTableModel * Returns a properly formatted cell, including alignment.This function is * specific to the implementation details of QAbstractTableModel. */ - QVariant + virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; /** * Adds custom formatting options for row and column headers. */ - QVariant headerData( + virtual QVariant headerData( int section, Qt::Orientation o, int role = Qt::DisplayRole) const override; @@ -75,11 +75,15 @@ class StorageView : public QAbstractTableModel public slots: void set_hex_display(bool hex); - private: + protected: /** * The number of rows in this table. */ int r; + /** + * The number of columns in this table. + */ + int c; /** * Whether or not the headers should be displayed in hex. */ diff --git a/src/id.cc b/src/id.cc index 7398f49..aebb054 100644 --- a/src/id.cc +++ b/src/id.cc @@ -136,8 +136,6 @@ Response ID::set_vlen(){ return r; } - - void ID::decode_R_type(signed int &s1) { unsigned int s0b, s1b, s2b; -- cgit v1.2.3 From 4f77c3161128ff965b26f9575853c5347c0d662d Mon Sep 17 00:00:00 2001 From: bd Date: Sun, 27 Apr 2025 17:34:16 -0400 Subject: Basic register display --- gui/digitlabeldelegate.cc | 8 +++++-- gui/gui.cc | 44 +++++++++------------------------------ gui/gui.h | 2 +- gui/registerview.cc | 24 +++++++++++++++++---- gui/registerview.h | 18 +++++++++++++++- gui/storageview.h | 2 ++ gui/worker.cc | 24 +++++++-------------- gui/worker.h | 21 +++++++++++++++---- inc/controller.h | 6 +++++- src/controller.cc | 8 ++++++- src/id.cc | 53 ++++++++++++++++++++++++++++------------------- 11 files changed, 125 insertions(+), 85 deletions(-) (limited to 'src/id.cc') diff --git a/gui/digitlabeldelegate.cc b/gui/digitlabeldelegate.cc index 430946c..7a6a1d5 100644 --- a/gui/digitlabeldelegate.cc +++ b/gui/digitlabeldelegate.cc @@ -37,9 +37,13 @@ void DigitLabelDelegate::paint( QString t; QStyleOptionViewItem o; QStyle *s; + QVariant a; + bool e; - v = index.data(Qt::DisplayRole).toInt(); - t = format_toggled_value(v, this->is_hex); + a = index.data(Qt::DisplayRole); + v = a.toInt(); + e = a.isNull(); + t = format_toggled_value(v, this->is_hex, e); o = option; initStyleOption(&o, index); diff --git a/gui/gui.cc b/gui/gui.cc index 63bb4f3..395c6e6 100644 --- a/gui/gui.cc +++ b/gui/gui.cc @@ -17,11 +17,11 @@ #include "gui.h" #include "./ui_gui.h" -#include "digitlabeldelegate.h" #include "cachewaysselector.h" +#include "digitlabeldelegate.h" #include "messages.h" -#include "storageview.h" #include "registerview.h" +#include "storageview.h" #include "util.h" #include #include @@ -112,32 +112,6 @@ GUI::~GUI() delete ui; } -void displayArrayHTML(QTextEdit *textEdit, const std::array &data) -{ - textEdit->setReadOnly(false); - QString tableText = ""; - - tableText += ""; - int index = 0; - for (int value : data) { - tableText += QString("") - .arg(QString::asprintf("%04X", value)) - .arg(index); - index++; - } - tableText += ""; - tableText += "
" - "%1 %2" - "
"; - - textEdit->setHtml(tableText); - textEdit->setReadOnly(true); -} - void GUI::on_worker_refresh_gui(int cycles, int pc) { ui->p_counter->set_value(pc); @@ -224,10 +198,13 @@ void GUI::onWorkerShowStorage(const QVector> &data, int i) this->tab_boxes.at(i)->set_data(data); } -void GUI::onWorkerShowRegisters(const std::array &data) +void GUI::onWorkerShowRegisters( + const QVector &gprs, const QVector> &vrs) { - ; - // displayArrayHTML(this->tab_boxes.at(0), data); + RegisterView *rv; + + rv = dynamic_cast(this->tab_boxes.at(0)); + rv->set_data(gprs, vrs); } void GUI::on_upload_intructions_btn_clicked() @@ -353,7 +330,7 @@ void GUI::make_tabs(int num) for (i = 0; i < num; ++i) { if (i == 0) { n = "Registers"; - e = new RegisterView(GPR_NUM+V_NUM, V_R_LIMIT, this); + e = new RegisterView(GPR_NUM + V_NUM, V_R_LIMIT, this); } else if (i == num - 1) { n = "DRAM"; e = new StorageView(MEM_LINES, LINE_SIZE, this); @@ -361,8 +338,7 @@ void GUI::make_tabs(int num) n = QString("L%1").arg(i); e = new StorageView( (1 << cache_size_mapper(this->curr_cache_levels - 1, i - 1)), - LINE_SIZE, - this); + LINE_SIZE, this); } t = new QTableView(ui->storage); diff --git a/gui/gui.h b/gui/gui.h index 8e0b5b4..edcde88 100644 --- a/gui/gui.h +++ b/gui/gui.h @@ -72,7 +72,7 @@ class GUI : public QMainWindow void onWorkerShowStorage(const QVector> &data, int i); - void onWorkerShowRegisters(const std::array &data); + void onWorkerShowRegisters(const QVector &gprs, const QVector> &vrs); void on_upload_intructions_btn_clicked(); diff --git a/gui/registerview.cc b/gui/registerview.cc index 5320afa..b1a1333 100644 --- a/gui/registerview.cc +++ b/gui/registerview.cc @@ -15,8 +15,8 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . +#include "pipe_spec.h" #include "registerview.h" -#include "definitions.h" #include "util.h" #include #include @@ -29,12 +29,22 @@ QVariant RegisterView::data(const QModelIndex &i, int role) const a = Qt::AlignRight | Qt::AlignVCenter; return QVariant(static_cast(a)); } + if (!i.isValid() || role != Qt::DisplayRole) return QVariant(); - return this->d[i.row()][i.column()]; + + if (i.row() < 16) { + if (i.column() < 1) + return this->gprs[i.row()]; + else + return QVariant(); + } + + return this->vrs[i.row() - GPR_NUM][i.column() - GPR_NUM]; } -QVariant RegisterView::headerData(int section, Qt::Orientation o, int role) const +QVariant +RegisterView::headerData(int section, Qt::Orientation o, int role) const { Qt::Alignment a; @@ -47,7 +57,13 @@ QVariant RegisterView::headerData(int section, Qt::Orientation o, int role) cons return QVariant(); if (o == Qt::Vertical) { - return format_toggled_value(section * 4, this->is_hex); + return format_toggled_value(section, this->is_hex); } return QVariant(); } + +void RegisterView::set_data(const QVector &gprs, const QVector> &vrs) +{ + this->gprs = gprs; + this->vrs = vrs; +} diff --git a/gui/registerview.h b/gui/registerview.h index e4cb940..cc5a1f8 100644 --- a/gui/registerview.h +++ b/gui/registerview.h @@ -18,8 +18,8 @@ #ifndef REGISTERVIEW_H #define REGISTERVIEW_H -#include #include "storageview.h" +#include #include // see https://doc.qt.io/qt-6/qabstracttablemodel.html @@ -43,6 +43,22 @@ class RegisterView : public StorageView int section, Qt::Orientation o, int role = Qt::DisplayRole) const override; + + /** + * @param field to assign to `this->gprs'. + * @param field to assign to `this->vrs'. + */ + void set_data(const QVector &gprs, const QVector> &vrs); + + private: + /** + * The general purpose registers. + */ + QVector gprs; + /** + * The vector registers. + */ + QVector> vrs; }; #endif // REGISTERVIEW_H diff --git a/gui/storageview.h b/gui/storageview.h index e8f3473..a0f8dbb 100644 --- a/gui/storageview.h +++ b/gui/storageview.h @@ -88,6 +88,8 @@ class StorageView : public QAbstractTableModel * Whether or not the headers should be displayed in hex. */ bool is_hex = true; + + private: /** * The data this table displays. */ diff --git a/gui/worker.cc b/gui/worker.cc index dd7b637..a48888c 100644 --- a/gui/worker.cc +++ b/gui/worker.cc @@ -78,9 +78,16 @@ void Worker::runSteps(int steps) void Worker::update() { unsigned long i; + std::array gprs; + std::array, V_NUM> vrs; this->ct_mutex.lock(); - emit register_storage(this->ct->get_gprs()); + gprs = this->ct->get_gprs(); + vrs = this->ct->get_vrs(); + std::vector> v(vrs.begin(), vrs.end()); + + emit register_storage( + QVector(gprs.begin(), gprs.end()), this->data_to_QT(v)); for (i = 0; i < s.size(); ++i) emit storage(this->data_to_QT(this->s.at(i)->get_data()), i + 1); @@ -93,18 +100,3 @@ void Worker::update() emit wb_info(this->wb_stage->get_instr()); this->ct_mutex.unlock(); } - -QVector> -Worker::data_to_QT(std::vector> data) -{ - QVector> r; - QVector tmp; - - r.reserve(static_cast(data.size())); - - for (const auto &line : data) { - tmp = QVector(line.begin(), line.end()); - r.append(tmp); - } - return r; -} diff --git a/gui/worker.h b/gui/worker.h index 5ffb6ef..2a362a4 100644 --- a/gui/worker.h +++ b/gui/worker.h @@ -64,9 +64,9 @@ class Worker : public QObject signals: void clock_cycles(int value, int pc); - void - storage(QVector> data, int i); - void register_storage(const std::array data); + void storage(QVector> data, int i); + void register_storage( + QVector gprs, QVector> vrs); void if_info(const InstrDTO *); void id_info(const InstrDTO *); void ex_info(const InstrDTO *); @@ -81,8 +81,21 @@ class Worker : public QObject * @param the original data * @return a less universal version of the same thing */ + template QVector> - data_to_QT(std::vector> data); + data_to_QT(const std::vector> &data) + { + QVector> r; + QVector tmp; + + r.reserve(static_cast(data.size())); + + for (const auto &line : data) { + tmp = QVector(line.begin(), line.end()); + r.append(tmp); + } + return r; + } /** * Sets the GUI signals to update the storage, clock cycle, and stage * displays. 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 get_gprs(); + std::array get_gprs(); + /** + * @return a copy of vrs. + */ + std::array, V_NUM> get_vrs(); /** * @return the pc. */ diff --git a/src/controller.cc b/src/controller.cc index 8df4b97..a84126d 100644 --- a/src/controller.cc +++ b/src/controller.cc @@ -15,6 +15,7 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . +#include "definitions.h" #include "controller.h" #include "ex.h" #include "response.h" @@ -47,7 +48,12 @@ void Controller::run_for(int number) int Controller::get_clock_cycle() { return this->clock_cycle; } -std::array Controller::get_gprs() { return this->gprs; } +std::array Controller::get_gprs() { return this->gprs; } + +std::array, V_NUM> Controller::get_vrs() +{ + return this->vrs; +} int Controller::get_pc() { return this->pc; } diff --git a/src/id.cc b/src/id.cc index aebb054..7db67c4 100644 --- a/src/id.cc +++ b/src/id.cc @@ -34,7 +34,8 @@ Response ID::read_guard(signed int &v) return r; } -Response ID::read_vec_guard(signed int v, std::array &vrs) +Response +ID::read_vec_guard(signed int v, std::array &vrs) { Response r; if (this->is_checked_out(v)) @@ -58,7 +59,8 @@ void ID::write_guard(signed int &v) v = this->dereference_register(v); } -void ID::write_vec_guard(signed int v, std::array &vrs){ +void ID::write_vec_guard(signed int v, std::array &vrs) +{ // zero register shouldn't be written. if (v != 0) { @@ -121,13 +123,14 @@ void ID::split_instr(signed int &raw, unsigned int &type, Mnemonic &m) raw = (unsigned int)raw >> (TYPE_SIZE + opcode_size); } -Response ID::set_vlen(){ +Response ID::set_vlen() +{ signed int vlen_reg = 4; Response r; r = this->read_guard(vlen_reg); vlen_reg = vlen_reg & 0xf; - if (r == OK){ - if (vlen_reg > V_R_LIMIT){ + if (r == OK) { + if (vlen_reg > V_R_LIMIT) { this->curr_instr->slot_A = V_R_LIMIT; } else { this->curr_instr->slot_A = vlen_reg; @@ -150,9 +153,11 @@ void ID::decode_R_type(signed int &s1) s2 = GET_MID_BITS(s1, s0b, s1b); s1 = GET_LS_BITS(s1, s0b); - if(this->is_vector_type(this->curr_instr->mnemonic)){ - r1 = this->read_vec_guard(s1, this->curr_instr->operands.vector.slot_one); - r2 = this->read_vec_guard(s2, this->curr_instr->operands.vector.slot_two); + if (this->is_vector_type(this->curr_instr->mnemonic)) { + r1 = this->read_vec_guard( + s1, this->curr_instr->operands.vector.slot_one); + r2 = this->read_vec_guard( + s2, this->curr_instr->operands.vector.slot_two); r3 = this->set_vlen(); } else { r1 = this->read_guard(s1); @@ -171,14 +176,16 @@ void ID::decode_R_type(signed int &s1) case SUBV: case MULV: case DIVV: - if(this->status == OK){ - this->write_vec_guard(s3, this->curr_instr->operands.vector.slot_three); + if (this->status == OK) { + this->write_vec_guard( + s3, this->curr_instr->operands.vector.slot_three); } break; default: - if (this->status == OK) + if (this->status == OK) { this->write_guard(s3); this->curr_instr->operands.integer.slot_three = s3; + } } } @@ -219,7 +226,8 @@ void ID::decode_I_type(signed int &s1) r1 = this->read_guard(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.load_store_vector.vector_register); + 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; @@ -234,7 +242,9 @@ void ID::decode_I_type(signed int &s1) r3 = this->set_vlen(); if (r1 == OK && r3 == OK) // vector destination - this->write_vec_guard(s2, this->curr_instr->operands.load_store_vector.vector_register); + 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: @@ -249,7 +259,7 @@ void ID::decode_I_type(signed int &s1) r1 = this->read_guard(s1); this->curr_instr->operands.integer.slot_one = s1; - if (r1 == OK){ + if (r1 == OK) { this->write_guard(s2); this->curr_instr->operands.integer.slot_two = s2; } @@ -259,7 +269,7 @@ void ID::decode_I_type(signed int &s1) void ID::decode_J_type(signed int &s1) { Response r1, r2; - signed int s2,s3; + signed int s2, s3; unsigned int s0b, s1b; s0b = REG_SIZE; @@ -271,11 +281,12 @@ void ID::decode_J_type(signed int &s1) switch (this->curr_instr->mnemonic) { case PUSH: s2 = s1; // source - s3 = 2; // stack pointer + s3 = 2; // stack pointer s1 = -1; // increment amount r1 = this->read_guard(s2); this->curr_instr->operands.integer.slot_two = s2; - r2 = (this->is_checked_out(s3)) ? STALLED : OK; // we read the stack pointer + r2 = (this->is_checked_out(s3)) ? STALLED + : OK; // we read the stack pointer if (r1 == OK && r2 == OK) { this->write_guard(s3); // we write the stack pointer this->curr_instr->operands.integer.slot_three = s3; @@ -284,9 +295,10 @@ void ID::decode_J_type(signed int &s1) break; case POP: s2 = s1; // destination - s3 = 2; // stack pointer - s1 = 1; // increment amount - r1 = (this->is_checked_out(s3)) ? STALLED : OK; // we read the stack pointer + s3 = 2; // stack pointer + s1 = 1; // increment amount + r1 = (this->is_checked_out(s3)) ? STALLED + : OK; // we read the stack pointer if (r1 == OK) { this->write_guard(s2); this->curr_instr->operands.integer.slot_two = s2; @@ -302,5 +314,4 @@ void ID::decode_J_type(signed int &s1) this->status = this->read_guard(s1); this->curr_instr->operands.integer.slot_one = s1; } - } -- 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 'src/id.cc') 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 'src/id.cc') 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