Refactor program state updating on processor cycle change
This removes the rather vague and messy updating previously used, which was mainly focussed on propagating out signals from the processorTab.
Now, relevant widgets will connect directly to the processorhandler to update only on the processor state changes that are relevant to them.
MODIFY
src/cachetab.cpp
src/cachetab.cpp
#include "cachesim/cacheview.h"
#include "cachesim/cachewidget.h"
+#include "processorhandler.h"
+
namespace Ripes {
CacheTab::CacheTab(QToolBar* toolbar, QWidget* parent) : RipesTab(toolbar, parent), m_ui(new Ui::CacheTab) {
m_ui->setupUi(this);
+ // During processor running, it should not be possible to interact with the cache tab
+ connect(ProcessorHandler::get(), &ProcessorHandler::runStarted, [=] { setEnabled(false); });
+ connect(ProcessorHandler::get(), &ProcessorHandler::runFinished, [=] { setEnabled(true); });
+
connect(m_ui->cacheView, &CacheView::cacheAddressSelected, this, &CacheTab::focusAddressChanged);
connect(m_ui->cacheTabWidget, &CacheTabWidget::cacheFocusChanged, [=](CacheWidget* widget) {

MODIFY
src/edittab.cpp
src/edittab.cpp
@@ -71,6 +71,8 @@ EditTab::EditTab(QToolBar* toolbar, QWidget* parent) : RipesTab(toolbar, parent)
connect(ProcessorHandler::get(), &ProcessorHandler::runStarted, [=] { m_buildAction->setEnabled(false); });
connect(ProcessorHandler::get(), &ProcessorHandler::runFinished,
[=] { m_buildAction->setEnabled(m_ui->setCInput->isChecked()); });
+ connect(ProcessorHandler::get(), &ProcessorHandler::procStateChangedNonRun, this,
+ &EditTab::updateProgramViewerHighlighting);
onProcessorChanged();
sourceTypeChanged();

MODIFY
src/instructionmodel.cpp
src/instructionmodel.cpp
@@ -9,6 +9,8 @@ InstructionModel::InstructionModel(QObject* parent) : QAbstractTableModel(parent
m_stageNames << ProcessorHandler::getProcessor()->stageName(i);
m_stageInfos[i];
}
+ connect(ProcessorHandler::get(), &ProcessorHandler::procStateChangedNonRun, this,
+ &InstructionModel::processorWasClocked);
}
int InstructionModel::columnCount(const QModelIndex&) const {

MODIFY
src/mainwindow.cpp
src/mainwindow.cpp
@@ -92,10 +92,6 @@ MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent), m_ui(new Ui::Main
setupMenus();
// setup and connect widgets
- connect(m_processorTab, &ProcessorTab::updateProcessorTab, this, &MainWindow::updateMemoryTab);
- connect(m_processorTab, &ProcessorTab::updateProcessorTab, m_editTab, &EditTab::updateProgramViewerHighlighting);
- connect(this, &MainWindow::updateMemoryTab, m_memoryTab, &MemoryTab::update);
- connect(m_stackedTabs, &QStackedWidget::currentChanged, m_memoryTab, &MemoryTab::update);
connect(m_editTab, &EditTab::programChanged, ProcessorHandler::get(), &ProcessorHandler::loadProgram);
connect(m_editTab, &EditTab::editorStateChanged, [=] { this->m_hasSavedFile = false; });
@@ -111,7 +107,7 @@ MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent), m_ui(new Ui::Main
connect(ProcessorHandler::get(), &ProcessorHandler::processorChanged, m_editTab, &EditTab::onProcessorChanged);
connect(ProcessorHandler::get(), &ProcessorHandler::stopping, m_processorTab, &ProcessorTab::pause);
- connect(m_processorTab, &ProcessorTab::processorWasReset, [=] { SystemIO::reset(); });
+ connect(ProcessorHandler::get(), &ProcessorHandler::processorReset, [=] { SystemIO::reset(); });
connect(m_ui->actionSystem_calls, &QAction::triggered, [=] {
SyscallViewer v;

MODIFY
src/mainwindow.h
src/mainwindow.h
@@ -46,11 +46,6 @@ private slots:
void settingsTriggered();
void tabChanged(int index);
- void processorUpdated() { emit updateMemoryTab(); }
-
-signals:
- void updateMemoryTab();
-
private:
void loadFile(const QString& filename, SourceType type);

MODIFY
src/memorytab.cpp
src/memorytab.cpp
@@ -32,10 +32,9 @@ MemoryTab::MemoryTab(QToolBar* toolbar, QWidget* parent) : RipesTab(toolbar, par
m_ui->memoryMapView->horizontalHeader()->setSectionResizeMode(MemoryMapModel::Size, QHeaderView::ResizeToContents);
m_ui->splitter->setStretchFactor(0, 1);
m_ui->splitter->setStretchFactor(1, 0);
-}
-void MemoryTab::update() {
- m_ui->memoryViewerWidget->updateView();
+ connect(ProcessorHandler::get(), &ProcessorHandler::procStateChangedNonRun,
+ [=] { m_ui->memoryViewerWidget->updateView(); });
}
MemoryTab::~MemoryTab() {

MODIFY
src/memorytab.h
src/memorytab.h
@@ -24,9 +24,6 @@ public:
MemoryTab(QToolBar* toolbar, QWidget* parent = nullptr);
~MemoryTab() override;
-public slots:
- void update();
-
private:
Ui::MemoryTab* m_ui = nullptr;
};

MODIFY
src/processorhandler.cpp
src/processorhandler.cpp
@@ -110,7 +110,10 @@ void ProcessorHandler::_run() {
};
// Start running through the VSRTL Widget interface
- connect(&m_runWatcher, &QFutureWatcher<void>::finished, this, &ProcessorHandler::runFinished);
+ connect(&m_runWatcher, &QFutureWatcher<void>::finished, [=] {
+ emit runFinished();
+ emit procStateChangedNonRun();
+ });
connect(&m_runWatcher, &QFutureWatcher<void>::finished, [=] { ProcessorStatusManager::clearStatus(); });
m_runWatcher.setFuture(m_vsrtlWidget->run(cycleFunctor));
@@ -212,12 +215,18 @@ void ProcessorHandler::_selectProcessor(const ProcessorID& id, const QStringList
void ProcessorHandler::processorWasClockedWrapper() {
emit processorClocked();
+ if (!_isRunning()) {
+ emit processorClockedNonRun();
+ emit procStateChangedNonRun();
+ }
}
void ProcessorHandler::processorResetWrapper() {
emit processorReset();
+ emit procStateChangedNonRun();
}
void ProcessorHandler::processorReversedWrapper() {
emit processorReversed();
+ emit procStateChangedNonRun();
}
int ProcessorHandler::_getCurrentProgramSize() const {

MODIFY
src/processors/ripesprocessor.h
src/processors/ripesprocessor.h
@@ -148,8 +148,8 @@ public:
virtual void setPCInitialValue(uint32_t address) = 0;
void reset() override {
- Design::reset();
m_instructionsRetired = 0;
+ Design::reset();
}
/**

MODIFY
src/processortab.cpp
src/processortab.cpp
@@ -89,14 +89,12 @@ ProcessorTab::ProcessorTab(QToolBar* controlToolbar, QToolBar* additionalToolbar
m_vsrtlWidget->setLocked(true);
m_stageModel = new StageTableModel(this);
- connect(this, &ProcessorTab::updateProcessorTab, m_stageModel, &StageTableModel::processorWasClocked);
updateInstructionModel();
m_ui->registerContainerWidget->initialize();
- connect(this, &ProcessorTab::updateProcessorTab, m_ui->registerContainerWidget,
- &RegisterContainerWidget::updateView);
- connect(this, &ProcessorTab::updateProcessorTab, this, &ProcessorTab::updateStatistics);
- connect(this, &ProcessorTab::updateProcessorTab, this, &ProcessorTab::updateInstructionLabels);
+ connect(ProcessorHandler::get(), &ProcessorHandler::procStateChangedNonRun, this, &ProcessorTab::updateStatistics);
+ connect(ProcessorHandler::get(), &ProcessorHandler::procStateChangedNonRun, this,
+ &ProcessorTab::updateInstructionLabels);
setupSimulatorActions(controlToolbar);
@@ -358,7 +356,6 @@ void ProcessorTab::processorSelection() {
if (m_displayValuesAction->isChecked()) {
m_vsrtlWidget->setOutputPortValuesVisible(true);
}
- emit updateProcessorTab();
}
}
@@ -381,8 +378,6 @@ void ProcessorTab::updateInstructionModel() {
m_ui->instructionView->horizontalHeader()->setSectionResizeMode(InstructionModel::Instruction,
QHeaderView::Stretch);
- connect(this, &ProcessorTab::updateProcessorTab, m_instrModel, &InstructionModel::processorWasClocked);
-
// Make the instruction view follow the instruction which is currently present in the first stage of the processor
connect(m_instrModel, &InstructionModel::firstStageInstrChanged, this, &ProcessorTab::setInstructionViewCenterAddr);
@@ -393,7 +388,6 @@ void ProcessorTab::updateInstructionModel() {
void ProcessorTab::restart() {
// Invoked when changes to binary simulation file has been made
- emit updateProcessorTab();
enableSimulatorControls();
}
@@ -451,8 +445,6 @@ void ProcessorTab::reset() {
m_autoClockAction->setChecked(false);
m_vsrtlWidget->reset();
m_stageModel->reset();
- emit updateProcessorTab();
- emit processorWasReset();
enableSimulatorControls();
printToLog("\n");
@@ -479,7 +471,6 @@ void ProcessorTab::runFinished() {
pause();
ProcessorHandler::checkProcessorFinished();
m_statUpdateTimer->stop();
- emit updateProcessorTab();
}
void ProcessorTab::run(bool state) {
@@ -514,7 +505,6 @@ void ProcessorTab::run(bool state) {
void ProcessorTab::reverse() {
m_vsrtlWidget->reverse();
enableSimulatorControls();
- emit updateProcessorTab();
}
void ProcessorTab::clock() {
@@ -525,8 +515,6 @@ void ProcessorTab::clock() {
}
ProcessorHandler::checkProcessorFinished();
m_reverseAction->setEnabled(m_vsrtlWidget->isReversible());
-
- emit updateProcessorTab();
}
void ProcessorTab::showStageTable() {

MODIFY
src/processortab.h
src/processortab.h
@@ -35,10 +35,6 @@ public:
void initRegWidget();
-signals:
- void updateProcessorTab();
- void processorWasReset();
-
public slots:
void pause();
void restart();

MODIFY
src/registercontainerwidget.cpp
src/registercontainerwidget.cpp
@@ -9,6 +9,8 @@ namespace Ripes {
RegisterContainerWidget::RegisterContainerWidget(QWidget* parent)
: QWidget(parent), m_ui(new Ui::RegisterContainerWidget) {
m_ui->setupUi(this);
+ connect(ProcessorHandler::get(), &ProcessorHandler::procStateChangedNonRun, this,
+ &RegisterContainerWidget::updateView);
}
RegisterContainerWidget::~RegisterContainerWidget() {
@@ -23,6 +25,7 @@ void RegisterContainerWidget::initialize() {
m_ui->tabWidget->insertTab(m_ui->tabWidget->count(), registerWidget, s_RegsterFileName.at(rfid));
registerWidget->initialize();
}
+ updateView();
}
void RegisterContainerWidget::updateView() {

MODIFY
src/stagetablemodel.cpp
src/stagetablemodel.cpp
@@ -11,7 +11,10 @@ static inline uint32_t indexToAddress(unsigned index) {
return 0;
}
-StageTableModel::StageTableModel(QObject* parent) : QAbstractTableModel(parent) {}
+StageTableModel::StageTableModel(QObject* parent) : QAbstractTableModel(parent) {
+ connect(ProcessorHandler::get(), &ProcessorHandler::procStateChangedNonRun, this,
+ &StageTableModel::processorWasClocked);
+}
QVariant StageTableModel::headerData(int section, Qt::Orientation orientation, int role) const {
if (role != Qt::DisplayRole)
@@ -41,9 +44,14 @@ void StageTableModel::reset() {
beginResetModel();
m_cycleStageInfos.clear();
endResetModel();
+ gatherStageInfo();
}
void StageTableModel::gatherStageInfo() {
+ long long cycleCount = ProcessorHandler::getProcessor()->getCycleCount();
+ if (m_cycleStageInfos.count(cycleCount)) {
+ return;
+ }
for (unsigned i = 0; i < ProcessorHandler::getProcessor()->stageCount(); i++) {
m_cycleStageInfos[ProcessorHandler::getProcessor()->getCycleCount()][i] =
ProcessorHandler::getProcessor()->stageInfo(i);

Refactor program state updating on processor cycle change

This removes the rather vague and messy updating previously used, which was mainly focussed on propagating out signals from the processorTab.
Now, relevant widgets will connect directly to the processorhandler to update only on the processor state changes that are relevant to them.