From 48c0b3ffcaef15aeac7b239e769bcc795b943bec Mon Sep 17 00:00:00 2001 From: Pavel Pisa Date: Thu, 7 Feb 2019 19:20:52 +0100 Subject: Implemented simple indication of presence of memory location in the cache. Signed-off-by: Pavel Pisa --- qtmips_gui/memorydock.cpp | 15 +++++++++++++-- qtmips_gui/memoryview.cpp | 13 ++++++++++++- qtmips_gui/memoryview.h | 2 ++ qtmips_machine/cache.cpp | 20 +++++++++++++++----- qtmips_machine/cache.h | 7 ++++++- qtmips_machine/memory.cpp | 2 +- qtmips_machine/memory.h | 2 +- qtmips_machine/physaddrspace.cpp | 2 +- qtmips_machine/physaddrspace.h | 2 +- 9 files changed, 52 insertions(+), 13 deletions(-) diff --git a/qtmips_gui/memorydock.cpp b/qtmips_gui/memorydock.cpp index 7feae4e..86f8f26 100644 --- a/qtmips_gui/memorydock.cpp +++ b/qtmips_gui/memorydock.cpp @@ -54,8 +54,19 @@ QList DataView::row_widget(std::uint32_t address, QWidget *parent) { l = new QLabel(parent); l->setTextInteractionFlags(Qt::TextSelectableByMouse); l->setFont(f); - if (memory != nullptr) - l->setText(QString("0x") + QString("%1").arg(memory->read_word(address), 8, 16, QChar('0')).toUpper()); + if (memory != nullptr) { + machine::LocationStatus loc_stat = machine::LOCSTAT_NONE; + QString val; + val = QString("0x") + QString("%1").arg(memory->read_word(address), 8, 16, QChar('0')).toUpper(); + if (cache_data != nullptr) { + loc_stat = cache_data->location_status(address); + if (loc_stat & machine::LOCSTAT_DIRTY) + val += " D"; + else if (loc_stat & machine::LOCSTAT_CACHED) + val += " C"; + } + l->setText(val); + } widgs.append(l); return widgs; diff --git a/qtmips_gui/memoryview.cpp b/qtmips_gui/memoryview.cpp index 0457633..c4d022a 100644 --- a/qtmips_gui/memoryview.cpp +++ b/qtmips_gui/memoryview.cpp @@ -48,6 +48,7 @@ MemoryView::MemoryView(QWidget *parent, std::uint32_t addr0) : QWidget(parent) { memory = nullptr; addr_0 = addr0; change_counter = 0; + cache_data_change_counter = 0; layout = new QVBoxLayout(this); @@ -67,6 +68,7 @@ MemoryView::MemoryView(QWidget *parent, std::uint32_t addr0) : QWidget(parent) { void MemoryView::setup(machine::QtMipsMachine *machine) { memory = (machine == nullptr) ? nullptr : machine->memory(); + cache_data = (machine == nullptr) ? nullptr : machine->cache_data(); if (machine != nullptr) connect(machine, SIGNAL(post_tick()), this, SLOT(check_for_updates())); reload_content(); @@ -97,10 +99,17 @@ void MemoryView::edit_load_focus() { } void MemoryView::check_for_updates() { + bool need_update = false; if (memory != nullptr) { if (change_counter != memory->get_change_counter()) - reload_content(); + need_update = true; } + if (cache_data != nullptr) { + if (cache_data_change_counter != cache_data->get_change_counter()) + need_update = true; + } + if (need_update) + reload_content(); } void MemoryView::reload_content() { @@ -108,6 +117,8 @@ void MemoryView::reload_content() { memf->widg->clearRows(); if (memory != nullptr) change_counter = memory->get_change_counter(); + if (cache_data != nullptr) + cache_data_change_counter = cache_data->get_change_counter(); update_content(count, 0); } diff --git a/qtmips_gui/memoryview.h b/qtmips_gui/memoryview.h index 17af34f..f60ac53 100644 --- a/qtmips_gui/memoryview.h +++ b/qtmips_gui/memoryview.h @@ -67,6 +67,7 @@ public slots: protected: const machine::Memory *memory; + const machine::Cache *cache_data; virtual QList row_widget(std::uint32_t address, QWidget *parent) = 0; @@ -82,6 +83,7 @@ private slots: private: std::uint32_t change_counter; + std::uint32_t cache_data_change_counter; unsigned count; std::uint32_t addr_0; // First address in view 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; } diff --git a/qtmips_machine/cache.h b/qtmips_machine/cache.h index 4d8cb6d..6027bd3 100644 --- a/qtmips_machine/cache.h +++ b/qtmips_machine/cache.h @@ -64,7 +64,11 @@ public: void reset(); // Reset whole state of cache const MachineConfigCache &config() const; - enum LocationStatus location_status(std::uint32_t address); + enum LocationStatus location_status(std::uint32_t address) const; + + inline std::uint32_t get_change_counter() const { + return *p_change_counter; + } signals: void hit_update(unsigned) const; void miss_update(unsigned) const; @@ -72,6 +76,7 @@ signals: void cache_update(unsigned associat, unsigned set, bool valid, bool dirty, std::uint32_t tag, const std::uint32_t *data) const; private: + std::uint32_t* p_change_counter; MachineConfigCache cnf; MemoryAccess *mem; unsigned access_pen_r, access_pen_w; diff --git a/qtmips_machine/memory.cpp b/qtmips_machine/memory.cpp index e1d65c4..79ac949 100644 --- a/qtmips_machine/memory.cpp +++ b/qtmips_machine/memory.cpp @@ -122,7 +122,7 @@ std::uint32_t MemoryAccess::read_ctl(enum AccessControl ctl, std::uint32_t offse void MemoryAccess::sync() { } -enum LocationStatus MemoryAccess::location_status(std::uint32_t address) { +enum LocationStatus MemoryAccess::location_status(std::uint32_t address) const { return LOCSTAT_NONE; } diff --git a/qtmips_machine/memory.h b/qtmips_machine/memory.h index 8c8a319..33caf46 100644 --- a/qtmips_machine/memory.h +++ b/qtmips_machine/memory.h @@ -60,7 +60,7 @@ public: std::uint32_t read_ctl(enum AccessControl ctl, std::uint32_t offset) const; virtual void sync(); - virtual enum LocationStatus location_status(std::uint32_t offset); + virtual enum LocationStatus location_status(std::uint32_t offset) const; protected: virtual bool wword(std::uint32_t offset, std::uint32_t value) = 0; diff --git a/qtmips_machine/physaddrspace.cpp b/qtmips_machine/physaddrspace.cpp index 9053e48..bb01b60 100644 --- a/qtmips_machine/physaddrspace.cpp +++ b/qtmips_machine/physaddrspace.cpp @@ -66,7 +66,7 @@ std::uint32_t PhysAddrSpace::rword(std::uint32_t address) const { return p_range->mem_acces->read_word(address - p_range->start_addr); } -enum LocationStatus PhysAddrSpace::location_status(std::uint32_t address) { +enum LocationStatus PhysAddrSpace::location_status(std::uint32_t address) const { const RangeDesc *p_range = find_range(address); if (p_range == nullptr) return LOCSTAT_ILLEGAL; diff --git a/qtmips_machine/physaddrspace.h b/qtmips_machine/physaddrspace.h index 6d9f91c..c6f5e81 100644 --- a/qtmips_machine/physaddrspace.h +++ b/qtmips_machine/physaddrspace.h @@ -57,7 +57,7 @@ public: bool insert_range(MemoryAccess *mem_acces, std::uint32_t start_addr, std::uint32_t last_addr, bool move_ownership); bool remove_range(MemoryAccess *mem_acces); void clean_range(std::uint32_t start_addr, std::uint32_t last_addr); - enum LocationStatus location_status(std::uint32_t offset); + enum LocationStatus location_status(std::uint32_t offset) const; private: class RangeDesc { public: -- cgit v1.2.3