From cc2781682a47dc331f7bbcb5d7842db5197d29fc Mon Sep 17 00:00:00 2001 From: Siddarth-Suresh <65844402+Siddarth-Suresh@users.noreply.github.com> Date: Tue, 1 Apr 2025 21:54:38 -0400 Subject: GUI and controller on separate threads --- gui/gui.cc | 228 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 228 insertions(+) (limited to 'gui/gui.cc') diff --git a/gui/gui.cc b/gui/gui.cc index 5a4c779..b96d65d 100644 --- a/gui/gui.cc +++ b/gui/gui.cc @@ -6,9 +6,237 @@ GUI::GUI(QWidget *parent) , ui(new Ui::GUI) { ui->setupUi(this); + + ui->enabl_cache_checkbox->setChecked(true); + ui->enable_pipeline_checkbox->setChecked(true); + + 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); + + // Display dram + connect(worker, &Worker::dram_storage, this, &GUI::onWorkerShowDram); + + // Display cache + connect(worker, &Worker::cache_storage, this, &GUI::onWorkerShowCache); + + // Display registers + connect(worker, &Worker::register_storage, this, &GUI::onWorkerShowRegisters); + + // 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 #steps + connect(this, &GUI::sendRunSteps, worker, &Worker::runSteps, Qt::QueuedConnection); + + // Advance controller by 1 step + connect(this, &GUI::sendRunStep, worker, &Worker::runStep, Qt::QueuedConnection); + + // Proper cleanup when worker finishes + connect(worker, &Worker::finished, this, &GUI::onWorkerFinished); + connect(worker, &Worker::finished, &workerThread, &QThread::quit); + connect(&workerThread, &QThread::finished, worker, &QObject::deleteLater); + + workerThread.start(); // Start the worker thread } GUI::~GUI() { + workerThread.quit(); + workerThread.wait(); // Ensure proper cleanup delete ui; } + +void displayArrayHTML(QTextEdit *textEdit, const std::array &data) { + textEdit->setReadOnly(false); + QString tableText = ""; + + tableText += ""; + int index = 1; + for (int value : data) { + tableText += QString("") + .arg(QString::asprintf("%04X", value)) + .arg(index); + index++; + } + tableText += ""; + tableText += "
" + "%1 %2" + "
"; + + textEdit->setHtml(tableText); + textEdit->setReadOnly(true); +} + +void displayTableHTML(QTextEdit *textEdit, const std::vector> &data) { + textEdit->setReadOnly(false); + QString tableText = ""; + + int index = 1; + for (const auto &row : data) { + tableText += ""; + for (signed int value : row) { + tableText += QString("") + .arg(QString::asprintf("%04X", value)) + .arg(index); + index++; + } + tableText += ""; + } + + tableText += "
" + "%1 %2" + "
"; + + textEdit->setHtml(tableText); + textEdit->setReadOnly(true); +} + +void browseAndUploadFile(QTextEdit *textEdit) { + QString filePath = QFileDialog::getOpenFileName(nullptr, "Open File", QDir::homePath(), "Text Files (*.txt);;All Files (*.*)"); + + if (filePath.isEmpty()) { + return; + } + + QFile file(filePath); + if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { + textEdit->setPlainText("Error: Unable to open file!"); + return; + } + + QTextStream in(&file); + QString content; + int lineNumber = 1; + + while (!in.atEnd()) { + QString line = in.readLine(); + + content += QString("
" + "%1." + "%2" + "

") + .arg(lineNumber) + .arg(line); + + lineNumber++; + } + + file.close(); + + textEdit->setReadOnly(false); + textEdit->setHtml(content); + textEdit->setReadOnly(true); +} + +void GUI::onWorkerClockCycles(int cycles, int pc) { + ui->cycles_label->setText("Clock Cycles: " + QString::number(cycles) + "\t\t" + "PC: " + QString::number(pc)); +} + +void GUI::onWorkerShowDram(const std::vector> data) { + displayTableHTML(ui->dram_table, data); +} + +void GUI::onWorkerShowCache(const std::vector> data) { + displayTableHTML(ui->cache_table, data); +} + +void GUI::onWorkerShowRegisters(const std::array &data) { + displayArrayHTML(ui->register_table, data); +} + +void GUI::onWorkerFinished() { + qDebug() << "Worker has finished processing."; +} + +void GUI::on_upload_intructions_btn_clicked() +{ + qDebug() << "Upload intructions button clicked."; + browseAndUploadFile(ui->instruction_table); + +} + + +void GUI::on_upload_program_state_btn_clicked() +{ + //TODO:Upload and set program state ( have to decide how to use this) + qDebug() << "upload program state button is clicked."; +} + + +void GUI::on_refresh_dram_btn_clicked() +{ + qDebug() << "Refresh DRAM button clicked."; + emit sendRefreshDram(); + +} + + +void GUI::on_refresh_cache_btn_clicked() +{ + qDebug() << "Refresh cache button clicked."; + emit sendRefreshCache(); +} + + +void GUI::on_refresh_registers_btn_clicked() +{ + qDebug() << "Refresh registers button clicked."; + emit sendRefreshRegisters(); +} + + +void GUI::on_enable_pipeline_checkbox_checkStateChanged(const Qt::CheckState &arg1) +{ + //TODO: handle pipeline enabling + if(arg1 == Qt::CheckState::Checked) { + qDebug() << "enable pipeline checkbox checked."; + } else { + qDebug() << "enable pipeline checkbox unchecked."; + } +} + + +void GUI::on_enabl_cache_checkbox_checkStateChanged(const Qt::CheckState &arg1) +{ + //TODO: handle cache enabling + if(arg1 == Qt::CheckState::Checked) { + qDebug() << "enable cache checkbox checked."; + } else { + qDebug() << "enable cache checkbox unchecked."; + } + +} + + +void GUI::on_run_steps_btn_clicked() +{ + qDebug() << "Run steps button clicked."; + emit sendRunSteps(ui->number_steps_inp->text().toInt()); +} + + +void GUI::on_step_btn_clicked() +{ + qDebug() << "Run step button clicked."; + emit sendRunStep(); +} + + +void GUI::on_save_program_state_btn_clicked() +{ + //TODO: save program state + qDebug() << "save program state button is clicked."; +} + -- cgit v1.2.3