diff options
Diffstat (limited to 'qtmips_gui/cacheview.cpp')
-rw-r--r-- | qtmips_gui/cacheview.cpp | 118 |
1 files changed, 118 insertions, 0 deletions
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; + } +} |