diff options
Diffstat (limited to 'src/sim/wb.cc')
-rw-r--r-- | src/sim/wb.cc | 75 |
1 files changed, 48 insertions, 27 deletions
diff --git a/src/sim/wb.cc b/src/sim/wb.cc index 276d1d0..01768e8 100644 --- a/src/sim/wb.cc +++ b/src/sim/wb.cc @@ -8,33 +8,54 @@ WB::WB(Stage *stage) : Stage(stage) { this->id = WRITE; } 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(); - } + 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); +} |