aboutsummaryrefslogtreecommitdiff
path: root/qtmips_machine/cache.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'qtmips_machine/cache.cpp')
-rw-r--r--qtmips_machine/cache.cpp65
1 files changed, 52 insertions, 13 deletions
diff --git a/qtmips_machine/cache.cpp b/qtmips_machine/cache.cpp
index 753027a..acc48b1 100644
--- a/qtmips_machine/cache.cpp
+++ b/qtmips_machine/cache.cpp
@@ -2,11 +2,15 @@
using namespace machine;
-Cache::Cache(Memory *m, const MachineConfigCache *cc) : cnf(cc) {
+Cache::Cache(Memory *m, const MachineConfigCache *cc, unsigned memory_access_penalty_r, unsigned memory_access_penalty_w) : cnf(cc) {
mem = m;
+ access_pen_r = memory_access_penalty_r;
+ access_pen_w = memory_access_penalty_w;
// Zero hit and miss rate
- hitc = 0;
- missc = 0;
+ hit_read = 0;
+ hit_write = 0;
+ miss_read = 0;
+ miss_write = 0;
// Skip any other initialization if cache is disabled
if (!cc->enabled())
return;
@@ -73,11 +77,31 @@ void Cache::sync() {
}
unsigned Cache::hit() const {
- return hitc;
+ return hit_read + hit_write;
}
unsigned Cache::miss() const {
- return missc;
+ return miss_read + miss_write;
+}
+
+unsigned Cache::stalled_cycles() const {
+ return miss_read * (access_pen_r - 1) + miss_write * (access_pen_w - 1);
+}
+
+double Cache::speed_improvement() const {
+ unsigned comp = hit_read + hit_write + miss_read + miss_write;
+ if (comp == 0)
+ return 100.0;
+ return (double)((miss_read + hit_read) * access_pen_r + (miss_write + hit_write) * access_pen_w) \
+ / (double)(hit_write + hit_read + miss_read * access_pen_r + miss_write * access_pen_w) \
+ * 100;
+}
+
+double Cache::usage_efficiency() const {
+ unsigned comp = hit_read + hit_write + miss_read + miss_write;
+ if (comp == 0)
+ return 0.0;
+ return (double)(hit_read + hit_write) / (double)comp * 100.0;
}
void Cache::reset() {
@@ -90,11 +114,14 @@ void Cache::reset() {
dt[as][st].valid = false;
// Note: we don't have to zero replacement policy data as those are zeroed when first used on invalid cell
// Zero hit and miss rate
- hitc = 0;
- missc = 0;
+ hit_read = 0;
+ hit_write = 0;
+ miss_read = 0;
+ miss_write = 0;
// Trigger signals
- emit hit_update(hitc);
- emit miss_update(missc);
+ emit hit_update(hit());
+ emit miss_update(miss());
+ update_statistics();
for (unsigned as = 0; as < cnf.associativity(); as++)
for (unsigned st = 0; st < cnf.sets(); st++)
emit cache_update(as, st, false, false, 0, 0);
@@ -157,11 +184,19 @@ void Cache::access(std::uint32_t address, std::uint32_t *data, bool write, std::
// Update statistics and otherwise read from memory
if (cd.valid) {
- hitc++;
- emit hit_update(hitc);
+ if (write)
+ hit_write++;
+ else
+ hit_read++;
+ emit hit_update(hit());
+ update_statistics();
} else {
- missc++;
- emit miss_update(missc);
+ if (write)
+ miss_write++;
+ else
+ miss_read++;
+ emit miss_update(miss());
+ update_statistics();
for (unsigned i = 0; i < cnf.blocks(); i++)
cd.data[i] = mem->rword(base_address(tag, row) + (4*i));
}
@@ -209,3 +244,7 @@ void Cache::kick(unsigned associat_indx, unsigned row) const {
std::uint32_t Cache::base_address(std::uint32_t tag, unsigned row) const {
return ((tag * cnf.blocks() * cnf.sets()) + (row * cnf.blocks())) << 2;
}
+
+void Cache::update_statistics() const {
+ emit statistics_update(stalled_cycles(), speed_improvement(), usage_efficiency());
+}