aboutsummaryrefslogtreecommitdiff
path: root/qtmips_machine
diff options
context:
space:
mode:
Diffstat (limited to 'qtmips_machine')
-rw-r--r--qtmips_machine/cache.cpp32
-rw-r--r--qtmips_machine/cache.h8
-rw-r--r--qtmips_machine/core.cpp19
-rw-r--r--qtmips_machine/core.h8
-rw-r--r--qtmips_machine/qtmipsmachine.cpp17
-rw-r--r--qtmips_machine/qtmipsmachine.h5
-rw-r--r--qtmips_machine/tests/testcore.cpp12
7 files changed, 64 insertions, 37 deletions
diff --git a/qtmips_machine/cache.cpp b/qtmips_machine/cache.cpp
index f37db38..7432119 100644
--- a/qtmips_machine/cache.cpp
+++ b/qtmips_machine/cache.cpp
@@ -2,8 +2,15 @@
using namespace machine;
-Cache::Cache(Memory *m, MachineConfigCache *cc) : cnf(cc) {
+Cache::Cache(Memory *m, const MachineConfigCache *cc) : cnf(cc) {
mem = m;
+ // Zero hit and miss rate
+ hitc = 0;
+ missc = 0;
+ // Skip any other initialization if cache is disabled
+ if (!cc->enabled())
+ return;
+
// Allocate cache data structure
dt = new struct cache_data*[cc->associativity()];
for (unsigned i = 0; i < cc->associativity(); i++) {
@@ -27,12 +34,14 @@ Cache::Cache(Memory *m, MachineConfigCache *cc) : cnf(cc) {
default:
break;
}
- // Zero hit and miss rate
- hitc = 0;
- missc = 0;
}
void Cache::wword(std::uint32_t address, std::uint32_t value) {
+ if (!cnf.enabled()) {
+ mem->write_word(address, value);
+ return;
+ }
+
std::uint32_t *data;
access(address, &data, false);
*data = value;
@@ -42,27 +51,36 @@ void Cache::wword(std::uint32_t address, std::uint32_t value) {
}
std::uint32_t Cache::rword(std::uint32_t address) const {
+ if (!cnf.enabled())
+ return mem->read_word(address);
+
std::uint32_t *data;
access(address, &data, true);
return *data;
}
void Cache::flush() {
+ if (!cnf.enabled())
+ return;
+
for (unsigned as = 0; as < cnf.associativity(); as++)
for (unsigned st = 0; st < cnf.sets(); st++)
if (dt[as][st].valid)
kick(as, st);
}
-unsigned Cache::hit() {
+unsigned Cache::hit() const {
return hitc;
}
-unsigned Cache::miss() {
+unsigned Cache::miss() const {
return missc;
}
void Cache::reset() {
+ if (!cnf.enabled())
+ return;
+
// Set all cells to ne invalid
for (unsigned as = 0; as < cnf.associativity(); as++)
for (unsigned st = 0; st < cnf.sets(); st++)
@@ -73,7 +91,7 @@ void Cache::reset() {
missc = 0;
}
-const MachineConfigCache &Cache::config() {
+const MachineConfigCache &Cache::config() const {
return cnf;
}
diff --git a/qtmips_machine/cache.h b/qtmips_machine/cache.h
index 9372a1a..8fe7475 100644
--- a/qtmips_machine/cache.h
+++ b/qtmips_machine/cache.h
@@ -11,19 +11,19 @@ namespace machine {
class Cache : public MemoryAccess {
Q_OBJECT
public:
- Cache(Memory *m, MachineConfigCache *c);
+ Cache(Memory *m, const MachineConfigCache *c);
void wword(std::uint32_t address, std::uint32_t value);
std::uint32_t rword(std::uint32_t address) const;
void flush(); // flush/sync cache
- unsigned hit(); // Number of recorded hits
- unsigned miss(); // Number of recorded misses
+ unsigned hit() const; // Number of recorded hits
+ unsigned miss() const; // Number of recorded misses
void reset(); // Reset whole state of cache
- const MachineConfigCache &config();
+ const MachineConfigCache &config() const;
// TODO getters for cells
private:
diff --git a/qtmips_machine/core.cpp b/qtmips_machine/core.cpp
index 273842d..98b60e9 100644
--- a/qtmips_machine/core.cpp
+++ b/qtmips_machine/core.cpp
@@ -90,13 +90,14 @@ static const struct DecodeMap dmap[] = {
NOPE // 63
};
-Core::Core(Registers *regs, MemoryAccess *mem) {
+Core::Core(Registers *regs, MemoryAccess *mem_program, MemoryAccess *mem_data) {
this->regs = regs;
- this->mem = mem;
+ this->mem_program = mem_program;
+ this->mem_data = mem_data;
}
struct Core::dtFetch Core::fetch() {
- Instruction inst(mem->read_word(regs->read_pc()));
+ Instruction inst(mem_program->read_word(regs->read_pc()));
emit instruction_fetched(inst);
return {
.inst = inst
@@ -152,9 +153,9 @@ struct Core::dtMemory Core::memory(const struct dtExecute &dt) {
std::uint32_t towrite_val = dt.alu_val;
if (dt.memwrite)
- mem->write_ctl(dt.memctl, dt.alu_val, dt.val_rt);
+ mem_data->write_ctl(dt.memctl, dt.alu_val, dt.val_rt);
else if (dt.memread)
- towrite_val = mem->read_ctl(dt.memctl, dt.alu_val);
+ towrite_val = mem_data->read_ctl(dt.memctl, dt.alu_val);
return {
.inst = dt.inst,
@@ -256,8 +257,8 @@ void Core::dtMemoryInit(struct dtMemory &dt) {
dt.towrite_val = 0;
}
-CoreSingle::CoreSingle(Registers *regs, MemoryAccess *mem, bool jmp_delay_slot) : \
- Core(regs, mem) {
+CoreSingle::CoreSingle(Registers *regs, MemoryAccess *mem_program, MemoryAccess *mem_data, bool jmp_delay_slot) : \
+ Core(regs, mem_program, mem_data) {
if (jmp_delay_slot)
jmp_delay_decode = new struct Core::dtDecode();
else
@@ -288,8 +289,8 @@ void CoreSingle::reset() {
Core::dtDecodeInit(*jmp_delay_decode);
}
-CorePipelined::CorePipelined(Registers *regs, MemoryAccess *mem, enum MachineConfig::HazardUnit hazard_unit) : \
- Core(regs, mem) {
+CorePipelined::CorePipelined(Registers *regs, MemoryAccess *mem_program, MemoryAccess *mem_data, enum MachineConfig::HazardUnit hazard_unit) : \
+ Core(regs, mem_program, mem_data) {
this->hazard_unit = hazard_unit;
reset();
}
diff --git a/qtmips_machine/core.h b/qtmips_machine/core.h
index a0bc2a2..98f3e4a 100644
--- a/qtmips_machine/core.h
+++ b/qtmips_machine/core.h
@@ -14,7 +14,7 @@ namespace machine {
class Core : public QObject {
Q_OBJECT
public:
- Core(Registers *regs, MemoryAccess *mem);
+ Core(Registers *regs, MemoryAccess *mem_program, MemoryAccess *mem_data);
virtual void step() = 0; // Do single step
@@ -30,7 +30,7 @@ signals:
protected:
Registers *regs;
- MemoryAccess *mem;
+ MemoryAccess *mem_data, *mem_program;
struct dtFetch {
Instruction inst; // Loaded instruction
@@ -80,7 +80,7 @@ protected:
class CoreSingle : public Core {
public:
- CoreSingle(Registers *regs, MemoryAccess *mem, bool jmp_delay_slot);
+ CoreSingle(Registers *regs, MemoryAccess *mem_program, MemoryAccess *mem_data, bool jmp_delay_slot);
~CoreSingle();
void step();
@@ -93,7 +93,7 @@ private:
class CorePipelined : public Core {
public:
- CorePipelined(Registers *regs, MemoryAccess *mem, enum MachineConfig::HazardUnit hazard_unit = MachineConfig::HU_STALL_FORWARD);
+ CorePipelined(Registers *regs, MemoryAccess *mem_program, MemoryAccess *mem_data, enum MachineConfig::HazardUnit hazard_unit = MachineConfig::HU_STALL_FORWARD);
void step();
diff --git a/qtmips_machine/qtmipsmachine.cpp b/qtmips_machine/qtmipsmachine.cpp
index e96924a..4a2b0f2 100644
--- a/qtmips_machine/qtmipsmachine.cpp
+++ b/qtmips_machine/qtmipsmachine.cpp
@@ -13,11 +13,13 @@ QtMipsMachine::QtMipsMachine(const MachineConfig &cc) : QObject(), mcnf(&cc) {
regs = new Registers();
mem = new Memory(*mem_program_only);
+ cch_program = new Cache(mem, &cc.cache_program());
+ cch_data = new Cache(mem, &cc.cache_data());
if (cc.pipelined())
- cr = new CorePipelined(regs, mem, cc.hazard_unit());
+ cr = new CorePipelined(regs, cch_program, cch_data, cc.hazard_unit());
else
- cr = new CoreSingle(regs, mem, cc.delay_slot());
+ cr = new CoreSingle(regs, cch_program, cch_data, cc.delay_slot());
run_t = new QTimer(this);
set_speed(0); // In default run as fast as possible
@@ -40,8 +42,12 @@ const Memory *QtMipsMachine::memory() {
return mem;
}
-const Cache *QtMipsMachine::cache() {
- return cch;
+const Cache *QtMipsMachine::cache_program() {
+ return cch_program;
+}
+
+const Cache *QtMipsMachine::cache_data() {
+ return cch_data;
}
const Core *QtMipsMachine::core() {
@@ -105,7 +111,8 @@ void QtMipsMachine::restart() {
pause();
regs->reset();
mem->reset(*mem_program_only);
- // TODO cache
+ cch_program->reset();
+ cch_data->reset();
cr->reset();
set_status(ST_READY);
}
diff --git a/qtmips_machine/qtmipsmachine.h b/qtmips_machine/qtmipsmachine.h
index 05e2917..46405e5 100644
--- a/qtmips_machine/qtmipsmachine.h
+++ b/qtmips_machine/qtmipsmachine.h
@@ -23,7 +23,8 @@ public:
const Registers *registers();
const Memory *memory();
- const Cache *cache();
+ const Cache *cache_program();
+ const Cache *cache_data();
const Core *core();
const CoreSingle *core_singe();
const CorePipelined *core_pipelined();
@@ -55,7 +56,7 @@ private:
Registers *regs;
Memory *mem, *mem_program_only;
- Cache *cch;
+ Cache *cch_program, *cch_data;
Core *cr;
QTimer *run_t;
diff --git a/qtmips_machine/tests/testcore.cpp b/qtmips_machine/tests/testcore.cpp
index 3a1ce48..30cf3c7 100644
--- a/qtmips_machine/tests/testcore.cpp
+++ b/qtmips_machine/tests/testcore.cpp
@@ -186,7 +186,7 @@ void MachineTests::singlecore_regs() {
mem.write_word(res.read_pc(), i.data()); // Store single instruction (anything else should be 0 so NOP effectively)
Memory mem_used(mem); // Create memory copy
- CoreSingle core(&init, &mem_used, true);
+ CoreSingle core(&init, &mem_used, &mem_used, true);
core.step(); // Single step should be enought as this is risc without pipeline
res.pc_inc(); // We did single step so increment program counter accordingly
@@ -206,7 +206,7 @@ void MachineTests::pipecore_regs() {
res.pc_jmp(0x14);
- CorePipelined core(&init, &mem_used);
+ CorePipelined core(&init, &mem_used, &mem_used);
for (int i = 0; i < 5; i++)
core.step(); // Fire steps for five pipelines stages
@@ -275,7 +275,7 @@ void MachineTests::singlecore_jmp() {
Memory mem_used(mem);
Registers regs_used(regs);
- CoreSingle core(&regs_used, &mem_used, true);
+ CoreSingle core(&regs_used, &mem_used, &mem_used, true);
core.step();
QCOMPARE(regs.read_pc() + 4, regs_used.read_pc()); // First execute delay slot
core.step();
@@ -296,7 +296,7 @@ void MachineTests::pipecore_jmp() {
Memory mem_used(mem);
Registers regs_used(regs);
- CorePipelined core(&regs_used, &mem_used);
+ CorePipelined core(&regs_used, &mem_used, &mem_used);
core.step();
QCOMPARE(regs.read_pc() + 4, regs_used.read_pc()); // First just fetch
core.step();
@@ -400,7 +400,7 @@ void MachineTests::singlecore_mem() {
mem_init.write_word(regs_init.read_pc(), i.data());
mem_res.write_word(regs_init.read_pc(), i.data());
- CoreSingle core(&regs_init, &mem_init, true);
+ CoreSingle core(&regs_init, &mem_init, &mem_init, true);
core.step();
regs_res.pc_inc();
@@ -419,7 +419,7 @@ void MachineTests::pipecore_mem() {
mem_init.write_word(regs_init.read_pc(), i.data());
mem_res.write_word(regs_init.read_pc(), i.data());
- CorePipelined core(&regs_init, &mem_init);
+ CorePipelined core(&regs_init, &mem_init, &mem_init);
for (int i = 0; i < 5; i++)
core.step(); // Fire steps for five pipelines stages