From 08dc0c06d8874698c7d93e9804a0b236e60201dd Mon Sep 17 00:00:00 2001 From: Pavel Pisa Date: Wed, 30 Jan 2019 17:53:10 +0100 Subject: 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 --- qtmips_machine/core.cpp | 37 +++++++++++++++++++++++-------------- 1 file 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(); -- cgit v1.2.3