aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPavel Pisa <pisa@cmp.felk.cvut.cz>2019-01-30 17:53:10 +0100
committerPavel Pisa <pisa@cmp.felk.cvut.cz>2019-01-30 17:53:10 +0100
commit08dc0c06d8874698c7d93e9804a0b236e60201dd (patch)
treeda75785f605a7b211578b3eacb141b4764086166
parentd8c771ec9d00df34efc42c41747d5d41678d3b78 (diff)
downloadqtmips-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.cpp37
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();