Implement dirty bit graphics
MODIFY
src/cacheconfigwidget.h
src/cacheconfigwidget.h
@@ -20,10 +20,10 @@ public:
public slots:
void setHitRate(double hitrate);
- void setCacheSize(unsigned);
void configChanged();
private:
+ void updateCacheSize();
void updateIndexingText();
void setupPresets();
void showSizeBreakdown();

MODIFY
src/cacheconfigwidget.ui
src/cacheconfigwidget.ui
<layout class="QGridLayout" name="gridLayout_5">
<item row="0" column="0">
<layout class="QGridLayout" name="gridLayout_4">
- <item row="1" column="2">
- <widget class="QPushButton" name="sizeBreakdownButton">
- <property name="text">
- <string>Breakdown</string>
- </property>
- </widget>
- </item>
<item row="0" column="1">
<widget class="QLineEdit" name="hitrate"/>
</item>
</property>
</widget>
</item>
- <item row="1" column="1">
- <widget class="QLineEdit" name="size"/>
- </item>
<item row="0" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<item row="2" column="1">
<widget class="QLineEdit" name="writebacks"/>
</item>
+ <item row="1" column="1">
+ <layout class="QHBoxLayout" name="horizontalLayout_3">
+ <item>
+ <widget class="QLineEdit" name="size"/>
+ </item>
+ <item>
+ <widget class="QToolButton" name="sizeBreakdownButton">
+ <property name="text">
+ <string>...</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
</layout>
</item>
<item row="1" column="0">

