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.cpp20
1 files changed, 15 insertions, 5 deletions
diff --git a/qtmips_machine/cache.cpp b/qtmips_machine/cache.cpp
index 94e314b..e327d7b 100644
--- a/qtmips_machine/cache.cpp
+++ b/qtmips_machine/cache.cpp
@@ -51,6 +51,7 @@ Cache::Cache(MemoryAccess *m, const MachineConfigCache *cc, unsigned memory_acc
dt = nullptr;
replc.lfu = nullptr;
replc.lru = nullptr;
+ p_change_counter = new std::uint32_t(0);
// Skip any other initialization if cache is disabled
if (!cc->enabled())
@@ -89,6 +90,7 @@ Cache::Cache(MemoryAccess *m, const MachineConfigCache *cc, unsigned memory_acc
}
Cache::~Cache(){
+ delete p_change_counter;
if (dt != nullptr) {
for (unsigned i = 0; i < cnf.associativity(); i++) {
if (dt[i]) {
@@ -216,15 +218,17 @@ const MachineConfigCache &Cache::config() const {
return cnf;
}
-enum LocationStatus Cache::location_status(std::uint32_t address) {
+enum LocationStatus Cache::location_status(std::uint32_t address) const {
+ address = address >> 2;
unsigned ssize = cnf.blocks() * cnf.sets();
std::uint32_t tag = address / ssize;
std::uint32_t index = address % ssize;
std::uint32_t row = index / cnf.blocks();
for (unsigned indx = 0; indx < cnf.associativity(); indx++) {
- if (dt[indx][row].valid && dt[indx][row].tag != tag) {
- if (dt[indx][row].dirty)
+ if (dt[indx][row].valid && dt[indx][row].tag == tag) {
+ if (dt[indx][row].dirty &&
+ cnf.write_policy() == MachineConfigCache::WP_BACK)
return (enum LocationStatus)(LOCSTAT_CACHED | LOCSTAT_DIRTY);
else
return (enum LocationStatus)LOCSTAT_CACHED;
@@ -282,8 +286,10 @@ bool Cache::access(std::uint32_t address, std::uint32_t *data, bool write, std::
struct cache_data &cd = dt[indx][row];
// Verify if we are not replacing
- if (cd.valid && cd.tag != tag)
+ if (cd.valid && cd.tag != tag) {
kick(indx, row);
+ (*p_change_counter)++;
+ }
// Update statistics and otherwise read from memory
if (cd.valid) {
@@ -300,8 +306,10 @@ bool Cache::access(std::uint32_t address, std::uint32_t *data, bool write, std::
miss_read++;
emit miss_update(miss());
update_statistics();
- for (unsigned i = 0; i < cnf.blocks(); i++)
+ for (unsigned i = 0; i < cnf.blocks(); i++) {
cd.data[i] = mem->read_word(base_address(tag, row) + (4*i));
+ (*p_change_counter)++;
+ }
}
// Update replc
@@ -327,6 +335,8 @@ bool Cache::access(std::uint32_t address, std::uint32_t *data, bool write, std::
}
emit cache_update(indx, row, cd.valid, cd.dirty, cd.tag, cd.data);
+ if (changed)
+ (*p_change_counter)++;
return changed;
}