diff options
-rw-r--r-- | gui/cachewaysselector.cc | 58 | ||||
-rw-r--r-- | gui/cachewaysselector.h (renamed from gui/dynamicwaysentry.h) | 45 | ||||
-rw-r--r-- | gui/dynamicwaysentry.cc | 99 | ||||
-rw-r--r-- | gui/gui.cc | 23 | ||||
-rw-r--r-- | gui/gui.h | 2 | ||||
-rw-r--r-- | gui/gui.ui | 111 | ||||
-rw-r--r-- | gui/messages.h | 3 | ||||
-rw-r--r-- | gui/resources.qrc | 4 | ||||
-rw-r--r-- | gui/resources/arrow_down.png | bin | 0 -> 228 bytes | |||
-rw-r--r-- | gui/resources/arrow_down_pressed.png | bin | 0 -> 234 bytes | |||
-rw-r--r-- | gui/resources/arrow_up.png | bin | 0 -> 221 bytes | |||
-rw-r--r-- | gui/resources/arrow_up_pressed.png | bin | 0 -> 227 bytes | |||
-rw-r--r-- | gui/resources/styles.qss | 62 | ||||
-rw-r--r-- | gui/worker.cc | 1 | ||||
-rw-r--r-- | gui/worker.h | 1 |
15 files changed, 176 insertions, 233 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/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(); -} @@ -18,7 +18,7 @@ #include "gui.h" #include "./ui_gui.h" #include "digitlabeldelegate.h" -#include "dynamicwaysentry.h" +#include "cachewaysselector.h" #include "messages.h" #include "storageview.h" #include "registerview.h" @@ -73,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); @@ -140,7 +142,6 @@ 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) @@ -216,6 +217,8 @@ 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); @@ -302,21 +305,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()) { @@ -68,6 +68,8 @@ 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); @@ -6,7 +6,7 @@ <rect> <x>0</x> <y>0</y> - <width>1499</width> + <width>1522</width> <height>621</height> </rect> </property> @@ -25,7 +25,7 @@ <widget class="QTabWidget" name="storage"> <property name="minimumSize"> <size> - <width>700</width> + <width>1250</width> <height>0</height> </size> </property> @@ -45,7 +45,7 @@ </size> </property> <property name="title"> - <string> </string> + <string/> </property> <property name="alignment"> <set>Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignTop</set> @@ -376,93 +376,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 +596,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/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 Binary files differnew file mode 100644 index 0000000..80b1753 --- /dev/null +++ b/gui/resources/arrow_down.png diff --git a/gui/resources/arrow_down_pressed.png b/gui/resources/arrow_down_pressed.png Binary files differnew file mode 100644 index 0000000..0981cf2 --- /dev/null +++ b/gui/resources/arrow_down_pressed.png diff --git a/gui/resources/arrow_up.png b/gui/resources/arrow_up.png Binary files differnew file mode 100644 index 0000000..69b65af --- /dev/null +++ b/gui/resources/arrow_up.png diff --git a/gui/resources/arrow_up_pressed.png b/gui/resources/arrow_up_pressed.png Binary files differnew file mode 100644 index 0000000..98d50ac --- /dev/null +++ b/gui/resources/arrow_up_pressed.png 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/worker.cc b/gui/worker.cc index 0ba364b..dd7b637 100644 --- a/gui/worker.cc +++ b/gui/worker.cc @@ -72,6 +72,7 @@ void Worker::runSteps(int steps) { this->ct->run_for(steps); this->update(); + emit steps_done(); } void Worker::update() diff --git a/gui/worker.h b/gui/worker.h index c62f4ed..5ffb6ef 100644 --- a/gui/worker.h +++ b/gui/worker.h @@ -72,6 +72,7 @@ class Worker : public QObject void ex_info(const InstrDTO *); void mm_info(const InstrDTO *); void wb_info(const InstrDTO *); + void steps_done(); void finished(); private: |