diff options
Diffstat (limited to 'src/sim/wb.cc')
-rw-r--r-- | src/sim/wb.cc | 82 |
1 files changed, 52 insertions, 30 deletions
diff --git a/src/sim/wb.cc b/src/sim/wb.cc index ac47f25..01768e8 100644 --- a/src/sim/wb.cc +++ b/src/sim/wb.cc @@ -6,34 +6,56 @@ 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_mnemonic() != NOP && + this->curr_instr->get_type() != INV) { + if (this->should_write()) + this->write_handler(); + else if (this->should_jump()) + this->jump_handler(); + } + this->status = OK; +} + +void WB::write_handler() +{ + signed int reg; + + if (this->checked_out.size() < 1) + throw std::runtime_error("instruction tried to pop a register out of " + "an empty queue during writeback."); + + reg = this->checked_out.front(); + this->checked_out.pop_front(); + this->store_register(reg, this->curr_instr->get_s1()); +} + +void WB::jump_handler() +{ + if (this->curr_instr->get_s1() > 0) { + if (this->curr_instr->get_mnemonic() == JAL) + this->gprs[1] = this->pc + 1; + this->pc = this->curr_instr->get_s1(); + this->checked_out = {}; + this->next->squash(); + } +} + +bool WB::should_jump() +{ + Type t; + + t = this->curr_instr->get_type(); + return t == J; +} + +bool WB::should_write() +{ + Mnemonic m; + Type t; + + m = this->curr_instr->get_mnemonic(); + t = this->curr_instr->get_type(); + return (t == R || t == I) && (m != STORE && m != STOREV); } |