Initial commit for processor selection
ADD
src/processorregistry.h
+#pragma once
+
+#include <QMetaType>
+#include <map>
+
+#include "processors/ripesprocessor.h"
+
+// Processors
+#include "processors/ss/riscv_ss.h"
+
+enum class ProcessorID { RISCV_SS, RISCV_5S_WF, RISCV_5S_WOF };
+
+struct ProcessorDescription {
+ ProcessorID id;
+ QString ISA;
+ QString name;
+ QString description;
+};
+
+Q_DECLARE_METATYPE(ProcessorID);
+
+class ProcessorRegistry {
+public:
+ static constexpr ProcessorID defaultProcessor = ProcessorID::RISCV_SS;
+
+ using ProcessorMap = std::map<ProcessorID, ProcessorDescription>;
+ static Ripes::RipesProcessor* getProcessor() { return instance().m_currentProcessor.get(); }
+ static ProcessorID currentProcessorID() { return instance().m_currentProcessorID; }
+ static const ProcessorMap& getAvailableProcessors() { return instance().m_descriptions; }
+
+ /**
+ * @brief selectProcessor
+ * @param id
+ * @returns true if current processor changed
+ */
+ static bool selectProcessor(ProcessorID id) {
+ if (id == instance().m_currentProcessorID) {
+ return false;
+ }
+
+ // Create the new processor...
+ instance().m_currentProcessorID = id;
+ instance().createProcessor();
+ return true;
+ }
+
+private:
+ void createProcessor() {
+ switch (m_currentProcessorID) {
+ case ProcessorID::RISCV_5S_WOF:
+ case ProcessorID::RISCV_5S_WF:
+ case ProcessorID::RISCV_SS:
+ break;
+ // m_currentProcessor = std::make_unique<vsrtl::RISCV::SingleCycleRISCV>();
+ }
+ }
+
+ ProcessorRegistry() {
+ // Initialize processors
+
+ // RISC-V single cycle
+ ProcessorDescription desc;
+ desc.id = ProcessorID::RISCV_SS;
+ desc.ISA = "RV32IM";
+ desc.name = "RISC-V Single Cycle";
+ desc.description = "A single cycle RISC-V processor";
+ m_descriptions[desc.id] = desc;
+
+ // RISC-V 5-Stage with forwarding
+ desc.id = ProcessorID::RISCV_5S_WF;
+ desc.ISA = "RV32IM";
+ desc.name = "RISC-V 5-Stage with forwarding";
+ desc.description = "A 5-Stage in-order RISC-V processor with hazard detection and forwarding.";
+ m_descriptions[desc.id] = desc;
+
+ // RISC-V 5-stage without forwarding
+ desc.id = ProcessorID::RISCV_5S_WOF;
+ desc.ISA = "RV32IM";
+ desc.name = "RISC-V 5-Stage without forwarding";
+ desc.description =
+ "A 5-Stage in-order RISC-V processor with no hazard detection and forwarding. \n\nThe user is expected to "
+ "resolve all data hazard through insertions of NOP instructions to correctly schedule the code.";
+ m_descriptions[desc.id] = desc;
+
+ createProcessor();
+ }
+
+ static ProcessorRegistry& instance() {
+ static ProcessorRegistry pr;
+ return pr;
+ }
+
+ ProcessorID m_currentProcessorID = defaultProcessor;
+ std::unique_ptr<Ripes::RipesProcessor> m_currentProcessor;
+
+ ProcessorMap m_descriptions;
+};

MODIFY
src/processors/ss/riscv_ss.h
src/processors/ss/riscv_ss.h
#include "VSRTL/core/vsrtl_logicgate.h"
#include "VSRTL/core/vsrtl_multiplexer.h"
-#include "ripesprocessor.h"
+#include "../ripesprocessor.h"
#include "alu.h"
#include "branch.h"

ADD
src/processorselectiondialog.cpp
+#include "processorselectiondialog.h"
+#include "ui_processorselectiondialog.h"
+
+#include <QDialogButtonBox>
+#include <QListWidget>
+
+#include "processorregistry.h"
+
+ProcessorSelectionDialog::ProcessorSelectionDialog(QWidget* parent)
+ : QDialog(parent), ui(new Ui::ProcessorSelectionDialog) {
+ ui->setupUi(this);
+ setWindowTitle("Select Processor");
+
+ // Initialize processor list
+ for (auto& desc : ProcessorRegistry::getAvailableProcessors()) {
+ QListWidgetItem* item = new QListWidgetItem(desc.second.name);
+ item->setData(Qt::UserRole, QVariant::fromValue(desc.second.id));
+ if (desc.second.id == ProcessorRegistry::currentProcessorID()) {
+ auto font = item->font();
+ font.setBold(true);
+ item->setFont(font);
+ }
+ ui->processorList->addItem(item);
+ }
+
+ connect(ui->processorList, &QListWidget::currentItemChanged, this, &ProcessorSelectionDialog::selectionChanged);
+
+ connect(ui->buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept);
+ connect(ui->buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject);
+}
+
+ProcessorSelectionDialog::~ProcessorSelectionDialog() {
+ delete ui;
+}
+
+void ProcessorSelectionDialog::accept() {
+ ProcessorID id = qvariant_cast<ProcessorID>(ui->processorList->currentItem()->data(Qt::UserRole));
+ ProcessorRegistry::selectProcessor(id);
+ return QDialog::accept();
+}
+
+void ProcessorSelectionDialog::selectionChanged(QListWidgetItem* current, QListWidgetItem* previous) {
+ ProcessorID id = qvariant_cast<ProcessorID>(current->data(Qt::UserRole));
+ const auto& desc = ProcessorRegistry::getAvailableProcessors().at(id);
+
+ ui->name->setText(desc.name);
+ ui->ISA->setText(desc.ISA);
+ ui->description->setPlainText(desc.description);
+}

