diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/sim/controller.cc | 4 | ||||
-rw-r--r-- | src/sim/dum.cc | 8 | ||||
-rw-r--r-- | src/sim/id.cc | 23 | ||||
-rw-r--r-- | src/sim/if.cc | 4 | ||||
-rw-r--r-- | src/sim/instrDTO.cc | 2 | ||||
-rw-r--r-- | src/sim/mm.cc | 44 | ||||
-rw-r--r-- | src/sim/stage.cc | 23 | ||||
-rw-r--r-- | src/sim/wb.cc | 61 |
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; } |