summaryrefslogtreecommitdiff
path: root/gui
diff options
context:
space:
mode:
Diffstat (limited to 'gui')
-rw-r--r--gui/cachewaysselector.cc58
-rw-r--r--gui/cachewaysselector.h (renamed from gui/dynamicwaysentry.h)45
-rw-r--r--gui/digitlabeldelegate.cc8
-rw-r--r--gui/dynamicwaysentry.cc99
-rw-r--r--gui/gui.cc65
-rw-r--r--gui/gui.h4
-rw-r--r--gui/gui.ui128
-rw-r--r--gui/messages.h3
-rw-r--r--gui/registerview.cc69
-rw-r--r--gui/registerview.h64
-rw-r--r--gui/resources.qrc4
-rw-r--r--gui/resources/arrow_down.pngbin0 -> 228 bytes
-rw-r--r--gui/resources/arrow_down_pressed.pngbin0 -> 234 bytes
-rw-r--r--gui/resources/arrow_up.pngbin0 -> 221 bytes
-rw-r--r--gui/resources/arrow_up_pressed.pngbin0 -> 227 bytes
-rw-r--r--gui/resources/styles.qss62
-rw-r--r--gui/storageview.cc5
-rw-r--r--gui/storageview.h14
-rw-r--r--gui/worker.cc25
-rw-r--r--gui/worker.h22
20 files changed, 374 insertions, 301 deletions
diff --git a/gui/cachewaysselector.cc b/gui/cachewaysselector.cc
new file mode 100644
index 0000000..14dae6f
--- /dev/null
+++ b/gui/cachewaysselector.cc
@@ -0,0 +1,58 @@
+// Simulator for the RISC-V[ECTOR] mini-ISA
+// Copyright (C) 2025 Siddarth Suresh
+// Copyright (C) 2025 bdunahu
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+#include "cachewaysselector.h"
+#include <QHBoxLayout>
+#include <QLabel>
+#include <QSpinBox>
+#include <QVBoxLayout>
+
+CacheWaysSelector::CacheWaysSelector(QWidget *parent) : QWidget(parent)
+{
+ QVBoxLayout *v;
+ QHBoxLayout *l;
+ QSpinBox *sb;
+ QLabel *b;
+ int i;
+
+ v = new QVBoxLayout(this);
+
+ for (i = 1; i <= 6; ++i) {
+ l = new QHBoxLayout;
+
+ b = new QLabel(QString("L%1 2^").arg(i), this);
+
+ sb = new QSpinBox;
+ sb->setRange(-1, 4);
+ sb->setValue(-1);
+
+ l->addWidget(b);
+ l->addWidget(sb);
+
+ v->addLayout(l);
+ this->sbs.append(sb);
+ }
+}
+
+QList<int> CacheWaysSelector::values() const
+{
+ QList<int> r;
+ for (const QSpinBox *sb : this->sbs) {
+ r.append(sb->value());
+ }
+ return r;
+}
diff --git a/gui/dynamicwaysentry.h b/gui/cachewaysselector.h
index 26b8b3e..4612b0c 100644
--- a/gui/dynamicwaysentry.h
+++ b/gui/cachewaysselector.h
@@ -15,37 +15,36 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
-#ifndef DYNAMICWAYSENTRY_H
-#define DYNAMICWAYSENTRY_H
+#ifndef CACHEWAYSSELECTOR_H
+#define CACHEWAYSSELECTOR_H
-
-#include <QLineEdit>
-#include <QStringList>
-#include <QVBoxLayout>
-#include <QVector>
+#include <QSpinBox>
#include <QWidget>
-class DynamicWaysEntry : public QWidget
+class CacheWaysSelector : public QWidget
{
+ Q_OBJECT
+
public:
- DynamicWaysEntry(QWidget *parent = nullptr);
- QStringList get_entries() const;
/**
- * Parses a string from this entry field, if it is valid.
- * @param a string
- * @param -1 if the string is not suitable as a way, an integer compatible
- * with the cache constructor otherwise.
+ * Constructor.
+ * This class provides a simple group of labeled spinboxs meant for
+ * selecting cache ways.
+ * @param The parent widget.
+ * @param a newly allocated CacheWaysSelector
*/
- int parse_valid_way(QString t);
- private slots:
- void on_number_enter(const QString &t);
+ explicit CacheWaysSelector(QWidget *parent = nullptr);
+
+ /**
+ * @return the values in the spinboxes.
+ */
+ QList<int> values() const;
private:
- QVBoxLayout *l;
- QVector<QLineEdit *> fields;
- QStringList entries;
- void add_field();
- void remove_last_field();
+ /**
+ * A list of spinboxes.
+ */
+ QList<QSpinBox *> sbs;
};
-#endif // DYNAMICWAYSENTRY_H
+#endif // CACHEWAYSSELECTOR_H
diff --git a/gui/digitlabeldelegate.cc b/gui/digitlabeldelegate.cc
index 430946c..7a6a1d5 100644
--- a/gui/digitlabeldelegate.cc
+++ b/gui/digitlabeldelegate.cc
@@ -37,9 +37,13 @@ void DigitLabelDelegate::paint(
QString t;
QStyleOptionViewItem o;
QStyle *s;
+ QVariant a;
+ bool e;
- v = index.data(Qt::DisplayRole).toInt();
- t = format_toggled_value(v, this->is_hex);
+ a = index.data(Qt::DisplayRole);
+ v = a.toInt();
+ e = a.isNull();
+ t = format_toggled_value(v, this->is_hex, e);
o = option;
initStyleOption(&o, index);
diff --git a/gui/dynamicwaysentry.cc b/gui/dynamicwaysentry.cc
deleted file mode 100644
index cbd5342..0000000
--- a/gui/dynamicwaysentry.cc
+++ /dev/null
@@ -1,99 +0,0 @@
-// Simulator for the RISC-V[ECTOR] mini-ISA
-// Copyright (C) 2025 Siddarth Suresh
-// Copyright (C) 2025 bdunahu
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with this program. If not, see <https://www.gnu.org/licenses/>.
-
-#include "dynamicwaysentry.h"
-#include <QLabel>
-#include <QLineEdit>
-#include <QStringList>
-#include <QVBoxLayout>
-#include <QVector>
-#include <QWidget>
-
-DynamicWaysEntry::DynamicWaysEntry(QWidget *parent) : QWidget(parent)
-{
- this->l = new QVBoxLayout(this);
- this->l->setAlignment(Qt::AlignTop);
- this->l->setSpacing(6);
- this->l->setContentsMargins(0, 0, 0, 0);
- this->setLayout(l);
- this->add_field();
-}
-
-QStringList DynamicWaysEntry::get_entries() const { return this->entries; }
-
-int DynamicWaysEntry::parse_valid_way(QString t)
-{
- bool s;
- int i;
- i = t.toInt(&s);
- return (s && i >= 0 && 5 > i) ? i : -1;
-}
-
-// TODO if you enter something valid and then make it invalid,
-// the next box still shows
-void DynamicWaysEntry::on_number_enter(const QString &t)
-{
- int i;
- QLineEdit *sender_field;
-
- sender_field = qobject_cast<QLineEdit *>(sender());
- i = fields.indexOf(sender_field);
- entries[i] = t;
-
- if (i == this->fields.size() - 1 && !t.isEmpty() &&
- (this->parse_valid_way(t) >= 0) && fields.size() < 4)
- add_field();
-
- // TODO, unlink, don't trash everything after
- if (t.isEmpty()) {
- while (this->fields.size() > i + 1) {
- remove_last_field();
- }
- while (entries.size() > fields.size()) {
- entries.removeLast();
- }
- }
-}
-
-void DynamicWaysEntry::add_field()
-{
- QLineEdit *f;
-
- f = new QLineEdit(this);
- f->setPlaceholderText("# ways (a power of 2)");
-
- this->l->addWidget(f);;
- this->fields.append(f);
- this->entries.append(QString());
- connect(
- f, &QLineEdit::textChanged, this, &DynamicWaysEntry::on_number_enter);
-}
-
-void DynamicWaysEntry::remove_last_field()
-{
- QLineEdit *f;
-
- if (this->fields.isEmpty())
- return;
-
- f = this->fields.takeLast();
- this->l->removeWidget(f);
- f->deleteLater();
-
- if (!this->entries.isEmpty())
- entries.removeLast();
-}
diff --git a/gui/gui.cc b/gui/gui.cc
index b4feda6..395c6e6 100644
--- a/gui/gui.cc
+++ b/gui/gui.cc
@@ -17,9 +17,10 @@
#include "gui.h"
#include "./ui_gui.h"
+#include "cachewaysselector.h"
#include "digitlabeldelegate.h"
-#include "dynamicwaysentry.h"
#include "messages.h"
+#include "registerview.h"
#include "storageview.h"
#include "util.h"
#include <QHeaderView>
@@ -72,6 +73,8 @@ GUI::GUI(QWidget *parent) : QMainWindow(parent), ui(new Ui::GUI)
connect(worker, &Worker::wb_info, this, &GUI::onWorkerWriteBackInfo);
+ connect(worker, &Worker::steps_done, this, &GUI::onWorkerStepsDone);
+
// Display cache
connect(worker, &Worker::storage, this, &GUI::onWorkerShowStorage);
@@ -109,37 +112,10 @@ GUI::~GUI()
delete ui;
}
-void displayArrayHTML(QTextEdit *textEdit, const std::array<int, GPR_NUM> &data)
-{
- textEdit->setReadOnly(false);
- QString tableText = "<table border='1' cellspacing='0' cellpadding='8' "
- "style='border-collapse: collapse; width: 100%; "
- "border: 2px solid black;'>";
-
- tableText += "<tr>";
- int index = 0;
- for (int value : data) {
- tableText += QString("<td align='center' style='border: 2px solid "
- "black; min-width: 60px; padding: 10px;'>"
- "%1 <sup style='font-size: 10px; font-weight: "
- "bold; color: black;'>%2</sup>"
- "</td>")
- .arg(QString::asprintf("%04X", value))
- .arg(index);
- index++;
- }
- tableText += "</tr>";
- tableText += "</table>";
-
- textEdit->setHtml(tableText);
- textEdit->setReadOnly(true);
-}
-
void GUI::on_worker_refresh_gui(int cycles, int pc)
{
ui->p_counter->set_value(pc);
ui->cycle_counter->set_value(cycles);
- this->set_status(get_waiting, "idle");
}
void GUI::onWorkerFetchInfo(const InstrDTO *i)
@@ -215,15 +191,20 @@ void GUI::onWorkerWriteBackInfo(const InstrDTO *i)
}
}
+void GUI::onWorkerStepsDone() { this->set_status(get_waiting, "idle"); }
+
void GUI::onWorkerShowStorage(const QVector<QVector<int>> &data, int i)
{
this->tab_boxes.at(i)->set_data(data);
}
-void GUI::onWorkerShowRegisters(const std::array<int, GPR_NUM> &data)
+void GUI::onWorkerShowRegisters(
+ const QVector<signed int> &gprs, const QVector<QVector<signed int>> &vrs)
{
- ;
- // displayArrayHTML(this->tab_boxes.at(0), data);
+ RegisterView *rv;
+
+ rv = dynamic_cast<RegisterView *>(this->tab_boxes.at(0));
+ rv->set_data(gprs, vrs);
}
void GUI::on_upload_intructions_btn_clicked()
@@ -301,21 +282,15 @@ void GUI::on_config_clicked()
{
std::vector<unsigned int> ways;
QStringList entries;
- signed int i;
- DynamicWaysEntry *dwe = ui->cache_way_selector;
+ CacheWaysSelector *cws = ui->cache_ways_selector;
- for (const QString &s : dwe->get_entries()) {
+ for (int i : cws->values()) {
- if (s.isEmpty())
+ // invalid
+ if (i == -1)
continue;
- i = dwe->parse_valid_way(s);
- if (i >= 0) {
- ways.push_back((unsigned int)i);
- } else {
- this->set_status(get_bad_cache, "angry");
- return;
- }
+ ways.push_back((unsigned int)i);
}
if (this->p.empty()) {
@@ -355,15 +330,15 @@ void GUI::make_tabs(int num)
for (i = 0; i < num; ++i) {
if (i == 0) {
n = "Registers";
- e = new StorageView(0, this);
+ e = new RegisterView(GPR_NUM + V_NUM, V_R_LIMIT, this);
} else if (i == num - 1) {
n = "DRAM";
- e = new StorageView(MEM_LINES, this);
+ e = new StorageView(MEM_LINES, LINE_SIZE, this);
} else {
n = QString("L%1").arg(i);
e = new StorageView(
(1 << cache_size_mapper(this->curr_cache_levels - 1, i - 1)),
- this);
+ LINE_SIZE, this);
}
t = new QTableView(ui->storage);
diff --git a/gui/gui.h b/gui/gui.h
index 830d852..edcde88 100644
--- a/gui/gui.h
+++ b/gui/gui.h
@@ -68,9 +68,11 @@ class GUI : public QMainWindow
void onWorkerWriteBackInfo(const InstrDTO *);
+ void onWorkerStepsDone();
+
void onWorkerShowStorage(const QVector<QVector<int>> &data, int i);
- void onWorkerShowRegisters(const std::array<int, GPR_NUM> &data);
+ void onWorkerShowRegisters(const QVector<signed int> &gprs, const QVector<QVector<signed int>> &vrs);
void on_upload_intructions_btn_clicked();
diff --git a/gui/gui.ui b/gui/gui.ui
index 67cca60..5a5a037 100644
--- a/gui/gui.ui
+++ b/gui/gui.ui
@@ -6,7 +6,7 @@
<rect>
<x>0</x>
<y>0</y>
- <width>1499</width>
+ <width>1686</width>
<height>621</height>
</rect>
</property>
@@ -18,14 +18,17 @@
<item>
<layout class="QGridLayout" name="gridLayout_2" rowstretch="0" columnstretch="0">
<item row="0" column="0">
- <layout class="QHBoxLayout" name="control_separator">
+ <layout class="QHBoxLayout" name="control_separator" stretch="6,1">
+ <property name="spacing">
+ <number>6</number>
+ </property>
<item>
<layout class="QVBoxLayout" name="storage_pipe_separator">
<item>
<widget class="QTabWidget" name="storage">
<property name="minimumSize">
<size>
- <width>700</width>
+ <width>0</width>
<height>0</height>
</size>
</property>
@@ -35,7 +38,7 @@
</widget>
</item>
<item>
- <layout class="QHBoxLayout" name="pipe_view">
+ <layout class="QHBoxLayout" name="pipe_view" stretch="1,2,2,2,2,2">
<item>
<widget class="QGroupBox" name="groupBox">
<property name="maximumSize">
@@ -45,7 +48,7 @@
</size>
</property>
<property name="title">
- <string> </string>
+ <string/>
</property>
<property name="alignment">
<set>Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignTop</set>
@@ -93,7 +96,7 @@
<widget class="QGroupBox" name="Fetch">
<property name="minimumSize">
<size>
- <width>200</width>
+ <width>0</width>
<height>0</height>
</size>
</property>
@@ -146,7 +149,7 @@
<widget class="QGroupBox" name="Decode">
<property name="minimumSize">
<size>
- <width>200</width>
+ <width>0</width>
<height>0</height>
</size>
</property>
@@ -199,7 +202,7 @@
<widget class="QGroupBox" name="Execute">
<property name="minimumSize">
<size>
- <width>200</width>
+ <width>0</width>
<height>0</height>
</size>
</property>
@@ -255,7 +258,7 @@
<widget class="QGroupBox" name="Memory">
<property name="minimumSize">
<size>
- <width>200</width>
+ <width>0</width>
<height>0</height>
</size>
</property>
@@ -308,7 +311,7 @@
<widget class="QGroupBox" name="WriteBack">
<property name="minimumSize">
<size>
- <width>200</width>
+ <width>0</width>
<height>0</height>
</size>
</property>
@@ -376,93 +379,14 @@
</widget>
</item>
<item>
- <layout class="QHBoxLayout" name="cache_controls">
- <property name="sizeConstraint">
- <enum>QLayout::SizeConstraint::SetMinimumSize</enum>
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>Ways Selector (powers of 2)</string>
</property>
- <item>
- <widget class="Line" name="line_8">
- <property name="orientation">
- <enum>Qt::Orientation::Vertical</enum>
- </property>
- </widget>
- </item>
- <item>
- <layout class="QVBoxLayout" name="cache_way_text">
- <property name="sizeConstraint">
- <enum>QLayout::SizeConstraint::SetMinimumSize</enum>
- </property>
- <item>
- <widget class="QLabel" name="label">
- <property name="maximumSize">
- <size>
- <width>16777215</width>
- <height>16777215</height>
- </size>
- </property>
- <property name="text">
- <string>C1 2^</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLabel" name="label_2">
- <property name="maximumSize">
- <size>
- <width>16777215</width>
- <height>16777215</height>
- </size>
- </property>
- <property name="text">
- <string>C2 2^</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLabel" name="label_3">
- <property name="minimumSize">
- <size>
- <width>0</width>
- <height>0</height>
- </size>
- </property>
- <property name="maximumSize">
- <size>
- <width>16777215</width>
- <height>16777215</height>
- </size>
- </property>
- <property name="text">
- <string>C3 2^</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLabel" name="label_4">
- <property name="maximumSize">
- <size>
- <width>16777215</width>
- <height>16777215</height>
- </size>
- </property>
- <property name="text">
- <string>C4 2^</string>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <widget class="DynamicWaysEntry" name="cache_way_selector" native="true">
- <property name="minimumSize">
- <size>
- <width>0</width>
- <height>0</height>
- </size>
- </property>
- </widget>
- </item>
- </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="CacheWaysSelector" name="cache_ways_selector" native="true"/>
</item>
<item>
<widget class="QCheckBox" name="enable_pipeline_checkbox">
@@ -675,16 +599,16 @@
</widget>
<customwidgets>
<customwidget>
- <class>DynamicWaysEntry</class>
- <extends>QWidget</extends>
- <header>dynamicwaysentry.h</header>
- <container>1</container>
- </customwidget>
- <customwidget>
<class>DigitLabel</class>
<extends>QLabel</extends>
<header location="global">digitlabel.h</header>
</customwidget>
+ <customwidget>
+ <class>CacheWaysSelector</class>
+ <extends>QWidget</extends>
+ <header>cachewaysselector.h</header>
+ <container>1</container>
+ </customwidget>
</customwidgets>
<resources/>
<connections/>
diff --git a/gui/messages.h b/gui/messages.h
index 461c461..0c38751 100644
--- a/gui/messages.h
+++ b/gui/messages.h
@@ -35,8 +35,6 @@ const std::vector<std::string> load_file = {
const std::vector<std::string> no_instructions = {
"NO PROGRAM PROVIDED", "NOTHING TO DO, GIVING UP", "INSTRUCTIONS MISSING",
"404 INSTRUCTIONS NOT FOUND"};
-const std::vector<std::string> bad_cache = {
- "WAYS CANNOT BE BELOW 0 OR ABOVE 4"};
const std::vector<std::string> no_pipeline = {
"SIMULATION READY: NO PIPE", "PIPE OFF, SIMULATION READY"};
const std::vector<std::string> no_cache = {
@@ -59,7 +57,6 @@ std::string get_load_file() { return RANDOM_MESSAGE(load_file); }
* @return a friendly reminder that the simulation is not configured yet
*/
std::string get_no_instructions() { return RANDOM_MESSAGE(no_instructions); }
-std::string get_bad_cache() { return RANDOM_MESSAGE(bad_cache); }
/**
* @return unsolicited complaints for successful initialization
diff --git a/gui/registerview.cc b/gui/registerview.cc
new file mode 100644
index 0000000..b1a1333
--- /dev/null
+++ b/gui/registerview.cc
@@ -0,0 +1,69 @@
+// Simulator for the RISC-V[ECTOR] mini-ISA
+// Copyright (C) 2025 Siddarth Suresh
+// Copyright (C) 2025 bdunahu
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+#include "pipe_spec.h"
+#include "registerview.h"
+#include "util.h"
+#include <QAbstractTableModel>
+#include <QVector>
+
+QVariant RegisterView::data(const QModelIndex &i, int role) const
+{
+ Qt::Alignment a;
+
+ if (role == Qt::TextAlignmentRole) {
+ a = Qt::AlignRight | Qt::AlignVCenter;
+ return QVariant(static_cast<int>(a));
+ }
+
+ if (!i.isValid() || role != Qt::DisplayRole)
+ return QVariant();
+
+ if (i.row() < 16) {
+ if (i.column() < 1)
+ return this->gprs[i.row()];
+ else
+ return QVariant();
+ }
+
+ return this->vrs[i.row() - GPR_NUM][i.column() - GPR_NUM];
+}
+
+QVariant
+RegisterView::headerData(int section, Qt::Orientation o, int role) const
+{
+ Qt::Alignment a;
+
+ if (role == Qt::TextAlignmentRole) {
+ a = Qt::AlignRight | Qt::AlignVCenter;
+ return QVariant(static_cast<int>(a));
+ }
+
+ if (role != Qt::DisplayRole)
+ return QVariant();
+
+ if (o == Qt::Vertical) {
+ return format_toggled_value(section, this->is_hex);
+ }
+ return QVariant();
+}
+
+void RegisterView::set_data(const QVector<int> &gprs, const QVector<QVector<int>> &vrs)
+{
+ this->gprs = gprs;
+ this->vrs = vrs;
+}
diff --git a/gui/registerview.h b/gui/registerview.h
new file mode 100644
index 0000000..cc5a1f8
--- /dev/null
+++ b/gui/registerview.h
@@ -0,0 +1,64 @@
+// Simulator for the RISC-V[ECTOR] mini-ISA
+// Copyright (C) 2025 Siddarth Suresh
+// Copyright (C) 2025 bdunahu
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+#ifndef REGISTERVIEW_H
+#define REGISTERVIEW_H
+
+#include "storageview.h"
+#include <QAbstractTableModel>
+#include <QVector>
+
+// see https://doc.qt.io/qt-6/qabstracttablemodel.html
+class RegisterView : public StorageView
+{
+ Q_OBJECT
+ public:
+ using StorageView::StorageView;
+
+ /**
+ * Returns a properly formatted cell, including alignment.This function is
+ * specific to the implementation details of QAbstractTableModel.
+ */
+ QVariant
+ data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
+
+ /**
+ * Adds custom formatting options for row and column headers.
+ */
+ QVariant headerData(
+ int section,
+ Qt::Orientation o,
+ int role = Qt::DisplayRole) const override;
+
+ /**
+ * @param field to assign to `this->gprs'.
+ * @param field to assign to `this->vrs'.
+ */
+ void set_data(const QVector<int> &gprs, const QVector<QVector<int>> &vrs);
+
+ private:
+ /**
+ * The general purpose registers.
+ */
+ QVector<int> gprs;
+ /**
+ * The vector registers.
+ */
+ QVector<QVector<int>> vrs;
+};
+
+#endif // REGISTERVIEW_H
diff --git a/gui/resources.qrc b/gui/resources.qrc
index 569cc22..66cd6e4 100644
--- a/gui/resources.qrc
+++ b/gui/resources.qrc
@@ -1,6 +1,10 @@
<!DOCTYPE RCC>
<RCC version="1.0">
<qresource>
+ <file>resources/arrow_down.png</file>
+ <file>resources/arrow_up.png</file>
+ <file>resources/arrow_down_pressed.png</file>
+ <file>resources/arrow_up_pressed.png</file>
<file>resources/styles.qss</file>
<file>resources/idle.png</file>
<file>resources/angry.png</file>
diff --git a/gui/resources/arrow_down.png b/gui/resources/arrow_down.png
new file mode 100644
index 0000000..80b1753
--- /dev/null
+++ b/gui/resources/arrow_down.png
Binary files differ
diff --git a/gui/resources/arrow_down_pressed.png b/gui/resources/arrow_down_pressed.png
new file mode 100644
index 0000000..0981cf2
--- /dev/null
+++ b/gui/resources/arrow_down_pressed.png
Binary files differ
diff --git a/gui/resources/arrow_up.png b/gui/resources/arrow_up.png
new file mode 100644
index 0000000..69b65af
--- /dev/null
+++ b/gui/resources/arrow_up.png
Binary files differ
diff --git a/gui/resources/arrow_up_pressed.png b/gui/resources/arrow_up_pressed.png
new file mode 100644
index 0000000..98d50ac
--- /dev/null
+++ b/gui/resources/arrow_up_pressed.png
Binary files differ
diff --git a/gui/resources/styles.qss b/gui/resources/styles.qss
index a61035e..c6d8daa 100644
--- a/gui/resources/styles.qss
+++ b/gui/resources/styles.qss
@@ -4,6 +4,8 @@
color: "#00cc00";
background-color: "#000200";
border: 0px solid "#000200";
+ selection-background-color: "#00cc00";
+ selection-color: "#000200";
}
QStatusBar {
@@ -50,6 +52,66 @@ QGroupBox::title {
QLabel {
}
+QSpinBox {
+ padding-right: 15px; /* make room for the arrows */
+ border: none;
+}
+
+QSpinBox::up-button {
+ color: "#000200";
+ background-color: "#00cc00";
+ subcontrol-origin: border;
+ subcontrol-position: top right; /* position at the top right corner */
+
+ width: 16px;
+ border: none;
+ subcontrol-origin: border;
+}
+
+QSpinBox::up-arrow {
+ image: url(:/resources/arrow_up.png);
+ width: 7px;
+ height: 7px;
+}
+
+QSpinBox::up-arrow:pressed {
+ image: url(:/resources/arrow_up_pressed.png);
+ width: 7px;
+ height: 7px;
+}
+
+QSpinBox::up-button:pressed {
+ color: "#00cc00";
+ background-color: "#000200";
+}
+
+QSpinBox::down-button {
+ color: "#000200";
+ background-color: "#00cc00";
+ subcontrol-origin: border;
+ subcontrol-position: bottom right; /* position at bottom right corner */
+
+ width: 16px;
+ border: none;
+}
+
+QSpinBox::down-button:pressed {
+ color: "#00cc00";
+ background-color: "#000200";
+}
+
+QSpinBox::down-arrow {
+ image: url(:/resources/arrow_down.png);
+ width: 7px;
+ height: 7px;
+}
+
+QSpinBox::down-arrow:pressed {
+ image: url(:/resources/arrow_down_pressed.png);
+ width: 7px;
+ height: 7px;
+}
+
QTableView {
border: 0px;
selection-background-color: transparent;
diff --git a/gui/storageview.cc b/gui/storageview.cc
index 2f444a9..60391f9 100644
--- a/gui/storageview.cc
+++ b/gui/storageview.cc
@@ -21,10 +21,11 @@
#include <QAbstractTableModel>
#include <QVector>
-StorageView::StorageView(int rows, QObject *parent)
+StorageView::StorageView(int rows, int columns, QObject *parent)
: QAbstractTableModel(parent)
{
this->r = rows;
+ this->c = columns;
this->d.resize(rows);
for (auto &row : this->d)
row.resize(LINE_SIZE, 0);
@@ -32,7 +33,7 @@ StorageView::StorageView(int rows, QObject *parent)
int StorageView::rowCount(const QModelIndex &) const { return this->r; }
-int StorageView::columnCount(const QModelIndex &) const { return LINE_SIZE; }
+int StorageView::columnCount(const QModelIndex &) const { return this->c; }
QVariant StorageView::data(const QModelIndex &i, int role) const
{
diff --git a/gui/storageview.h b/gui/storageview.h
index 0518d8f..a0f8dbb 100644
--- a/gui/storageview.h
+++ b/gui/storageview.h
@@ -31,7 +31,7 @@ class StorageView : public QAbstractTableModel
* `rows' rows.
* @param the number of rows
*/
- StorageView(int rows, QObject *parent = nullptr);
+ StorageView(int rows, int columns, QObject *parent = nullptr);
/**
* Returns the number of rows in this table.
@@ -51,13 +51,13 @@ class StorageView : public QAbstractTableModel
* Returns a properly formatted cell, including alignment.This function is
* specific to the implementation details of QAbstractTableModel.
*/
- QVariant
+ virtual QVariant
data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
/**
* Adds custom formatting options for row and column headers.
*/
- QVariant headerData(
+ virtual QVariant headerData(
int section,
Qt::Orientation o,
int role = Qt::DisplayRole) const override;
@@ -75,15 +75,21 @@ class StorageView : public QAbstractTableModel
public slots:
void set_hex_display(bool hex);
- private:
+ protected:
/**
* The number of rows in this table.
*/
int r;
/**
+ * The number of columns in this table.
+ */
+ int c;
+ /**
* Whether or not the headers should be displayed in hex.
*/
bool is_hex = true;
+
+ private:
/**
* The data this table displays.
*/
diff --git a/gui/worker.cc b/gui/worker.cc
index 0ba364b..a48888c 100644
--- a/gui/worker.cc
+++ b/gui/worker.cc
@@ -72,14 +72,22 @@ void Worker::runSteps(int steps)
{
this->ct->run_for(steps);
this->update();
+ emit steps_done();
}
void Worker::update()
{
unsigned long i;
+ std::array<int, GPR_NUM> gprs;
+ std::array<std::array<signed int, V_R_LIMIT>, V_NUM> vrs;
this->ct_mutex.lock();
- emit register_storage(this->ct->get_gprs());
+ gprs = this->ct->get_gprs();
+ vrs = this->ct->get_vrs();
+ std::vector<std::array<signed int, V_R_LIMIT>> v(vrs.begin(), vrs.end());
+
+ emit register_storage(
+ QVector<int>(gprs.begin(), gprs.end()), this->data_to_QT(v));
for (i = 0; i < s.size(); ++i)
emit storage(this->data_to_QT(this->s.at(i)->get_data()), i + 1);
@@ -92,18 +100,3 @@ void Worker::update()
emit wb_info(this->wb_stage->get_instr());
this->ct_mutex.unlock();
}
-
-QVector<QVector<int>>
-Worker::data_to_QT(std::vector<std::array<signed int, LINE_SIZE>> data)
-{
- QVector<QVector<int>> r;
- QVector<int> tmp;
-
- r.reserve(static_cast<int>(data.size()));
-
- for (const auto &line : data) {
- tmp = QVector<int>(line.begin(), line.end());
- r.append(tmp);
- }
- return r;
-}
diff --git a/gui/worker.h b/gui/worker.h
index c62f4ed..2a362a4 100644
--- a/gui/worker.h
+++ b/gui/worker.h
@@ -64,14 +64,15 @@ class Worker : public QObject
signals:
void clock_cycles(int value, int pc);
- void
- storage(QVector<QVector<int>> data, int i);
- void register_storage(const std::array<int, GPR_NUM> data);
+ void storage(QVector<QVector<int>> data, int i);
+ void register_storage(
+ QVector<signed int> gprs, QVector<QVector<signed int>> vrs);
void if_info(const InstrDTO *);
void id_info(const InstrDTO *);
void ex_info(const InstrDTO *);
void mm_info(const InstrDTO *);
void wb_info(const InstrDTO *);
+ void steps_done();
void finished();
private:
@@ -80,8 +81,21 @@ class Worker : public QObject
* @param the original data
* @return a less universal version of the same thing
*/
+ template <size_t N>
QVector<QVector<int>>
- data_to_QT(std::vector<std::array<signed int, LINE_SIZE>> data);
+ data_to_QT(const std::vector<std::array<signed int, N>> &data)
+ {
+ QVector<QVector<int>> r;
+ QVector<int> tmp;
+
+ r.reserve(static_cast<int>(data.size()));
+
+ for (const auto &line : data) {
+ tmp = QVector<int>(line.begin(), line.end());
+ r.append(tmp);
+ }
+ return r;
+ }
/**
* Sets the GUI signals to update the storage, clock cycle, and stage
* displays.