aboutsummaryrefslogtreecommitdiff
path: root/qtmips_gui
diff options
context:
space:
mode:
authorKarel Kočí <cynerd@email.cz>2018-04-17 12:44:44 +0200
committerKarel Kočí <cynerd@email.cz>2018-04-17 12:44:44 +0200
commit95956a7457a1237385a314212c4e106bed88f05d (patch)
tree0ab000468c9e281c0a59fc5991252a87e115d154 /qtmips_gui
parent6c360d8e42053d9045bbe2fc78c23143f8a334b7 (diff)
downloadqtmips-95956a7457a1237385a314212c4e106bed88f05d.tar.gz
qtmips-95956a7457a1237385a314212c4e106bed88f05d.tar.bz2
qtmips-95956a7457a1237385a314212c4e106bed88f05d.zip
Initial implementation of cache view
It needs some more work to look nice but it already works.
Diffstat (limited to 'qtmips_gui')
-rw-r--r--qtmips_gui/cachedock.cpp17
-rw-r--r--qtmips_gui/cachedock.h4
-rw-r--r--qtmips_gui/cacheview.cpp118
-rw-r--r--qtmips_gui/cacheview.h39
-rw-r--r--qtmips_gui/mainwindow.cpp4
-rw-r--r--qtmips_gui/qtmips_gui.pro2
6 files changed, 178 insertions, 6 deletions
diff --git a/qtmips_gui/cachedock.cpp b/qtmips_gui/cachedock.cpp
index eb96e06..79097b3 100644
--- a/qtmips_gui/cachedock.cpp
+++ b/qtmips_gui/cachedock.cpp
@@ -18,7 +18,10 @@ CacheDock::CacheDock(QWidget *parent, const QString &type) : QDockWidget(parent)
l_miss = new QLabel("0", top_form);
layout_top_form->addRow("Miss:", l_miss);
- // TODO cache view
+ graphicsview = new GraphicsView(top_widget);
+ graphicsview->setVisible(false);
+ layout_box->addWidget(graphicsview);
+ cachescene = nullptr;
setObjectName(type + "Cache");
setWindowTitle(type + " Cache");
@@ -27,12 +30,18 @@ CacheDock::CacheDock(QWidget *parent, const QString &type) : QDockWidget(parent)
void CacheDock::setup(const machine::Cache *cache) {
l_hit->setText("0");
l_miss->setText("0");
- if (cache) {
+ if (cache->config().enabled()) {
connect(cache, SIGNAL(hit_update(uint)), this, SLOT(hit_update(uint)));
connect(cache, SIGNAL(miss_update(uint)), this, SLOT(miss_update(uint)));
}
- top_form->setVisible((bool)cache);
- no_cache->setVisible(!(bool)cache);
+ top_form->setVisible(cache->config().enabled());
+ no_cache->setVisible(!cache->config().enabled());
+
+ if (cachescene)
+ delete cachescene;
+ cachescene = new CacheViewScene(cache);
+ graphicsview->setScene(cachescene);
+ graphicsview->setVisible(cache->config().enabled());
}
void CacheDock::hit_update(unsigned val) {
diff --git a/qtmips_gui/cachedock.h b/qtmips_gui/cachedock.h
index a13cd08..598a9c7 100644
--- a/qtmips_gui/cachedock.h
+++ b/qtmips_gui/cachedock.h
@@ -4,6 +4,8 @@
#include <QDockWidget>
#include <QLabel>
#include <QFormLayout>
+#include "cacheview.h"
+#include "graphicsview.h"
#include "qtmipsmachine.h"
class CacheDock : public QDockWidget {
@@ -22,6 +24,8 @@ private:
QWidget *top_widget, *top_form;
QFormLayout *layout_top_form;
QLabel *l_hit, *l_miss, *no_cache;
+ GraphicsView *graphicsview;
+ CacheViewScene *cachescene;
};
#endif // CACHEDOCK_H
diff --git a/qtmips_gui/cacheview.cpp b/qtmips_gui/cacheview.cpp
new file mode 100644
index 0000000..8582e63
--- /dev/null
+++ b/qtmips_gui/cacheview.cpp
@@ -0,0 +1,118 @@
+#include "cacheview.h"
+
+//////////////////////
+#define ROW_HEIGHT 14
+#define VD_WIDTH 10
+#define DATA_WIDTH 72
+#define PENW 1
+//////////////////////
+
+CacheViewBlock::CacheViewBlock(const machine::Cache *cache, unsigned block) : QGraphicsObject(nullptr) {
+ this->block = block;
+ rows = cache->config().sets();
+ columns = cache->config().blocks();
+
+ QFont font;
+ font.setPointSize(7);
+
+ validity = new QGraphicsSimpleTextItem*[rows];
+ if (cache->config().write_policy() == machine::MachineConfigCache::WP_BACK)
+ dirty = new QGraphicsSimpleTextItem*[rows];
+ else
+ dirty = nullptr;
+ tag = new QGraphicsSimpleTextItem*[rows];
+ data = new QGraphicsSimpleTextItem**[rows];
+ int row_y = 1;
+ for (unsigned i = 0; i < rows; i++) {
+ int row_x = 2;
+ validity[i] = new QGraphicsSimpleTextItem("0", this);
+ validity[i]->setPos(row_x, row_y);
+ validity[i]->setFont(font);
+ row_x += VD_WIDTH;
+ if (dirty) {
+ dirty[i] = new QGraphicsSimpleTextItem(this);
+ dirty[i]->setPos(row_x, row_y);
+ dirty[i]->setFont(font);
+ row_x += VD_WIDTH;
+ }
+ tag[i] = new QGraphicsSimpleTextItem(this);
+ tag[i]->setPos(row_x, row_y);
+ tag[i]->setFont(font);
+ row_x += DATA_WIDTH;
+
+ data[i] = new QGraphicsSimpleTextItem*[columns];
+ for (unsigned y = 0; y < columns; y++) {
+ data[i][y] = new QGraphicsSimpleTextItem(this);
+ data[i][y]->setPos(row_x, row_y);
+ data[i][y]->setFont(font);
+ row_x += DATA_WIDTH;
+ }
+
+ row_y += ROW_HEIGHT;
+ }
+
+ connect(cache, SIGNAL(cache_update(uint,uint,bool,bool,std::uint32_t,const std::uint32_t*)), this, SLOT(cache_update(uint,uint,bool,bool,std::uint32_t,const std::uint32_t*)));
+}
+
+CacheViewBlock::~CacheViewBlock() {
+ delete validity;
+ delete dirty;
+ delete tag;
+ for (unsigned y = 0; y < rows; y++)
+ delete data[y];
+ delete data;
+}
+
+QRectF CacheViewBlock::boundingRect() const {
+ return QRectF(
+ -PENW / 2,
+ -PENW / 2,
+ VD_WIDTH + (dirty ? VD_WIDTH : 0) + DATA_WIDTH*(columns+1) + PENW,
+ ROW_HEIGHT*rows + PENW
+ );
+}
+
+void CacheViewBlock::paint(QPainter *painter, const QStyleOptionGraphicsItem *option __attribute__((unused)), QWidget *widget __attribute__((unused))) {
+ // Draw horizontal lines
+ for (unsigned i = 0; i <= rows; i++)
+ painter->drawLine(0, i * ROW_HEIGHT, VD_WIDTH + (dirty ? VD_WIDTH : 0) + DATA_WIDTH*(columns + 1), i * ROW_HEIGHT);
+ // Draw vertical lines
+ painter->drawLine(0, 0, 0, rows*ROW_HEIGHT);
+ int c_width = VD_WIDTH;
+ painter->drawLine(c_width, 0, c_width, rows*ROW_HEIGHT);
+ if (dirty) {
+ c_width += VD_WIDTH;
+ painter->drawLine(c_width, 0, c_width, rows*ROW_HEIGHT);
+ }
+ c_width += DATA_WIDTH;
+ painter->drawLine(c_width, 0, c_width, rows*ROW_HEIGHT);
+ for (unsigned i = 0; i <= columns; i++) {
+ c_width += DATA_WIDTH;
+ painter->drawLine(c_width, 0, c_width, rows*ROW_HEIGHT);
+ }
+}
+
+void CacheViewBlock::cache_update(unsigned associat, unsigned set, bool valid, bool dirty, std::uint32_t tag, const std::uint32_t *data) {
+ if (associat != block)
+ return; // Ignore blocks that are not us
+ validity[set]->setText(valid ? "1" : "0");
+ if (this->dirty)
+ this->dirty[set]->setText(valid ? (dirty ? "1" : "0") : "");
+ // TODO calculate correct size of tag
+ this->tag[set]->setText(valid ? QString("0x") + QString("%1").arg(tag, 8, 16, QChar('0')).toUpper() : "");
+ for (unsigned i = 0; i < columns; i++)
+ this->data[set][i]->setText(valid ? QString("0x") + QString("%1").arg(data[i], 8, 16, QChar('0')).toUpper() : "");
+}
+
+
+CacheViewScene::CacheViewScene(const machine::Cache *cache) {
+ associativity = cache->config().associativity();
+ block = new CacheViewBlock*[associativity];
+ int offset = 0;
+ for (unsigned i = 0; i < associativity; i++) {
+ block[i] = new CacheViewBlock(cache, i);
+ addItem(block[i]);
+ block[i]->setPos(1, offset);
+ offset += block[i]->boundingRect().height() + 3;
+ }
+}
diff --git a/qtmips_gui/cacheview.h b/qtmips_gui/cacheview.h
new file mode 100644
index 0000000..1fb224f
--- /dev/null
+++ b/qtmips_gui/cacheview.h
@@ -0,0 +1,39 @@
+#ifndef CACHEVIEW_H
+#define CACHEVIEW_H
+
+#include <QGraphicsView>
+#include <QGraphicsScene>
+#include <QGraphicsObject>
+#include "graphicsview.h"
+#include "qtmipsmachine.h"
+
+class CacheViewBlock : public QGraphicsObject {
+ Q_OBJECT
+public:
+ CacheViewBlock(const machine::Cache *cache, unsigned block);
+ ~CacheViewBlock();
+
+ QRectF boundingRect() const;
+
+ void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
+
+private slots:
+ void cache_update(unsigned associat, unsigned set, bool valid, bool dirty, std::uint32_t tag, const std::uint32_t *data);
+
+private:
+ unsigned block;
+ unsigned rows, columns;
+ QGraphicsSimpleTextItem **validity, **dirty, **tag, ***data;
+};
+
+class CacheViewScene : public QGraphicsScene {
+ Q_OBJECT
+public:
+ CacheViewScene(const machine::Cache *cache);
+
+private:
+ unsigned associativity;
+ CacheViewBlock **block;
+};
+
+#endif // CACHEVIEW_H
diff --git a/qtmips_gui/mainwindow.cpp b/qtmips_gui/mainwindow.cpp
index d3434bc..4fb9cbf 100644
--- a/qtmips_gui/mainwindow.cpp
+++ b/qtmips_gui/mainwindow.cpp
@@ -118,8 +118,8 @@ void MainWindow::create_core(const machine::MachineConfig &config) {
registers->setup(machine);
program->setup(machine);
memory->setup(machine);
- cache_program->setup(machine->config().cache_program().enabled() ? machine->cache_program() : nullptr);
- cache_data->setup(machine->config().cache_data().enabled() ? machine->cache_data() : nullptr);
+ cache_program->setup(machine->cache_program());
+ cache_data->setup(machine->cache_data());
// Set status to ready
machine_status(machine::QtMipsMachine::ST_READY);
}
diff --git a/qtmips_gui/qtmips_gui.pro b/qtmips_gui/qtmips_gui.pro
index e12eaef..eb5f392 100644
--- a/qtmips_gui/qtmips_gui.pro
+++ b/qtmips_gui/qtmips_gui.pro
@@ -36,6 +36,7 @@ SOURCES += \
coreview/logicblock.cpp \
coreview/and.cpp \
statictable.cpp \
+ cacheview.cpp \
cachedock.cpp \
graphicsview.cpp
@@ -61,6 +62,7 @@ HEADERS += \
coreview/logicblock.h \
coreview/and.h \
statictable.h \
+ cacheview.h \
cachedock.h \
graphicsview.h