diff options
author | bd <bdunahu@operationnull.com> | 2025-04-19 02:23:03 -0400 |
---|---|---|
committer | bd <bdunahu@operationnull.com> | 2025-04-19 02:23:03 -0400 |
commit | da25748edb6997629ffb380683c8c736f24033a8 (patch) | |
tree | c7ffcaccc57afde2235fb53a16679225c06c0ed9 | |
parent | f18eac2ac2e5760a4cb81784ad2f23f91b6643d6 (diff) |
Add custom QWidget to keep track of up to 4 user cache ways
-rw-r--r-- | gui/CMakeLists.txt | 2 | ||||
-rw-r--r-- | gui/dynamicwaysentry.cc | 80 | ||||
-rw-r--r-- | gui/dynamicwaysentry.h | 28 | ||||
-rw-r--r-- | gui/gui.cc | 15 | ||||
-rw-r--r-- | gui/gui.h | 25 | ||||
-rw-r--r-- | gui/gui.ui | 109 | ||||
-rw-r--r-- | gui/messages.h | 4 | ||||
-rw-r--r-- | gui/resources/styles.qss | 3 |
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(); +}; @@ -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()) + "\""); } @@ -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 @@ -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"; |