diff options
author | bd <bdunahu@operationnull.com> | 2025-04-01 15:57:14 -0400 |
---|---|---|
committer | bd <bdunahu@operationnull.com> | 2025-04-01 15:57:14 -0400 |
commit | 25ce77db5f0dbfe6064eb0553591f1b956bad24a (patch) | |
tree | 5a1c347f05f14496d2d3a2f1befd88be9020cad3 /src/sim/wb.cc | |
parent | 6579f7272905d1e25b43ef051da6c2180e60ca2b (diff) |
Fix a lot of pipeline bugs
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); +} |