diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/sim/controller.cc | 5 | ||||
-rw-r--r-- | src/sim/ex.cc | 8 | ||||
-rw-r--r-- | src/sim/id.cc | 13 | ||||
-rw-r--r-- | src/sim/instrDTO.cc | 7 | ||||
-rw-r--r-- | src/sim/mm.cc | 22 | ||||
-rw-r--r-- | src/sim/stage.cc | 10 | ||||
-rw-r--r-- | src/sim/wb.cc | 32 |
7 files changed, 83 insertions, 14 deletions
diff --git a/src/sim/controller.cc b/src/sim/controller.cc index 06591af..89ff4e7 100644 --- a/src/sim/controller.cc +++ b/src/sim/controller.cc @@ -31,10 +31,11 @@ int Controller::get_pc() { return this->pc; } InstrDTO *Controller::advance(Response p) { InstrDTO *r; - r = this->next->advance(p); ++this->clock_cycle; return r; } -void Controller::advance_helper() {} +void Controller::advance_helper() { + // TODO: check halt condition and call UI to refresh +} diff --git a/src/sim/ex.cc b/src/sim/ex.cc index 83c72d5..3d95917 100644 --- a/src/sim/ex.cc +++ b/src/sim/ex.cc @@ -282,28 +282,28 @@ EX::EX(Stage *stage) : Stage(stage) INIT_INSTRUCTION( BEQ, { - s1 = this->pc + s2; + (this->get_condition(EQ)) ? s1 = this->pc + s2 : s1 = this->pc; (void)s3; }), INIT_INSTRUCTION( BGT, { - s1 = this->pc + s2; + (this->get_condition(GT)) ? s1 = this->pc + s2 : s1 = this->pc; (void)s3; }), INIT_INSTRUCTION( BUF, { - s1 = this->pc + s2; + (this->get_condition(UF)) ? s1 = this->pc + s2 : s1 = this->pc; (void)s3; }), INIT_INSTRUCTION( BOF, { - s1 = this->pc + s2; + (this->get_condition(OF)) ? s1 = this->pc + s2 : s1 = this->pc; (void)s3; }), diff --git a/src/sim/id.cc b/src/sim/id.cc index edf74e2..0b75b64 100644 --- a/src/sim/id.cc +++ b/src/sim/id.cc @@ -46,38 +46,43 @@ void ID::advance_helper() { signed int s1, s2, s3; Mnemonic m; + Type t; // it may be good to ensure we are not doing // work that has already been done - if (this->curr_instr) { + if (this->curr_instr && this->curr_instr->get_mnemonic() == NONE) { s1 = curr_instr->get_instr_bits(); - get_instr_fields(s1, s2, s3, m); + 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) +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); switch (type) { case 0b00: + t = R; this->decode_R_type(s1, s2, s3); break; case 0b01: + t = I; this->decode_I_type(s1, s2, s3); break; case 0b10: + t = J; this->decode_J_type(s1, s2); break; case 0b11: + t = INV; this->status = OK; } } diff --git a/src/sim/instrDTO.cc b/src/sim/instrDTO.cc index 5a7fe3b..b33c26b 100644 --- a/src/sim/instrDTO.cc +++ b/src/sim/instrDTO.cc @@ -7,7 +7,8 @@ InstrDTO::InstrDTO() this->s1 = 0; this->s2 = 0; this->s3 = 0; - this->mnemonic = NOP; + this->mnemonic = NONE; + this->type = INV; } int InstrDTO::get_time_of(Accessor a) { return this->hist[a]; } @@ -22,6 +23,8 @@ signed int InstrDTO::get_s3() { return this->s3; } Mnemonic InstrDTO::get_mnemonic() { return this->mnemonic; } +Type InstrDTO::get_type() { return this->type; } + void InstrDTO::set_time_of(Accessor a, int i) { this->hist[a] = i; } void InstrDTO::set_instr_bits(signed int instr) { this->instr_bits = instr; } @@ -33,3 +36,5 @@ void InstrDTO::set_s2(signed int s) { this->s2 = s; } void InstrDTO::set_s3(signed int s) { this->s3 = s; } void InstrDTO::set_mnemonic(Mnemonic m) { this->mnemonic = m; } + +void InstrDTO::set_type(Type t) { this->type = t; } diff --git a/src/sim/mm.cc b/src/sim/mm.cc index 2b73207..cd85056 100644 --- a/src/sim/mm.cc +++ b/src/sim/mm.cc @@ -6,4 +6,24 @@ MM::MM(Stage *stage) : Stage(stage) { this->id = MEM; } -void MM::advance_helper() {} +void MM::advance_helper() { + Response r; + 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; + } + } +} diff --git a/src/sim/stage.cc b/src/sim/stage.cc index 11eb822..0f13d65 100644 --- a/src/sim/stage.cc +++ b/src/sim/stage.cc @@ -36,7 +36,7 @@ InstrDTO *Stage::advance(Response p) if (this->curr_instr && this->status != OK) this->advance_helper(); - if (this->curr_instr && p == OK) { + if (this->status == OK && p == OK && this->curr_instr) { // mutual consent this->curr_instr->set_time_of(this->id, this->clock_cycle); r = new InstrDTO(*this->curr_instr); @@ -79,3 +79,11 @@ bool Stage::is_checked_out(signed int r) return std::find(this->checked_out.begin(), this->checked_out.end(), r) != this->checked_out.end(); } + +void Stage::squash(){ + this->curr_instr->set_mnemonic(NOP); + this->status = OK; + if(this->next){ + this->next->squash(); + } +} diff --git a/src/sim/wb.cc b/src/sim/wb.cc index 9337aa0..ac47f25 100644 --- a/src/sim/wb.cc +++ b/src/sim/wb.cc @@ -6,4 +6,34 @@ WB::WB(Stage *stage) : Stage(stage) { this->id = WRITE; } -void WB::advance_helper() {} +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; +} |