Make cache configuration changes prompt a processor reset
MODIFY
src/cachesim/cacheconfigwidget.cpp
src/cachesim/cacheconfigwidget.cpp
@@ -52,7 +52,8 @@ void CacheConfigWidget::setCache(CacheSim* cache) {
m_cache->setWriteAllocatePolicy(qvariant_cast<CacheSim::WriteAllocPolicy>(m_ui->wrMiss->itemData(index)));
});
- connect(m_cache, &CacheSim::configurationChanged, this, &CacheConfigWidget::configChanged);
+ connect(m_cache, &CacheSim::configurationChanged, this, &CacheConfigWidget::handleConfigurationChanged);
+ connect(m_cache, &CacheSim::configurationChanged, [=] { emit configurationChanged(); });
connect(m_cache, &CacheSim::hitrateChanged, this, &CacheConfigWidget::updateHitrate);
setupPresets();
@@ -71,7 +72,7 @@ void CacheConfigWidget::setCache(CacheSim* cache) {
connect(m_ui->undo, &QPushButton::clicked, m_cache, &CacheSim::undo);
// Synchronize config widgets with initial cache configuration
- configChanged();
+ handleConfigurationChanged();
QTimer* timer = new QTimer(this);
timer->setInterval(20);
@@ -157,7 +158,7 @@ void CacheConfigWidget::setupPresets() {
void CacheConfigWidget::updateCacheSize() {}
-void CacheConfigWidget::configChanged() {
+void CacheConfigWidget::handleConfigurationChanged() {
std::vector<QObject*> configItems{m_ui->ways, m_ui->lines, m_ui->blocks, m_ui->replacementPolicy,
m_ui->wrMiss, m_ui->wrHit};

MODIFY
src/cachesim/cacheconfigwidget.h
src/cachesim/cacheconfigwidget.h
@@ -18,9 +18,12 @@ public:
void setCache(CacheSim* cache);
+signals:
+ void configurationChanged();
+
public slots:
void updateHitrate();
- void configChanged();
+ void handleConfigurationChanged();
void showCachePlot();
private:

MODIFY
src/cachesim/cachesim.cpp
src/cachesim/cachesim.cpp
@@ -482,7 +482,7 @@ void CacheSim::updateConfiguration() {
m_tagMask = generateBitmask(32 - bitoffset) << bitoffset;
- // Reset the graphical view
+ // Reset the graphical view & processor
emit configurationChanged();
if (m_memory.rw || m_memory.rom) {
@@ -493,15 +493,22 @@ void CacheSim::updateConfiguration() {
}
void CacheSim::processorReset() {
+ /** see comment of m_isResetting */
+ if (m_isResetting) {
+ return;
+ }
+
+ m_isResetting = true;
// The processor might have changed. Since our signals/slot library cannot check for existing connection, we do the
// safe, slightly redundant, thing of disconnecting and reconnecting the VSRTL design update signals.
reassociateMemory();
auto* proc = ProcessorHandler::get()->getProcessorNonConst();
proc->designWasClocked.Connect(this, &CacheSim::processorWasClocked);
proc->designWasReversed.Connect(this, &CacheSim::processorWasReversed);
- proc->designWasReset.Connect(this, &CacheSim::updateConfiguration);
+ proc->designWasReset.Connect(this, &CacheSim::processorReset);
updateConfiguration();
+ m_isResetting = false;
}
void CacheSim::setBlocks(unsigned blocks) {

MODIFY
src/cachesim/cachesim.h
src/cachesim/cachesim.h
@@ -257,6 +257,15 @@ private:
*/
std::deque<CacheTrace> m_traceStack;
+ /**
+ * @brief m_isResetting
+ * The cacheSim can be reset by either internally modyfing cache configuration parameters or externally through a
+ * processor reset. Given that modifying the cache parameters itself will prompt a reset of the processor, we need a
+ * way to distinquish whether a processor reset request originated from an internal cache configuration change. If
+ * so, we do not emit a processor request signal, avoiding a signalling loop.
+ */
+ bool m_isResetting = false;
+
CacheTrace popTrace();
void pushTrace(const CacheTrace& trace);
};

MODIFY
src/cachesim/cachewidget.cpp
src/cachesim/cachewidget.cpp
@@ -21,6 +21,8 @@ CacheWidget::CacheWidget(QWidget* parent) : QWidget(parent), m_ui(new Ui::CacheW
connect(m_ui->cacheView, &CacheView::cacheAddressSelected,
[=](uint32_t address) { emit cacheAddressSelected(address); });
+
+ connect(m_cacheSim, &CacheSim::configurationChanged, [=] { emit configurationChanged(); });
}
void CacheWidget::setType(CacheSim::CacheType type) {

MODIFY
src/cachesim/cachewidget.h
src/cachesim/cachewidget.h
@@ -25,6 +25,7 @@ public:
signals:
void cacheAddressSelected(uint32_t);
+ void configurationChanged();
private:
Ui::CacheWidget* m_ui;

MODIFY
src/mainwindow.cpp
src/mainwindow.cpp
@@ -77,12 +77,15 @@ MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent), m_ui(new Ui::Main
connect(m_editTab, &EditTab::programChanged, ProcessorHandler::get(), &ProcessorHandler::loadProgram);
connect(m_editTab, &EditTab::editorStateChanged, [=] { this->m_hasSavedFile = false; });
- connect(ProcessorHandler::get(), &ProcessorHandler::reqProcessorReset, m_processorTab, &ProcessorTab::reset);
- connect(ProcessorHandler::get(), &ProcessorHandler::reqReloadProgram, m_editTab, &EditTab::emitProgramChanged);
connect(ProcessorHandler::get(), &ProcessorHandler::print, m_processorTab, &ProcessorTab::printToLog);
connect(ProcessorHandler::get(), &ProcessorHandler::exit, m_processorTab, &ProcessorTab::processorFinished);
connect(ProcessorHandler::get(), &ProcessorHandler::runFinished, m_processorTab, &ProcessorTab::runFinished);
+ // Reset and program reload signals
+ connect(m_memoryTab, &MemoryTab::reqProcessorReset, m_processorTab, &ProcessorTab::reset);
+ connect(ProcessorHandler::get(), &ProcessorHandler::reqProcessorReset, m_processorTab, &ProcessorTab::reset);
+ connect(ProcessorHandler::get(), &ProcessorHandler::reqReloadProgram, m_editTab, &EditTab::emitProgramChanged);
+
connect(m_ui->actionOpen_wiki, &QAction::triggered, this, &MainWindow::wiki);
connect(m_ui->actionVersion, &QAction::triggered, this, &MainWindow::version);
}

MODIFY
src/memorytab.cpp
src/memorytab.cpp
@@ -22,6 +22,10 @@ MemoryTab::MemoryTab(QToolBar* toolbar, QWidget* parent) : RipesTab(toolbar, par
&MemoryViewerWidget::setCentralAddress);
connect(m_ui->instructionCache, &CacheWidget::cacheAddressSelected, m_ui->memoryViewerWidget,
&MemoryViewerWidget::setCentralAddress);
+
+ // Make cache configuration changes emit processor reset requests
+ connect(m_ui->dataCache, &CacheWidget::configurationChanged, [=] { emit reqProcessorReset(); });
+ connect(m_ui->instructionCache, &CacheWidget::configurationChanged, [=] { emit reqProcessorReset(); });
}
void MemoryTab::update() {

MODIFY
src/memorytab.h
src/memorytab.h
@@ -23,6 +23,9 @@ public:
MemoryTab(QToolBar* toolbar, QWidget* parent = nullptr);
~MemoryTab() override;
+signals:
+ void reqProcessorReset();
+
public slots:
void update();

Make cache configuration changes prompt a processor reset