diff options
author | Pavel Pisa <pisa@cmp.felk.cvut.cz> | 2019-01-30 17:53:10 +0100 |
---|---|---|
committer | Pavel Pisa <pisa@cmp.felk.cvut.cz> | 2019-01-30 17:53:10 +0100 |
commit | 08dc0c06d8874698c7d93e9804a0b236e60201dd (patch) | |
tree | da75785f605a7b211578b3eacb141b4764086166 | |
parent | d8c771ec9d00df34efc42c41747d5d41678d3b78 (diff) | |
download | qtmips-08dc0c06d8874698c7d93e9804a0b236e60201dd.tar.gz qtmips-08dc0c06d8874698c7d93e9804a0b236e60201dd.tar.bz2 qtmips-08dc0c06d8874698c7d93e9804a0b236e60201dd.zip |
Correct hazards processing.
The shorter loop has priority. This is achieved by later
processing when it replaces possible result from longer
loop over W stage.
Signed-off-by: Pavel Pisa <pisa@cmp.felk.cvut.cz>
-rw-r--r-- | qtmips_machine/core.cpp | 37 |
1 files changed, 23 insertions, 14 deletions
diff --git a/qtmips_machine/core.cpp b/qtmips_machine/core.cpp index 49149f7..5a0e831 100644 --- a/qtmips_machine/core.cpp +++ b/qtmips_machine/core.cpp @@ -367,10 +367,23 @@ void CorePipelined::do_step() { #define HAZARD(STAGE) ( \ (STAGE).regwrite && (STAGE).rwrite != 0 && \ ((STAGE).rwrite == dt_d.inst.rs() || ( \ - ((STAGE).inst.type() == Instruction::T_R || (STAGE).inst.is_store()) && \ + (dt_d.inst.type() == Instruction::T_R || (STAGE).inst.is_store()) && \ (STAGE).rwrite == dt_d.inst.rt()) \ )) // Note: We make exception with $0 as that has no effect and is used in nop instruction + if (HAZARD(dt_m)) { + // Hazard with instruction in memory stage + if (hazard_unit == MachineConfig::HU_STALL_FORWARD) { + // Forward result value + if (dt_m.rwrite == dt_d.inst.rs()) { + dt_d.val_rs = dt_m.towrite_val; + } + if (dt_m.rwrite == dt_d.inst.rt()) { + dt_d.val_rt = dt_m.towrite_val; + } + } else + stall = true; + } if (HAZARD(dt_e)) { // Hazard with instruction in execute stage if (hazard_unit == MachineConfig::HU_STALL_FORWARD) { @@ -378,29 +391,25 @@ void CorePipelined::do_step() { stall = true; else { // Forward result value - if (dt_e.rwrite == dt_d.inst.rs()) + if (dt_e.rwrite == dt_d.inst.rs()) { dt_d.val_rs = dt_e.alu_val; - if (dt_e.rwrite == dt_d.inst.rt()) + } + if (dt_e.rwrite == dt_d.inst.rt()) { dt_d.val_rt = dt_e.alu_val; + } } } else stall = true; } - if (HAZARD(dt_m)) { - // Hazard with instruction in memory stage - if (hazard_unit == MachineConfig::HU_STALL_FORWARD) { - // Forward result value - if (dt_m.rwrite == dt_d.inst.rs()) - dt_d.val_rs = dt_m.towrite_val; - if (dt_m.rwrite == dt_d.inst.rt()) - dt_d.val_rt = dt_m.towrite_val; - } else - stall = true; - } // Write back stage combinatoricly propagates written instruction to decode stage so nothing has to be done for that stage #undef HAZARD } +#if 0 + printf("M: regwrite %d inst.type %d rwrite [%d] E: regwrite %d inst.type %d rwrite [%d] D: inst.type %d dt_d.inst.rs [%d] dt_d.inst.rt [%d] dt_d.ff_rs %d dt_d.ff_rt %d\n", + dt_m.regwrite, dt_m.inst.type(), dt_m.rwrite, dt_e.regwrite, dt_e.inst.type(), dt_e.rwrite, dt_d.inst.type(), dt_d.inst.rs(), dt_d.inst.rt(), dt_d.ff_rs, dt_d.ff_rt); +#endif + // Now process program counter (loop connections from decode stage) if (!stall) { dt_f = fetch(); |