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.cpp30
1 files changed, 26 insertions, 4 deletions
diff --git a/qtmips_machine/cache.cpp b/qtmips_machine/cache.cpp
index c1e4e7b..ad85c8a 100644
--- a/qtmips_machine/cache.cpp
+++ b/qtmips_machine/cache.cpp
@@ -37,10 +37,12 @@
using namespace machine;
-Cache::Cache(MemoryAccess *m, const MachineConfigCache *cc, unsigned memory_access_penalty_r, unsigned memory_access_penalty_w) : cnf(cc) {
+Cache::Cache(MemoryAccess *m, const MachineConfigCache *cc, unsigned memory_access_penalty_r,
+ unsigned memory_access_penalty_w, unsigned memory_access_penalty_b) : cnf(cc) {
mem = m;
access_pen_r = memory_access_penalty_r;
access_pen_w = memory_access_penalty_w;
+ access_pen_b = memory_access_penalty_b;
uncached_start = 0xf0000000;
uncached_last = 0xffffffff;
// Zero hit and miss rate
@@ -50,6 +52,8 @@ Cache::Cache(MemoryAccess *m, const MachineConfigCache *cc, unsigned memory_acc
miss_write = 0;
mem_reads = 0;
mem_writes = 0;
+ burst_reads = 0;
+ burst_writes = 0;
dt = nullptr;
replc.lfu = nullptr;
replc.lru = nullptr;
@@ -132,6 +136,7 @@ bool Cache::wword(std::uint32_t address, std::uint32_t value) {
(address >= uncached_start && address <= uncached_last)) {
mem_writes++;
emit memory_writes_update(mem_writes);
+ update_statistics();
return mem->write_word(address, value);
}
@@ -141,6 +146,7 @@ bool Cache::wword(std::uint32_t address, std::uint32_t value) {
if (cnf.write_policy() != MachineConfigCache::WP_BACK) {
mem_writes++;
emit memory_writes_update(mem_writes);
+ update_statistics();
return mem->write_word(address, value);
}
return changed;
@@ -151,6 +157,7 @@ std::uint32_t Cache::rword(std::uint32_t address, bool debug_access) const {
(address >= uncached_start && address <= uncached_last)) {
mem_reads++;
emit memory_reads_update(mem_reads);
+ update_statistics();
return mem->read_word(address, debug_access);
}
@@ -172,6 +179,7 @@ void Cache::flush() {
for (unsigned st = 0; st < cnf.sets(); st++)
if (dt[as][st].valid)
kick(as, st);
+ update_statistics();
}
void Cache::sync() {
@@ -195,19 +203,28 @@ unsigned Cache::memory_writes() const {
}
unsigned Cache::stalled_cycles() const {
- return miss_read * (access_pen_r - 1) + miss_write * (access_pen_w - 1);
+ unsigned st_cycles = mem_reads * (access_pen_r - 1) + mem_writes * (access_pen_w - 1);
+ if (access_pen_b != 0)
+ st_cycles -= burst_reads * (access_pen_r - access_pen_b) +
+ burst_writes * (access_pen_w - access_pen_b);
+ return st_cycles;
}
double Cache::speed_improvement() const {
unsigned lookup_time;
+ unsigned mem_access_time;
unsigned comp = hit_read + hit_write + miss_read + miss_write;
if (comp == 0)
return 100.0;
lookup_time = hit_read + miss_read;
if (cnf.write_policy() == MachineConfigCache::WP_BACK)
lookup_time += hit_write + miss_write;
+ mem_access_time = mem_reads * access_pen_r + mem_writes * access_pen_w;
+ if (access_pen_b != 0)
+ mem_access_time -= burst_reads * (access_pen_r - access_pen_b) +
+ burst_writes * (access_pen_w - access_pen_b);
return (double)((miss_read + hit_read) * access_pen_r + (miss_write + hit_write) * access_pen_w) \
- / (double)(lookup_time + mem_reads * access_pen_r + mem_writes * access_pen_w) \
+ / (double)(lookup_time + mem_access_time) \
* 100;
}
@@ -233,6 +250,8 @@ void Cache::reset() {
miss_write = 0;
mem_reads = 0;
mem_writes = 0;
+ burst_reads = 0;
+ burst_writes = 0;
// Trigger signals
emit hit_update(hit());
emit miss_update(miss());
@@ -292,6 +311,7 @@ bool Cache::access(std::uint32_t address, std::uint32_t *data, bool write, std::
if (write && cnf.write_policy() == MachineConfigCache::WP_TROUGH_NOALLOC) {
miss_write++;
emit miss_update(miss());
+ update_statistics();
return false;
}
// We have to kick something
@@ -346,13 +366,14 @@ bool Cache::access(std::uint32_t address, std::uint32_t *data, bool write, std::
else
miss_read++;
emit miss_update(miss());
- update_statistics();
for (unsigned i = 0; i < cnf.blocks(); i++) {
cd.data[i] = mem->read_word(base_address(tag, row) + (4*i));
change_counter++;
}
mem_reads += cnf.blocks();
+ burst_reads += cnf.blocks() - 1;
emit memory_reads_update(mem_reads);
+ update_statistics();
}
// Update replcement data
@@ -403,6 +424,7 @@ void Cache::kick(unsigned associat_indx, unsigned row) const {
for (unsigned i = 0; i < cnf.blocks(); i++)
mem->write_word(base_address(cd.tag, row) + (4*i), cd.data[i]);
mem_writes += cnf.blocks();
+ burst_writes += cnf.blocks() - 1;
emit memory_writes_update(mem_writes);
}
cd.valid = false;