summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorbd <bdunahu@operationnull.com>2025-03-29 20:49:32 -0400
committerbd <bdunahu@operationnull.com>2025-03-29 20:49:32 -0400
commit4055b56b5d06e0188d764380d67e40b5b07359ac (patch)
treedd6ae93279b5922761b9ec36f39f54d3248d9d1e /src
parent24a7d608aa84d6549a52e54726e1379e97cac146 (diff)
Add advance logic for decode
Diffstat (limited to 'src')
-rw-r--r--src/sim/id.cc130
-rw-r--r--src/sim/if.cc4
2 files changed, 78 insertions, 56 deletions
diff --git a/src/sim/id.cc b/src/sim/id.cc
index c04b31f..68ac555 100644
--- a/src/sim/id.cc
+++ b/src/sim/id.cc
@@ -5,68 +5,26 @@
#include "logger.h"
#include "response.h"
#include "stage.h"
-#include <algorithm>
ID::ID(Stage *stage) : Stage(stage) { this->id = DCDE; }
Response ID::advance(InstrDTO &next_instr, Response p)
{
- Response r;
- signed int s1, s2, s3;
- Mnemonic m;
-
- s1 = next_instr.get_instr_bits();
-
- get_instr_fields(s1, s2, s3, m);
- return r;
-}
-
-void ID::decode_R_type(signed int &s1, signed int &s2, signed int &s3)
-{
- unsigned int s0b, s1b, s2b;
- Response r1, r2;
-
- s0b = REG_SIZE;
- s1b = s0b + REG_SIZE;
- s2b = s1b + REG_SIZE;
- s3 = GET_MID_BITS(s1, s1b, s2b);
- s2 = GET_MID_BITS(s1, s0b, s1b);
- s1 = GET_LS_BITS(s1, s0b);
-
- r1 = this->read_guard(s1);
- r2 = this->read_guard(s2);
- this->write_guard(s3);
-
- this->status = std::max(r1, r2);
-}
-void ID::decode_I_type(signed int &s1, signed int &s2, signed int &s3)
-{
- unsigned int s0b, s1b, s2b;
-
- s0b = REG_SIZE;
- s1b = s0b + REG_SIZE;
- s2b = WORD_SPEC;
- s3 = GET_MID_BITS(s1, s1b, s2b);
- s2 = GET_MID_BITS(s1, s0b, s1b);
- s1 = GET_LS_BITS(s1, s0b);
-
- this->status = this->read_guard(s1);
- this->write_guard(s2);
-}
-
-void ID::decode_J_type(signed int &s1, signed int &s2)
-{
- unsigned int s0b, s1b;
-
- s0b = REG_SIZE;
- s1b = WORD_SPEC;
- s2 = GET_MID_BITS(s1, s0b, s1b);
- s1 = GET_LS_BITS(s1, s0b);
+ Response n;
+
+ this->advance_helper();
+ if (this->status == OK && p == OK) {
+ // mutual consent
+ this->curr_instr->set_time_of(this->id, this->clock_cycle);
+ next_instr = *this->curr_instr;
+ curr_instr = nullptr;
+ }
- this->status = this->read_guard(*&s1);
+ n = (p != OK || this->status != OK) ? BLOCKED : OK;
+ // the power of consent
+ n = this->next->advance(next_instr, n);
}
-// TODO this function is ugly
void ID::get_instr_fields(
signed int &s1, signed int &s2, signed int &s3, Mnemonic &m)
{
@@ -119,3 +77,67 @@ void ID::write_guard(signed int &v)
this->checked_out.push_back(v);
v = this->dereference_register(v);
}
+
+void ID::advance_helper()
+{
+ signed int s1, s2, s3;
+ Mnemonic m;
+
+ // it may be good to ensure we are not doing
+ // work that has already been done
+ if (this->curr_instr) {
+ s1 = curr_instr->get_instr_bits();
+ get_instr_fields(s1, s2, s3, m);
+ if (this->status == OK) {
+ curr_instr->set_s1(s1);
+ curr_instr->set_s2(s2);
+ curr_instr->set_s3(s3);
+ curr_instr->set_mnemonic(m);
+ }
+ }
+}
+
+void ID::decode_R_type(signed int &s1, signed int &s2, signed int &s3)
+{
+ unsigned int s0b, s1b, s2b;
+ Response r1, r2;
+
+ s0b = REG_SIZE;
+ s1b = s0b + REG_SIZE;
+ s2b = s1b + REG_SIZE;
+ s3 = GET_MID_BITS(s1, s1b, s2b);
+ s2 = GET_MID_BITS(s1, s0b, s1b);
+ s1 = GET_LS_BITS(s1, s0b);
+
+ r1 = this->read_guard(s1);
+ r2 = this->read_guard(s2);
+ this->write_guard(s3);
+
+ this->status = (r1 == BLOCKED || r2 == BLOCKED) ? BLOCKED : OK;
+}
+void ID::decode_I_type(signed int &s1, signed int &s2, signed int &s3)
+{
+ unsigned int s0b, s1b, s2b;
+
+ s0b = REG_SIZE;
+ s1b = s0b + REG_SIZE;
+ s2b = WORD_SPEC;
+ s3 = GET_MID_BITS(s1, s1b, s2b);
+ s2 = GET_MID_BITS(s1, s0b, s1b);
+ s1 = GET_LS_BITS(s1, s0b);
+
+ this->status = this->read_guard(s1);
+ this->write_guard(s2);
+}
+
+void ID::decode_J_type(signed int &s1, signed int &s2)
+{
+ unsigned int s0b, s1b;
+
+ s0b = REG_SIZE;
+ s1b = WORD_SPEC;
+ s2 = GET_MID_BITS(s1, s0b, s1b);
+ s1 = GET_LS_BITS(s1, s0b);
+
+ this->status = this->read_guard(*&s1);
+}
diff --git a/src/sim/if.cc b/src/sim/if.cc
index de044f8..7d3291b 100644
--- a/src/sim/if.cc
+++ b/src/sim/if.cc
@@ -8,7 +8,7 @@ IF::IF(Stage *stage) : Stage(stage) { this->id = FETCH; }
Response IF::advance(InstrDTO &next_instr, Response p)
{
- this->fetch_with_buffer();
+ this->advance_helper();
if (this->status == OK && p == OK) {
// mutual consent
++this->pc;
@@ -19,7 +19,7 @@ Response IF::advance(InstrDTO &next_instr, Response p)
return this->status;
}
-void IF::fetch_with_buffer()
+void IF::advance_helper()
{
Response r;
signed int bits;