summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorbd <bdunahu@operationnull.com>2025-04-01 00:49:52 -0400
committerbd <bdunahu@operationnull.com>2025-04-01 00:49:52 -0400
commit6579f7272905d1e25b43ef051da6c2180e60ca2b (patch)
treea4b217aa56126f7d05304ab93f6c36b66fd6b694 /src
parenta4e0e5ff6208205f6ebd980f9ed1eca91dcc4311 (diff)
Ensure all stages only do work if they are not 'OK'
Diffstat (limited to 'src')
-rw-r--r--src/sim/controller.cc4
-rw-r--r--src/sim/dum.cc8
-rw-r--r--src/sim/id.cc23
-rw-r--r--src/sim/if.cc4
-rw-r--r--src/sim/instrDTO.cc2
-rw-r--r--src/sim/mm.cc44
-rw-r--r--src/sim/stage.cc23
-rw-r--r--src/sim/wb.cc61
8 files changed, 84 insertions, 85 deletions
diff --git a/src/sim/controller.cc b/src/sim/controller.cc
index 89ff4e7..293ee73 100644
--- a/src/sim/controller.cc
+++ b/src/sim/controller.cc
@@ -9,6 +9,7 @@ Controller::Controller(Stage *stage, Storage *storage, bool is_pipelined)
this->storage = storage;
this->is_pipelined = is_pipelined;
this->pc = 0x0;
+ this->checked_out = {};
this->gprs = {0};
// grant side-door access
this->id = SIDE;
@@ -36,6 +37,7 @@ InstrDTO *Controller::advance(Response p)
return r;
}
-void Controller::advance_helper() {
+void Controller::advance_helper()
+{
// TODO: check halt condition and call UI to refresh
}
diff --git a/src/sim/dum.cc b/src/sim/dum.cc
index dd16660..76d4acd 100644
--- a/src/sim/dum.cc
+++ b/src/sim/dum.cc
@@ -9,13 +9,12 @@ DUM::DUM(Stage *stage) : Stage(stage) { this->id = IDLE; }
InstrDTO *DUM::advance(Response p)
{
- InstrDTO *r = curr_instr;
+ InstrDTO *r = nullptr;
- this->advance_helper();
- if (this->status == OK && p == OK) {
+ if (this->curr_instr && p == WAIT) {
this->curr_instr->set_time_of(this->id, this->clock_cycle);
r = new InstrDTO(*this->curr_instr);
- delete curr_instr;
+ delete this->curr_instr;
curr_instr = nullptr;
}
@@ -27,5 +26,4 @@ void DUM::advance_helper() {}
void DUM::set_curr_instr(InstrDTO *d)
{
this->curr_instr = d;
- this->status = OK;
}
diff --git a/src/sim/id.cc b/src/sim/id.cc
index 0b75b64..4a55d04 100644
--- a/src/sim/id.cc
+++ b/src/sim/id.cc
@@ -48,22 +48,19 @@ void ID::advance_helper()
Mnemonic m;
Type t;
- // it may be good to ensure we are not doing
- // work that has already been done
- if (this->curr_instr && this->curr_instr->get_mnemonic() == NONE) {
- s1 = curr_instr->get_instr_bits();
- get_instr_fields(s1, s2, s3, m ,t);
- if (this->status == OK) {
- curr_instr->set_s1(s1);
- curr_instr->set_s2(s2);
- curr_instr->set_s3(s3);
- curr_instr->set_mnemonic(m);
- curr_instr->set_type(t);
- }
+ s1 = curr_instr->get_instr_bits();
+ get_instr_fields(s1, s2, s3, m, t);
+ if (this->status == OK) {
+ curr_instr->set_s1(s1);
+ curr_instr->set_s2(s2);
+ curr_instr->set_s3(s3);
+ curr_instr->set_mnemonic(m);
+ curr_instr->set_type(t);
}
}
-void ID::get_instr_fields(signed int &s1, signed int &s2, signed int &s3, Mnemonic &m, Type &t)
+void ID::get_instr_fields(
+ signed int &s1, signed int &s2, signed int &s3, Mnemonic &m, Type &t)
{
unsigned int type;
this->split_instr(s1, type, m);
diff --git a/src/sim/if.cc b/src/sim/if.cc
index fa8f6c2..bc40688 100644
--- a/src/sim/if.cc
+++ b/src/sim/if.cc
@@ -11,14 +11,13 @@ InstrDTO *IF::advance(Response p)
InstrDTO *r = nullptr;
this->advance_helper();
- if (this->curr_instr != nullptr && p == OK) {
+ if (this->curr_instr != nullptr && p == WAIT) {
// mutual consent
++this->pc;
this->curr_instr->set_time_of(this->id, this->clock_cycle);
r = new InstrDTO(*this->curr_instr);
delete curr_instr;
curr_instr = nullptr;
- this->status = STALLED;
}
return r;
@@ -32,7 +31,6 @@ void IF::advance_helper()
if (this->curr_instr == nullptr) {
r = this->storage->read_word(this->id, this->pc, bits);
if (r == OK) {
- this->status = r;
this->curr_instr = new InstrDTO();
this->curr_instr->set_instr_bits(bits);
}
diff --git a/src/sim/instrDTO.cc b/src/sim/instrDTO.cc
index b33c26b..28364b7 100644
--- a/src/sim/instrDTO.cc
+++ b/src/sim/instrDTO.cc
@@ -7,7 +7,7 @@ InstrDTO::InstrDTO()
this->s1 = 0;
this->s2 = 0;
this->s3 = 0;
- this->mnemonic = NONE;
+ this->mnemonic = NOP;
this->type = INV;
}
diff --git a/src/sim/mm.cc b/src/sim/mm.cc
index cd85056..c83ae7d 100644
--- a/src/sim/mm.cc
+++ b/src/sim/mm.cc
@@ -4,26 +4,32 @@
#include "response.h"
#include "stage.h"
-MM::MM(Stage *stage) : Stage(stage) { this->id = MEM; }
+MM::MM(Stage *stage) : Stage(stage) { this->id = MEM; }
-void MM::advance_helper() {
- Response r;
+void MM::advance_helper()
+{
signed int data;
- if(this->curr_instr){
- if (this->curr_instr->get_mnemonic() == LOAD) {
- r = this->storage->read_word(this->id, this->curr_instr->get_s1(), data);
- if(r == OK){
- this->status = OK;
- this->curr_instr->set_s2(data);
- }
- } else if (this->curr_instr->get_mnemonic() == STORE) {
- r = this->storage->write_word(this->id, this->curr_instr->get_s2(), this->curr_instr->get_s1());
- if(r == OK){
- this->status = OK;
- }
- } else {
- // Mem has no work so just forward the instruction to WB
- this->status = OK;
+
+ switch (this->curr_instr->get_mnemonic()) {
+ case LOAD:
+ this->status = this->storage->read_word(
+ this->id, this->curr_instr->get_s1(), data);
+ if (this->status == OK) {
+ this->curr_instr->set_s2(data);
+ } else
+ this->status = STALLED;
+ break;
+
+ case STORE:
+ // TODO signed issues, we aren't wrapping addresses
+ this->status = this->storage->write_word(
+ this->id, this->curr_instr->get_s2(), this->curr_instr->get_s1());
+ if (this->status != OK) {
+ this->status = STALLED;
}
- }
+ break;
+
+ default:
+ this->status = OK;
+ }
}
diff --git a/src/sim/stage.cc b/src/sim/stage.cc
index 0f13d65..31d7d0d 100644
--- a/src/sim/stage.cc
+++ b/src/sim/stage.cc
@@ -2,13 +2,13 @@
#include "utils.h"
#include <array>
#include <deque>
+#include <iostream>
Stage::Stage(Stage *next)
{
this->next = next;
this->curr_instr = nullptr;
- this->status = OK;
- this->checked_out = {};
+ this->status = WAIT;
}
Stage::~Stage() { delete this->next; };
@@ -21,13 +21,9 @@ Storage *Stage::storage;
bool Stage::is_pipelined;
int Stage::clock_cycle;
-bool Stage::get_condition(CC c) {
- return (this->gprs[3] >> c) & 1;
-}
+bool Stage::get_condition(CC c) { return (this->gprs[3] >> c) & 1; }
-void Stage::set_pc(unsigned int pc) {
- this->pc = pc;
-}
+void Stage::set_pc(unsigned int pc) { this->pc = pc; }
InstrDTO *Stage::advance(Response p)
{
@@ -36,16 +32,16 @@ InstrDTO *Stage::advance(Response p)
if (this->curr_instr && this->status != OK)
this->advance_helper();
- if (this->status == OK && p == OK && this->curr_instr) {
+ if (this->status == OK && p == WAIT && this->curr_instr) {
// mutual consent
this->curr_instr->set_time_of(this->id, this->clock_cycle);
r = new InstrDTO(*this->curr_instr);
delete curr_instr;
curr_instr = nullptr;
- this->status = STALLED;
+ this->status = WAIT;
}
- n = (p != OK || this->status != OK) ? STALLED : OK;
+ n = (p != WAIT || this->status != WAIT) ? STALLED : WAIT;
// the power of consent
this->curr_instr = this->next->advance(n);
return r;
@@ -80,10 +76,11 @@ bool Stage::is_checked_out(signed int r)
this->checked_out.end();
}
-void Stage::squash(){
+void Stage::squash()
+{
this->curr_instr->set_mnemonic(NOP);
this->status = OK;
- if(this->next){
+ if (this->next) {
this->next->squash();
}
}
diff --git a/src/sim/wb.cc b/src/sim/wb.cc
index ac47f25..276d1d0 100644
--- a/src/sim/wb.cc
+++ b/src/sim/wb.cc
@@ -6,34 +6,35 @@
WB::WB(Stage *stage) : Stage(stage) { this->id = WRITE; }
-void WB::advance_helper() {
- if(this -> curr_instr) {
- if(this->curr_instr->get_type() == R || this->curr_instr->get_type() == I){
- if(this->checked_out.size() > 0) {
- signed int reg = this->checked_out.front();
- this->checked_out.pop_front();
- if(reg >= GPR_NUM){
- // TODO: handle vector instructions
- } else {
- if(this->curr_instr->get_mnemonic() != STORE && this->curr_instr->get_mnemonic() != STOREV){
- this->gprs[reg] = this->curr_instr->get_s1();
- }
- }
- }
- } else if (this->curr_instr->get_type() == J) {
- // TODO:handle push pop
- // branch taken
- if(this->pc != this->curr_instr->get_s1()) {
- if(this->curr_instr->get_mnemonic() == JAL){
- // set link register to next instruction
- this->gprs[1] = this->pc + 1;
- }
- this->pc = this->curr_instr->get_s1();
- //clear pending registers and squash pipeline
- this->checked_out = {};
- this->next->squash();
- }
- }
- }
- this->status = OK;
+void WB::advance_helper()
+{
+ if (this->curr_instr->get_type() == R ||
+ this->curr_instr->get_type() == I) {
+ if (this->checked_out.size() > 0) {
+ signed int reg = this->checked_out.front();
+ this->checked_out.pop_front();
+ if (reg >= GPR_NUM) {
+ // TODO: handle vector instructions
+ } else {
+ if (this->curr_instr->get_mnemonic() != STORE &&
+ this->curr_instr->get_mnemonic() != STOREV) {
+ this->gprs[reg] = this->curr_instr->get_s1();
+ }
+ }
+ }
+ } else if (this->curr_instr->get_type() == J) {
+ // TODO:handle push pop
+ // branch taken
+ if (this->pc != this->curr_instr->get_s1()) {
+ if (this->curr_instr->get_mnemonic() == JAL) {
+ // set link register to next instruction
+ this->gprs[1] = this->pc + 1;
+ }
+ this->pc = this->curr_instr->get_s1();
+ // clear pending registers and squash pipeline
+ this->checked_out = {};
+ this->next->squash();
+ }
+ }
+ this->status = OK;
}