Added new Ports to hazard unit for correct identifikation of hazards
MODIFY
src/processors/RISC-V/rv5s_no_fw/rv5s_no_fw.h
src/processors/RISC-V/rv5s_no_fw/rv5s_no_fw.h
// Stage separating registers
#include "../rv5s_no_fw_hz/rv5s_no_fw_hz_ifid.h"
-#include "../rv5s/rv5s_exmem.h"
+#include "rv5s_no_fw_exmem.h"
#include "../rv5s/rv5s_memwb.h"
#include "rv5s_no_fw_idex.h"
@@ -195,6 +195,7 @@ public:
idex_reg->mem_do_write_out >> exmem_reg->mem_do_write_in;
idex_reg->mem_do_read_out >> exmem_reg->mem_do_read_in;
idex_reg->mem_op_out >> exmem_reg->mem_op_in;
+ idex_reg->alu_op2_ctrl_out >> exmem_reg->alu_op2_ctrl_in;
idex_reg->valid_out >> exmem_reg->valid_in;
@@ -222,14 +223,15 @@ public:
decode->r2_reg_idx >> hzunit->id_reg2_idx;
idex_reg->mem_do_read_out >> hzunit->ex_do_mem_read_en;
- idex_reg->wr_reg_idx_out >> hzunit->ex_reg_wr_idx;
idex_reg->reg_do_write_out >> hzunit->ex_do_reg_write;
+ idex_reg->wr_reg_idx_out >> hzunit->ex_reg_wr_idx;
+ idex_reg->alu_op2_ctrl_out >> hzunit->ex_alu_op_ctrl_2;
exmem_reg->reg_do_write_out >> hzunit->mem_do_reg_write;
exmem_reg->wr_reg_idx_out >> hzunit->mem_reg_wr_idx;
+ exmem_reg->alu_op2_ctrl_out >> hzunit->mem_alu_op_ctrl_2;
memwb_reg->reg_do_write_out >> hzunit->wb_do_reg_write;
- memwb_reg->wr_reg_idx_out >> hzunit->wb_reg_wr_idx;
idex_reg->opcode_out >> hzunit->opcode;
}
@@ -249,7 +251,7 @@ public:
// Stage seperating registers
SUBCOMPONENT(ifid_reg, IFID);
SUBCOMPONENT(idex_reg, RV5S_NO_FW_IDEX);
- SUBCOMPONENT(exmem_reg, RV5S_EXMEM);
+ SUBCOMPONENT(exmem_reg, RV5S_NO_FW_EXMEM);
SUBCOMPONENT(memwb_reg, RV5S_MEMWB);
// Multiplexers

ADD
src/processors/RISC-V/rv5s_no_fw/rv5s_no_fw_exmem.h
+#pragma once
+
+#include "VSRTL/core/vsrtl_component.h"
+#include "VSRTL/core/vsrtl_register.h"
+
+#include "../riscv.h"
+
+#include "../rv5s_no_fw_hz/rv5s_no_fw_hz_exmem.h"
+
+namespace vsrtl {
+namespace core {
+using namespace Ripes;
+
+class RV5S_NO_FW_EXMEM : public EXMEM {
+public:
+ RV5S_NO_FW_EXMEM(std::string name, SimComponent* parent) : EXMEM(name, parent) {
+
+ // Need ctrl-Signal to identify if reg2 is register or immediate
+ CONNECT_REGISTERED_CLEN_INPUT(alu_op2_ctrl, clear, enable);
+
+ // We want stalling info to persist through clearing of the register, so stalled register is always enabled and
+ // never cleared.
+ CONNECT_REGISTERED_CLEN_INPUT(stalled, 0, 1);
+ }
+
+ REGISTERED_CLEN_INPUT(alu_op2_ctrl, AluSrc2::width());
+
+ REGISTERED_CLEN_INPUT(stalled, 1);
+};
+
+} // namespace core
+} // namespace vsrtl

