aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKarel Kočí <cynerd@email.cz>2018-03-06 21:57:07 +0100
committerKarel Kočí <cynerd@email.cz>2018-03-06 21:57:07 +0100
commita56b25212865c57251719a1d4a5d9d6a79b339c5 (patch)
tree5e5412c14a407b19a7e3a245cc39cb4fc80b6ec4
parentc75024c81ba92efbcc70e80520599a27b4aff0d8 (diff)
downloadqtmips-a56b25212865c57251719a1d4a5d9d6a79b339c5.tar.gz
qtmips-a56b25212865c57251719a1d4a5d9d6a79b339c5.tar.bz2
qtmips-a56b25212865c57251719a1d4a5d9d6a79b339c5.zip
Implement Cache configuration
This commit implements both cache configuration for machine and for gui.
-rw-r--r--qtmips_cli/qtmips_cli.pro3
-rw-r--r--qtmips_gui/NewDialog.ui18
-rw-r--r--qtmips_gui/NewDialogCache.ui54
-rw-r--r--qtmips_gui/newdialog.cpp159
-rw-r--r--qtmips_gui/newdialog.h32
-rw-r--r--qtmips_machine/machineconfig.cpp99
-rw-r--r--qtmips_machine/machineconfig.h32
7 files changed, 299 insertions, 98 deletions
diff --git a/qtmips_cli/qtmips_cli.pro b/qtmips_cli/qtmips_cli.pro
index 32952b7..fdf4a24 100644
--- a/qtmips_cli/qtmips_cli.pro
+++ b/qtmips_cli/qtmips_cli.pro
@@ -1,5 +1,4 @@
-QT += core
-QT -= gui
+QT += core gui widgets
TARGET = qtmips_cli
CONFIG += console
diff --git a/qtmips_gui/NewDialog.ui b/qtmips_gui/NewDialog.ui
index 0490ca3..3c1eaba 100644
--- a/qtmips_gui/NewDialog.ui
+++ b/qtmips_gui/NewDialog.ui
@@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>558</width>
- <height>254</height>
+ <height>316</height>
</rect>
</property>
<property name="windowTitle">
@@ -50,9 +50,23 @@
</widget>
</item>
<item>
+ <widget class="QRadioButton" name="preset_pipelined_bare">
+ <property name="text">
+ <string>Pipelined without hazard unit and without cache</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QRadioButton" name="preset_pipelined_hazard">
+ <property name="text">
+ <string>Pipelined with hazard unit and without cache</string>
+ </property>
+ </widget>
+ </item>
+ <item>
<widget class="QRadioButton" name="preset_pipelined">
<property name="text">
- <string>Pipelined and cache</string>
+ <string>Pipelined with hazard unit and cache</string>
</property>
</widget>
</item>
diff --git a/qtmips_gui/NewDialogCache.ui b/qtmips_gui/NewDialogCache.ui
index 072251c..5c09de6 100644
--- a/qtmips_gui/NewDialogCache.ui
+++ b/qtmips_gui/NewDialogCache.ui
@@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>435</width>
- <height>272</height>
+ <height>204</height>
</rect>
</property>
<property name="windowTitle">
@@ -24,70 +24,43 @@
</property>
<layout class="QFormLayout" name="formLayout">
<item row="0" column="0">
- <widget class="QLabel" name="label">
- <property name="text">
- <string>Capacity:</string>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
- <widget class="QSpinBox" name="capcity"/>
- </item>
- <item row="1" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Number of sets:</string>
</property>
</widget>
</item>
- <item row="1" column="1">
+ <item row="0" column="1">
<widget class="QSpinBox" name="number_of_sets"/>
</item>
- <item row="2" column="0">
+ <item row="1" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Block size:</string>
</property>
</widget>
</item>
- <item row="2" column="1">
+ <item row="1" column="1">
<widget class="QSpinBox" name="block_size"/>
</item>
- <item row="3" column="0">
- <widget class="QLabel" name="label_4">
- <property name="text">
- <string>Number of blocks:</string>
- </property>
- </widget>
- </item>
- <item row="3" column="1">
- <widget class="QSpinBox" name="number_of_blocks"/>
- </item>
- <item row="4" column="0">
+ <item row="2" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Degree of associativity:</string>
</property>
</widget>
</item>
- <item row="4" column="1">
- <widget class="QSpinBox" name="degree_if_associativity"/>
+ <item row="2" column="1">
+ <widget class="QSpinBox" name="degree_of_associativity"/>
</item>
- <item row="5" column="0">
+ <item row="3" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
<string>Replacement policy:</string>
</property>
</widget>
</item>
- <item row="6" column="0">
- <widget class="QLabel" name="label_writeback">
- <property name="text">
- <string>Writeback policy:</string>
- </property>
- </widget>
- </item>
- <item row="5" column="1">
+ <item row="3" column="1">
<widget class="QComboBox" name="replacement_policy">
<item>
<property name="text">
@@ -111,7 +84,14 @@
</item>
</widget>
</item>
- <item row="6" column="1">
+ <item row="4" column="0">
+ <widget class="QLabel" name="label_writeback">
+ <property name="text">
+ <string>Writeback policy:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="1">
<widget class="QComboBox" name="writeback_policy">
<item>
<property name="text">
diff --git a/qtmips_gui/newdialog.cpp b/qtmips_gui/newdialog.cpp
index b760626..ee957cb 100644
--- a/qtmips_gui/newdialog.cpp
+++ b/qtmips_gui/newdialog.cpp
@@ -20,8 +20,9 @@ NewDialog::NewDialog(QWidget *parent, QSettings *settings) : QDialog(parent) {
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_bare, SIGNAL(toggled(bool)), this, SLOT(set_preset()));
+ connect(ui->preset_pipelined_hazard, 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)));
@@ -32,8 +33,8 @@ NewDialog::NewDialog(QWidget *parent, QSettings *settings) : QDialog(parent) {
connect(ui->mem_protec_exec, SIGNAL(clicked(bool)), this, SLOT(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)));
+ cache_handler_d = new NewDialogCacheHandler(this, ui_cache_d);
+ cache_handler_p = new NewDialogCacheHandler(this, ui_cache_p);
load_settings(); // Also configures gui
}
@@ -46,6 +47,11 @@ NewDialog::~NewDialog() {
delete config;
}
+void NewDialog::switch2custom() {
+ ui->preset_custom->setChecked(true);
+ config_gui();
+}
+
void NewDialog::closeEvent(QCloseEvent *) {
load_settings(); // Reset from settings
// Close main window if not already configured
@@ -90,101 +96,111 @@ void NewDialog::browse_elf() {
}
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();
+ unsigned pres_n = preset_number();
+ if (pres_n > 0) {
+ config->preset((enum machine::ConfigPresets)(pres_n - 1));
+ 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;
+ switch2custom();
}
void NewDialog::delay_slot_change(bool val) {
config->set_delay_slot(val);
- CHANGE_COMMON;
+ switch2custom();
}
void NewDialog::hazard_unit_change() {
- if (ui->hazard_unit->isChecked())
+ if (ui->hazard_unit->isChecked()) {
config->set_hazard_unit(ui->hazard_stall->isChecked() ? machine::MachineConfig::HU_STALL : machine::MachineConfig::HU_STALL_FORWARD);
- else
+ } else {
config->set_hazard_unit(machine::MachineConfig::HU_NONE);
- CHANGE_COMMON;
+ }
+ switch2custom();
}
void NewDialog::mem_protec_exec_change(bool v) {
config->set_memory_execute_protection(v);
- CHANGE_COMMON;
+ switch2custom();
}
void NewDialog::mem_protec_write_change(bool v) {
config->set_memory_write_protection(v);
- CHANGE_COMMON;
-}
-
-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;
+ switch2custom();
}
void NewDialog::config_gui() {
- // Set values
+ // Basic
ui->elf_file->setText(config->elf());
+ // Core
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->setChecked(config->hazard_unit() == machine::MachineConfig::HU_STALL_FORWARD);
+ // Memory
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());
+ // Cache
+ cache_handler_d->config_gui();
+ cache_handler_p->config_gui();
+
// Disable various sections according to configuration
ui->delay_slot->setEnabled(!config->pipelined());
ui->hazard_unit->setEnabled(config->pipelined());
}
+unsigned NewDialog::preset_number() {
+ enum machine::ConfigPresets preset;
+ if (ui->preset_no_pipeline->isChecked())
+ preset = machine::CP_SINGLE;
+ else if (ui->preset_pipelined_bare->isChecked())
+ preset = machine::CP_PIPE_NO_HAZARD;
+ else if (ui->preset_pipelined_hazard->isChecked())
+ preset = machine::CP_PIPE_NO_CACHE;
+ else if (ui->preset_pipelined->isChecked())
+ preset = machine::CP_PIPE_CACHE;
+ else
+ return 0;
+ return (unsigned)preset + 1;
+}
+
void NewDialog::load_settings() {
if (config != nullptr)
delete config;
// Load config
config = new machine::MachineConfig(settings);
+ cache_handler_d->set_config(config->access_cache_data());
+ cache_handler_p->set_config(config->access_cache_program());
// Load preset
unsigned preset = settings->value("Preset", 1).toUInt();
if (preset != 0) {
- enum machine::ConfigPresets p = (enum machine::ConfigPresets)(preset - 1);
+ auto 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:
+ case machine::CP_PIPE_NO_HAZARD:
+ ui->preset_pipelined_bare->setChecked(true);
+ break;
+ case machine::CP_PIPE_NO_CACHE:
+ ui->preset_pipelined_hazard->setChecked(true);
+ break;
+ case machine::CP_PIPE_CACHE:
ui->preset_pipelined->setChecked(true);
break;
}
- } else
+ } else {
ui->preset_custom->setChecked(true);
+ }
config_gui();
}
@@ -192,8 +208,65 @@ void NewDialog::load_settings() {
void NewDialog::store_settings() {
config->store(settings);
- if (ui->preset_custom->isChecked())
+ // Presets are not stored in settings so we have to store them explicitly
+ 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);
+ } else {
+ settings->setValue("Preset", preset_number());
+ }
+}
+
+NewDialogCacheHandler::NewDialogCacheHandler(NewDialog *nd, Ui::NewDialogCache *cui) {
+ this->nd = nd;
+ this->ui = cui;
+ this->config = nullptr;
+ connect(ui->enabled, SIGNAL(clicked(bool)), this, SLOT(enabled(bool)));
+ connect(ui->number_of_sets, SIGNAL(editingFinished()), this, SLOT(numsets()));
+ connect(ui->block_size, SIGNAL(editingFinished()), this, SLOT(blocksize()));
+ connect(ui->degree_of_associativity, SIGNAL(editingFinished()), this, SLOT(degreeassociativity()));
+ connect(ui->replacement_policy, SIGNAL(activated(int)), this, SLOT(replacement(int)));
+ connect(ui->writeback_policy, SIGNAL(activated(int)), this, SLOT(writeback(int)));
+}
+
+void NewDialogCacheHandler::set_config(machine::MachineConfigCache *config) {
+ this->config = config;
+}
+
+void NewDialogCacheHandler::config_gui() {
+ ui->enabled->setChecked(config->enabled());
+ ui->number_of_sets->setValue(config->sets());
+ ui->block_size->setValue(config->blocks());
+ ui->degree_of_associativity->setValue(config->associativity());
+ ui->replacement_policy->setCurrentIndex((int)config->replacement_policy());
+ ui->writeback_policy->setCurrentIndex((int)config->write_policy());
+}
+
+void NewDialogCacheHandler::enabled(bool val) {
+ config->set_enabled(val);
+ nd->switch2custom();
+}
+
+void NewDialogCacheHandler::numsets() {
+ config->set_sets(ui->number_of_sets->value());
+ nd->switch2custom();
+}
+
+void NewDialogCacheHandler::blocksize() {
+ config->set_blocks(ui->block_size->value());
+ nd->switch2custom();
+}
+
+void NewDialogCacheHandler::degreeassociativity() {
+ config->set_associativity(ui->degree_of_associativity->value());
+ nd->switch2custom();
+}
+
+void NewDialogCacheHandler::replacement(int val) {
+ config->set_replacement_policy((enum machine::MachineConfigCache::ReplacementPolicy)val);
+ nd->switch2custom();
+}
+
+void NewDialogCacheHandler::writeback(int val) {
+ config->set_write_policy((enum machine::MachineConfigCache::WritePolicy)val);
+ nd->switch2custom();
}
diff --git a/qtmips_gui/newdialog.h b/qtmips_gui/newdialog.h
index 5b50a41..79616a2 100644
--- a/qtmips_gui/newdialog.h
+++ b/qtmips_gui/newdialog.h
@@ -9,12 +9,16 @@
#include "ui_NewDialogCache.h"
#include "machineconfig.h"
+class NewDialogCacheHandler;
+
class NewDialog : public QDialog {
Q_OBJECT
public:
NewDialog(QWidget *parent, QSettings *settings);
~NewDialog();
+ void switch2custom();
+
protected:
void closeEvent(QCloseEvent *);
@@ -29,9 +33,6 @@ private slots:
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;
@@ -40,8 +41,33 @@ private:
machine::MachineConfig *config;
void config_gui(); // Apply configuration to gui
+ unsigned preset_number();
void load_settings();
void store_settings();
+ NewDialogCacheHandler *cache_handler_p, *cache_handler_d;
+};
+
+class NewDialogCacheHandler : QObject {
+ Q_OBJECT
+public:
+ NewDialogCacheHandler(NewDialog *nd, Ui::NewDialogCache *ui);
+
+ void set_config(machine::MachineConfigCache *config);
+
+ void config_gui();
+
+private slots:
+ void enabled(bool);
+ void numsets();
+ void blocksize();
+ void degreeassociativity();
+ void replacement(int);
+ void writeback(int);
+
+private:
+ NewDialog *nd;
+ Ui::NewDialogCache *ui;
+ machine::MachineConfigCache *config;
};
#endif // NEWDIALOG_H
diff --git a/qtmips_machine/machineconfig.cpp b/qtmips_machine/machineconfig.cpp
index ab6f2a5..ea9dc9d 100644
--- a/qtmips_machine/machineconfig.cpp
+++ b/qtmips_machine/machineconfig.cpp
@@ -15,36 +15,67 @@ using namespace machine;
//////////////////////////////////////////////////////////////////////////////
/// Default config of MachineConfigCache
#define DFC_EN false
+#define DFC_SETS 1
+#define DFC_BLOCKS 1
+#define DFC_ASSOC 1
+#define DFC_REPLAC RP_RAND
+#define DFC_WRITE WP_TROUGH
//////////////////////////////////////////////////////////////////////////////
MachineConfigCache::MachineConfigCache() {
en = DFC_EN;
+ n_sets = DFC_SETS;
+ n_blocks = DFC_BLOCKS;
+ d_associativity = DFC_ASSOC;
+ replac_pol = DFC_REPLAC;
+ write_pol = DFC_WRITE;
}
MachineConfigCache::MachineConfigCache(const MachineConfigCache *cc) {
en = cc->enabled();
+ n_sets = cc->sets();
+ n_blocks = cc->blocks();
+ d_associativity = cc->associativity();
+ replac_pol = cc->replacement_policy();
+ write_pol = cc->write_policy();
}
#define N(STR) (prefix + QString(STR))
MachineConfigCache::MachineConfigCache(const QSettings *sts, const QString &prefix) {
en = sts->value(N("Enabled"), DFC_EN).toBool();
+ n_sets = sts->value(N("Sets"), DFC_SETS).toUInt();
+ n_blocks = sts->value(N("Blocks"), DFC_BLOCKS).toUInt();
+ d_associativity = sts->value(N("Associativity"), DFC_ASSOC).toUInt();
+ replac_pol = (enum ReplacementPolicy)sts->value(N("Replacement"), DFC_REPLAC).toUInt();
+ write_pol = (enum WritePolicy)sts->value(N("Write"), DFC_WRITE).toUInt();
}
void MachineConfigCache::store(QSettings *sts, const QString &prefix) {
- sts->setValue(N("Enabled"), en);
+ sts->setValue(N("Enabled"), enabled());
+ sts->setValue(N("Sets"), sets());
+ sts->setValue(N("Blocks"), blocks());
+ sts->setValue(N("Associativity"), associativity());
+ sts->setValue(N("Replacement"), (unsigned)replacement_policy());
+ sts->setValue(N("Write"), (unsigned)write_policy());
}
#undef N
void MachineConfigCache::preset(enum ConfigPresets p) {
switch (p) {
- case CP_SINGLE:
- set_enabled(false);
+ case CP_PIPE_CACHE:
+ set_enabled(true);
+ set_sets(3);
+ set_blocks(1);
+ set_associativity(1);
+ set_replacement_policy(RP_RAND);
+ set_write_policy(WP_TROUGH);
break;
- case CP_PIPE_WITH_CACHE:
+ case CP_SINGLE:
+ case CP_PIPE_NO_HAZARD:
+ case CP_PIPE_NO_CACHE:
set_enabled(false);
- break;
}
}
@@ -52,13 +83,60 @@ void MachineConfigCache::set_enabled(bool v) {
en = v;
}
+void MachineConfigCache::set_sets(unsigned v) {
+ // TODO verify that this is 2^N
+ n_sets = v;
+}
+
+void MachineConfigCache::set_blocks(unsigned v) {
+ // TODO even more verifications for 2^N
+ n_blocks = v;
+}
+
+void MachineConfigCache::set_associativity(unsigned v) {
+ d_associativity = v;
+}
+
+void MachineConfigCache::set_replacement_policy(enum ReplacementPolicy v) {
+ replac_pol = v;
+}
+
+void MachineConfigCache::set_write_policy(enum WritePolicy v) {
+ write_pol = v;
+}
+
bool MachineConfigCache::enabled() const {
return en;
}
+unsigned MachineConfigCache::sets() const {
+ return n_sets;
+}
+
+unsigned MachineConfigCache::blocks() const {
+ return n_blocks;
+}
+
+unsigned MachineConfigCache::associativity() const {
+ return d_associativity;
+}
+
+enum MachineConfigCache::ReplacementPolicy MachineConfigCache::replacement_policy() const {
+ return replac_pol;
+}
+
+enum MachineConfigCache::WritePolicy MachineConfigCache::write_policy() const {
+ return write_pol;
+}
+
bool MachineConfigCache::operator==(const MachineConfigCache &c) const {
#define CMP(GETTER) (GETTER)() == (c.GETTER)()
- return CMP(enabled);
+ return CMP(enabled) && \
+ CMP(sets) && \
+ CMP(blocks) && \
+ CMP(associativity) && \
+ CMP(replacement_policy) && \
+ CMP(write_policy);
#undef CMP
}
@@ -97,7 +175,7 @@ MachineConfig::MachineConfig(const MachineConfig *cc) {
MachineConfig::MachineConfig(const QSettings *sts, const QString &prefix) {
pipeline = sts->value(N("Pipelined"), DF_PIPELINE).toBool();
delayslot = sts->value(N("DelaySlot"), DF_DELAYSLOT).toBool();
- hunit = (enum HazardUnit)sts->value(N("HazardUnit"), DF_HUNIT).toUInt(); // TODO probably rather save as string
+ hunit = (enum HazardUnit)sts->value(N("HazardUnit"), DF_HUNIT).toUInt();
exec_protect = sts->value(N("MemoryExecuteProtection"), DF_EXEC_PROTEC).toBool();
write_protect = sts->value(N("MemoryWriteProtection"), DF_WRITE_PROTEC).toBool();
mem_acc_read = sts->value(N("MemoryRead"), DF_MEM_ACC_READ).toUInt();
@@ -125,7 +203,12 @@ void MachineConfig::preset(enum ConfigPresets p) {
set_pipelined(false);
set_delay_slot(true);
break;
- case CP_PIPE_WITH_CACHE:
+ case CP_PIPE_NO_HAZARD:
+ set_pipelined(true);
+ set_hazard_unit(MachineConfig::HU_NONE);
+ break;
+ case CP_PIPE_CACHE:
+ case CP_PIPE_NO_CACHE:
set_pipelined(true);
set_hazard_unit(MachineConfig::HU_STALL_FORWARD);
break;
diff --git a/qtmips_machine/machineconfig.h b/qtmips_machine/machineconfig.h
index 90c9b75..a713a4c 100644
--- a/qtmips_machine/machineconfig.h
+++ b/qtmips_machine/machineconfig.h
@@ -7,8 +7,10 @@
namespace machine {
enum ConfigPresets {
- CP_SINGLE,
- CP_PIPE_WITH_CACHE
+ CP_SINGLE, // No pipeline cpu without cache
+ CP_PIPE_NO_HAZARD, // Pipelined cpu without hazard unit
+ CP_PIPE_NO_CACHE, // Pipelined cpu without cache
+ CP_PIPE_CACHE // Full pipelined cpu
};
class MachineConfigCache {
@@ -21,17 +23,41 @@ public:
void preset(enum ConfigPresets);
+ enum ReplacementPolicy {
+ RP_RAND, // Random
+ RP_LRU, // Least recently used
+ RP_LFU, // Least frequently used
+ RP_ARC // Adaptive replacement cache
+ };
+
+ enum WritePolicy {
+ WP_TROUGH, // Write trough
+ WP_BACK // Write back
+ };
+
// If cache should be used or not
void set_enabled(bool);
+ void set_sets(unsigned); // Number of sets bits used in cache
+ void set_blocks(unsigned); // Number of blocks
+ void set_associativity(unsigned); // Degree of associativity
+ void set_replacement_policy(enum ReplacementPolicy);
+ void set_write_policy(enum WritePolicy);
bool enabled() const;
+ unsigned sets() const;
+ unsigned blocks() const;
+ unsigned associativity() const;
+ enum ReplacementPolicy replacement_policy() const;
+ enum WritePolicy write_policy() const;
bool operator ==(const MachineConfigCache &c) const;
bool operator !=(const MachineConfigCache &c) const;
private:
bool en;
- // TODO
+ unsigned n_sets, n_blocks, d_associativity;
+ enum ReplacementPolicy replac_pol;
+ enum WritePolicy write_pol;
};
class MachineConfig {