Make cache view zoomable
MODIFY
src/cacheconfigwidget.cpp
src/cacheconfigwidget.cpp
@@ -37,6 +37,16 @@ void CacheConfigWidget::setCache(CacheSim* cache) {
m_ui->replacementPolicy->setCurrentIndex(0);
updateIndexingText();
+
+ // For testing purposes only
+ connect(m_ui->randomread, &QPushButton::clicked, [=] {
+ unsigned address = std::rand() % 128;
+ m_cache->read(address);
+ });
+ connect(m_ui->randomwrite, &QPushButton::clicked, [=] {
+ unsigned address = std::rand() % 128;
+ m_cache->write(address);
+ });
}
void CacheConfigWidget::setupPresets() {

MODIFY
src/cacheconfigwidget.ui
src/cacheconfigwidget.ui
<string>Statistics:</string>
</property>
<layout class="QGridLayout" name="gridLayout_5">
+ <item row="1" column="0">
+ <widget class="QPushButton" name="randomread">
+ <property name="text">
+ <string>Random read</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="0">
+ <spacer name="verticalSpacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
<item row="0" column="0">
<layout class="QGridLayout" name="gridLayout_4">
<item row="1" column="2">
</item>
</layout>
</item>
- <item row="1" column="0">
- <spacer name="verticalSpacer">
- <property name="orientation">
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>20</width>
- <height>40</height>
- </size>
- </property>
- </spacer>
- </item>
- </layout>
- </widget>
- </item>
- <item>
- <widget class="QGroupBox" name="groupBox_3">
- <property name="title">
- <string>View settings:</string>
- </property>
- <layout class="QGridLayout" name="gridLayout_7">
- <item row="0" column="0">
- <layout class="QGridLayout" name="gridLayout_6">
- <item row="0" column="0">
- <widget class="QCheckBox" name="checkBox_3">
+ <item row="2" column="0">
+ <widget class="QPushButton" name="randomwrite">
<property name="text">
- <string>Follow accesses</string>
+ <string>Random write</string>
</property>
</widget>
</item>
</layout>
- </item>
- <item row="1" column="0">
- <spacer name="verticalSpacer_2">
- <property name="orientation">
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>20</width>
- <height>40</height>
- </size>
- </property>
- </spacer>
- </item>
- </layout>
</widget>
</item>
</layout>

MODIFY
src/cachegraphic.cpp
src/cachegraphic.cpp
@@ -165,9 +165,13 @@ void CacheGraphic::initializeControlBits() {
}
}
-void CacheGraphic::cacheParametersChanged() {
- prepareGeometryChange();
+QRectF CacheGraphic::boundingRect() const {
+ // We do not paint anything in Cachegraphic; only instantiate other QGraphicsItem-derived objects. So just return
+ // the bounding rect of child items
+ return childrenBoundingRect();
+}
+void CacheGraphic::cacheParametersChanged() {
// Remove all items
m_highlightingItems.clear();
m_cacheTextItems.clear();

MODIFY
src/cachegraphic.h
src/cachegraphic.h
@@ -12,7 +12,7 @@ class CacheGraphic : public QGraphicsObject {
public:
CacheGraphic(CacheSim& cache);
- QRectF boundingRect() const override {}
+ QRectF boundingRect() const override;
void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget = nullptr) override {}

MODIFY
src/cachesim.cpp
src/cachesim.cpp
namespace Ripes {
+CacheSim::CacheSim(QObject* parent) : QObject(parent) {
+ updateConfiguration();
+}
+
void CacheSim::updateCacheLineLRU(CacheLine& line, unsigned lruIdx) {
// Find previous LRU value for the updated index
const unsigned preLRU = line[lruIdx].lru;

MODIFY
src/cachesim.h
src/cachesim.h
@@ -26,7 +26,7 @@ struct CachePreset {
class CacheSim : public QObject {
Q_OBJECT
public:
- CacheSim(QObject* parent) : QObject(parent) {}
+ CacheSim(QObject* parent);
void setReplacementPolicy(CacheReplPlcy policy) {
m_policy = policy;

ADD
src/cacheview.cpp
+#include "cacheview.h"
+
+#include <qmath.h>
+#include <QWheelEvent>
+
+namespace Ripes {
+
+CacheView::CacheView(QWidget* parent) : QGraphicsView(parent) {
+ m_zoom = 250;
+
+ setDragMode(QGraphicsView::RubberBandDrag);
+ setTransformationAnchor(QGraphicsView::AnchorUnderMouse);
+ setRenderHint(QPainter::Antialiasing, false);
+ setInteractive(true);
+ setupMatrix();
+}
+
+void CacheView::wheelEvent(QWheelEvent* e) {
+ if (e->modifiers() & Qt::ControlModifier) {
+ if (e->delta() > 0)
+ zoomIn(6);
+ else
+ zoomOut(6);
+ e->accept();
+ } else {
+ QGraphicsView::wheelEvent(e);
+ }
+}
+
+void CacheView::zoomIn(int level) {
+ m_zoom += level;
+ setupMatrix();
+}
+
+void CacheView::zoomOut(int level) {
+ m_zoom -= level;
+ setupMatrix();
+}
+
+void CacheView::setupMatrix() {
+ qreal scale = qPow(qreal(2), (m_zoom - 250) / qreal(50));
+
+ QMatrix matrix;
+ matrix.scale(scale, scale);
+
+ setMatrix(matrix);
+}
+
+} // namespace Ripes

ADD
src/cacheview.h
+#pragma once
+
+#include <QGraphicsView>
+
+namespace Ripes {
+
+class CacheView : public QGraphicsView {
+public:
+ CacheView(QWidget* parent);
+
+protected:
+ void wheelEvent(QWheelEvent*) override;
+
+private slots:
+ void setupMatrix();
+ void zoomIn(int level = 1);
+ void zoomOut(int level = 1);
+
+private:
+ qreal m_zoom;
+};
+
+} // namespace Ripes

ADD
src/cachewidget.cpp
+#include "cachewidget.h"
+#include "ui_cachewidget.h"
+
+#include <QGraphicsScene>
+#include <QGraphicsView>
+
+#include "cachegraphic.h"
+#include "cachesim.h"
+
+namespace Ripes {
+
+CacheWidget::CacheWidget(QWidget* parent) : QWidget(parent), m_ui(new Ui::CacheWidget) {
+ m_ui->setupUi(this);
+
+ auto* scene = new QGraphicsScene(this);
+ auto* cacheSim = new CacheSim(this);
+ m_ui->cacheConfig->setCache(cacheSim);
+
+ connect(cacheSim, &CacheSim::hitRateChanged, m_ui->cacheConfig, &CacheConfigWidget::setHitRate);
+ auto* cacheGraphic = new CacheGraphic(*cacheSim);
+ m_ui->cacheView->setScene(scene);
+ scene->addItem(cacheGraphic);
+}
+
+CacheWidget::~CacheWidget() {
+ delete m_ui;
+}
+
+} // namespace Ripes

ADD
src/cachewidget.h
+#pragma once
+
+#include <QWidget>
+
+namespace Ripes {
+
+namespace Ui {
+class CacheWidget;
+}
+
+class CacheWidget : public QWidget {
+ Q_OBJECT
+
+public:
+ explicit CacheWidget(QWidget* parent = nullptr);
+ ~CacheWidget();
+
+private:
+ Ui::CacheWidget* m_ui;
+};
+
+} // namespace Ripes

ADD
src/cachewidget.ui
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>Ripes::CacheWidget</class>
+ <widget class="QWidget" name="Ripes::CacheWidget">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>400</width>
+ <height>300</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Form</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="0" column="0">
+ <layout class="QVBoxLayout" name="verticalLayout" stretch="0,1">
+ <item>
+ <widget class="CacheConfigWidget" name="cacheConfig" native="true"/>
+ </item>
+ <item>
+ <widget class="CacheView" name="cacheView"/>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>CacheConfigWidget</class>
+ <extends>QWidget</extends>
+ <header>cacheconfigwidget.h</header>
+ <container>1</container>
+ </customwidget>
+ <customwidget>
+ <class>CacheView</class>
+ <extends>QGraphicsView</extends>
+ <header>cacheview.h</header>
+ </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections/>
+</ui>

MODIFY
src/memorytab.cpp
src/memorytab.cpp
#include "memorytab.h"
#include "ui_memorytab.h"
-#include "cachesim.h"
-#include "cachegraphic.h"
-
#include <QGraphicsItem>
-#include <QGraphicsScene>
-#include <QGraphicsView>
#include <QToolBar>
#include <QTimer>
@@ -19,15 +14,7 @@ MemoryTab::MemoryTab(QToolBar* toolbar, QWidget* parent) : RipesTab(toolbar, par
m_ui->memoryViewerWidget->updateModel();
m_ui->memoryViewerWidget->updateView();
- auto* scene = new QGraphicsScene(this);
- auto* cacheSim = new CacheSim(this);
- m_ui->cacheConfig->setCache(cacheSim);
-
- connect(cacheSim, &CacheSim::hitRateChanged, m_ui->cacheConfig, &CacheConfigWidget::setHitRate);
- auto* cacheGraphic = new CacheGraphic(*cacheSim);
- m_ui->cacheView->setScene(scene);
- scene->addItem(cacheGraphic);
-
+ /*
auto* accessTimer = new QTimer(this);
accessTimer->setInterval(100);
connect(accessTimer, &QTimer::timeout, [=] {
@@ -40,6 +27,7 @@ MemoryTab::MemoryTab(QToolBar* toolbar, QWidget* parent) : RipesTab(toolbar, par
});
accessTimer->start();
+ */
}
void MemoryTab::update() {

MODIFY
src/memorytab.ui
src/memorytab.ui
<property name="windowTitle">
<string>Form</string>
</property>
- <layout class="QGridLayout" name="gridLayout">
+ <layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<widget class="QSplitter" name="splitter">
<property name="orientation">
</sizepolicy>
</property>
</widget>
- <widget class="QWidget" name="">
- <layout class="QVBoxLayout" name="verticalLayout" stretch="0,1">
- <item>
- <widget class="CacheConfigWidget" name="cacheConfig" native="true"/>
+ <widget class="QTabWidget" name="tabWidget">
+ <property name="currentIndex">
+ <number>1</number>
+ </property>
+ <widget class="QWidget" name="tab_3">
+ <attribute name="title">
+ <string>Data cache</string>
+ </attribute>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="0" column="0">
+ <widget class="CacheWidget" name="dataCache" native="true"/>
</item>
- <item>
- <widget class="QGraphicsView" name="cacheView"/>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="tab_4">
+ <attribute name="title">
+ <string>Instruction cache</string>
+ </attribute>
+ <layout class="QGridLayout" name="gridLayout_3">
+ <item row="0" column="0">
+ <widget class="CacheWidget" name="instructionCache" native="true"/>
</item>
</layout>
</widget>
</widget>
+ </widget>
</item>
</layout>
</widget>
<container>1</container>
</customwidget>
<customwidget>
- <class>CacheConfigWidget</class>
+ <class>CacheWidget</class>
<extends>QWidget</extends>
- <header>cacheconfigwidget.h</header>
+ <header>cachewidget.h</header>
<container>1</container>
</customwidget>
</customwidgets>

Make cache view zoomable