aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--qtmips_gui/programdock.cpp22
-rw-r--r--qtmips_gui/programdock.h1
-rw-r--r--qtmips_gui/programmodel.cpp37
-rw-r--r--qtmips_gui/programmodel.h12
-rw-r--r--qtmips_machine/core.cpp20
-rw-r--r--qtmips_machine/core.h4
-rw-r--r--qtmips_machine/machinedefs.h2
7 files changed, 88 insertions, 10 deletions
diff --git a/qtmips_gui/programdock.cpp b/qtmips_gui/programdock.cpp
index 60a23b0..f3d3d78 100644
--- a/qtmips_gui/programdock.cpp
+++ b/qtmips_gui/programdock.cpp
@@ -101,6 +101,8 @@ ProgramDock::ProgramDock(QWidget *parent, QSettings *settings) : Super(parent) {
program_content, SLOT(focus_address_with_save(std::uint32_t)));
connect(program_content, SIGNAL(doubleClicked(QModelIndex)),
program_model, SLOT(toggle_hw_break(QModelIndex)));
+ connect(this, SIGNAL(stage_addr_changed(uint,std::uint32_t)),
+ program_model, SLOT(update_stage_addr(uint,std::uint32_t)));
}
void ProgramDock::setup(machine::QtMipsMachine *machine) {
@@ -121,31 +123,41 @@ void ProgramDock::set_follow_inst(int follow) {
}
void ProgramDock::fetch_inst_addr(std::uint32_t addr) {
- follow_addr[FOLLOWSRC_FETCH] = addr;
+ if (addr != machine::STAGEADDR_NONE)
+ follow_addr[FOLLOWSRC_FETCH] = addr;
+ emit stage_addr_changed(ProgramModel::STAGEADDR_FETCH, addr);
if (follow_source == FOLLOWSRC_FETCH)
update_follow_position();
}
void ProgramDock::decode_inst_addr(std::uint32_t addr) {
- follow_addr[FOLLOWSRC_DECODE] = addr;
+ if (addr != machine::STAGEADDR_NONE)
+ follow_addr[FOLLOWSRC_DECODE] = addr;
+ emit stage_addr_changed(ProgramModel::STAGEADDR_DECODE, addr);
if (follow_source == FOLLOWSRC_DECODE)
update_follow_position();
}
void ProgramDock::execute_inst_addr(std::uint32_t addr) {
- follow_addr[FOLLOWSRC_EXECUTE] = addr;
+ if (addr != machine::STAGEADDR_NONE)
+ follow_addr[FOLLOWSRC_EXECUTE] = addr;
+ emit stage_addr_changed(ProgramModel::STAGEADDR_EXECUTE, addr);
if (follow_source == FOLLOWSRC_EXECUTE)
update_follow_position();
}
void ProgramDock::memory_inst_addr(std::uint32_t addr) {
- follow_addr[FOLLOWSRC_MEMORY] = addr;
+ if (addr != machine::STAGEADDR_NONE)
+ follow_addr[FOLLOWSRC_MEMORY] = addr;
+ emit stage_addr_changed(ProgramModel::STAGEADDR_MEMORY, addr);
if (follow_source == FOLLOWSRC_MEMORY)
update_follow_position();
}
void ProgramDock::writeback_inst_addr(std::uint32_t addr) {
- follow_addr[FOLLOWSRC_WRITEBACK] = addr;
+ if (addr != machine::STAGEADDR_NONE)
+ follow_addr[FOLLOWSRC_WRITEBACK] = addr;
+ emit stage_addr_changed(ProgramModel::STAGEADDR_WRITEBACK, addr);
if (follow_source == FOLLOWSRC_WRITEBACK)
update_follow_position();
}
diff --git a/qtmips_gui/programdock.h b/qtmips_gui/programdock.h
index 356666f..0dec65d 100644
--- a/qtmips_gui/programdock.h
+++ b/qtmips_gui/programdock.h
@@ -57,6 +57,7 @@ signals:
void jump_to_pc(std::uint32_t);
void focus_addr(std::uint32_t);
void focus_addr_with_save(std::uint32_t);
+ void stage_addr_changed(uint stage, std::uint32_t addr);
public slots:
void set_follow_inst(int);
void fetch_inst_addr(std::uint32_t addr);
diff --git a/qtmips_gui/programmodel.cpp b/qtmips_gui/programmodel.cpp
index 838c058..6fda037 100644
--- a/qtmips_gui/programmodel.cpp
+++ b/qtmips_gui/programmodel.cpp
@@ -44,6 +44,9 @@ ProgramModel::ProgramModel(QObject *parent)
machine = nullptr;
memory_change_counter = 0;
cache_program_change_counter = 0;
+ for (int i = 0 ; i < STAGEADDR_COUNT; i++)
+ stage_addr[i] = machine::STAGEADDR_NONE;
+ stages_need_update = false;
}
int ProgramModel::rowCount(const QModelIndex & /*parent*/) const {
@@ -125,6 +128,26 @@ QVariant ProgramModel::data(const QModelIndex &index, int role) const {
} else if (index.column() == 0 && machine->is_hwbreak(address)) {
QBrush bgd(Qt::red);
return bgd;
+ } else if (index.column() == 3) {
+ if (address == stage_addr[STAGEADDR_WRITEBACK]) {
+ QBrush bgd(QColor(255, 173, 230));
+ return bgd;
+ } else if (address == stage_addr[STAGEADDR_MEMORY]) {
+ QBrush bgd(QColor(173, 255, 229));
+ return bgd;
+ } else if (address == stage_addr[STAGEADDR_MEMORY]) {
+ QBrush bgd(QColor(173, 255, 229));
+ return bgd;
+ } else if (address == stage_addr[STAGEADDR_EXECUTE]) {
+ QBrush bgd(QColor(193, 255, 173));
+ return bgd;
+ } else if (address == stage_addr[STAGEADDR_DECODE]) {
+ QBrush bgd(QColor(255, 212, 173));
+ return bgd;
+ } else if (address == stage_addr[STAGEADDR_FETCH]) {
+ QBrush bgd(QColor(255, 173, 173));
+ return bgd;
+ }
}
return QVariant();
}
@@ -135,6 +158,8 @@ QVariant ProgramModel::data(const QModelIndex &index, int role) const {
void ProgramModel::setup(machine::QtMipsMachine *machine) {
this->machine = machine;
+ for (int i = 0 ; i < STAGEADDR_COUNT; i++)
+ stage_addr[i] = machine::STAGEADDR_NONE;
if (machine != nullptr)
connect(machine, SIGNAL(post_tick()), this, SLOT(check_for_updates()));
emit update_all();
@@ -146,11 +171,12 @@ void ProgramModel::update_all() {
if (machine->cache_program() != nullptr)
cache_program_change_counter = machine->cache_program()->get_change_counter();
}
+ stages_need_update = false;
emit dataChanged(index(0, 0), index(rowCount() - 1, columnCount() - 1));
}
void ProgramModel::check_for_updates() {
- bool need_update = false;
+ bool need_update = stages_need_update;
if (machine == nullptr)
return;
if (machine->memory() == nullptr)
@@ -240,3 +266,12 @@ bool ProgramModel::setData(const QModelIndex & index, const QVariant & value, in
}
return true;
}
+
+void ProgramModel::update_stage_addr(uint stage, std::uint32_t addr) {
+ if (stage < STAGEADDR_COUNT) {
+ if (stage_addr[stage] != addr) {
+ stage_addr[stage] = addr;
+ stages_need_update = true;
+ }
+ }
+}
diff --git a/qtmips_gui/programmodel.h b/qtmips_gui/programmodel.h
index f5159af..a7c1699 100644
--- a/qtmips_gui/programmodel.h
+++ b/qtmips_gui/programmodel.h
@@ -84,10 +84,20 @@ public:
return true;
}
+ enum StageAddress {
+ STAGEADDR_FETCH,
+ STAGEADDR_DECODE,
+ STAGEADDR_EXECUTE,
+ STAGEADDR_MEMORY,
+ STAGEADDR_WRITEBACK,
+ STAGEADDR_COUNT,
+ };
+
public slots:
void setup(machine::QtMipsMachine *machine);
void check_for_updates();
void toggle_hw_break(const QModelIndex & index);
+ void update_stage_addr(uint stage, std::uint32_t addr);
private:
std::uint32_t index0_offset;
@@ -95,6 +105,8 @@ private:
machine::QtMipsMachine *machine;
std::uint32_t memory_change_counter;
std::uint32_t cache_program_change_counter;
+ std::uint32_t stage_addr[STAGEADDR_COUNT];
+ bool stages_need_update;
};
#endif // PROGRAMMODEL_H
diff --git a/qtmips_machine/core.cpp b/qtmips_machine/core.cpp
index 45b08ec..64c309b 100644
--- a/qtmips_machine/core.cpp
+++ b/qtmips_machine/core.cpp
@@ -275,6 +275,7 @@ struct Core::dtFetch Core::fetch(bool skip_break) {
.inst_addr = inst_addr,
.excause = excause,
.in_delay_slot = false,
+ .is_valid = true,
};
}
@@ -316,7 +317,7 @@ struct Core::dtDecode Core::decode(const struct dtFetch &dt) {
excause = dt.inst.encoded_exception();
}
- emit decode_inst_addr_value(dt.inst_addr);
+ emit decode_inst_addr_value(dt.is_valid? dt.inst_addr: STAGEADDR_NONE);
emit instruction_decoded(dt.inst, dt.inst_addr, excause);
emit decode_instruction_value(dt.inst.data());
emit decode_reg1_value(val_rs);
@@ -374,6 +375,7 @@ struct Core::dtDecode Core::decode(const struct dtFetch &dt) {
.in_delay_slot = dt.in_delay_slot,
.stall = false,
.stop_if = !!(flags & IMF_STOP_IF),
+ .is_valid = dt.is_valid,
};
}
@@ -447,7 +449,7 @@ struct Core::dtExecute Core::execute(const struct dtDecode &dt) {
}
}
- emit execute_inst_addr_value(dt.inst_addr);
+ emit execute_inst_addr_value(dt.is_valid? dt.inst_addr: STAGEADDR_NONE);
emit instruction_executed(dt.inst, dt.inst_addr, excause);
emit execute_alu_value(alu_val);
emit execute_reg1_value(dt.val_rs);
@@ -485,6 +487,7 @@ struct Core::dtExecute Core::execute(const struct dtDecode &dt) {
.excause = excause,
.in_delay_slot = dt.in_delay_slot,
.stop_if = dt.stop_if,
+ .is_valid = dt.is_valid,
};
}
@@ -514,7 +517,7 @@ struct Core::dtMemory Core::memory(const struct dtExecute &dt) {
regwrite = false;
}
- emit memory_inst_addr_value(dt.inst_addr);
+ emit memory_inst_addr_value(dt.is_valid? dt.inst_addr: STAGEADDR_NONE);
emit instruction_memory(dt.inst, dt.inst_addr, dt.excause);
emit memory_alu_value(dt.alu_val);
emit memory_rt_value(dt.val_rt);
@@ -537,11 +540,12 @@ struct Core::dtMemory Core::memory(const struct dtExecute &dt) {
.excause = dt.excause,
.in_delay_slot = dt.in_delay_slot,
.stop_if = dt.stop_if,
+ .is_valid = dt.is_valid,
};
}
void Core::writeback(const struct dtMemory &dt) {
- emit writeback_inst_addr_value(dt.inst_addr);
+ emit writeback_inst_addr_value(dt.is_valid? dt.inst_addr: STAGEADDR_NONE);
emit instruction_writeback(dt.inst, dt.inst_addr, dt.excause);
emit writeback_value(dt.towrite_val);
emit writeback_regw_value(dt.regwrite);
@@ -600,6 +604,7 @@ void Core::dtFetchInit(struct dtFetch &dt) {
dt.inst = Instruction(0x00);
dt.excause = EXCAUSE_NONE;
dt.in_delay_slot = false;
+ dt.is_valid = false;
}
void Core::dtDecodeInit(struct dtDecode &dt) {
@@ -632,6 +637,7 @@ void Core::dtDecodeInit(struct dtDecode &dt) {
dt.in_delay_slot = false;
dt.stall = false;
dt.stop_if = false;
+ dt.is_valid = false;
}
void Core::dtExecuteInit(struct dtExecute &dt) {
@@ -646,6 +652,7 @@ void Core::dtExecuteInit(struct dtExecute &dt) {
dt.excause = EXCAUSE_NONE;
dt.in_delay_slot = false;
dt.stop_if = false;
+ dt.is_valid = false;
}
void Core::dtMemoryInit(struct dtMemory &dt) {
@@ -658,6 +665,7 @@ void Core::dtMemoryInit(struct dtMemory &dt) {
dt.excause = EXCAUSE_NONE;
dt.in_delay_slot = false;
dt.stop_if = false;
+ dt.is_valid = false;
}
CoreSingle::CoreSingle(Registers *regs, MemoryAccess *mem_program, MemoryAccess *mem_data,
@@ -742,16 +750,19 @@ void CorePipelined::do_step(bool skip_break) {
if (excpt_in_progress) {
dtExecuteInit(dt_e);
emit instruction_executed(dt_e.inst, dt_e.inst_addr, dt_e.excause);
+ emit execute_inst_addr_value(STAGEADDR_NONE);
}
excpt_in_progress = excpt_in_progress || dt_e.excause != EXCAUSE_NONE;
if (excpt_in_progress) {
dtDecodeInit(dt_d);
emit instruction_decoded(dt_d.inst, dt_d.inst_addr, dt_d.excause);
+ emit decode_inst_addr_value(STAGEADDR_NONE);
}
excpt_in_progress = excpt_in_progress || dt_e.excause != EXCAUSE_NONE;
if (excpt_in_progress) {
dtFetchInit(dt_f);
emit instruction_fetched(dt_f.inst, dt_f.inst_addr, dt_f.excause);
+ emit fetch_inst_addr_value(STAGEADDR_NONE);
if (dt_m.excause != EXCAUSE_NONE) {
regs->pc_abs_jmp(dt_e.inst_addr);
handle_exception(this, regs, dt_m.excause, dt_m.inst_addr,
@@ -867,6 +878,7 @@ void CorePipelined::do_step(bool skip_break) {
if (dt_d.nb_skip_ds) {
dtFetchInit(dt_f);
emit instruction_fetched(dt_f.inst, dt_f.inst_addr, dt_f.excause);
+ emit fetch_inst_addr_value(STAGEADDR_NONE);
}
}
} else {
diff --git a/qtmips_machine/core.h b/qtmips_machine/core.h
index 52cadb4..5658726 100644
--- a/qtmips_machine/core.h
+++ b/qtmips_machine/core.h
@@ -186,6 +186,7 @@ protected:
uint32_t inst_addr; // Address of instruction
enum ExceptionCause excause;
bool in_delay_slot;
+ bool is_valid;
};
struct dtDecode {
Instruction inst;
@@ -222,6 +223,7 @@ protected:
bool in_delay_slot;
bool stall;
bool stop_if;
+ bool is_valid;
};
struct dtExecute {
Instruction inst;
@@ -236,6 +238,7 @@ protected:
enum ExceptionCause excause;
bool in_delay_slot;
bool stop_if;
+ bool is_valid;
};
struct dtMemory {
Instruction inst;
@@ -248,6 +251,7 @@ protected:
enum ExceptionCause excause;
bool in_delay_slot;
bool stop_if;
+ bool is_valid;
};
struct dtFetch fetch(bool skip_break = false);
diff --git a/qtmips_machine/machinedefs.h b/qtmips_machine/machinedefs.h
index d8219b6..9f85240 100644
--- a/qtmips_machine/machinedefs.h
+++ b/qtmips_machine/machinedefs.h
@@ -141,6 +141,8 @@ enum LocationStatus {
LOCSTAT_ILLEGAL = 1 << 3,
};
+const std::uint32_t STAGEADDR_NONE = 0xffffffff;
+
}
#endif // MACHINEDEFS_H