diff options
author | bd <bdunaisky@umass.edu> | 2025-04-18 04:10:49 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-04-18 04:10:49 +0000 |
commit | dbf7e900336214041da8880d6986d59126c35a72 (patch) | |
tree | 5bc5c848ca6b5326480c7b0760087db79c8653f1 | |
parent | 480181957b3f3dbcf7731023504c2cacc8d181ea (diff) | |
parent | 360e6cbffb3d2c1279ae7c3a02c2850f5523eeb2 (diff) |
Merge pull request #55 from bdunahu/dev-sid
Allow dynamic program loading (by Sid)
-rw-r--r-- | gui/gui.cc | 72 | ||||
-rw-r--r-- | gui/gui.h | 1 | ||||
-rw-r--r-- | gui/gui.ui | 2 | ||||
-rw-r--r-- | gui/worker.cc | 79 | ||||
-rw-r--r-- | gui/worker.h | 1 | ||||
-rw-r--r-- | inc/instrDTO.h | 12 | ||||
-rw-r--r-- | src/sim/if.cc | 5 | ||||
-rw-r--r-- | src/sim/instrDTO.cc | 5 | ||||
-rw-r--r-- | src/sim/stage.cc | 4 |
9 files changed, 72 insertions, 109 deletions
@@ -1,5 +1,6 @@ #include "gui.h" #include "./ui_gui.h" +#include "byteswap.h" GUI::GUI(QWidget *parent) : QMainWindow(parent) @@ -37,10 +38,13 @@ GUI::GUI(QWidget *parent) // Display registers connect(worker, &Worker::register_storage, this, &GUI::onWorkerShowRegisters); - + // Refresh DRAM from worker thread connect(this, &GUI::sendRefreshDram, worker, &Worker::refreshDram, Qt::QueuedConnection); + // Load program from worker thread + connect(this, &GUI::sendLoadProgram, worker, &Worker::loadProgram, Qt::QueuedConnection); + // Refresh Cache from worker thread connect(this, &GUI::sendRefreshCache, worker, &Worker::refreshCache, Qt::QueuedConnection); @@ -82,7 +86,7 @@ void displayArrayHTML(QTextEdit *textEdit, const std::array<int, GPR_NUM> &data) .arg(index); index++; } - tableText += "</tr>"; + tableText += "</tr>"; tableText += "</table>"; textEdit->setHtml(tableText); @@ -113,52 +117,35 @@ void displayTableHTML(QTextEdit *textEdit, const std::vector<std::array<signed i textEdit->setReadOnly(true); } -void browseAndUploadFile(QWidget* parent) { - QString filePath = QFileDialog::getOpenFileName(nullptr, "Open File", QDir::homePath(), "Text Files (*.txt);;All Files (*.*)"); - - if (filePath.isEmpty()) { - return; - } +std::vector<signed int> browseAndRetrieveFile(QWidget* parent) { + QString filePath = QFileDialog::getOpenFileName(parent, "Open Binary File", QDir::homePath(), "Binary Files (*.bin *.rv);;All Files (*.*)"); + std::vector<signed int> program; + + if (filePath.isEmpty()) return program; QFile file(filePath); - if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { - // textEdit->setPlainText("Error: Unable to open file!"); - QMessageBox::critical(parent, "File Upload", "Unable to open file!"); - return; + if (!file.open(QIODevice::ReadOnly)) { + QMessageBox::critical(parent, "File Upload", "Unable to open file!"); + return program; } - QTextStream in(&file); - QString content; - int lineNumber = 0; - - while (!in.atEnd()) { - QString line = in.readLine(); - - content += QString("<div id='line_%1' style='display: flex; justify-content: space-between; align-items: center;'>" - "<span style='font-size: 10px; font-weight: bold; color: gray;'>%1.</span>" - "<span>%2</span>" - "</div><hr>") - .arg(lineNumber) - .arg(line); - - lineNumber++; + while (!file.atEnd()) { + int32_t word = 0; + if (file.read(reinterpret_cast<char*>(&word), sizeof(int32_t)) == sizeof(int32_t)) { + program.push_back(static_cast<signed int>(bswap_32(word))); + } } file.close(); - - QMessageBox::information(parent, "File Upload", "Instructions loaded successfully!"); - - // textEdit->setReadOnly(false); - // textEdit->setHtml(content); - // textEdit->setReadOnly(true); + return program; } void GUI::onWorkerClockCycles(int cycles, int pc) { - QFont font = ui->cycles_label->font(); + QFont font = ui->cycles_label->font(); font.setBold(true); font.setItalic(true); - font.setPointSize(14); + font.setPointSize(14); ui->cycles_label->setFont(font); ui->cycles_label->setText("Clock Cycles: " + QString::number(cycles) + "\t\t" + "PC: " + QString::number(pc)); } @@ -257,8 +244,14 @@ void GUI::onWorkerFinished() { void GUI::on_upload_intructions_btn_clicked() { qDebug() << "Upload intructions button clicked."; - browseAndUploadFile(ui->register_table); - + std::vector<signed int> program; + program = browseAndRetrieveFile(ui->register_table); + if(program.empty()){ + QMessageBox::critical(ui->register_table, "File Upload", "Invalid Program File!"); + } + emit sendLoadProgram(program); + emit sendRefreshDram(); + QMessageBox::information(ui->register_table, "File Upload", "Instructions loaded successfully!"); } @@ -305,10 +298,10 @@ void GUI::on_enable_pipeline_checkbox_checkStateChanged(const Qt::CheckState &ar void GUI::on_enabl_cache_checkbox_checkStateChanged(const Qt::CheckState &arg1) { //TODO: handle cache enabling - if(arg1 == Qt::CheckState::Checked) { + if(arg1 == Qt::CheckState::Checked) { qDebug() << "enable cache checkbox checked."; } else { - qDebug() << "enable cache checkbox unchecked."; + qDebug() << "enable cache checkbox unchecked."; } } @@ -333,4 +326,3 @@ void GUI::on_save_program_state_btn_clicked() //TODO: save program state qDebug() << "save program state button is clicked."; } - @@ -30,6 +30,7 @@ signals: void sendRefreshRegisters(); void sendRunSteps(int steps); void sendRunStep(); + void sendLoadProgram(std::vector<signed int> program); private slots: void onWorkerClockCycles(int value, int pc); @@ -18,7 +18,7 @@ <item> <layout class="QGridLayout" name="gridLayout_2" rowstretch="0,0,0" columnstretch="0,3,0,1,0"> <item row="0" column="1"> - <layout class="QVBoxLayout" name="verticalLayout_19"> + <layout class="QVBoxLayout" name="verticalLayout_19" stretch="1,0,3"> <item> <layout class="QVBoxLayout" name="verticalLayout_20"> <item> diff --git a/gui/worker.cc b/gui/worker.cc index a912e06..e4e3bdf 100644 --- a/gui/worker.cc +++ b/gui/worker.cc @@ -6,73 +6,18 @@ void Worker::doWork() { qDebug() << "Initializing..."; this->d = new Dram(0); - this->c = new Cache(this->d, 5, 0, 0); + this->c = new Cache(this->d, 8, 0, 0); this->if_stage = new IF(nullptr); this->id_stage = new ID(if_stage); 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, this->c, false); + this->ct = new Controller(wb_stage, this->c, true); emit clock_cycles(this->ct->get_clock_cycle(), this->ct->get_pc()); - emit dram_storage(this->d->view(0, 32)); - emit cache_storage(this->c->view(0, 7)); + emit dram_storage(this->d->view(0, 255)); + emit cache_storage(this->c->view(0, 255)); emit register_storage(this->ct->get_gprs()); - - std::vector<signed int> p; - - p.push_back(0b00000000000000010010100000001101); - p.push_back(0b00000000000000000000000101100010); - p.push_back(0b00000000000000010010100101001101); - p.push_back(0b00000000000000000000000101100010); - p.push_back(0b00000000000000010010100101001101); - p.push_back(0b00000000000000000000000101100010); - p.push_back(0b00000000000000010010100101001101); - p.push_back(0b00000000000000000000000101100010); - p.push_back(0b00000000000000000000000101100110); - p.push_back(0b00000000000000000000000110100110); - p.push_back(0b00000000000000000000000111100110); - p.push_back(0b00000000000000000000001000100110); - p.push_back(0b00000000000000000000000000101110); - p.push_back(0b00000000000000000000000000101110); - p.push_back(0b00000000000000000000000000010000); - - // p.push_back(0b00000000000000000010100010001101); - // p.push_back(0b11111111111101010011000000001101); - // p.push_back(0b00000000000000000000000110100010); - // p.push_back(0b00000000000000000011000000001110); - // p.push_back(0b00000000000000000000000110100110); - // p.push_back(0b00000000001000100011000000101001); - // p.push_back(0b00000000000000000000000101100010); - // p.push_back(0b00000000000000000010100010001101); - // p.push_back(0b00000000000000010001000010010001); - // p.push_back(0b11111111111010010011000000001101); - // p.push_back(0b11111111111111000011000101101001); - // p.push_back(0b00000000000001000010100111000101); - // p.push_back(0b11111111111111000010100110000101); - // p.push_back(0b00000000000011000111001100000100); - // p.push_back(0b00000000000000000000000110100010); - // p.push_back(0b00000000000000001010100000001110); - // p.push_back(0b00000000000000000000000110100110); - // p.push_back(0b00000000000001000011000101101001); - // p.push_back(0b00000000000000000001000101001101); - // p.push_back(0b00000000000000000000000101100110); - // p.push_back(0b00000000000000000000000000101010); - // p.push_back(0b00000000000000000000000101100010); - // p.push_back(0b00000000000000000010100010001101); - // p.push_back(0b00000000000000010001000010010001); - // p.push_back(0b00000000010011000011000000001101); - // p.push_back(0b11111111111111000011000101101001); - // p.push_back(0b00000000000001000010100111000101); - // p.push_back(0b11111111111111000010100110000101); - // p.push_back(0b00000000000011000111001100000100); - // p.push_back(0b00000000000001000011000101101001); - // p.push_back(0b00000000000000000001000101001101); - // p.push_back(0b00000000000000000000000101100110); - // p.push_back(0b00000000000000000000000000101010); - // p.push_back(0b00000000000000000000000000010000); - // p.push_back(0b00000000000000000000000000000000); - this->d->load(p); } Worker::~Worker() @@ -84,16 +29,20 @@ Worker::~Worker() delete this->c; } +void Worker::loadProgram(std::vector<signed int> p) { + this->d->load(p); +} + void Worker::refreshDram() { qDebug() << "Refreshing Dram"; - emit dram_storage(this->d->view(0, 32)); + emit dram_storage(this->d->view(0, 31)); } void Worker::refreshCache() { qDebug() << "Refreshing Dram"; - emit cache_storage(this->c->view(24, 31)); + emit cache_storage(this->c->view(0, 255)); } void Worker::refreshRegisters() @@ -106,8 +55,8 @@ void Worker::runSteps(int steps) { qDebug() << "Running for steps: " << steps; this->ct->run_for(steps); - emit dram_storage(this->d->view(0, 256)); - emit cache_storage(this->c->view(0, 7)); + emit dram_storage(this->d->view(0, 255)); + emit cache_storage(this->c->view(0, 255)); 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()); @@ -121,8 +70,8 @@ void Worker::runStep() { qDebug() << "Running for 1 step "; this->ct->run_for(1); - emit dram_storage(this->d->view(0, 256)); - emit cache_storage(this->c->view(24, 8)); + emit dram_storage(this->d->view(0, 255)); + emit cache_storage(this->c->view(0, 255)); 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()); diff --git a/gui/worker.h b/gui/worker.h index ee8926b..8fde554 100644 --- a/gui/worker.h +++ b/gui/worker.h @@ -34,6 +34,7 @@ public: public slots: void doWork(); void refreshDram(); + void loadProgram(std::vector<signed int> p); void refreshCache(); void refreshRegisters(); void runSteps(int steps); diff --git a/inc/instrDTO.h b/inc/instrDTO.h index 755ab9f..72ea67d 100644 --- a/inc/instrDTO.h +++ b/inc/instrDTO.h @@ -48,6 +48,10 @@ class InstrDTO * @return the program counter at the time this instruction was fetched */ unsigned int get_pc(); + /** + * @return 1 if this instruction is invalid, 0 otherwise + */ + int is_squashed(); /** * @param instr_bits @@ -82,6 +86,10 @@ class InstrDTO * @param the program counter at the time this instruction was fetched */ void set_pc(unsigned int pc); + /** + * squashes this instruction + */ + void squash(); private: /** @@ -115,6 +123,10 @@ class InstrDTO * The PC of the instruction */ unsigned int pc; + /** + * If this instruction was made dead + */ + unsigned int squashed; }; #endif /* INSTRDTO_H_INCLUDED */ diff --git a/src/sim/if.cc b/src/sim/if.cc index bab2608..6494912 100644 --- a/src/sim/if.cc +++ b/src/sim/if.cc @@ -12,8 +12,9 @@ InstrDTO *IF::advance(Response p) this->advance_helper(); if (this->curr_instr != nullptr && p == WAIT) { - // mutual consent - ++this->pc; + // don't increment PC if the PC was just set by wb + if (this->curr_instr->is_squashed() != 1) + ++this->pc; r = new InstrDTO(*this->curr_instr); delete curr_instr; curr_instr = nullptr; diff --git a/src/sim/instrDTO.cc b/src/sim/instrDTO.cc index a82ef28..fb6c82b 100644 --- a/src/sim/instrDTO.cc +++ b/src/sim/instrDTO.cc @@ -11,6 +11,7 @@ InstrDTO::InstrDTO() this->mnemonic = ADD; this->type = INV; this->pc = 0; + this->squashed = 0; } signed int InstrDTO::get_instr_bits() { return this->instr_bits; } @@ -29,6 +30,8 @@ Type InstrDTO::get_type() { return this->type; } unsigned int InstrDTO::get_pc() { return this->pc; } +int InstrDTO::is_squashed() { return this->squashed; } + void InstrDTO::set_instr_bits(signed int instr) { this->instr_bits = instr; } void InstrDTO::set_checked_out(signed int checked_out) @@ -47,3 +50,5 @@ void InstrDTO::set_mnemonic(Mnemonic m) { this->mnemonic = m; } void InstrDTO::set_type(Type t) { this->type = t; } void InstrDTO::set_pc(unsigned int pc) { this->pc = pc; } + +void InstrDTO::squash() { this->squashed = 1; } diff --git a/src/sim/stage.cc b/src/sim/stage.cc index 9528e4b..d65ca87 100644 --- a/src/sim/stage.cc +++ b/src/sim/stage.cc @@ -34,6 +34,8 @@ InstrDTO *Stage::advance(Response p) // for (long unsigned int i = 0; i < this->checked_out.size(); ++i) // std::cout << this->checked_out[i] << " "; // std::cout << std::endl; + if (this->curr_instr && this->curr_instr->is_squashed() == 1) + this->status = OK; if (this->curr_instr && this->status != OK) { this->advance_helper(); } @@ -108,7 +110,7 @@ bool Stage::is_checked_out(signed int r) void Stage::squash() { if (curr_instr) { - this->curr_instr->set_mnemonic(NOP); + this->curr_instr->squash(); this->status = OK; } if (this->next) { |