aboutsummaryrefslogtreecommitdiff
path: root/qtmips_gui/cacheview.cpp
blob: 8582e63190b80e82e4d6e2990c07967b03596cb4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
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;
    }
}