MODIFY
src/processors/RISC-V/rv5s_no_fw/rv5s_no_fw_hazardunit.h
src/processors/RISC-V/rv5s_no_fw/rv5s_no_fw_hazardunit.h
@@ -14,7 +14,7 @@ public:
hazardFEEnable << [=] { return !hasHazard(); };
hazardIDEXEnable << [=] { return !hasEcallHazard(); };
hazardEXMEMClear << [=] { return hasEcallHazard(); };
- hazardIDEXClear << [=] { return hasLoadUseHazard(); };
+ hazardIDEXClear << [=] { return hasDataOrLoadUseHazard(); };
stallEcallHandling << [=] { return hasEcallHazard(); };
}
@@ -22,17 +22,18 @@ public:
INPUTPORT(id_reg2_idx, RV_REGS_BITS);
INPUTPORT(ex_reg_wr_idx, RV_REGS_BITS);
+
INPUTPORT(ex_do_mem_read_en, 1);
INPUTPORT(ex_do_reg_write, 1);
INPUTPORT(mem_reg_wr_idx, RV_REGS_BITS);
+
INPUTPORT(mem_do_reg_write, 1);
- INPUTPORT(wb_reg_wr_idx, RV_REGS_BITS);
INPUTPORT(wb_do_reg_write, 1);
-
-
+ INPUTPORT_ENUM(ex_alu_op_ctrl_2, AluSrc2);
+ INPUTPORT_ENUM(mem_alu_op_ctrl_2, AluSrc2);
INPUTPORT_ENUM(opcode, RVInstr);
// Hazard Front End enable: Low when stalling the front end (shall be connected to a register 'enable' input port).
@@ -51,7 +52,11 @@ public:
OUTPUTPORT(stallEcallHandling, 1);
private:
- bool hasHazard() { return hasLoadUseHazard() || hasEcallHazard(); }
+ bool hasHazard() { return hasDataOrLoadUseHazard() || hasEcallHazard(); }
+
+ bool hasDataOrLoadUseHazard(){ return hasDataHazard() || hasLoadUseHazard(); }
+
+ bool hasDataHazard() { return hasDataHazardEx() || hasDataHazardMem(); }
bool hasLoadUseHazard() const {
const unsigned exidx = ex_reg_wr_idx.uValue();
@@ -71,11 +76,30 @@ private:
return isEcall && (mem_do_reg_write.uValue() || wb_do_reg_write.uValue());
}
- bool hasDataHazard() const {
- // RAW-Conflict
- //const bool rawConflict =
+ bool hasDataHazardEx() const {
+ const unsigned idx1 = id_reg1_idx.uValue();
+ const unsigned idx2 = id_reg2_idx.uValue();
+ const bool idx2isReg = ex_alu_op_ctrl_2.uValue() == AluSrc2::REG2;
const unsigned exidx = ex_reg_wr_idx.uValue();
- return true;
+ const bool regw = ex_do_reg_write.uValue();
+ // If destination is x0 ignore hazard
+ if(exidx == 0){
+ return false;
+ }
+ return ((exidx == idx1) || ((exidx == idx2) && idx2isReg)) && regw;
+ }
+
+ bool hasDataHazardMem() const {
+ const unsigned idx1 = id_reg1_idx.uValue();
+ const unsigned idx2 = id_reg2_idx.uValue();
+ const bool idx2isReg = mem_alu_op_ctrl_2.uValue() == AluSrc2::REG2;
+ const unsigned memidx = mem_reg_wr_idx.uValue();
+ const bool regw = mem_do_reg_write.uValue();
+ // If destination is x0 ignore hazard
+ if(memidx == 0){
+ return false;
+ }
+ return ((memidx == idx1) || ((memidx == idx2) && idx2isReg)) && regw;
}
};
} // namespace core

Added new Ports to hazard unit for correct identifikation of hazards