Work on creating display delegate for drawing correct number bases
MODIFY
RISC-V-sim.pro
RISC-V-sim.pro
@@ -21,7 +21,8 @@ SOURCES += src/main.cpp \
src/cachebase.cpp \
src/runnercache.cpp \
src/cacheinspector.cpp \
- src/memorymodel.cpp
+ src/memorymodel.cpp \
+ src/memorydisplaydelegate.cpp
HEADERS += \
src/parser.h \
@@ -39,7 +40,8 @@ HEADERS += \
src/cachebase.h \
src/runnercache.h \
src/cacheinspector.h \
- src/memorymodel.h
+ src/memorymodel.h \
+ src/memorydisplaydelegate.h
FORMS += \
src/mainwindow.ui \

MODIFY
src/defines.h
src/defines.h
#define DEFINES_H
#include "unordered_map"
+#include <QList>
+#include <QPair>
#include <QString>
#include <cstdint>
#include <map>
#include <vector>
+enum displayTypeN { Hex = 1, Binary = 2, Decimal = 3, Unsigned = 4, ASCII = 5 };
+
+namespace {
+static QMap<QString, displayTypeN> initDisplayTypes() {
+ QMap<QString, displayTypeN> types;
+ types.insert("Hex", displayTypeN::Hex);
+ types.insert("Binary", displayTypeN::Binary);
+ types.insert("Decimal", displayTypeN::Decimal);
+ types.insert("Unsigned", displayTypeN::Unsigned);
+ types.insert("ASCII", displayTypeN::ASCII);
+ return types;
+}
+}
+
+const static QMap<QString, displayTypeN> displayTypes = initDisplayTypes();
+
enum instrType {
LUI = 0b0110111,
JAL = 0b1101111,

MODIFY
src/mainwindow.ui
src/mainwindow.ui
</size>
</property>
<property name="currentIndex">
- <number>3</number>
+ <number>2</number>
</property>
<widget class="QWidget" name="tab">
<attribute name="title">

ADD
src/memorydisplaydelegate.cpp
+#include "memorydisplaydelegate.h"
+
+MemoryDisplayDelegate::MemoryDisplayDelegate(QWidget *parent)
+ : QStyledItemDelegate(parent) {}
+
+QString MemoryDisplayDelegate::displayText(const QVariant &value,
+ const QLocale & /*locale*/) const {
+ QString retVal;
+ switch (m_displayType) {
+ case displayTypeN::Hex:
+ retVal.setNum(value.toUInt(), 16);
+ break;
+ case displayTypeN::Unsigned:
+ retVal.setNum(value.toUInt());
+ break;
+ case displayTypeN::Decimal:
+ retVal.setNum(value.toInt());
+ break;
+ case displayTypeN::ASCII:
+ retVal = QChar(value.toInt());
+ break;
+ case displayTypeN::Binary:
+ retVal.setNum(value.toUInt(), 2);
+ }
+ return retVal;
+}
+
+void MemoryDisplayDelegate::setDisplayType(const QString &type) {
+ // Given a display type "type", sets validators for the input.
+ auto iter = displayTypes.find(type);
+ if (iter != displayTypes.end()) {
+ m_displayType = iter.value();
+ }
+}

ADD
src/memorydisplaydelegate.h
+#ifndef MEMORYDISPLAYDELEGATE_H
+#define MEMORYDISPLAYDELEGATE_H
+
+#include <QStyledItemDelegate>
+
+#include "defines.h"
+
+class MemoryDisplayDelegate : public QStyledItemDelegate {
+public:
+ MemoryDisplayDelegate(QWidget *parent = nullptr);
+
+ QString displayText(const QVariant &value,
+ const QLocale &locale) const override;
+
+public slots:
+ void setDisplayType(const QString &type);
+
+private:
+ displayTypeN m_displayType = displayTypeN::Hex;
+};
+
+#endif // MEMORYDISPLAYDELEGATE_H

MODIFY
src/memorymodel.cpp
src/memorymodel.cpp
@@ -7,19 +7,32 @@ MemoryModel::MemoryModel(memory *memoryPtr, QObject *parent)
// Create initial view
// i is a byte index
for (int i = 0; i < m_addressRadius * 2 + 1; i++) {
- auto lineAddress = m_centralAddress + m_addressRadius - i * 4;
+ auto lineAddress = m_centralAddress + (m_addressRadius * 4) - i * 4;
auto iter = m_memoryPtr->find(lineAddress);
if (iter != m_memoryPtr->end()) {
- setItem(i, 0, new QStandardItem(iter->first));
- setItem(i, 1, new QStandardItem(iter->second));
+ auto addr = new QStandardItem();
+ addr->setData(
+ QString("0x%1").arg(
+ QString().setNum(iter->first, 16).rightJustified(8, '0')),
+ Qt::DisplayRole);
+ auto b1 = new QStandardItem();
+ b1->setData(iter->second, Qt::DisplayRole);
+ b1->setTextAlignment(Qt::AlignCenter);
+ setItem(i, 0, addr);
+ setItem(i, 1, b1);
}
for (int j = 1; j < 4; j++) {
// Locate the remaining 3 bytes in the word
+ auto byte = new QStandardItem();
if ((iter = m_memoryPtr->find(lineAddress + j)) != m_memoryPtr->end()) {
- setItem(i, j + 1, new QStandardItem(iter->second));
+ byte->setData(iter->second, Qt::DisplayRole);
+ byte->setTextAlignment(Qt::AlignCenter);
+ setItem(i, j + 1, byte);
} else {
// Memory is not initialized, set model data value to 0
- setItem(i, j + 1, 0);
+ byte->setData(0, Qt::DisplayRole);
+ byte->setTextAlignment(Qt::AlignCenter);
+ setItem(i, j + 1, byte);
}
}
}

MODIFY
src/memorymodel.h
src/memorymodel.h
@@ -26,7 +26,7 @@ private:
// doesnt exist
memory *m_memoryPtr;
- uint32_t m_centralAddress = 0; // Address at the center of the model
+ uint32_t m_centralAddress = 30; // Address at the center of the model
int m_addressRadius = 5; // amount of addresses in each direction, from
// centralAddress
};

