diff options
author | Karel Kočí <cynerd@email.cz> | 2018-01-15 13:17:07 +0100 |
---|---|---|
committer | Karel Kočí <cynerd@email.cz> | 2018-01-15 13:17:07 +0100 |
commit | 1f6cf37d350f01b15be9ca2d2ceec034d87e09b5 (patch) | |
tree | c6582214bd9265b4e9146603848469596a83cc73 /qtmips_machine | |
parent | e1b4028d0feb045abf4dd413d5e3bb80269c84b7 (diff) | |
download | qtmips-1f6cf37d350f01b15be9ca2d2ceec034d87e09b5.tar.gz qtmips-1f6cf37d350f01b15be9ca2d2ceec034d87e09b5.tar.bz2 qtmips-1f6cf37d350f01b15be9ca2d2ceec034d87e09b5.zip |
Implement hazard unit
Diffstat (limited to 'qtmips_machine')
-rw-r--r-- | qtmips_machine/core.cpp | 48 | ||||
-rw-r--r-- | qtmips_machine/core.h | 5 |
2 files changed, 42 insertions, 11 deletions
diff --git a/qtmips_machine/core.cpp b/qtmips_machine/core.cpp index 805d9be..264e871 100644 --- a/qtmips_machine/core.cpp +++ b/qtmips_machine/core.cpp @@ -110,10 +110,6 @@ struct Core::dtDecode Core::decode(const struct dtFetch &dt) { // TODO message throw QTMIPS_EXCEPTION(UnsupportedInstruction, "", ""); - // TODO solve forwarding somehow in here - std::uint32_t rs = regs->read_gp(dt.inst.rs()); - std::uint32_t rt = regs->read_gp(dt.inst.rt()); - return { .inst = dt.inst, .memread = dec.flags & DM_MEMREAD, @@ -123,8 +119,8 @@ struct Core::dtDecode Core::decode(const struct dtFetch &dt) { .regwrite = dec.flags & DM_REGWRITE, .aluop = dt.inst.opcode() == 0 ? (enum AluOp)dt.inst.funct() : dec.alu, .memctl = dec.mem_ctl, - .val_rs = rs, - .val_rt = rt, + .val_rs = regs->read_gp(dt.inst.rs()), + .val_rt = regs->read_gp(dt.inst.rt()), }; // TODO on jump there should be delay slot. Does processor addes it or compiler. And do we care? } @@ -293,19 +289,51 @@ void CoreSingle::reset() { Core::dtDecodeInit(*jmp_delay_decode); } -CorePipelined::CorePipelined(Registers *regs, MemoryAccess *mem) : \ +CorePipelined::CorePipelined(Registers *regs, MemoryAccess *mem, enum MachineConfig::HazardUnit hazard_unit) : \ Core(regs, mem) { + this->hazard_unit = hazard_unit; reset(); } void CorePipelined::step() { - // TODO implement forward unit + // Process stages writeback(dt_m); dt_m = memory(dt_e); dt_e = execute(dt_d); dt_d = decode(dt_f); - dt_f = fetch(); - handle_pc(dt_d); + + // TODO signals + bool stall = false; + if (hazard_unit != MachineConfig::HU_NONE) { + // Note: We make exception with $0 as that has no effect when written and is used in nop instruction +#define HAZARD(STAGE) ((STAGE).regwrite && (STAGE).rwrite != 0 && ((STAGE).rwrite == dt_d.inst.rs() || (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_e)) { + // Hazard with instruction in execute stage + // This always results to stall + 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 + } + + // Now process program counter (loop connections from decode stage) + if (!stall) { + dt_f = fetch(); + handle_pc(dt_d); + } else + // clear decode latch (insert nope to execute stage) + dtDecodeInit(dt_d); } void CorePipelined::reset() { diff --git a/qtmips_machine/core.h b/qtmips_machine/core.h index 3078c95..3ff6a98 100644 --- a/qtmips_machine/core.h +++ b/qtmips_machine/core.h @@ -3,6 +3,7 @@ #include <QObject> #include <qtmipsexception.h> +#include <machineconfig.h> #include <registers.h> #include <memory.h> #include <instruction.h> @@ -91,7 +92,7 @@ private: class CorePipelined : public Core { public: - CorePipelined(Registers *regs, MemoryAccess *mem); + CorePipelined(Registers *regs, MemoryAccess *mem, enum MachineConfig::HazardUnit hazard_unit = MachineConfig::HU_STALL_FORWARD); void step(); @@ -102,6 +103,8 @@ private: struct Core::dtDecode dt_d; struct Core::dtExecute dt_e; struct Core::dtMemory dt_m; + + enum MachineConfig::HazardUnit hazard_unit; }; } |