From 5c2de6eccd2d4b32ce81082b82917e8768394ed1 Mon Sep 17 00:00:00 2001 From: bd Date: Fri, 18 Apr 2025 20:08:21 -0400 Subject: Initial retro-theme change --- gui/resources/styles.qss | 139 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 139 insertions(+) create mode 100644 gui/resources/styles.qss (limited to 'gui/resources/styles.qss') diff --git a/gui/resources/styles.qss b/gui/resources/styles.qss new file mode 100644 index 0000000..1f1b82f --- /dev/null +++ b/gui/resources/styles.qss @@ -0,0 +1,139 @@ +* { + font-family: "BigBlueTermPlusNerdFontMono", "monospace"; + font-size: 20pt; + color: "#00cc00"; + background-color: "#000004"; +} + +/* main window */ +QWidget { +} + +QGroupBox { + font-size: 17pt; + background-color: "#000004"; + border: 4px solid ; + border-radius: 0px; + margin-bottom: 1ex; /* leave space at the bottom for the title */ +} + +QGroupBox::title { + subcontrol-origin: margin; + subcontrol-position: bottom left; + border-radius: 0px; + padding: 0 2px; + background-color: "#00cc00"; + color: "#000000"; +} + +QLabel { +} + +/* text entry */ +QLineEdit { + font-size: 15pt; + border-radius: 0px; + padding: 0 4px; + selection-background-color: "#00cc00"; +} + +QTextEdit, QListView { + font-size: 10pt; + background-color: "#000004"; +} + +QPushButton { + border: 4px solid "#00cc00"; +} + +QPushButton:pressed { + color: "#000004"; + background-color: "#00cc00"; +} + +QPushButton:flat { + border: none; /* no border for a flat push button */ +} + +QPushButton:default { + border-color: "#00cc00"; +} + +QMenuBar { + background-color: "#00cc00"; + spacing: 3px; /* spacing between menu bar items */ +} + +QMenuBar::item { + padding: 1px 4px; + background: transparent; + border-radius: 4px; +} + +QMenuBar::item:selected { /* when selected using mouse or keyboard */ + background: #a8a8a8; +} + +QMenuBar::item:pressed { + background: #888888; +} + +QCheckBox { + spacing: 5px; +} + +QCheckBox::indicator { + width: 13px; + height: 13px; + border: 2px solid "#00cc00"; +} + +QCheckBox::indicator:unchecked { +} + +/* QCheckBox::indicator:unchecked:pressed { */ +/* image: url(:/images/checkbox_unchecked_pressed.png); */ +/* } */ + +QCheckBox::indicator:checked { + background: "#00cc00"; +} + +QSlider::groove:horizontal { + height: 5px; /* the groove expands to the size of the slider by default. by giving it a height, it has a fixed size */ + background: "#00cc00"; + margin: 2px 0; +} + +QSlider::handle:horizontal { + background: "#00cc00"; + width: 10px; + margin: -30px 0; /* handle is placed by default on the contents rect of the groove. Expand outside the groove */ + border-radius: 3px; +} + +QScrollBar:horizontal { + border: 2px solid "#00cc00"; + height: 4px; + margin: 0px 20px 0 20px; +} +QScrollBar::handle:horizontal { + min-width: 20px; +} +QScrollBar::add-line:horizontal { + border: 2px solid "#00cc00"; + width: 4px; + subcontrol-position: right; + subcontrol-origin: margin; +} + +QScrollBar::sub-line:horizontal { + border: 2px solid "#00cc00"; + width: 4px; + subcontrol-position: left; + subcontrol-origin: margin; +} + +/* Local Variables: */ +/* mode: css */ +/* End: */ -- cgit v1.2.3 From 04d8976223821833ef9d93ae03b8058626d4e1e6 Mon Sep 17 00:00:00 2001 From: bd Date: Fri, 18 Apr 2025 21:09:10 -0400 Subject: invert button colors --- gui/resources/styles.qss | 32 +++++++++++++------------------- 1 file changed, 13 insertions(+), 19 deletions(-) (limited to 'gui/resources/styles.qss') diff --git a/gui/resources/styles.qss b/gui/resources/styles.qss index 1f1b82f..7b5944d 100644 --- a/gui/resources/styles.qss +++ b/gui/resources/styles.qss @@ -14,16 +14,14 @@ QGroupBox { background-color: "#000004"; border: 4px solid ; border-radius: 0px; - margin-bottom: 1ex; /* leave space at the bottom for the title */ + margin-top: 1ex; /* leave space at the top for the title */ } QGroupBox::title { subcontrol-origin: margin; - subcontrol-position: bottom left; + subcontrol-position: top left; border-radius: 0px; padding: 0 2px; - background-color: "#00cc00"; - color: "#000000"; } QLabel { @@ -43,12 +41,16 @@ QTextEdit, QListView { } QPushButton { - border: 4px solid "#00cc00"; + color: "#000004"; + background-color: "#00cc00"; + border-radius: 0px; + padding: 1px; } + QPushButton:pressed { - color: "#000004"; - background-color: "#00cc00"; + color: "#00cc00"; + background-color: "#000004"; } QPushButton:flat { @@ -70,14 +72,6 @@ QMenuBar::item { border-radius: 4px; } -QMenuBar::item:selected { /* when selected using mouse or keyboard */ - background: #a8a8a8; -} - -QMenuBar::item:pressed { - background: #888888; -} - QCheckBox { spacing: 5px; } @@ -100,15 +94,15 @@ QCheckBox::indicator:checked { } QSlider::groove:horizontal { - height: 5px; /* the groove expands to the size of the slider by default. by giving it a height, it has a fixed size */ + height: 10px; /* the groove expands to the size of the slider by default. by giving it a height, it has a fixed size */ background: "#00cc00"; - margin: 2px 0; + margin: 50px 0; } QSlider::handle:horizontal { background: "#00cc00"; - width: 10px; - margin: -30px 0; /* handle is placed by default on the contents rect of the groove. Expand outside the groove */ + width: 20px; + margin: -50px 0; /* handle is placed by default on the contents rect of the groove. Expand outside the groove */ border-radius: 3px; } -- cgit v1.2.3 From da25748edb6997629ffb380683c8c736f24033a8 Mon Sep 17 00:00:00 2001 From: bd Date: Sat, 19 Apr 2025 02:23:03 -0400 Subject: Add custom QWidget to keep track of up to 4 user cache ways --- gui/CMakeLists.txt | 2 +- gui/dynamicwaysentry.cc | 80 ++++++++++++++++++++++++++++++++++ gui/dynamicwaysentry.h | 28 ++++++++++++ gui/gui.cc | 15 ++++--- gui/gui.h | 25 +++++++++-- gui/gui.ui | 109 +++++++++++++++++++++++++++++++++++++---------- gui/messages.h | 4 +- gui/resources/styles.qss | 3 +- 8 files changed, 229 insertions(+), 37 deletions(-) create mode 100644 gui/dynamicwaysentry.cc create mode 100644 gui/dynamicwaysentry.h (limited to 'gui/resources/styles.qss') 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 +#include +#include +#include +#include +#include + +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(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 +#include +#include +#include +#include + +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 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 &func) +void GUI::set_status(const std::function &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 ways; + + /** + * Uses `func' to set the current status. + * @param a function which returns a string. + */ + void set_status(const std::function &func); signals: void sendRefreshDram(); @@ -82,11 +90,21 @@ class GUI : public QMainWindow */ std::vector p; + /** + * The current cache configurations. + */ + std::vector c; + + /** + * If this stage is pipelined or not. + */ + bool is_pipelined = false; + QThread workerThread; Worker *worker; - QVector step_values = {1, 5, 10, 50, 250, 1000, 10000}; + QVector step_values = {1, 5, 20, 50, 250, 1000, 10000}; const std::map 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 &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 @@ -133,6 +133,85 @@ + + + + + + QLayout::SizeConstraint::SetMinimumSize + + + + + + 16777215 + 16777215 + + + + C1 2^ + + + + + + + + 16777215 + 16777215 + + + + C2 2^ + + + + + + + + 0 + 0 + + + + + 16777215 + 16777215 + + + + C3 2^ + + + + + + + + 16777215 + 16777215 + + + + C4 2^ + + + + + + + + + + 0 + 0 + + + + + + @@ -142,9 +221,6 @@ - - - @@ -533,18 +609,6 @@ - - - - - true - - - - Run - - - @@ -598,19 +662,20 @@ - - - - GroupBox - - - + + + DynamicWaysEntry + QWidget +
dynamicwaysentry.h
+ 1 +
+
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 #include +#include /** * Humorous computer speak. @@ -16,7 +16,7 @@ const std::vector 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"; -- cgit v1.2.3 From 5ad39ec769fa09b9ac4dcc8f66232ef51384a3c6 Mon Sep 17 00:00:00 2001 From: bd Date: Sat, 19 Apr 2025 12:18:14 -0400 Subject: Safely delete old controller object when re-initializing --- gui/gui.cc | 25 +++++-------- gui/gui.h | 5 +-- gui/gui.ui | 93 ++++++++++++++++++++---------------------------- gui/messages.h | 12 +++++-- gui/resources/styles.qss | 9 +++-- gui/worker.cc | 42 +++++++++------------- gui/worker.h | 10 +++--- 7 files changed, 84 insertions(+), 112 deletions(-) (limited to 'gui/resources/styles.qss') diff --git a/gui/gui.cc b/gui/gui.cc index dc77fc9..6cb9ada 100644 --- a/gui/gui.cc +++ b/gui/gui.cc @@ -18,9 +18,6 @@ GUI::GUI(QWidget *parent) : QMainWindow(parent), ui(new Ui::GUI) worker = new Worker(); worker->moveToThread(&workerThread); - // Connect worker thread lifecycle - // connect(&workerThread, &QThread::started, worker, &Worker::doWork); - // display clock cycles and PC connect(worker, &Worker::clock_cycles, this, &GUI::onWorkerClockCycles); @@ -49,19 +46,6 @@ GUI::GUI(QWidget *parent) : QMainWindow(parent), ui(new Ui::GUI) this, &GUI::sendConfigure, worker, &Worker::configure, Qt::QueuedConnection); - // // Refresh DRAM from worker thread - // connect(this, &GUI::sendRefreshDram, worker, &Worker::refreshDram, - // Qt::QueuedConnection); - - // // Refresh Cache from worker thread - // connect(this, &GUI::sendRefreshCache, worker, &Worker::refreshCache, - // Qt::QueuedConnection); - - // Refresh Registers from worker thread - connect( - this, &GUI::sendRefreshRegisters, worker, &Worker::refreshRegisters, - Qt::QueuedConnection); - // Advance controller by some steps connect( this, &GUI::sendRunSteps, worker, &Worker::runSteps, @@ -303,10 +287,17 @@ void GUI::on_enable_pipeline_checkbox_checkStateChanged( void GUI::on_step_btn_clicked() { qDebug() << "Run step button clicked."; + // try to configure first + if (!this->ready) + this->on_config_clicked(); + // try again if (!this->ready) - return this->on_config_clicked(); + return; + + this->set_status(get_running); int steps = step_values[ui->step_slider->value()]; emit sendRunSteps(steps); + this->set_status(get_waiting); } void GUI::on_save_program_state_btn_clicked() diff --git a/gui/gui.h b/gui/gui.h index cbd482b..4c47874 100644 --- a/gui/gui.h +++ b/gui/gui.h @@ -38,9 +38,6 @@ class GUI : public QMainWindow void set_status(const std::function &func); signals: - void sendRefreshDram(); - void sendRefreshCache(); - void sendRefreshRegisters(); void sendRunSteps(int steps); void sendConfigure( std::vector ways, @@ -110,7 +107,7 @@ class GUI : public QMainWindow /** * If this stage is pipelined or not. */ - bool is_pipelined = false; + bool is_pipelined = true; /** * The possible step slider values. diff --git a/gui/gui.ui b/gui/gui.ui index b9ad041..acd9c53 100644 --- a/gui/gui.ui +++ b/gui/gui.ui @@ -604,60 +604,23 @@ - - - - - 0 - - - 6 - - - 1 - - - Qt::Orientation::Horizontal - - - QSlider::TickPosition::NoTicks - - - 1 - - - - - - - Qt::Orientation::Vertical - - - - - - - - - - true - - - - Program State - - - - - - - Clock Cycles - - - - - - + + + + true + + + + Program State + + + + + + + Clock Cycles + + @@ -666,6 +629,28 @@ + + + + 0 + + + 6 + + + 1 + + + Qt::Orientation::Horizontal + + + QSlider::TickPosition::NoTicks + + + 1 + + + diff --git a/gui/messages.h b/gui/messages.h index c2a86b9..2b31037 100644 --- a/gui/messages.h +++ b/gui/messages.h @@ -9,14 +9,19 @@ #define RANDOM_MESSAGE(v) (v[std::rand() % v.size()]) const std::vector waiting = { - "WAITING FOR USER", "FRIENDS MISSING", "BORED", "SLEEPING"}; + "WAITING FOR USER", "BORED", "SLEEPING", "TIRED", "IDLE", "EXCITED"}; +const std::vector running = { + "CALCULATING", "COMPUTING", + "EXTERMINATE" + "WORKING", + "BUSY"}; const std::vector load_file = { "FILE LOADED", "FINISHED READING DATA. EAGERLY WAITING"}; const std::vector no_instructions = { "NO PROGRAM PROVIDED", "INSTRUCTIONS NOT INCLUDED", "NOTHING TO DO, GIVING UP"}; const std::vector bad_cache = { - "INVALID NUMBER OF WAYS", "WAYS CANNOT BE BELOW 0 OR ABOVE 5"}; + "WAYS CANNOT BE BELOW 0 OR ABOVE 5"}; const std::vector no_pipeline = { "PIPELINE--HUMANS PROBABLY WORKED HARD ON THAT", "I WOULD PREFER YOU LEAVE THE PIPE ON", "SLOW MODE ENABLED", @@ -26,9 +31,10 @@ const std::vector no_cache = { const std::vector initialize = {"SIMULATION READY"}; /** - * @return an unsolicited waiting message + * @return an unsolicited status messages */ std::string get_waiting() { return RANDOM_MESSAGE(waiting); } +std::string get_running() { return RANDOM_MESSAGE(running); } /** * @return confirmation of file upload diff --git a/gui/resources/styles.qss b/gui/resources/styles.qss index 9b63249..59d36ca 100644 --- a/gui/resources/styles.qss +++ b/gui/resources/styles.qss @@ -2,7 +2,8 @@ font-family: "BigBlueTermPlusNerdFontMono", "monospace"; font-size: 20pt; color: "#00cc00"; - background-color: "#000004"; + background-color: "#000200"; + border: 0px solid "#000200"; } /* main window */ @@ -12,7 +13,6 @@ QWidget { QGroupBox { text-decoration: underline "#00cc00"; font-size: 17pt; - background-color: "#000004"; border: 4px solid ; border-radius: 0px; margin-top: 1ex; /* leave space at the top for the title */ @@ -38,11 +38,10 @@ QLineEdit { QTextEdit, QListView { font-size: 10pt; - background-color: "#000004"; } QPushButton { - color: "#000004"; + color: "#000200"; background-color: "#00cc00"; border-radius: 0px; padding: 1px; @@ -51,7 +50,7 @@ QPushButton { QPushButton:pressed { color: "#00cc00"; - background-color: "#000004"; + background-color: "#000200"; } QPushButton:flat { diff --git a/gui/worker.cc b/gui/worker.cc index cd79821..88248e8 100644 --- a/gui/worker.cc +++ b/gui/worker.cc @@ -18,21 +18,23 @@ void Worker::configure( { Dram *d; Storage *s; + Stage *old; int i; + this->ct_mutex.lock(); if (ways.size() != 0) { // will ensure the largest cache is only half of DRAM this->size_inc = (MEM_LINE_SPEC / ways.size()) / 2; } d = new Dram(DRAM_DELAY); - s = (Storage *)d; + s = static_cast(d); this->s.push_front(s); d->load(program); for (i = ways.size(); i > 0; --i) { - s = (Storage *)new Cache( - s, this->size_inc * (i), ways.at(i - 1), CACHE_DELAY + i); + s = static_cast(new Cache( + s, this->size_inc * (i), ways.at(i - 1), CACHE_DELAY + i)); this->s.push_front(s); } @@ -41,37 +43,26 @@ void Worker::configure( this->ex_stage = new EX(id_stage); this->mm_stage = new MM(ex_stage); this->wb_stage = new WB(mm_stage); - this->ct = - new Controller(wb_stage, s, is_pipelined); - emit clock_cycles(this->ct->get_clock_cycle(), this->ct->get_pc()); -} - -void Worker::refreshDram() -{ - qDebug() << "Refreshing Dram"; - emit dram_storage(this->s.back()->view(0, 255)); -} - -void Worker::refreshCache() -{ - qDebug() << "Refreshing Cache"; - if(this->s.size() > 0) { - emit cache_storage(this->s.at(0)->view(0, 1 << this->size_inc)); - } -} + old = static_cast(this->ct); + this->ct = new Controller(wb_stage, s, is_pipelined); + if (old) + delete old; + this->ct_mutex.unlock(); -void Worker::refreshRegisters() -{ - qDebug() << "Refreshing Registers"; - emit register_storage(this->ct->get_gprs()); + emit clock_cycles(this->ct->get_clock_cycle(), this->ct->get_pc()); } void Worker::runSteps(int steps) { + this->ct_mutex.lock(); qDebug() << "Running for " << steps << "steps"; this->ct->run_for(steps); + // TODO move these to separate functions emit dram_storage(this->s.back()->view(0, 255)); + if (this->s.size() > 1) { + emit cache_storage(this->s.at(0)->view(0, 1 << this->size_inc)); + } emit register_storage(this->ct->get_gprs()); emit clock_cycles(this->ct->get_clock_cycle(), this->ct->get_pc()); emit if_info(this->if_stage->stage_info()); @@ -79,4 +70,5 @@ void Worker::runSteps(int steps) emit ex_info(this->ex_stage->stage_info()); emit mm_info(this->mm_stage->stage_info()); emit wb_info(this->wb_stage->stage_info()); + this->ct_mutex.unlock(); } diff --git a/gui/worker.h b/gui/worker.h index acfffcf..20a9838 100644 --- a/gui/worker.h +++ b/gui/worker.h @@ -12,6 +12,7 @@ #include #include #include +#include #include class Worker : public QObject @@ -28,7 +29,10 @@ class Worker : public QObject EX *ex_stage; MM *mm_stage; WB *wb_stage; - Controller *ct; + + Controller *ct = nullptr; + QMutex ct_mutex; + /** * The size each progressive cache level increases by. */ @@ -37,11 +41,9 @@ class Worker : public QObject public: explicit Worker(QObject *parent = nullptr); ~Worker(); + QMutex& get_ct_mutex() { return ct_mutex; } public slots: - void refreshDram(); - void refreshCache(); - void refreshRegisters(); void runSteps(int steps); void configure( std::vector ways, -- cgit v1.2.3 From e4a2ceefd77a8d53ebb9fb225a0fa6d9ee8d5d91 Mon Sep 17 00:00:00 2001 From: bd Date: Sat, 19 Apr 2025 12:36:03 -0400 Subject: Modify scrollbar css --- gui/messages.h | 16 +++++----------- gui/resources/styles.qss | 36 ++++++++++++++++++++++++------------ 2 files changed, 29 insertions(+), 23 deletions(-) (limited to 'gui/resources/styles.qss') diff --git a/gui/messages.h b/gui/messages.h index 2b31037..adae777 100644 --- a/gui/messages.h +++ b/gui/messages.h @@ -9,25 +9,19 @@ #define RANDOM_MESSAGE(v) (v[std::rand() % v.size()]) const std::vector waiting = { - "WAITING FOR USER", "BORED", "SLEEPING", "TIRED", "IDLE", "EXCITED"}; + "WAITING FOR USER", "READY", "BORED", "SLEEPING"}; const std::vector running = { - "CALCULATING", "COMPUTING", - "EXTERMINATE" - "WORKING", - "BUSY"}; -const std::vector load_file = { - "FILE LOADED", "FINISHED READING DATA. EAGERLY WAITING"}; + "COMPUTING", "WORKING", "BUSY"}; +const std::vector load_file = {"FILE LOADED"}; const std::vector no_instructions = { "NO PROGRAM PROVIDED", "INSTRUCTIONS NOT INCLUDED", "NOTHING TO DO, GIVING UP"}; const std::vector bad_cache = { "WAYS CANNOT BE BELOW 0 OR ABOVE 5"}; const std::vector no_pipeline = { - "PIPELINE--HUMANS PROBABLY WORKED HARD ON THAT", - "I WOULD PREFER YOU LEAVE THE PIPE ON", "SLOW MODE ENABLED", - "SIMULATION READY"}; + "SIMULATION READY: NO PIPE :(", "SIMULATION READY"}; const std::vector no_cache = { - "NO CACHE HAS NO WAY TO GO", "SLOW MODE ENABLED", "SIMULATION READY"}; + "SIMULATION READY: NO WAYS", "SIMULATION READY"}; const std::vector initialize = {"SIMULATION READY"}; /** diff --git a/gui/resources/styles.qss b/gui/resources/styles.qss index 59d36ca..9562b69 100644 --- a/gui/resources/styles.qss +++ b/gui/resources/styles.qss @@ -107,25 +107,37 @@ QSlider::handle:horizontal { } QScrollBar:horizontal { - border: 2px solid "#00cc00"; - height: 4px; - margin: 0px 20px 0 20px; + border: 4px solid "#00cc00"; } + QScrollBar::handle:horizontal { - min-width: 20px; + height: 16px; + background-color: "#00cc00"; } + QScrollBar::add-line:horizontal { - border: 2px solid "#00cc00"; - width: 4px; - subcontrol-position: right; - subcontrol-origin: margin; + border: 4px solid "#00cc00"; } QScrollBar::sub-line:horizontal { - border: 2px solid "#00cc00"; - width: 4px; - subcontrol-position: left; - subcontrol-origin: margin; + border: 4px solid "#00cc00"; +} + +QScrollBar:vertical { + border: 4px solid "#00cc00"; +} + +QScrollBar::handle:vertical { + width: 16px; + background-color: "#00cc00"; +} + +QScrollBar::add-line:vertical { + border: 4px solid "#00cc00"; +} + +QScrollBar::sub-line:vertical { + border: 4px solid "#00cc00"; } /* Local Variables: */ -- cgit v1.2.3 From 9fe7235d7c06677f152e20b9deac85e633f429a6 Mon Sep 17 00:00:00 2001 From: bd Date: Mon, 21 Apr 2025 13:41:45 -0400 Subject: Add some expression --- gui/gui.cc | 52 ++++++++++++++++++++++++++++++++++------------- gui/gui.h | 14 +++++++++---- gui/messages.h | 14 +++++-------- gui/resources.qrc | 4 ++++ gui/resources/angry.png | Bin 0 -> 319 bytes gui/resources/busy.png | Bin 0 -> 329 bytes gui/resources/happy.png | Bin 0 -> 322 bytes gui/resources/idle.png | Bin 0 -> 322 bytes gui/resources/styles.qss | 22 ++++++++++++++++++++ 9 files changed, 79 insertions(+), 27 deletions(-) create mode 100644 gui/resources/angry.png create mode 100644 gui/resources/busy.png create mode 100644 gui/resources/happy.png create mode 100644 gui/resources/idle.png (limited to 'gui/resources/styles.qss') diff --git a/gui/gui.cc b/gui/gui.cc index 3440916..2744a06 100644 --- a/gui/gui.cc +++ b/gui/gui.cc @@ -19,16 +19,29 @@ #include "./ui_gui.h" #include "dynamicwaysentry.h" #include "messages.h" +#include +#include GUI::GUI(QWidget *parent) : QMainWindow(parent), ui(new Ui::GUI) { ui->setupUi(this); + /* setup the status bar */ + ui->statusBar->setFixedHeight(20); + + this->avatar = new QLabel(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); + + avatar->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + avatar->setObjectName("avatar_label"); + status_label->setObjectName("msg_label"); + risc_vector->setObjectName("info_label"); + ui->statusBar->setSizeGripEnabled(false); + + this->set_status(get_waiting, "idle.png"); + ui->statusBar->addWidget(avatar); ui->statusBar->addWidget(status_label); ui->statusBar->addPermanentWidget(risc_vector); @@ -252,7 +265,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->set_status(get_no_instructions); + this->set_status(get_no_instructions, "angry"); return; } @@ -270,9 +283,9 @@ void GUI::on_upload_intructions_btn_clicked() } if (this->p.empty()) - this->set_status(get_no_instructions); + this->set_status(get_no_instructions, "angry"); else - this->set_status(get_load_file); + this->set_status(get_load_file, "happy"); file.close(); } @@ -305,10 +318,10 @@ void GUI::on_step_btn_clicked() if (!this->ready) return; - this->set_status(get_running); + this->set_status(get_running, "busy"); int steps = step_values[ui->step_slider->value()]; emit sendRunSteps(steps); - this->set_status(get_waiting); + this->set_status(get_waiting, "idle"); } void GUI::on_save_program_state_btn_clicked() @@ -333,13 +346,13 @@ void GUI::on_config_clicked() if (i != -1) { ways.push_back((unsigned int)i); } else { - this->set_status(get_bad_cache); + this->set_status(get_bad_cache, "angry"); return; } } if (this->p.empty()) { - this->set_status(get_no_instructions); + this->set_status(get_no_instructions, "angry"); return; } @@ -347,17 +360,28 @@ void GUI::on_config_clicked() // say something snarky if (!is_pipelined) - this->set_status(get_no_pipeline); + this->set_status(get_no_pipeline, "angry"); else if (ways.size() == 0) - this->set_status(get_no_cache); + this->set_status(get_no_cache, "angry"); else - this->set_status(get_initialize); + this->set_status(get_initialize, "happy"); emit sendConfigure(ways, this->p, is_pipelined); } -void GUI::set_status(const std::function &func) +void GUI::set_status( + const std::function &func, const QString &img) { this->status_label->setText( - "COMPUTER SAYS: \"" + QString::fromStdString(func()) + "\""); + "-> \"" + QString::fromStdString(func()) + "\""); + + QString img_path = ":resources/" + img; + QPixmap pixmap(img_path); + + if (!pixmap) { + return; + } + + this->avatar->setPixmap(pixmap); + this->avatar->show(); } diff --git a/gui/gui.h b/gui/gui.h index 7c5b440..7efde1f 100644 --- a/gui/gui.h +++ b/gui/gui.h @@ -51,15 +51,16 @@ class GUI : public QMainWindow /** * Uses `func' to set the current status. * @param a function which returns a string. + * @param a path to the desired avatar */ - void set_status(const std::function &func); + void set_status( + const std::function &func, + const QString &img = "idle.png"); signals: void sendRunSteps(int steps); void sendConfigure( - std::vector ways, - vector program, - bool is_pipelined); + std::vector ways, vector program, bool is_pipelined); private slots: void on_worker_refresh_gui(int value, int pc); @@ -116,6 +117,11 @@ class GUI : public QMainWindow */ QLabel *status_label; + /** + * The robot image displayed on the status bar. + */ + QLabel *avatar; + /** * The currently loaded program. */ diff --git a/gui/messages.h b/gui/messages.h index adae777..03c0ab3 100644 --- a/gui/messages.h +++ b/gui/messages.h @@ -9,19 +9,15 @@ #define RANDOM_MESSAGE(v) (v[std::rand() % v.size()]) const std::vector waiting = { - "WAITING FOR USER", "READY", "BORED", "SLEEPING"}; -const std::vector running = { - "COMPUTING", "WORKING", "BUSY"}; + "WAITING FOR USER", "IDLE", "BORED", "SLEEPING"}; +const std::vector running = {"COMPUTING", "WORKING", "BUSY"}; const std::vector load_file = {"FILE LOADED"}; const std::vector no_instructions = { - "NO PROGRAM PROVIDED", "INSTRUCTIONS NOT INCLUDED", - "NOTHING TO DO, GIVING UP"}; + "NO PROGRAM PROVIDED", "NOTHING TO DO, GIVING UP"}; const std::vector bad_cache = { "WAYS CANNOT BE BELOW 0 OR ABOVE 5"}; -const std::vector no_pipeline = { - "SIMULATION READY: NO PIPE :(", "SIMULATION READY"}; -const std::vector no_cache = { - "SIMULATION READY: NO WAYS", "SIMULATION READY"}; +const std::vector no_pipeline = {"SIMULATION READY: NO PIPE"}; +const std::vector no_cache = {"SIMULATION READY: NO CACHE"}; const std::vector initialize = {"SIMULATION READY"}; /** diff --git a/gui/resources.qrc b/gui/resources.qrc index 59fb36f..569cc22 100644 --- a/gui/resources.qrc +++ b/gui/resources.qrc @@ -2,6 +2,10 @@ resources/styles.qss + resources/idle.png + resources/angry.png + resources/happy.png + resources/busy.png resources/BigBlueTermPlusNerdFontMono-Regular.ttf diff --git a/gui/resources/angry.png b/gui/resources/angry.png new file mode 100644 index 0000000..3299eb4 Binary files /dev/null and b/gui/resources/angry.png differ diff --git a/gui/resources/busy.png b/gui/resources/busy.png new file mode 100644 index 0000000..df1b36a Binary files /dev/null and b/gui/resources/busy.png differ diff --git a/gui/resources/happy.png b/gui/resources/happy.png new file mode 100644 index 0000000..6168e89 Binary files /dev/null and b/gui/resources/happy.png differ diff --git a/gui/resources/idle.png b/gui/resources/idle.png new file mode 100644 index 0000000..f894716 Binary files /dev/null and b/gui/resources/idle.png differ diff --git a/gui/resources/styles.qss b/gui/resources/styles.qss index 9562b69..dbaa623 100644 --- a/gui/resources/styles.qss +++ b/gui/resources/styles.qss @@ -6,6 +6,28 @@ border: 0px solid "#000200"; } +QStatusBar { + font-size: 12pt; + color: "#000200"; + background-color: "#00cc00"; +} + +QLabel#msg_label { + font-size: 12pt; + color: "#000200"; + background-color: "#00cc00"; +} + +QLabel#info_label { + font-size: 12pt; + color: "#000200"; + background-color: "#00cc00"; +} + +QLabel#avatar_label { + background-color: "#00cc00"; +} + /* main window */ QWidget { } -- cgit v1.2.3