summaryrefslogtreecommitdiff
path: root/src/sim/wb.cc
diff options
context:
space:
mode:
authorbd <bdunaisky@umass.edu>2025-04-02 04:05:18 +0000
committerGitHub <noreply@github.com>2025-04-02 04:05:18 +0000
commit9fb95d655393777dde5929182f94de36f903821d (patch)
tree4462f35895737460a01fab891a15f87aba2efb70 /src/sim/wb.cc
parent24f0bd8af57381ab3112b5774d4ad23ac80f0718 (diff)
parent3eeb345d673bee6d62b04fc8a8a95ab822dc1e45 (diff)
Merge pull request #46 from bdunahu/bdunahu
Ensure all stages only do work if they are not 'OK'
Diffstat (limited to 'src/sim/wb.cc')
-rw-r--r--src/sim/wb.cc82
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);
}