From 2aabad6ed432831d6686700118cd189cb157e5cc Mon Sep 17 00:00:00 2001 From: bd Date: Thu, 8 May 2025 20:00:14 -0400 Subject: Use templates rather than two write guard methods --- inc/id.h | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) (limited to 'inc/id.h') diff --git a/inc/id.h b/inc/id.h index e8e9c36..ccce961 100644 --- a/inc/id.h +++ b/inc/id.h @@ -25,8 +25,8 @@ class ID : public Stage { public: - using Stage::Stage; using Stage::advance; + using Stage::Stage; /* The following methods are made public so that they may be tested, and are * not to be called from outside classes during standard execution. @@ -42,18 +42,7 @@ class ID : public Stage * @return OK if `r` is not checked out, STALLED otherwise. */ Response read_guard(signed int &r); - /** - * Facilitates register checkout and data hazard management. - * Checks out a register and returns it. - * - * @param the registers number, to be dereferenced and checked out. - */ - void write_guard(signed int &r); - Response read_vec_guard(signed int r, std::array &v); - - void write_vec_guard(signed int r, std::array &v); - Response set_vlen(); private: @@ -95,6 +84,26 @@ class ID : public Stage * @param the resulting type. */ void split_instr(signed int &raw, unsigned int &type, Mnemonic &m); + /** + * Facilitates register checkout and data hazard management. + * Checks out a register and returns it. + * + * @param the registers number, to be dereferenced and checked out. + */ + template T write_guard(int v) + { + T r; + // these registers shouldn't be written. + if (v != 0 && v != 16) { + // 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; + } + r = this->dereference_register(v); + return r; + } }; #endif /* ID_H_INCLUDED */ -- cgit v1.2.3 From d0bb0aaf39bb61736e72b30e4d8f1a4a39536a0c Mon Sep 17 00:00:00 2001 From: bd Date: Sat, 10 May 2025 15:17:40 -0400 Subject: Combine read_vec_guard and read_guard using templates --- inc/id.h | 31 ++++++++++++++++++++----------- src/id.cc | 51 +++++++++++++-------------------------------------- tests/id.cc | 15 --------------- 3 files changed, 33 insertions(+), 64 deletions(-) (limited to 'inc/id.h') diff --git a/inc/id.h b/inc/id.h index ccce961..c1928ed 100644 --- a/inc/id.h +++ b/inc/id.h @@ -32,17 +32,6 @@ class ID : public Stage * not to be called from outside classes during standard execution. */ - /** - * Facilitates register checkout and data hazard management. - * It does this by checking that the register passed in is not currently - * checked out. If true, then replaces r with the value of the register and - * returns OK. If false, returns STALLED. - * - * @param the registers number, to be dereferenced. - * @return OK if `r` is not checked out, STALLED otherwise. - */ - Response read_guard(signed int &r); - Response read_vec_guard(signed int r, std::array &v); Response set_vlen(); private: @@ -104,6 +93,26 @@ class ID : public Stage r = this->dereference_register(v); return r; } + /** + * Facilitates register checkout and data hazard management. + * It does this by checking that the register passed in is not currently + * checked out. If true, then replaces reg with the value of the register and + * returns OK. If false, returns STALLED. + * + * @param the registers number, to be dereferenced. + * @return OK if `reg` is not checked out, STALLED otherwise. + */ + template Response read_guard(int reg, T &result) + { + Response response; + if (this->is_checked_out(reg)) + response = STALLED; + else { + response = OK; + result = this->dereference_register(reg); + } + return response; + } }; #endif /* ID_H_INCLUDED */ diff --git a/src/id.cc b/src/id.cc index 430bf09..bc6b873 100644 --- a/src/id.cc +++ b/src/id.cc @@ -22,31 +22,6 @@ #include "response.h" #include "stage.h" -Response ID::read_guard(signed int &v) -{ - Response r; - if (this->is_checked_out(v)) - r = STALLED; - else { - r = OK; - v = this->dereference_register(v); - } - return r; -} - -Response -ID::read_vec_guard(signed int v, std::array &vrs) -{ - Response r; - if (this->is_checked_out(v)) - r = STALLED; - else { - r = OK; - vrs = this->dereference_register>(v); - } - return r; -} - void ID::advance_helper() { signed int s1; @@ -102,7 +77,7 @@ Response ID::set_vlen() { signed int vlen_reg = 4; Response r; - r = this->read_guard(vlen_reg); + r = this->read_guard(vlen_reg, vlen_reg); vlen_reg = vlen_reg & 0xf; if (r == OK) { if (vlen_reg > V_R_LIMIT) { @@ -129,15 +104,15 @@ void ID::decode_R_type(signed int &s1) s1 = GET_LS_BITS(s1, s0b); if (instr::is_vector_type(this->curr_instr->mnemonic)) { - r1 = this->read_vec_guard( + r1 = this->read_guard>( s1, this->curr_instr->operands.vector.slot_one); - r2 = this->read_vec_guard( + r2 = this->read_guard>( s2, this->curr_instr->operands.vector.slot_two); r3 = this->set_vlen(); } else { - r1 = this->read_guard(s1); + r1 = this->read_guard(s1, s1); this->curr_instr->operands.integer.slot_one = s1; - r2 = this->read_guard(s2); + r2 = this->read_guard(s2, s2); this->curr_instr->operands.integer.slot_two = s2; } @@ -185,10 +160,10 @@ void ID::decode_I_type(signed int &s1) // both operands are read values // s1 is base address - r1 = this->read_guard(s1); + r1 = this->read_guard(s1, s1); this->curr_instr->operands.integer.slot_one = s1; // s2 is value to be stored - r2 = this->read_guard(s2); + r2 = this->read_guard(s2, s2); this->curr_instr->operands.integer.slot_two = s2; this->status = (r1 == OK && r2 == OK) ? OK : STALLED; return; @@ -198,10 +173,10 @@ void ID::decode_I_type(signed int &s1) s1 = GET_LS_BITS(s1, s0b); // base address - r1 = this->read_guard(s1); + r1 = this->read_guard(s1, s1); this->curr_instr->operands.load_store_vector.base_addr = s1; // vector value to be stored - r2 = this->read_vec_guard( + r2 = this->read_guard>( s2, this->curr_instr->operands.load_store_vector.vector_register); r3 = this->set_vlen(); @@ -212,7 +187,7 @@ void ID::decode_I_type(signed int &s1) s2 = GET_LS_BITS(s1, s0b); s1 = GET_MID_BITS(s1, s0b, s1b); // base address - r1 = this->read_guard(s1); + r1 = this->read_guard(s1, s1); this->curr_instr->operands.load_store_vector.base_addr = s1; r3 = this->set_vlen(); if (r1 == OK && r3 == OK) @@ -232,7 +207,7 @@ void ID::decode_I_type(signed int &s1) s1 = GET_LS_BITS(s1, s0b); } - r1 = this->read_guard(s1); + r1 = this->read_guard(s1, s1); this->curr_instr->operands.integer.slot_one = s1; if (r1 == OK) { this->curr_instr->operands.integer.slot_two = @@ -258,7 +233,7 @@ void ID::decode_J_type(signed int &s1) s2 = s1; // source s3 = 2; // stack pointer s1 = -1; // increment amount - r1 = this->read_guard(s2); + r1 = this->read_guard(s2, s2); this->curr_instr->operands.integer.slot_one = s1; this->curr_instr->operands.integer.slot_two = s2; r2 = (this->is_checked_out(s3)) ? STALLED @@ -290,7 +265,7 @@ void ID::decode_J_type(signed int &s1) s1 = 1; // link register [[fallthrough]]; default: - this->status = this->read_guard(s1); + this->status = this->read_guard(s1, s1); if (this->status == OK) { this->curr_instr->operands.integer.slot_one = s1; this->curr_instr->operands.integer.slot_two = s2; diff --git a/tests/id.cc b/tests/id.cc index ca10677..0e7de3b 100644 --- a/tests/id.cc +++ b/tests/id.cc @@ -191,18 +191,3 @@ TEST_CASE_METHOD(IDFixture, "Parse arbitrary j-type # two", "[id]") delete i; } - -TEST_CASE_METHOD(IDFixture, "read does not conflict with read", "[id]") -{ - signed int v; - Response r; - - v = 0b1; - r = this->d->read_guard(v); - CHECK(v == 0b0); - REQUIRE(r == OK); - - v = 0b1; - this->d->read_guard(v); - REQUIRE(v == 0b0); -} -- cgit v1.2.3 From 5beea0c476101ec7b122f3b2181d92ce096492fb Mon Sep 17 00:00:00 2001 From: bd Date: Sat, 10 May 2025 15:30:29 -0400 Subject: Further small simplifications --- inc/id.h | 9 +++++---- src/id.cc | 27 +++++++++++++-------------- 2 files changed, 18 insertions(+), 18 deletions(-) (limited to 'inc/id.h') diff --git a/inc/id.h b/inc/id.h index c1928ed..5fda2b4 100644 --- a/inc/id.h +++ b/inc/id.h @@ -60,7 +60,7 @@ class ID : public Stage * @param the resulting third field, which varies per type. * @param the resulting mnemonic. */ - void get_instr_fields(signed int &s1); + void get_instr_fields(signed int instr_bits); void decode_R_type(signed int &s1); void decode_I_type(signed int &s1); void decode_J_type(signed int &s1); @@ -96,10 +96,11 @@ class ID : public Stage /** * Facilitates register checkout and data hazard management. * It does this by checking that the register passed in is not currently - * checked out. If true, then replaces reg with the value of the register and - * returns OK. If false, returns STALLED. + * checked out. If true, then sets `result' with the value of the register + * and returns OK. If false, returns STALLED. * - * @param the registers number, to be dereferenced. + * @param the registers number + * @param the dereferenced register value * @return OK if `reg` is not checked out, STALLED otherwise. */ template Response read_guard(int reg, T &result) diff --git a/src/id.cc b/src/id.cc index bc6b873..43975fb 100644 --- a/src/id.cc +++ b/src/id.cc @@ -24,37 +24,35 @@ void ID::advance_helper() { - signed int s1; - if (this->curr_instr->mnemonic == NOP) this->status = OK; else { // instuction in bits in s1 - s1 = this->curr_instr->slot_A; - get_instr_fields(s1); + get_instr_fields(this->curr_instr->slot_A); } } -void ID::get_instr_fields(signed int &s1) +void ID::get_instr_fields(signed int instr_bits) { unsigned int type; Mnemonic m; - this->split_instr(s1, type, m); + this->split_instr(instr_bits, type, m); this->curr_instr->mnemonic = m; switch (type) { case 0b00: - this->decode_R_type(s1); + this->decode_R_type(instr_bits); break; case 0b01: - this->decode_I_type(s1); + this->decode_I_type(instr_bits); break; case 0b10: - this->decode_J_type(s1); + this->decode_J_type(instr_bits); break; case 0b11: - // not defined, m = NOP + this->curr_instr->mnemonic = NOP; this->status = OK; } + } void ID::split_instr(signed int &raw, unsigned int &type, Mnemonic &m) @@ -233,9 +231,10 @@ void ID::decode_J_type(signed int &s1) s2 = s1; // source s3 = 2; // stack pointer s1 = -1; // increment amount - r1 = this->read_guard(s2, s2); + this->curr_instr->operands.integer.slot_one = s1; - this->curr_instr->operands.integer.slot_two = s2; + r1 = this->read_guard( + s2, this->curr_instr->operands.integer.slot_two); r2 = (this->is_checked_out(s3)) ? STALLED : OK; // we read the stack pointer if (r1 == OK && r2 == OK) { @@ -265,9 +264,9 @@ void ID::decode_J_type(signed int &s1) s1 = 1; // link register [[fallthrough]]; default: - this->status = this->read_guard(s1, s1); + this->status = this->read_guard( + s1, this->curr_instr->operands.integer.slot_one); 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