MODIFY
src/memorytab.cpp
src/memorytab.cpp
MemoryTab::MemoryTab(QWidget *parent)
: QWidget(parent), m_ui(new Ui::MemoryTab) {
m_ui->setupUi(this);
+
+ // Add display types to display comboboxes
+ for (const auto &type : displayTypes.keys()) {
+ m_ui->registerdisplaytype->insertItem(0, type);
+ m_ui->memorydisplaytype->insertItem(0, type);
+ }
+ m_ui->registerdisplaytype->setCurrentIndex(displayTypeN::Hex);
+ m_ui->memorydisplaytype->setCurrentIndex(displayTypeN::Hex);
}
void MemoryTab::init() {
@@ -93,8 +101,9 @@ void MemoryTab::initializeRegisterView() {
reg->setNumber(i);
reg->setToolTip(descriptions[i]);
reg->setDisplayType(m_ui->registerdisplaytype->currentText());
- connect(m_ui->registerdisplaytype, &QComboBox::currentTextChanged,
- [=](const QString &text) { reg->setDisplayType(text); });
+ connect(m_ui->registerdisplaytype,
+ QOverload<const QString &>::of(&QComboBox::currentTextChanged), reg,
+ &RegisterWidget::setDisplayType);
m_ui->registerLayout->addWidget(reg);
}
m_regWidgetPtrs[0]->setEnabled(false);
@@ -107,32 +116,20 @@ void MemoryTab::updateRegisterWidget(int n) {
}
void MemoryTab::initializeMemoryView() {
- /*
-std::vector<std::pair<uint32_t, uint8_t>> sortedMemory(m_memoryPtr->begin(),
- m_memoryPtr->end());
-std::sort(sortedMemory.begin(), sortedMemory.end(),
- [](std::pair<uint32_t, uint8_t> a, std::pair<uint32_t, uint8_t> b) {
- return a.first > b.first;
- });
-m_ui->memoryView->setRowCount(sortedMemory.size());
-m_ui->memoryView->setColumnCount(2);
-m_ui->memoryView->setSortingEnabled(false);
-m_ui->memoryView->setHorizontalHeaderLabels(QStringList() << "Address"
- << "Value");
-m_ui->memoryView->verticalHeader()->setVisible(false);
-int i = 0;
-for (const auto &entry : sortedMemory) {
- auto addr = new QTableWidgetItem(QString().setNum(entry.first, 16));
- auto val = new QTableWidgetItem(QString("%1").arg(entry.second));
- m_ui->memoryView->setItem(i, 0, addr);
- m_ui->memoryView->setItem(i, 1, val);
- i++;
-}
-*/
m_model = new MemoryModel(m_memoryPtr);
+ m_delegate = new MemoryDisplayDelegate();
m_ui->memoryView->setModel(m_model);
m_ui->memoryView->horizontalHeader()->setStretchLastSection(true);
m_ui->memoryView->verticalHeader()->hide();
+ // Only set delegate on byte columns
+ m_ui->memoryView->setItemDelegateForColumn(1, m_delegate);
+ m_ui->memoryView->setItemDelegateForColumn(2, m_delegate);
+ m_ui->memoryView->setItemDelegateForColumn(3, m_delegate);
+ m_ui->memoryView->setItemDelegateForColumn(4, m_delegate);
+ connect(m_ui->memorydisplaytype, &QComboBox::currentTextChanged, m_delegate,
+ &MemoryDisplayDelegate::setDisplayType);
+ connect(m_ui->memorydisplaytype, &QComboBox::currentTextChanged,
+ [=] { m_ui->memoryView->viewport()->repaint(); });
}
MemoryTab::~MemoryTab() { delete m_ui; }

MODIFY
src/memorytab.h
src/memorytab.h
#include <unordered_map>
+#include "memorydisplaydelegate.h"
#include "memorymodel.h"
namespace Ui {
@@ -35,6 +36,7 @@ private:
Ui::MemoryTab *m_ui;
MemoryModel *m_model;
+ MemoryDisplayDelegate *m_delegate;
memory *m_memoryPtr;
std::vector<uint32_t> *m_regPtr;

MODIFY
src/memorytab.ui
src/memorytab.ui
</widget>
</item>
<item>
- <widget class="QComboBox" name="registerdisplaytype">
- <item>
- <property name="text">
- <string>Hex</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>Binary</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>Decimal</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>Unsigned</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>ASCII</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>Float (IEEE-754)</string>
- </property>
- </item>
- </widget>
+ <widget class="QComboBox" name="registerdisplaytype"/>
</item>
<item>
<spacer name="horizontalSpacer_2">
</widget>
</item>
<item>
- <widget class="QComboBox" name="comboBox">
+ <widget class="QComboBox" name="memorydisplaytype">
<property name="enabled">
- <bool>false</bool>
- </property>
- <item>
- <property name="text">
- <string>Hex</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>Binary</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>Decimal</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>Unsigned</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>ASCII</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>Float (IEEE-754)</string>
+ <bool>true</bool>
</property>
- </item>
</widget>
</item>
<item>

MODIFY
src/registerwidget.cpp
src/registerwidget.cpp
@@ -33,27 +33,31 @@ void RegisterWidget::validateInput() {
void RegisterWidget::setText() {
// Sets line edit text based on current display type and register value
- if (m_displayType == displayTypes[0]) {
+ if (m_displayType == displayTypeN::Hex) {
// hex
m_ui->value->setText(
QString()
.setNum(*m_regPtr, 16)
.rightJustified(8, '0')); // zero padding on hex numbers
- } else if (m_displayType == displayTypes[1]) {
+ } else if (m_displayType == displayTypeN::Binary) {
// binary
m_ui->value->setText(QString().setNum(*m_regPtr, 2));
- } else if (m_displayType == displayTypes[2]) {
+ } else if (m_displayType == displayTypeN::Decimal) {
// Decimal
m_ui->value->setText(QString().setNum(*(int32_t *)m_regPtr, 10));
- } else if (m_displayType == displayTypes[3]) {
+ } else if (m_displayType == displayTypeN::Unsigned) {
// Unsigned
m_ui->value->setText(QString().setNum(*m_regPtr, 10));
- } else if (m_displayType == displayTypes[4]) {
+ } else if (m_displayType == displayTypeN::ASCII) {
// ASCII - valid ascii characters will not be able to fill the 32-bit range
+ QString out;
+ auto value = *m_regPtr;
+ for (int i = 0; i < 4; i++) {
+ out.append(QChar(value & 0xff));
+ value >>= 8;
+ }
+ m_ui->value->setText(out);
m_ui->value->setInputMask("nnnn");
- } else if (m_displayType == displayTypes[5]) {
- // float
- m_ui->value->setInputMask("B");
}
}
@@ -61,42 +65,42 @@ void RegisterWidget::setNumber(int number) {
m_ui->number->setText(QString("x(%1)").arg(number));
}
-void RegisterWidget::setDisplayType(QString type) {
+void RegisterWidget::setDisplayType(const QString &type) {
// Given a display type "type", sets validators for the input.
+ auto iter = displayTypes.find(type);
+ if (iter == displayTypes.end()) {
+ return;
+ }
- m_displayType = type;
- if (type == displayTypes[0]) {
- // hex
+ m_displayType = *iter;
+ if (m_displayType == displayTypeN::Hex) {
m_displayBase = 16;
m_ui->value->setInputMask("hhhhhhhh");
m_range = rangePair(0, (long long)4294967295);
setText();
- } else if (type == displayTypes[1]) {
+ } else if (m_displayType == displayTypeN::Binary) {
// binary
m_displayBase = 2;
m_ui->value->setInputMask("bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb");
setText();
m_range = rangePair(0, (long long)4294967295);
- } else if (type == displayTypes[2]) {
+ } else if (m_displayType == displayTypeN::Decimal) {
// Decimal
m_displayBase = 10;
m_ui->value->setInputMask("#0000000000");
setText();
m_range = rangePair(-(long long)2147483648, (long long)2147483647);
- } else if (type == displayTypes[3]) {
+ } else if (m_displayType == displayTypeN::Unsigned) {
// Unsigned
m_displayBase = 10;
m_ui->value->setInputMask("0000000000");
setText();
m_range = rangePair(0, (long long)4294967295);
- } else if (type == displayTypes[4]) {
+ } else if (m_displayType == displayTypeN::ASCII) {
// ASCII - valid ascii characters will not be able to fill the 32-bit range
m_ui->value->setInputMask("nnnn");
+ setText();
m_range = rangePair(0, (long long)4294967295);
- } else if (type == displayTypes[5]) {
- // float
- m_ui->value->setInputMask("B");
- m_range = {0, (long)4294967295};
}
}

MODIFY
src/registerwidget.h
src/registerwidget.h
#include <QValidator>
#include <QWidget>
-const static QStringList displayTypes = QStringList() << "Hex"
- << "Binary"
- << "Decimal"
- << "Unsigned"
- << "ASCII"
- << "Float (IEEE-754)";
+#include "defines.h"
namespace Ui {
class RegisterWidget;
@@ -32,12 +27,12 @@ public:
void setAlias(QString text);
void setNumber(int number);
- void setDisplayType(QString type);
void setRegPtr(uint32_t *ptr) { m_regPtr = ptr; }
void enableInput(bool state);
public slots:
void setText();
+ void setDisplayType(const QString &type);
private slots:
void validateInput();
@@ -45,7 +40,7 @@ private slots:
private:
Ui::RegisterWidget *m_ui;
QIntValidator m_validator;
- QString m_displayType;
+ int m_displayType;
int m_displayBase = 10;
uint32_t *m_regPtr;

Work on creating display delegate for drawing correct number bases