diff options
Diffstat (limited to 'qtmips_gui/newdialog.cpp')
-rw-r--r-- | qtmips_gui/newdialog.cpp | 190 |
1 files changed, 127 insertions, 63 deletions
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); } |