Make assembled file be loaded into the current processor
MODIFY
external/VSRTL
external/VSRTL
-Subproject commit acedab39500616eb1fdbf08b968127f78cc10d72
+Subproject commit a72c31b9188936f133f5b058ab4d98336b6f2afb

MODIFY
src/assembler.cpp
src/assembler.cpp
@@ -806,3 +806,10 @@ const QByteArray& Assembler::assemble(const QTextDocument& doc) {
return m_textSegment;
}
+
+const std::map<uint32_t, QByteArray*> Assembler::getSegments() {
+ std::map<uint32_t, QByteArray*> segs;
+ segs[0] = &m_textSegment;
+ segs[DATASTART] = &m_dataSegment;
+ return segs;
+}

MODIFY
src/assembler.h
src/assembler.h
@@ -14,6 +14,8 @@ public:
const QByteArray& getDataSegment() { return m_dataSegment; }
void clear() { m_textSegment.clear(); }
+ const std::map<uint32_t, QByteArray*> getSegments();
+
private:
uint32_t getRegisterNumber(const QString& reg);
void unpackPseudoOp(const QStringList& fields, int& pos);

MODIFY
src/edittab.cpp
src/edittab.cpp
@@ -41,6 +41,10 @@ void EditTab::clear() {
m_assembler->clear();
}
+void EditTab::emitProgramChanged() {
+ emit programChanged(m_assembler->getSegments());
+}
+
void EditTab::assemble() {
if (m_ui->assemblyedit->syntaxAccepted()) {
const QByteArray& ret = m_assembler->assemble(*m_ui->assemblyedit->document());
@@ -49,12 +53,14 @@ void EditTab::assemble() {
if (m_assembler->hasData()) {
assemblingComplete(m_assembler->getDataSegment(), false, DATASTART);
}
+ emit programChanged(m_assembler->getSegments());
} else {
QMessageBox err;
err.setText("Error during assembling of program");
err.exec();
}
}
+
// Restart the simulator to trigger the data memory to be loaded into the main memory. Bad code that this is done
// from here, but it works
Pipeline::getPipeline()->restart();

MODIFY
src/edittab.h
src/edittab.h
#pragma once
+#include <QByteArray>
#include <QFile>
#include <QWidget>
+#include <map>
#include "assembler.h"
#include "ripestab.h"
@@ -30,6 +32,10 @@ public:
signals:
void updateSimulator(); // Emitted when a file has been successfully loaded or assembled, and binary info must be
// sent to the processor
+ void programChanged(const std::map<uint32_t, QByteArray*> program);
+
+public slots:
+ void emitProgramChanged();
private slots:
void assemble();

MODIFY
src/mainwindow.cpp
src/mainwindow.cpp
@@ -71,6 +71,9 @@ MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent), m_ui(new Ui::Main
connect(this, &MainWindow::update, m_processorTab, &ProcessorTab::restart);
connect(this, &MainWindow::updateMemoryTab, m_memoryTab, &MemoryTab::update);
connect(m_stackedTabs, &QStackedWidget::currentChanged, m_memoryTab, &MemoryTab::update);
+ connect(m_editTab, &EditTab::programChanged, m_processorHandler, &ProcessorHandler::loadProgram);
+ connect(m_processorHandler, &ProcessorHandler::reqProcessorReset, m_processorTab, &ProcessorTab::reset);
+ connect(m_processorHandler, &ProcessorHandler::reqReloadProgram, m_editTab, &EditTab::emitProgramChanged);
connect(m_ui->actionAbout, &QAction::triggered, this, &MainWindow::about);
connect(m_ui->actionOpen_wiki, &QAction::triggered, this, &MainWindow::wiki);

MODIFY
src/processorhandler.cpp
src/processorhandler.cpp
@@ -7,16 +7,19 @@ ProcessorHandler::ProcessorHandler() {
selectProcessor(m_currentProcessorID);
}
-void ProcessorHandler::loadProgramData(const std::map<uint32_t, QByteArray&>& segments) {
+void ProcessorHandler::loadProgram(const std::map<uint32_t, QByteArray*>& segments) {
auto& mem = m_currentProcessor->getMemory();
mem.clearInitializationMemories();
for (const auto& seg : segments) {
- mem.addInitializationMemory(seg.first, seg.second.data(), sizeof(char));
+ mem.addInitializationMemory(seg.first, seg.second->data(), seg.second->length());
}
+
+ emit reqProcessorReset();
}
void ProcessorHandler::selectProcessor(ProcessorID id) {
m_currentProcessorID = id;
m_currentProcessor = ProcessorRegistry::constructProcessor(m_currentProcessorID);
+ emit reqReloadProgram();
}

MODIFY
src/processorhandler.h
src/processorhandler.h
#pragma once
+#include <QObject>
+
#include "processorregistry.h"
/**
* Manages construction and destruction of a VSRTL processor design, when selecting between processors.
* Manages all interaction and control of the current processor.
*/
-class ProcessorHandler {
+class ProcessorHandler : public QObject {
+ Q_OBJECT
public:
ProcessorHandler();
Ripes::RipesProcessor* getProcessor() { return m_currentProcessor.get(); }
ProcessorID currentID() const { return m_currentProcessorID; }
void selectProcessor(ProcessorID id);
- void loadProgramData(const std::map<uint32_t, QByteArray&>& segments);
+
+signals:
+ /**
+ * @brief reqProcessorReset
+ * Emitted whenever changes to the internal state of the processor has been made, and a reset of any depending
+ * widgets is required
+ */
+ void reqProcessorReset();
+
+ /**
+ * @brief reqReloadProgram
+ * Emitted whenever the processor has been changed, and we require the currently assembled program to be inserted
+ * into the newly loaded processors memory
+ */
+ void reqReloadProgram();
+
+public slots:
+ void loadProgram(const std::map<uint32_t, QByteArray*>& segments);
private:
static constexpr ProcessorID defaultProcessor = ProcessorID::RISCV_SS;

MODIFY
src/processortab.h
src/processortab.h
@@ -44,6 +44,7 @@ signals:
public slots:
void restart();
+ void reset();
void run();
void processorSelection();
@@ -51,7 +52,6 @@ public slots:
private slots:
void expandView();
void displayValues(bool checked);
- void reset();
void clock();
void setCurrentInstruction(int row);
void showPipeliningTable();

Make assembled file be loaded into the current processor