MODIFY
src/cachegraphic.cpp
src/cachegraphic.cpp
@@ -60,7 +60,6 @@ void CacheGraphic::dataChanged(const CacheSim::CacheTransaction& transaction) {
QGraphicsSimpleTextItem* tagTextItem = tryCreateGraphicsTextItem(&cacheline.tag, x, y);
const QString tagText = encodeRadixValue(transaction.tag, Radix::Hex);
tagTextItem->setText(tagText);
- tagTextItem->setToolTip("Address: " + encodeRadixValue(transaction.address, Radix::Hex));
// Update all blocks
for (unsigned i = 0; i < m_cache.getBlocks(); i++) {
@@ -73,6 +72,7 @@ void CacheGraphic::dataChanged(const CacheSim::CacheTransaction& transaction) {
const auto data = ProcessorHandler::get()->getMemory().readMemConst(addressForBlock);
const QString text = encodeRadixValue(data, Radix::Hex);
blockTextItem->setText(text);
+ blockTextItem->setToolTip("Address: " + encodeRadixValue(addressForBlock, Radix::Hex));
}
// Update valid
@@ -96,7 +96,7 @@ void CacheGraphic::dataChanged(const CacheSim::CacheTransaction& transaction) {
// LRU text might have changed; update LRU field position to center in column
const qreal y = transaction.lineIdx * m_lineHeight + way.first * m_setHeight;
- const qreal x = m_bitWidth + m_lruWidth / 2 - fm.horizontalAdvance(lruText) / 2;
+ const qreal x = m_widthBeforeLRU + m_lruWidth / 2 - fm.horizontalAdvance(lruText) / 2;
way.second.lru->setPos(x, y);
}
@@ -107,10 +107,11 @@ void CacheGraphic::dataChanged(const CacheSim::CacheTransaction& transaction) {
updateHighlighting(true, &transaction);
}
-void CacheGraphic::drawText(const QString& text, qreal x, qreal y) {
+QGraphicsSimpleTextItem* CacheGraphic::drawText(const QString& text, qreal x, qreal y) {
auto* textItem = new QGraphicsSimpleTextItem(text, this);
textItem->setFont(m_font);
textItem->setPos(x, y);
+ return textItem;
}
void CacheGraphic::updateHighlighting(bool active, const CacheSim::CacheTransaction* transaction) {
@@ -165,22 +166,20 @@ void CacheGraphic::initializeControlBits() {
qreal x;
// Create valid field
- auto* validItem = new QGraphicsSimpleTextItem(this);
- validItem->setFont(m_font);
- validItem->setText("0");
- x = fm.horizontalAdvance(validItem->text()) / 2;
- validItem->setPos(x, y);
- line[setIdx].valid = validItem;
+ x = m_bitWidth / 2 - fm.horizontalAdvance("0") / 2;
+ line[setIdx].valid = drawText("0", x, y);
+
+ if (m_cache.getWritePolicy() == CacheWrPlcy::WriteBack) {
+ // Create dirty bit field
+ x = m_widthBeforeDirty + m_bitWidth / 2 - fm.horizontalAdvance("0") / 2;
+ line[setIdx].dirty = drawText("0", x, y);
+ }
if (m_cache.getReplacementPolicy() == CacheReplPlcy::LRU && m_cache.getWays() > 1) {
// Create LRU field
- auto* lruItem = new QGraphicsSimpleTextItem(this);
- lruItem->setFont(m_font);
const QString lruText = QString::number(m_cache.getWays() - 1);
- lruItem->setText(lruText);
- x = m_bitWidth + m_lruWidth / 2 - fm.horizontalAdvance(lruText) / 2;
- lruItem->setPos(x, y);
- line[setIdx].lru = lruItem;
+ x = m_widthBeforeLRU + m_lruWidth / 2 - fm.horizontalAdvance(lruText) / 2;
+ line[setIdx].lru = drawText(lruText, x, y);
}
}
}
@@ -210,22 +209,37 @@ void CacheGraphic::cacheParametersChanged() {
m_tagWidth = m_blockWidth;
// Draw cache:
+ new QGraphicsLineItem(0, 0, 0, m_cacheHeight, this);
qreal horizontalAdvance = 0;
// Draw valid bit column
- new QGraphicsLineItem(0, 0, 0, m_cacheHeight, this);
new QGraphicsLineItem(m_bitWidth, 0, m_bitWidth, m_cacheHeight, this);
const QString validBitText = "V";
- drawText(validBitText, 0, -metrics.height());
+ auto* validItem = drawText(validBitText, 0, -metrics.height());
+ validItem->setToolTip("Valid bit");
horizontalAdvance += m_bitWidth;
+ if (m_cache.getWritePolicy() == CacheWrPlcy::WriteBack) {
+ m_widthBeforeDirty = horizontalAdvance;
+
+ // Draw dirty bit column
+ new QGraphicsLineItem(horizontalAdvance + m_bitWidth, 0, horizontalAdvance + m_bitWidth, m_cacheHeight, this);
+ const QString dirtyBitText = "D";
+ auto* dirtyItem = drawText(dirtyBitText, m_widthBeforeDirty, -metrics.height());
+ dirtyItem->setToolTip("Dirty bit");
+ horizontalAdvance += m_bitWidth;
+ }
+
+ m_widthBeforeLRU = horizontalAdvance;
+
if (m_cache.getReplacementPolicy() == CacheReplPlcy::LRU && m_cache.getWays() > 1) {
// Draw LRU bit column
- new QGraphicsLineItem(horizontalAdvance, 0, horizontalAdvance, m_cacheHeight, this);
- new QGraphicsLineItem(m_bitWidth + m_lruWidth, 0, m_bitWidth + m_lruWidth, m_cacheHeight, this);
+ new QGraphicsLineItem(horizontalAdvance + m_lruWidth, 0, horizontalAdvance + m_lruWidth, m_cacheHeight, this);
const QString LRUBitText = "LRU";
+ auto* textItem =
drawText(LRUBitText, horizontalAdvance + m_lruWidth / 2 - metrics.horizontalAdvance(LRUBitText) / 2,
-metrics.height());
+ textItem->setToolTip("Least Recently Used bits");
horizontalAdvance += m_lruWidth;
}

MODIFY
src/cachegraphic.h
src/cachegraphic.h
@@ -34,7 +34,7 @@ private:
*/
void initializeControlBits();
void updateHighlighting(bool active, const CacheSim::CacheTransaction* transaction);
- void drawText(const QString& text, qreal x, qreal y);
+ QGraphicsSimpleTextItem* drawText(const QString& text, qreal x, qreal y);
QGraphicsSimpleTextItem* tryCreateGraphicsTextItem(QGraphicsSimpleTextItem** item, qreal x, qreal y);
QFont m_font = QFont("Inconsolata", 12);
@@ -52,6 +52,8 @@ private:
qreal m_cacheWidth = 0;
qreal m_widthBeforeBlocks = 0;
qreal m_widthBeforeTag = 0;
+ qreal m_widthBeforeLRU = 0;
+ qreal m_widthBeforeDirty = 0;
qreal m_lruWidth = 0;
// Data structure modelling the cache; keeping graphics text items for each entry
@@ -60,6 +62,7 @@ private:
QGraphicsSimpleTextItem* tag = nullptr;
QGraphicsSimpleTextItem* lru = nullptr;
QGraphicsSimpleTextItem* valid = nullptr;
+ QGraphicsSimpleTextItem* dirty = nullptr;
};
using CacheLine = std::map<unsigned, CacheWay>;

MODIFY
src/cachesim.cpp
src/cachesim.cpp
@@ -34,7 +34,14 @@ CacheSim::CacheSize CacheSim::getCacheSize() const {
size.components.push_back("Valid bits: " + QString::number(componentBits));
size.bits += componentBits;
- if (m_policy == CacheReplPlcy::LRU) {
+ if (m_wrPolicy == CacheWrPlcy::WriteBack) {
+ // Dirty bits
+ unsigned componentBits = entries; // 1 bit per entry
+ size.components.push_back("Dirty bits: " + QString::number(componentBits));
+ size.bits += componentBits;
+ }
+
+ if (m_replPolicy == CacheReplPlcy::LRU) {
// LRU bits
componentBits = getWaysBits() * entries;
size.components.push_back("LRU bits: " + QString::number(componentBits));
@@ -60,11 +67,11 @@ void CacheSim::evictAndUpdate(CacheTransaction& transaction) {
CacheWay* currentWay = nullptr;
// Update based on replacement policy
- if (m_policy == CacheReplPlcy::Random) {
+ if (m_replPolicy == CacheReplPlcy::Random) {
// Select a random way
transaction.wayIdx = std::rand() % getWays();
currentWay = &cacheLine[transaction.wayIdx];
- } else if (m_policy == CacheReplPlcy::LRU) {
+ } else if (m_replPolicy == CacheReplPlcy::LRU) {
if (getWays() == 1) {
// Nothing to do if we are in LRU and only have 1 set
transaction.wayIdx = 0;
@@ -193,6 +200,7 @@ void CacheSim::updateConfiguration() {
// Cache configuration changes shall enforce a full reset of the computing system
m_cacheLines.clear();
m_accessTrace.clear();
+ m_hitrate = 0;
// Recalculate masks
int bitoffset = 2; // 2^2 = 4-byte offset (32-bit words in cache)

MODIFY
src/cachesim.h
src/cachesim.h
namespace Ripes {
+enum class CacheWrPlcy { WriteThrough, WriteBack };
enum class CacheReplPlcy { Random, LRU };
static std::map<CacheReplPlcy, QString> s_cachePolicyStrings{{CacheReplPlcy::Random, "Random"},
{CacheReplPlcy::LRU, "LRU"}};
@@ -55,8 +56,13 @@ public:
CacheSim(QObject* parent);
+ void setWritePolicy(CacheWrPlcy policy) {
+ m_wrPolicy = policy;
+ updateConfiguration();
+ }
+
void setReplacementPolicy(CacheReplPlcy policy) {
- m_policy = policy;
+ m_replPolicy = policy;
updateConfiguration();
}
@@ -65,9 +71,10 @@ public:
void undo();
void reset();
- CacheReplPlcy getReplacementPolicy() const { return m_policy; }
+ CacheReplPlcy getReplacementPolicy() const { return m_replPolicy; }
+ CacheWrPlcy getWritePolicy() const { return m_wrPolicy; }
- double getHitRate() const;
+ double getHitRate() const { return m_hitrate; }
CacheSize getCacheSize() const;
int getBlockBits() const { return m_blocks; }
@@ -105,7 +112,8 @@ private:
void analyzeCacheAccess(CacheTransaction& transaction);
void updateConfiguration();
- CacheReplPlcy m_policy = CacheReplPlcy::LRU;
+ CacheReplPlcy m_replPolicy = CacheReplPlcy::LRU;
+ CacheWrPlcy m_wrPolicy = CacheWrPlcy::WriteBack;
unsigned m_blockMask = -1;
unsigned m_lineMask = -1;

Implement dirty bit graphics