diff options
Diffstat (limited to 'qtmips_machine')
| -rw-r--r-- | qtmips_machine/cache.cpp | 19 | ||||
| -rw-r--r-- | qtmips_machine/cache.h | 4 | ||||
| -rw-r--r-- | qtmips_machine/memory.cpp | 26 | ||||
| -rw-r--r-- | qtmips_machine/memory.h | 18 | ||||
| -rw-r--r-- | qtmips_machine/qtmipsmachine.cpp | 1 | ||||
| -rw-r--r-- | qtmips_machine/qtmipsmachine.h | 1 | 
6 files changed, 45 insertions, 24 deletions
diff --git a/qtmips_machine/cache.cpp b/qtmips_machine/cache.cpp index acc48b1..9f4bfb0 100644 --- a/qtmips_machine/cache.cpp +++ b/qtmips_machine/cache.cpp @@ -40,17 +40,18 @@ Cache::Cache(Memory *m, const MachineConfigCache *cc, unsigned memory_access_pen      }  } -void Cache::wword(std::uint32_t address, std::uint32_t value) { +bool Cache::wword(std::uint32_t address, std::uint32_t value) { +    bool changed;      if (!cnf.enabled()) { -        mem->write_word(address, value); -        return; +        return mem->write_word(address, value);      }      std::uint32_t data; -    access(address, &data, true, value); +    changed = access(address, &data, true, value);      if (cnf.write_policy() == MachineConfigCache::WP_TROUGH) -        mem->wword(address, value); +        return mem->wword(address, value); +    return changed;  }  std::uint32_t Cache::rword(std::uint32_t address) const { @@ -131,7 +132,8 @@ const MachineConfigCache &Cache::config() const {      return cnf;  } -void Cache::access(std::uint32_t address, std::uint32_t *data, bool write, std::uint32_t value) const { +bool Cache::access(std::uint32_t address, std::uint32_t *data, bool write, std::uint32_t value) const { +    bool changed = false;      address = address >> 2;      unsigned ssize = cnf.blocks() * cnf.sets();      std::uint32_t tag = address / ssize; @@ -218,10 +220,13 @@ void Cache::access(std::uint32_t address, std::uint32_t *data, bool write, std::      cd.tag = tag;      *data = cd.data[col]; -    if (write) +    if (write) { +        changed = cd.data[col] != value;          cd.data[col] = value; +    }      emit cache_update(indx, row, cd.valid, cd.dirty, cd.tag, cd.data); +    return changed;  }  void Cache::kick(unsigned associat_indx, unsigned row) const { diff --git a/qtmips_machine/cache.h b/qtmips_machine/cache.h index 6cf3a2c..1c356c7 100644 --- a/qtmips_machine/cache.h +++ b/qtmips_machine/cache.h @@ -13,7 +13,7 @@ class Cache : public MemoryAccess {  public:      Cache(Memory *m, const MachineConfigCache *c, unsigned memory_access_penalty_r = 1, unsigned memory_access_penalty_w = 1); -    void wword(std::uint32_t address, std::uint32_t value); +    bool wword(std::uint32_t address, std::uint32_t value);      std::uint32_t rword(std::uint32_t address) const;      void flush(); // flush cache @@ -54,7 +54,7 @@ private:      mutable unsigned hit_read, miss_read, hit_write, miss_write; // Hit and miss counters -    void access(std::uint32_t address, std::uint32_t *data, bool write, std::uint32_t value = 0) const; +    bool access(std::uint32_t address, std::uint32_t *data, bool write, std::uint32_t value = 0) const;      void kick(unsigned associat_indx, unsigned row) const;      std::uint32_t base_address(std::uint32_t tag, unsigned row) const;      void update_statistics() const; diff --git a/qtmips_machine/memory.cpp b/qtmips_machine/memory.cpp index 3b47ca7..77f2909 100644 --- a/qtmips_machine/memory.cpp +++ b/qtmips_machine/memory.cpp @@ -10,20 +10,20 @@ using namespace machine;  #define SH_NTH_16(OFFSET) (((OFFSET) & 0b10) * 16)  #endif -void MemoryAccess::write_byte(std::uint32_t offset, std::uint8_t value) { +bool MemoryAccess::write_byte(std::uint32_t offset, std::uint8_t value) {      int nth = SH_NTH_8(offset);      std::uint32_t mask = 0xff << nth; // Mask for n-th byte -    wword(offset, (rword(offset) & ~mask) | (((std::uint32_t)value << nth) & mask)); +    return wword(offset, (rword(offset) & ~mask) | (((std::uint32_t)value << nth) & mask));  } -void MemoryAccess::write_hword(std::uint32_t offset, std::uint16_t value) { +bool MemoryAccess::write_hword(std::uint32_t offset, std::uint16_t value) {      int nth = SH_NTH_16(offset);      std::uint32_t mask = 0xffff << nth; // Mask for n-th half-word -    wword(offset, (rword(offset) & ~mask) | (((std::uint32_t)value << nth) & mask)); +    return wword(offset, (rword(offset) & ~mask) | (((std::uint32_t)value << nth) & mask));  } -void MemoryAccess::write_word(std::uint32_t offset, std::uint32_t value) { -    wword(offset, value); +bool MemoryAccess::write_word(std::uint32_t offset, std::uint32_t value) { +    return wword(offset, value);  }  std::uint8_t MemoryAccess::read_byte(std::uint32_t offset) const { @@ -101,11 +101,14 @@ MemorySection::~MemorySection() {      delete this->dt;  } -void MemorySection::wword(std::uint32_t offset, std::uint32_t value) { +bool MemorySection::wword(std::uint32_t offset, std::uint32_t value) { +    bool changed;      offset = offset >> 2;      if (offset >= this->len)          throw QTMIPS_EXCEPTION(OutOfMemoryAccess, "Trying to write outside of the memory section", QString("Accessing using offset: ") + QString(offset)); +    changed = this->dt[offset] != value;      this->dt[offset] = value; +    return changed;  }  std::uint32_t MemorySection::rword(std::uint32_t offset) const { @@ -206,9 +209,14 @@ MemorySection *Memory::get_section(std::uint32_t address, bool create) const {  #define SECTION_OFFSET_MASK(ADDR) (ADDR & GENMASK(MEMORY_SECTION_BITS, 2)) -void Memory::wword(std::uint32_t address, std::uint32_t value) { +bool Memory::wword(std::uint32_t address, std::uint32_t value) { +    bool changed;      MemorySection *section = this->get_section(address, true); -    section->write_word(SECTION_OFFSET_MASK(address), value); +    changed = section->write_word(SECTION_OFFSET_MASK(address), value); +    write_counter++; +    if (changed) +        change_counter++; +    return changed;  }  std::uint32_t Memory::rword(std::uint32_t address) const { diff --git a/qtmips_machine/memory.h b/qtmips_machine/memory.h index e4777b3..4b40243 100644 --- a/qtmips_machine/memory.h +++ b/qtmips_machine/memory.h @@ -12,9 +12,9 @@ class MemoryAccess : public QObject {      Q_OBJECT  public:      // Note: hword and word methods are throwing away lowest bits so unaligned access is ignored without error. -    void write_byte(std::uint32_t offset, std::uint8_t value); -    void write_hword(std::uint32_t offset, std::uint16_t value); -    void write_word(std::uint32_t offset, std::uint32_t value); +    bool write_byte(std::uint32_t offset, std::uint8_t value); +    bool write_hword(std::uint32_t offset, std::uint16_t value); +    bool write_word(std::uint32_t offset, std::uint32_t value);      std::uint8_t read_byte(std::uint32_t offset) const;      std::uint16_t read_hword(std::uint32_t offset) const; @@ -34,7 +34,7 @@ public:      virtual void sync();  protected: -    virtual void wword(std::uint32_t offset, std::uint32_t value) = 0; +    virtual bool wword(std::uint32_t offset, std::uint32_t value) = 0;      virtual std::uint32_t rword(std::uint32_t offset) const = 0;  private: @@ -47,7 +47,7 @@ public:      MemorySection(const MemorySection&);      ~MemorySection(); -    void wword(std::uint32_t offset, std::uint32_t value); +    bool wword(std::uint32_t offset, std::uint32_t value);      std::uint32_t rword(std::uint32_t offset) const;      void merge(MemorySection&); @@ -77,7 +77,7 @@ public:      void reset(const Memory&);      MemorySection *get_section(std::uint32_t address, bool create) const; // returns section containing given address -    void wword(std::uint32_t address, std::uint32_t value); +    bool wword(std::uint32_t address, std::uint32_t value);      std::uint32_t rword(std::uint32_t address) const;      bool operator==(const Memory&) const; @@ -85,8 +85,14 @@ public:      const union MemoryTree *get_memorytree_root() const; +    inline std::uint32_t get_change_counter() const { +        return change_counter; +    } +  private:      union MemoryTree *mt_root; +    std::uint32_t change_counter; +    std::uint32_t write_counter;      static union MemoryTree *allocate_section_tree();      static void free_section_tree(union MemoryTree*, size_t depth);      static bool compare_section_tree(const union MemoryTree*, const union MemoryTree*, size_t depth); diff --git a/qtmips_machine/qtmipsmachine.cpp b/qtmips_machine/qtmipsmachine.cpp index 75d8b8e..9f769c7 100644 --- a/qtmips_machine/qtmipsmachine.cpp +++ b/qtmips_machine/qtmipsmachine.cpp @@ -108,6 +108,7 @@ void QtMipsMachine::step() {          if (stat == ST_BUSY)              set_status(stat_prev);      } +    emit post_tick();  }  void QtMipsMachine::restart() { diff --git a/qtmips_machine/qtmipsmachine.h b/qtmips_machine/qtmipsmachine.h index 46405e5..b7f229d 100644 --- a/qtmips_machine/qtmipsmachine.h +++ b/qtmips_machine/qtmipsmachine.h @@ -50,6 +50,7 @@ signals:      void program_trap(machine::QtMipsException &e);      void status_change(enum machine::QtMipsMachine::Status st);      void tick(); // Time tick +    void post_tick(); // Emitted after tick to allow updates  private:      MachineConfig mcnf;  | 