ADD
src/processorselectiondialog.h
+#pragma once
+
+#include <QDialog>
+#include <QListWidget>
+
+namespace Ui {
+class ProcessorSelectionDialog;
+}
+
+class ProcessorSelectionDialog : public QDialog {
+ Q_OBJECT
+
+public:
+ explicit ProcessorSelectionDialog(QWidget* parent = nullptr);
+ ~ProcessorSelectionDialog();
+
+public slots:
+ virtual void accept() override;
+
+private slots:
+ void selectionChanged(QListWidgetItem* current, QListWidgetItem* previous);
+
+private:
+ Ui::ProcessorSelectionDialog* ui;
+};

ADD
src/processorselectiondialog.ui
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>ProcessorSelectionDialog</class>
+ <widget class="QDialog" name="ProcessorSelectionDialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>706</width>
+ <height>315</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Dialog</string>
+ </property>
+ <property name="modal">
+ <bool>true</bool>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_4">
+ <item>
+ <layout class="QVBoxLayout" name="verticalLayout_3">
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout" stretch="0,1">
+ <item>
+ <widget class="QListWidget" name="processorList">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="MinimumExpanding" vsizetype="Expanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="0" column="0">
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>Name:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="label_3">
+ <property name="text">
+ <string>Description:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="label_2">
+ <property name="text">
+ <string>ISA:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QLineEdit" name="name">
+ <property name="readOnly">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QLineEdit" name="ISA">
+ <property name="readOnly">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QPlainTextEdit" name="description">
+ <property name="readOnly">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QVBoxLayout" name="verticalLayout_5">
+ <item>
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>

MODIFY
src/processortab.cpp
src/processortab.cpp
#include "instructionmodel.h"
#include "parser.h"
#include "pipeline.h"
+#include "processorselectiondialog.h"
#include "rundialog.h"
+#include "processors/ripesprocessor.h"
+
ProcessorTab::ProcessorTab(QToolBar* toolbar, QWidget* parent) : RipesTab(toolbar, parent), m_ui(new Ui::ProcessorTab) {
m_ui->setupUi(this);
@@ -40,6 +43,12 @@ ProcessorTab::ProcessorTab(QToolBar* toolbar, QWidget* parent) : RipesTab(toolba
}
void ProcessorTab::setupSimulatorActions() {
+ const QIcon processorIcon = QIcon(":/icons/cpu.svg");
+ m_selectProcessorAction = new QAction(processorIcon, "Select processor", this);
+ connect(m_selectProcessorAction, &QAction::triggered, this, &ProcessorTab::processorSelection);
+ m_toolbar->addAction(m_selectProcessorAction);
+ m_toolbar->addSeparator();
+
const QIcon resetIcon = QIcon(":/icons/reset.svg");
m_resetAction = new QAction(resetIcon, "Reset (F4)", this);
connect(m_resetAction, &QAction::triggered, this, &ProcessorTab::reset);
@@ -112,6 +121,11 @@ void ProcessorTab::setupSimulatorActions() {
m_toolbar->addAction(m_pipelineTableAction);
}
+void ProcessorTab::processorSelection() {
+ ProcessorSelectionDialog diag;
+ diag.exec();
+}
+
void ProcessorTab::restart() {
// Invoked when changes to binary simulation file has been made
emit update();
@@ -178,9 +192,6 @@ void ProcessorTab::updateActionState() {
m_clockAction->setEnabled(ready);
m_autoClockAction->setEnabled(ready);
m_runAction->setEnabled(ready);
- m_displayValuesAction->setEnabled(ready);
- m_fitViewAction->setEnabled(ready);
- m_pipelineTableAction->setEnabled(ready);
m_reverseAction->setEnabled(ready);
m_resetAction->setEnabled(ready);

MODIFY
src/processortab.h
src/processortab.h
@@ -35,6 +35,8 @@ public slots:
void restart();
void run();
+ void processorSelection();
+
private slots:
void expandView();
void displayValues(bool checked);
@@ -58,6 +60,7 @@ private:
InstructionModel* m_instrModel;
// Actions
+ QAction* m_selectProcessorAction = nullptr;
QAction* m_clockAction = nullptr;
QAction* m_autoClockAction = nullptr;
QAction* m_runAction = nullptr;

Initial commit for processor selection