Fix instructions being printed as "stuck" in ID stage
MODIFY
src/defines.h
src/defines.h
@@ -26,6 +26,7 @@ public:
bool initialized; // If false, no text will be written above a pipeline stage when pipeline is reset
uint32_t invalidReason; // 1: a stage has been flushed because of branch taken
// 2: A stage is stalled because of hazards
+ bool isValid() const { return invalidReason == 0; }
} PC;
StagePCS() {}
void reset() {

MODIFY
src/instructionmodel.cpp
src/instructionmodel.cpp
@@ -69,33 +69,33 @@ QVariant InstructionModel::data(const QModelIndex& index, int role) const {
QStringList retStrings;
uint32_t byteIndex = row * 4;
uint32_t maxInstr = m_textSize - 4;
- if (byteIndex == m_pcsptr.EX.pc && m_pcsptr.EX.initialized && m_pcsptr.EX.invalidReason == 0) {
+ if (byteIndex == m_pcsptr.EX.pc && m_pcsptr.EX.initialized && m_pcsptr.EX.isValid()) {
emit textChanged(Stage::EX, m_parserPtr->getInstructionString(row * 4));
if (byteIndex == maxInstr) {
emit textChanged(Stage::ID, "");
}
retStrings << "EX";
}
- if (byteIndex == m_pcsptr.ID.pc && m_pcsptr.ID.initialized && m_pcsptr.ID.invalidReason == 0) {
+ if (byteIndex == m_pcsptr.ID.pc && m_pcsptr.ID.initialized && m_pcsptr.ID.isValid()) {
emit textChanged(Stage::ID, m_parserPtr->getInstructionString(row * 4));
if (byteIndex == maxInstr) {
emit textChanged(Stage::IF, "");
}
retStrings << "ID";
}
- if (byteIndex == m_pcsptr.IF.pc && m_pcsptr.IF.initialized && m_pcsptr.IF.invalidReason == 0) {
+ if (byteIndex == m_pcsptr.IF.pc && m_pcsptr.IF.initialized && m_pcsptr.IF.isValid()) {
emit textChanged(Stage::IF, m_parserPtr->getInstructionString(row * 4));
emit currentIFRow(row); // for moving view to IF position
retStrings << "IF";
}
- if (byteIndex == m_pcsptr.MEM.pc && m_pcsptr.MEM.initialized && m_pcsptr.MEM.invalidReason == 0) {
+ if (byteIndex == m_pcsptr.MEM.pc && m_pcsptr.MEM.initialized && m_pcsptr.MEM.isValid()) {
emit textChanged(Stage::MEM, m_parserPtr->getInstructionString(row * 4));
if (byteIndex == maxInstr) {
emit textChanged(Stage::EX, "");
}
retStrings << "MEM";
}
- if (byteIndex == m_pcsptr.WB.pc && m_pcsptr.WB.initialized && m_pcsptr.WB.invalidReason == 0) {
+ if (byteIndex == m_pcsptr.WB.pc && m_pcsptr.WB.initialized && m_pcsptr.WB.isValid()) {
emit textChanged(Stage::WB, m_parserPtr->getInstructionString(row * 4));
if (byteIndex == maxInstr) {
emit textChanged(Stage::MEM, "");

MODIFY
src/pipeline.cpp
src/pipeline.cpp
@@ -664,8 +664,8 @@ void Pipeline::propagateCombinational() {
mux_PCSrc.update();
// Load nops if PC is greater than text size
- s_instr_IF = Signal<32>(
- (uint32_t)r_PC_IF > m_textSize ? 0 : m_memory.read((uint32_t)r_PC_IF)); // Read instruction at current PC
+ m_finishing = ((uint32_t)r_PC_IF > m_textSize) | m_finishing;
+ s_instr_IF = Signal<32>(m_finishing ? 0 : m_memory.read((uint32_t)r_PC_IF)); // Read instruction at current PC
// For GUI - set invalidPC (branch taken indicator) if PCSrc both PCSrc and s_IFID_write is asserted - in this
// case, a new program counter value is starting to propagate, indicating an invalid ID branch
@@ -683,7 +683,7 @@ void Pipeline::propagateCombinational() {
s_IFID_reset = m_finishing ? 1 : s_IFID_reset;
// if finishing, ECALL will stay in ID stage, and we will force overrideNext for idex stage
if (m_finishing) {
- r_invalidPC_IDEX.overrideNext(HazardReason::eof);
+ r_invalidPC_IFID.overrideNext(HazardReason::eof);
}
}
@@ -796,8 +796,8 @@ void Pipeline::setStagePCS() {
m_pcs.WB = m_pcs.MEM.initialized ? PCVAL(r_PC_MEMWB, r_invalidPC_MEMWB) : m_pcs.WB;
m_pcs.MEM = m_pcs.EX.initialized ? PCVAL(r_PC_EXMEM, r_invalidPC_EXMEM) : m_pcs.MEM;
m_pcs.EX = m_pcs.ID.initialized ? PCVAL(r_PC_IDEX, r_invalidPC_IDEX) : m_pcs.EX;
- m_pcs.ID = m_pcs.IF.initialized ? PCVAL(r_PC_IFID, r_invalidPC_IFID) : m_pcs.ID;
- m_pcs.IF = PCVAL(r_PC_IF, 0);
+ m_pcs.ID = m_pcs.IF.initialized | m_finishing ? PCVAL(r_PC_IFID, r_invalidPC_IFID) : m_pcs.ID;
+ m_pcs.IF = PCVAL(r_PC_IF, m_finishing | m_finished);
}
int Pipeline::run() {

Fix instructions being printed as "stuck" in ID stage