summaryrefslogtreecommitdiff
path: root/gui
diff options
context:
space:
mode:
authorbd <bdunahu@operationnull.com>2025-04-19 02:23:03 -0400
committerbd <bdunahu@operationnull.com>2025-04-19 02:23:03 -0400
commitda25748edb6997629ffb380683c8c736f24033a8 (patch)
treec7ffcaccc57afde2235fb53a16679225c06c0ed9 /gui
parentf18eac2ac2e5760a4cb81784ad2f23f91b6643d6 (diff)
Add custom QWidget to keep track of up to 4 user cache ways
Diffstat (limited to 'gui')
-rw-r--r--gui/CMakeLists.txt2
-rw-r--r--gui/dynamicwaysentry.cc80
-rw-r--r--gui/dynamicwaysentry.h28
-rw-r--r--gui/gui.cc15
-rw-r--r--gui/gui.h25
-rw-r--r--gui/gui.ui109
-rw-r--r--gui/messages.h4
-rw-r--r--gui/resources/styles.qss3
8 files changed, 229 insertions, 37 deletions
diff --git a/gui/CMakeLists.txt b/gui/CMakeLists.txt
index 0d73527..2c48beb 100644
--- a/gui/CMakeLists.txt
+++ b/gui/CMakeLists.txt
@@ -21,7 +21,7 @@ file(GLOB SRCS
qt_add_resources(GUI_RESOURCES "resources.qrc")
add_executable(risc_vector ${SRCS} ${GUI_RESOURCES})
-target_include_directories(${PROJECT_NAME} PRIVATE ${PROJECT_SOURCE_DIR}/inc)
+target_include_directories(${PROJECT_NAME} PRIVATE ${PROJECT_SOURCE_DIR}/inc ${PROJECT_SOURCE_DIR}/gui)
target_link_libraries(${PROJECT_NAME} PRIVATE ${PROJECT_NAME}_lib ram_lib Qt6::Widgets)
set_target_properties(risc_vector PROPERTIES
diff --git a/gui/dynamicwaysentry.cc b/gui/dynamicwaysentry.cc
new file mode 100644
index 0000000..f35c9ef
--- /dev/null
+++ b/gui/dynamicwaysentry.cc
@@ -0,0 +1,80 @@
+#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;
+}
+
+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/dynamicwaysentry.h b/gui/dynamicwaysentry.h
new file mode 100644
index 0000000..be42696
--- /dev/null
+++ b/gui/dynamicwaysentry.h
@@ -0,0 +1,28 @@
+#include <QLineEdit>
+#include <QStringList>
+#include <QVBoxLayout>
+#include <QVector>
+#include <QWidget>
+
+class DynamicWaysEntry : public QWidget
+{
+ 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.
+ */
+ int parse_valid_way(QString t);
+ private slots:
+ void on_number_enter(const QString &t);
+
+ private:
+ QVBoxLayout *l;
+ QVector<QLineEdit *> fields;
+ QStringList entries;
+ void add_field();
+ void remove_last_field();
+};
diff --git a/gui/gui.cc b/gui/gui.cc
index 699ab48..0ba4867 100644
--- a/gui/gui.cc
+++ b/gui/gui.cc
@@ -6,7 +6,8 @@ GUI::GUI(QWidget *parent) : QMainWindow(parent), ui(new Ui::GUI)
{
ui->setupUi(this);
- this->status_label = new QLabel(this->make_status(get_waiting), this);
+ this->status_label = new QLabel("", this);
+ this->set_status(get_waiting);
QLabel *risc_vector =
new QLabel("RISC V[ECTOR], CS535 UMASS AMHERST", this);
status_label->setMinimumWidth(1200);
@@ -250,7 +251,7 @@ void GUI::on_upload_intructions_btn_clicked()
"Binary Files (*.bin *.rv);;All Files (*.*)");
QFile file(filePath);
if (filePath.isEmpty() || !file.open(QIODevice::ReadOnly)) {
- this->status_label->setText(this->make_status(get_bad_file));
+ this->set_status(get_bad_file);
return;
}
@@ -267,7 +268,7 @@ void GUI::on_upload_intructions_btn_clicked()
}
}
- this->status_label->setText(this->make_status(get_load_file));
+ this->set_status(get_load_file);
file.close();
}
@@ -283,10 +284,10 @@ void GUI::on_enable_pipeline_checkbox_checkStateChanged(
{
if (arg1 == Qt::CheckState::Checked) {
qDebug() << "enable pipeline checkbox checked.";
- is_pipelined = true;
+ this->is_pipelined = true;
} else {
qDebug() << "enable pipeline checkbox unchecked.";
- is_pipelined = false;
+ this->is_pipelined = false;
}
}
@@ -303,7 +304,7 @@ void GUI::on_save_program_state_btn_clicked()
qDebug() << "save program state button is clicked.";
}
-QString GUI::make_status(const std::function<std::string()> &func)
+void GUI::set_status(const std::function<std::string()> &func)
{
- return "CPU SAYS: \"" + QString::fromStdString(func()) + "\"";
+ this->status_label->setText("CPU SAYS: \"" + QString::fromStdString(func()) + "\"");
}
diff --git a/gui/gui.h b/gui/gui.h
index 85f965a..09fe0d9 100644
--- a/gui/gui.h
+++ b/gui/gui.h
@@ -24,10 +24,18 @@ class GUI : public QMainWindow
Q_OBJECT
public:
+ /**
+ * Constructor.
+ * @return A newly allocated GUI object.
+ */
GUI(QWidget *parent = nullptr);
~GUI();
- bool is_pipelined = false;
- std::vector<int> ways;
+
+ /**
+ * Uses `func' to set the current status.
+ * @param a function which returns a string.
+ */
+ void set_status(const std::function<std::string()> &func);
signals:
void sendRefreshDram();
@@ -82,11 +90,21 @@ class GUI : public QMainWindow
*/
std::vector<signed int> p;
+ /**
+ * The current cache configurations.
+ */
+ std::vector<unsigned int> c;
+
+ /**
+ * If this stage is pipelined or not.
+ */
+ bool is_pipelined = false;
+
QThread workerThread;
Worker *worker;
- QVector<int> step_values = {1, 5, 10, 50, 250, 1000, 10000};
+ QVector<int> step_values = {1, 5, 20, 50, 250, 1000, 10000};
const std::map<Mnemonic, QString> mnemonicNameMap = {
{Mnemonic::ADD, "ADD"}, {Mnemonic::SUB, "SUB"},
@@ -115,6 +133,5 @@ class GUI : public QMainWindow
return (it != mnemonicNameMap.end()) ? it->second : "Unknown";
}
- QString make_status(const std::function<std::string()> &func);
};
#endif // GUI_H
diff --git a/gui/gui.ui b/gui/gui.ui
index a2cd6cb..a5a51f1 100644
--- a/gui/gui.ui
+++ b/gui/gui.ui
@@ -134,6 +134,85 @@
</widget>
</item>
<item>
+ <layout class="QHBoxLayout" name="horizontalLayout_9">
+ <item>
+ <layout class="QVBoxLayout" name="verticalLayout_9">
+ <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>
+ </item>
+ <item>
<widget class="Line" name="line_35">
<property name="orientation">
<enum>Qt::Orientation::Horizontal</enum>
@@ -143,9 +222,6 @@
<item>
<layout class="QVBoxLayout" name="verticalLayout_27">
<item>
- <widget class="QLineEdit" name="way_box_1"/>
- </item>
- <item>
<layout class="QHBoxLayout" name="horizontalLayout_10">
<item>
<widget class="QCheckBox" name="enable_pipeline_checkbox">
@@ -534,18 +610,6 @@
<item>
<layout class="QVBoxLayout" name="verticalLayout_6">
<item>
- <widget class="QLabel" name="label_14">
- <property name="font">
- <font>
- <bold>true</bold>
- </font>
- </property>
- <property name="text">
- <string>Run</string>
- </property>
- </widget>
- </item>
- <item>
<widget class="QSlider" name="step_slider">
<property name="minimum">
<number>0</number>
@@ -598,19 +662,20 @@
</property>
</widget>
</item>
- <item row="0" column="0">
- <widget class="QGroupBox" name="groupBox">
- <property name="title">
- <string>GroupBox</string>
- </property>
- </widget>
- </item>
</layout>
</item>
</layout>
</widget>
<widget class="QStatusBar" name="statusBar"/>
</widget>
+ <customwidgets>
+ <customwidget>
+ <class>DynamicWaysEntry</class>
+ <extends>QWidget</extends>
+ <header location="global">dynamicwaysentry.h</header>
+ <container>1</container>
+ </customwidget>
+ </customwidgets>
<resources/>
<connections/>
</ui>
diff --git a/gui/messages.h b/gui/messages.h
index 84b8318..8f852f7 100644
--- a/gui/messages.h
+++ b/gui/messages.h
@@ -1,7 +1,7 @@
#ifndef MESSAGES_H
#define MESSAGES_H
-#include <vector>
#include <string>
+#include <vector>
/**
* Humorous computer speak.
@@ -16,7 +16,7 @@ const std::vector<std::string> load_file = {
"FILE LOADED", "FINISHED READING DATA. EAGERLY WAITING"};
/**
- * @return a random waiting message
+ * @return an unsolicited waiting message
*/
std::string get_waiting() { return RANDOM_MESSAGE(waiting); }
diff --git a/gui/resources/styles.qss b/gui/resources/styles.qss
index 7b5944d..9b63249 100644
--- a/gui/resources/styles.qss
+++ b/gui/resources/styles.qss
@@ -10,6 +10,7 @@ QWidget {
}
QGroupBox {
+ text-decoration: underline "#00cc00";
font-size: 17pt;
background-color: "#000004";
border: 4px solid ;
@@ -29,7 +30,7 @@ QLabel {
/* text entry */
QLineEdit {
- font-size: 15pt;
+ font-size: 18pt;
border-radius: 0px;
padding: 0 4px;
selection-background-color: "#00cc00";