aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPavel Pisa <pisa@cmp.felk.cvut.cz>2019-02-18 14:50:52 +0100
committerPavel Pisa <pisa@cmp.felk.cvut.cz>2019-02-18 14:50:52 +0100
commit40ec86b16e297030f8fca02022dfa7a3e418b719 (patch)
tree1dce5df57fd66b171422d609a2ec26f31ca91ba1
parent22475cd499be28d86eee2d87a3dabd425cb0b69c (diff)
downloadqtmips-40ec86b16e297030f8fca02022dfa7a3e418b719.tar.gz
qtmips-40ec86b16e297030f8fca02022dfa7a3e418b719.tar.bz2
qtmips-40ec86b16e297030f8fca02022dfa7a3e418b719.zip
Stall the pipeline even for branch which requires memory read as argument.
This type of the hazard doe not cause problems in the simulator because processing of memory stage is already finished at time when PC handling is started but it would cause problems in real hardware where PC handling is processed in parallel to memory load. Signed-off-by: Pavel Pisa <pisa@cmp.felk.cvut.cz>
-rw-r--r--qtmips_machine/core.cpp11
-rw-r--r--qtmips_machine/core.h6
2 files changed, 16 insertions, 1 deletions
diff --git a/qtmips_machine/core.cpp b/qtmips_machine/core.cpp
index 58e1c17..1b030d6 100644
--- a/qtmips_machine/core.cpp
+++ b/qtmips_machine/core.cpp
@@ -309,6 +309,7 @@ struct Core::dtDecode Core::decode(const struct dtFetch &dt) {
.inst_addr = dt.inst_addr,
.excause = excause,
.in_delay_slot = dt.in_delay_slot,
+ .stall = false,
};
}
@@ -369,6 +370,7 @@ struct Core::dtExecute Core::execute(const struct dtDecode &dt) {
emit execute_alusrc_value(dt.alusrc);
emit execute_regdest_value(dt.regd);
emit execute_regw_num_value(dt.rwrite);
+ emit execute_stall_value(dt.stall);
return {
.inst = dt.inst,
@@ -421,9 +423,11 @@ struct Core::dtMemory Core::memory(const struct dtExecute &dt) {
emit memory_memread_value(dt.memread);
emit memory_memwrite_value(memwrite);
emit memory_regw_num_value(dt.rwrite);
+ emit memory_excause_value(excause);
return {
.inst = dt.inst,
+ .memtoreg = memread,
.regwrite = regwrite,
.rwrite = dt.rwrite,
.towrite_val = towrite_val,
@@ -517,6 +521,7 @@ void Core::dtDecodeInit(struct dtDecode &dt) {
dt.ff_rt = FORWARD_NONE;
dt.excause = EXCAUSE_NONE;
dt.in_delay_slot = false;
+ dt.stall = false;
}
void Core::dtExecuteInit(struct dtExecute &dt) {
@@ -534,6 +539,7 @@ void Core::dtExecuteInit(struct dtExecute &dt) {
void Core::dtMemoryInit(struct dtMemory &dt) {
dt.inst = Instruction(0x00);
+ dt.memtoreg = false;
dt.regwrite = false;
dt.rwrite = false;
dt.towrite_val = 0;
@@ -692,7 +698,7 @@ void CorePipelined::do_step(bool skip_break) {
(dt_d.bjr_req_rt && dt_d.inst.rt() == dt_e.rwrite))) {
stall = true;
} else {
- if (hazard_unit != MachineConfig::HU_STALL_FORWARD) {
+ if (hazard_unit != MachineConfig::HU_STALL_FORWARD || dt_m.memtoreg) {
if (dt_m.rwrite != 0 && dt_m.regwrite &&
((dt_d.bjr_req_rs && dt_d.inst.rs() == dt_m.rwrite) ||
(dt_d.bjr_req_rt && dt_d.inst.rt() == dt_m.rwrite)))
@@ -728,6 +734,9 @@ void CorePipelined::do_step(bool skip_break) {
printf("PC 0x%08lx\n", (unsigned long)dt_f.inst_addr);
#endif
+ dt_d.stall = stall;
+ emit hu_stall_value(stall);
+
// Now process program counter (loop connections from decode stage)
if (!stall) {
dt_f = fetch(skip_break);
diff --git a/qtmips_machine/core.h b/qtmips_machine/core.h
index 7784797..950fc0c 100644
--- a/qtmips_machine/core.h
+++ b/qtmips_machine/core.h
@@ -136,6 +136,7 @@ signals:
void execute_alusrc_value(std::uint32_t);
void execute_regdest_value(std::uint32_t);
void execute_regw_num_value(std::uint32_t);
+ void execute_stall_value(std::uint32_t);
void memory_inst_addr_value(std::uint32_t);
void memory_alu_value(std::uint32_t);
void memory_rt_value(std::uint32_t);
@@ -145,11 +146,14 @@ signals:
void memory_memwrite_value(std::uint32_t);
void memory_memread_value(std::uint32_t);
void memory_regw_num_value(std::uint32_t);
+ void memory_excause_value(std::uint32_t);
void writeback_inst_addr_value(std::uint32_t);
void writeback_value(std::uint32_t);
void writeback_regw_value(std::uint32_t);
void writeback_regw_num_value(std::uint32_t);
+ void hu_stall_value(std::uint32_t);
+
void stop_on_exception_reached();
protected:
@@ -202,6 +206,7 @@ protected:
uint32_t inst_addr; // Address of instruction
enum ExceptionCause excause;
bool in_delay_slot;
+ bool stall;
};
struct dtExecute {
Instruction inst;
@@ -218,6 +223,7 @@ protected:
};
struct dtMemory {
Instruction inst;
+ bool memtoreg;
bool regwrite;
std::uint8_t rwrite;
std::uint32_t towrite_val;