aboutsummaryrefslogtreecommitdiff
path: root/qtmips_gui/newdialog.cpp
diff options
context:
space:
mode:
authorKarel Kočí <cynerd@email.cz>2018-01-17 14:47:18 +0100
committerKarel Kočí <cynerd@email.cz>2018-01-17 14:47:18 +0100
commit5feb16d0738f57d220e5f2e6ba85e072c22135ee (patch)
tree73d136af8dba31e004a281c2072521b63a97ae19 /qtmips_gui/newdialog.cpp
parentd7d9860051a9a9eb2c6f11684535ac65cce38eb8 (diff)
downloadqtmips-5feb16d0738f57d220e5f2e6ba85e072c22135ee.tar.gz
qtmips-5feb16d0738f57d220e5f2e6ba85e072c22135ee.tar.bz2
qtmips-5feb16d0738f57d220e5f2e6ba85e072c22135ee.zip
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.
Diffstat (limited to 'qtmips_gui/newdialog.cpp')
-rw-r--r--qtmips_gui/newdialog.cpp190
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);
}