From 5feb16d0738f57d220e5f2e6ba85e072c22135ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karel=20Ko=C4=8D=C3=AD?= Date: Wed, 17 Jan 2018 14:47:18 +0100 Subject: Update how configuration is handled in newdialog In previous implementation were dependencies described on two places. In NewDialog and in MachineConfig. Now NewDialog sets options in MachineConfig and configuration is then applied to NewDialog. --- qtmips_gui/NewDialog.ui | 31 ++++++- qtmips_gui/NewDialogCache.ui | 169 +++++++++++++++++++++++++++----------- qtmips_gui/newdialog.cpp | 190 +++++++++++++++++++++++++++++-------------- qtmips_gui/newdialog.h | 15 +++- 4 files changed, 293 insertions(+), 112 deletions(-) (limited to 'qtmips_gui') diff --git a/qtmips_gui/NewDialog.ui b/qtmips_gui/NewDialog.ui index a39a014..0490ca3 100644 --- a/qtmips_gui/NewDialog.ui +++ b/qtmips_gui/NewDialog.ui @@ -37,7 +37,7 @@ - + Preset @@ -197,6 +197,35 @@ + + + + Access time (in cycles) + + + + + + Read: + + + + + + + + + + Write: + + + + + + + + + diff --git a/qtmips_gui/NewDialogCache.ui b/qtmips_gui/NewDialogCache.ui index 3c91824..04f15f7 100644 --- a/qtmips_gui/NewDialogCache.ui +++ b/qtmips_gui/NewDialogCache.ui @@ -6,63 +6,140 @@ 0 0 - 339 - 167 + 435 + 272 Form - - - - - Capacity: + + + + + - - - - - - - - - Number of sets: + + true + + + + + Capacity: + + + + + + + + + + Number of sets: + + + + + + + + + + Block size: + + + + + + + + + + Number of blocks: + + + + + + + + + + Degree of associativity: + + + + + + + + + + Replacement policy: + + + + + + + Writeback policy: + + + + + + + + Random + + + + + Least Recently Used (LRU) + + + + + Least Frequently Used (LFU) + + + + + Adaptive Replacement Cache (ARC) + + + + + + + + + Write trough + + + + + Write back + + + + + - - - - Block size: + + + + Qt::Vertical - - - - - - Number of blocks: + + + 20 + 40 + - - - - - - Degree of associativity: - - - - - - - - - - - - - - + diff --git a/qtmips_gui/newdialog.cpp b/qtmips_gui/newdialog.cpp index 6aec98a..033d0ce 100644 --- a/qtmips_gui/newdialog.cpp +++ b/qtmips_gui/newdialog.cpp @@ -5,32 +5,35 @@ NewDialog::NewDialog(QWidget *parent, QSettings *settings) : QDialog(parent) { setWindowTitle("New machine"); + this->settings = settings; + config = nullptr; + ui = new Ui::NewDialog(); ui->setupUi(this); ui_cache_p = new Ui::NewDialogCache(); ui_cache_p->setupUi(ui->tab_cache_program); ui_cache_d = new Ui::NewDialogCache(); ui_cache_d->setupUi(ui->tab_cache_data); - // TODO setup more? settings and configuration pull - - this->settings = settings; - - QObject::connect(ui->pushButton_load, SIGNAL(clicked(bool)), this, SLOT(create())); - QObject::connect(ui->pushButton_cancel, SIGNAL(clicked(bool)), this, SLOT(cancel())); - // Signals on Base tab - QObject::connect(ui->preset_no_pipeline, SIGNAL(toggled(bool)), this, SLOT(preset(bool))); - QObject::connect(ui->preset_pipelined, SIGNAL(toggled(bool)), this, SLOT(preset(bool))); - QObject::connect(ui->pushButton_browse, SIGNAL(clicked(bool)), this, SLOT(browse_elf())); -#define CUSTOM_PRESET(UI) QObject::connect(UI, SIGNAL(clicked(bool)), this, SLOT(set_custom_preset())) - // Signals on Core tab - CUSTOM_PRESET(ui->pipelined); - // Signals on Memory tab - CUSTOM_PRESET(ui->mem_protec_write); - CUSTOM_PRESET(ui->mem_protec_exec); -#undef CUSTOM_PRESET - // Load setting after signals are configured so that we can have correct settings - load_settings(); + connect(ui->pushButton_load, SIGNAL(clicked(bool)), this, SLOT(create())); + connect(ui->pushButton_cancel, SIGNAL(clicked(bool)), this, SLOT(cancel())); + connect(ui->pushButton_browse, SIGNAL(clicked(bool)), this, SLOT(browse_elf())); + //connect(ui->preset_box, SIGNAL(clicked(bool)), this, SLOT(set_preset())); + connect(ui->preset_no_pipeline, SIGNAL(toggled(bool)), this, SLOT(set_preset())); + connect(ui->preset_pipelined, SIGNAL(toggled(bool)), this, SLOT(set_preset())); + + connect(ui->pipelined, SIGNAL(clicked(bool)), this, SLOT(pipelined_change(bool))); + connect(ui->delay_slot, SIGNAL(clicked(bool)), this, SLOT(delay_slot_change(bool))); + connect(ui->hazard_unit, SIGNAL(clicked(bool)), this, SLOT(hazard_unit_change())); + connect(ui->hazard_stall, SIGNAL(clicked(bool)), this, SLOT(hazard_unit_change())); + connect(ui->hazard_stall_forward, SIGNAL(clicked(bool)), this, SLOT(hazard_unit_change())); + connect(ui->mem_protec_exec, SIGNAL(clicked(bool)), this, SIGNAL(mem_protec_exec_change(bool))); + connect(ui->mem_protec_write, SIGNAL(clicked(bool)), this, SLOT(mem_protec_write_change(bool))); + + connect(ui_cache_p->enabled, SIGNAL(clicked(bool)), this, SLOT(cache_program_change(bool))); + connect(ui_cache_d->enabled, SIGNAL(clicked(bool)), this, SLOT(cache_data_change(bool))); + + load_settings(); // Also configures gui } NewDialog::~NewDialog() { @@ -38,6 +41,7 @@ NewDialog::~NewDialog() { delete ui_cache_p; delete ui; // Settings is freed by parent + delete config; } void NewDialog::closeEvent(QCloseEvent *) { @@ -55,13 +59,8 @@ void NewDialog::cancel() { void NewDialog::create() { MainWindow *prnt = (MainWindow*)parent(); - machine::MachineConfig mc; - mc.set_elf(ui->elf_file->text()); - mc.set_pipelined(ui->pipelined->isChecked()); - // TODO other settings - try { - prnt->create_core(mc); + prnt->create_core(*config); } catch (const machine::QtMipsExceptionInput &e) { QMessageBox msg(this); msg.setText(e.msg(false)); @@ -80,54 +79,119 @@ void NewDialog::create() { void NewDialog::browse_elf() { QFileDialog elf_dialog(this); elf_dialog.setFileMode(QFileDialog::ExistingFile); - if (elf_dialog.exec()) - ui->elf_file->setText(elf_dialog.selectedFiles()[0]); + if (elf_dialog.exec()) { + QString path = elf_dialog.selectedFiles()[0]; + ui->elf_file->setText(path); + config->set_elf(path); + } + // Elf shouldn't have any other effect so we skip config_gui here +} + +void NewDialog::set_preset() { + if (ui->preset_no_pipeline->isChecked()) + config->preset(machine::CP_SINGLE); + else if (ui->preset_pipelined->isChecked()) + config->preset(machine::CP_PIPE_WITH_CACHE); + else + // Skip apply configuration as we changed nothing. + return; + config_gui(); +} + +// Common end section of *_change slots +#define CHANGE_COMMON do { \ + ui->preset_custom->setChecked(true); \ + config_gui(); \ + } while(false) + +void NewDialog::pipelined_change(bool val) { + config->set_pipelined(val); + CHANGE_COMMON; +} + +void NewDialog::delay_slot_change(bool val) { + config->set_delay_slot(val); + CHANGE_COMMON; } -void NewDialog::preset(bool value) { - if (value) { - bool pip = ui->preset_pipelined->isChecked(); - // Core settings - ui->pipelined->setChecked(pip); - // Memory settings - ui->mem_protec_write->setChecked(true); - ui->mem_protec_exec->setChecked(true); - } // Else custom so do no changes +void NewDialog::hazard_unit_change() { + if (ui->hazard_unit->isChecked()) + config->set_hazard_unit(ui->hazard_stall->isChecked() ? machine::MachineConfig::HU_STALL : machine::MachineConfig::HU_STALL_FORWARD); + else + config->set_hazard_unit(machine::MachineConfig::HU_NONE); + CHANGE_COMMON; } -void NewDialog::set_custom_preset() { - ui->preset_custom->setChecked(true); +void NewDialog::mem_protec_exec_change(bool v) { + config->set_memory_execute_protection(v); + CHANGE_COMMON; } -#define LOAD_BUTTON(NAME, DEF) ui->NAME->setChecked(settings->value(#NAME, DEF).toBool()) -#define LOAD_LINE(NAME, DEF) ui->NAME->setText(settings->value(#NAME, DEF).toString()) +void NewDialog::mem_protec_write_change(bool v) { + config->set_memory_write_protection(v); + CHANGE_COMMON; +} -#define STORE_BUTTON(NAME) settings->setValue(#NAME, ui->NAME->isChecked()) -#define STORE_LINE(NAME) settings->setValue(#NAME, ui->NAME->text()) +void NewDialog::cache_data_change(bool v) { + config->access_cache_data()->set_enabled(v); + CHANGE_COMMON; +} + +void NewDialog::cache_program_change(bool v) { + config->access_cache_program()->set_enabled(v); + CHANGE_COMMON; +} + +void NewDialog::config_gui() { + // Set values + ui->elf_file->setText(config->elf()); + ui->pipelined->setChecked(config->pipelined()); + ui->delay_slot->setChecked(config->delay_slot()); + ui->hazard_unit->setChecked(config->hazard_unit() != machine::MachineConfig::HU_NONE); + ui->hazard_stall->setChecked(config->hazard_unit() == machine::MachineConfig::HU_STALL); + // ui->hazard_stall_forward is configured automatically according to box exclusivity + ui->mem_protec_exec->setChecked(config->memory_execute_protection()); + ui->mem_protec_write->setChecked(config->memory_write_protection()); + ui->mem_time_read->setValue(config->memory_access_time_read()); + ui->mem_time_write->setValue(config->memory_access_time_write()); + ui_cache_p->enabled->setChecked(config->cache_program().enabled()); + ui_cache_d->enabled->setChecked(config->cache_data().enabled()); + // Disable various sections according to configuration + ui->delay_slot->setEnabled(!config->pipelined()); + ui->hazard_unit->setEnabled(config->pipelined()); +} void NewDialog::load_settings() { - // Core tab - LOAD_BUTTON(pipelined, false); - // Memory tab - LOAD_BUTTON(mem_protec_write, true); - LOAD_BUTTON(mem_protec_exec, true); - // Base tab - // We are doing this last so presets can reset previous configuration to somethin valid - LOAD_BUTTON(preset_no_pipeline, true); - LOAD_BUTTON(preset_pipelined, false); - LOAD_BUTTON(preset_custom, false); - LOAD_LINE(elf_file, ""); + if (config != nullptr) + delete config; + + // Load config + config = new machine::MachineConfig(settings); + + // Load preset + unsigned preset = settings->value("Preset", 1).toUInt(); + if (preset != 0) { + enum machine::ConfigPresets p = (enum machine::ConfigPresets)(preset - 1); + config->preset(p); + switch (p) { + case machine::CP_SINGLE: + ui->preset_no_pipeline->setChecked(true); + break; + case machine::CP_PIPE_WITH_CACHE: + ui->preset_pipelined->setChecked(true); + break; + } + } else + ui->preset_custom->setChecked(true); + + config_gui(); } void NewDialog::store_settings() { - // Core tab - STORE_BUTTON(pipelined); - // Memory tab - STORE_BUTTON(mem_protec_write); - STORE_BUTTON(mem_protec_exec); - // Base tab - STORE_BUTTON(preset_no_pipeline); - STORE_BUTTON(preset_pipelined); - STORE_BUTTON(preset_custom); - STORE_LINE(elf_file); + config->store(settings); + + if (ui->preset_custom->isChecked()) + settings->setValue("Preset", 0); + else + settings->setValue("Preset", ui->preset_no_pipeline->isChecked() ? machine::CP_SINGLE + 1 : machine::CP_PIPE_WITH_CACHE + 1); } diff --git a/qtmips_gui/newdialog.h b/qtmips_gui/newdialog.h index a088777..5b50a41 100644 --- a/qtmips_gui/newdialog.h +++ b/qtmips_gui/newdialog.h @@ -7,6 +7,7 @@ #include #include "ui_NewDialog.h" #include "ui_NewDialogCache.h" +#include "machineconfig.h" class NewDialog : public QDialog { Q_OBJECT @@ -21,14 +22,24 @@ private slots: void cancel(); void create(); void browse_elf(); - void preset(bool); - void set_custom_preset(); + void set_preset(); + void pipelined_change(bool); + void delay_slot_change(bool); + void hazard_unit_change(); + void mem_protec_exec_change(bool); + void mem_protec_write_change(bool); + + void cache_data_change(bool); + void cache_program_change(bool); private: Ui::NewDialog *ui; Ui::NewDialogCache *ui_cache_p, *ui_cache_d; QSettings *settings; + machine::MachineConfig *config; + void config_gui(); // Apply configuration to gui + void load_settings(); void store_settings(); }; -- cgit v1.2.3