Implement instruction model and work on string representation of instructions
MODIFY
src/defines.h
src/defines.h
#ifndef DEFINES_H
#define DEFINES_H
-#include "unordered_map"
#include <QList>
#include <QPair>
#include <QString>
#include <cstdint>
#include <map>
#include <vector>
+#include "unordered_map"
enum displayTypeN { Hex = 1, Binary = 2, Decimal = 3, Unsigned = 4, ASCII = 5 };
Q_DECLARE_METATYPE(displayTypeN)

MODIFY
src/instructionmodel.cpp
src/instructionmodel.cpp
#include "instructionmodel.h"
+#include "parser.h"
#include <QHeaderView>
-InstructionModel::InstructionModel(QObject *parent) : QStandardItemModel(parent) {
- setItem(0, 2, new QStandardItem());
+InstructionModel::InstructionModel(Parser* parser, QObject* parent) : m_parserPtr(parser), QAbstractTableModel(parent) {
+ /*
setHeaderData(0, Qt::Horizontal, "PC");
setHeaderData(1, Qt::Horizontal, "Stage");
setHeaderData(2, Qt::Horizontal, "Instruction");
+ */
+}
+
+void InstructionModel::setMemory(memory* mem, int textSize) {
+ beginResetModel();
+ m_memory = mem;
+ m_textSize = textSize;
+ endResetModel();
+}
+
+void InstructionModel::setTextSize(int textSize) {
+ beginResetModel();
+ m_textSize = textSize;
+ endResetModel();
+}
+
+int InstructionModel::rowCount(const QModelIndex&) const {
+ return m_textSize / 4;
+}
+
+int InstructionModel::columnCount(const QModelIndex&) const {
+ return 3;
+}
+
+QVariant InstructionModel::data(const QModelIndex& index, int role) const {
+ if (!index.isValid() || role != Qt::DisplayRole) {
+ return QVariant();
+ }
+ switch (index.column()) {
+ case 0:
+ return index.row() * 4;
+ case 1:
+ return "NaN";
+ case 2:
+ return m_parserPtr->genStringRepr(memRead(index.row() * 4));
+ default:
+ return QVariant();
+ }
+}
+
+QVariant InstructionModel::headerData(int section, Qt::Orientation orientation, int role) const {
+ if (orientation == Qt::Horizontal && role == Qt::DisplayRole) {
+ switch (section) {
+ case 0:
+ return "PC";
+ case 1:
+ return "Stage";
+ case 2:
+ return "Instruction";
+ default:
+ return QVariant();
+ }
+ }
+
+ return QVariant();
+}
+
+uint32_t InstructionModel::memRead(uint32_t address) const {
+ // Note: If address is not found in memory map, a default constructed object
+ // will be created, and read. in our case uint8_t() = 0
+ uint32_t read = ((*m_memory)[address] | ((*m_memory)[address + 1] << 8) | ((*m_memory)[address + 2] << 16) |
+ ((*m_memory)[address + 3] << 24));
+ return read;
}

MODIFY
src/instructionmodel.h
src/instructionmodel.h
#ifndef INSTRUCTIONMODEL_H
#define INSTRUCTIONMODEL_H
-#include <QStandardItemModel>
+#include "defines.h"
-class InstructionModel : public QStandardItemModel
-{
+#include <QAbstractTableModel>
+
+class Parser;
+class InstructionModel : public QAbstractTableModel {
Q_OBJECT
public:
- explicit InstructionModel(QObject *parent = nullptr);
+ explicit InstructionModel(Parser* parser = nullptr, QObject* parent = nullptr);
+
+ int rowCount(const QModelIndex& parent = QModelIndex()) const override;
+ int columnCount(const QModelIndex& parent = QModelIndex()) const override;
+
+ QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
+ QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
+
+ void setMemory(memory* mem, int textSize = 0);
+ void setTextSize(int textSize);
+
+private:
+ memory* m_memory;
+ Parser* m_parserPtr;
+ int m_textSize = 0; // text segment, in bytes
+
+ uint32_t memRead(uint32_t address) const;
signals:

MODIFY
src/mainwindow.cpp
src/mainwindow.cpp
@@ -44,6 +44,7 @@ MainWindow::MainWindow(Runner* runnerPtr, Parser* parserPtr, QWidget* parent)
m_ui->memorytab->setMemoryPtr(m_runnerPtr->getMemoryPtr());
m_ui->memorytab->setRegPtr(m_runnerPtr->getRegPtr());
m_ui->processortab->initRegWidget(m_runnerPtr->getRegPtr());
+ m_ui->processortab->initInstructionView(m_runnerPtr->getMemoryPtr(), m_parserPtr, m_runnerPtr->getTextSize());
m_ui->memorytab->init();

MODIFY
src/parser.cpp
src/parser.cpp
@@ -131,17 +131,17 @@ QString Parser::generateBranchString(uint32_t instr) const {
int offset = signextend<int32_t, 13>((fields[0] << 12) | (fields[1] << 5) | (fields[5] << 1) | (fields[6] << 11));
switch (fields[4]) {
case 0b000: // BEQ
- return QString("beq x%1 x%2 %3").arg(fields[2]).arg(fields[3]).arg(offset);
+ return QString("beq x%1 x%2 %3").arg(fields[3]).arg(fields[2]).arg(offset);
case 0b001: // BNE
- return QString("bne x%1 x%2 %3").arg(fields[2]).arg(fields[3]).arg(offset);
+ return QString("bne x%1 x%2 %3").arg(fields[3]).arg(fields[2]).arg(offset);
case 0b100: // BLT - signed comparison
- return QString("blt x%1 x%2 %3").arg(fields[2]).arg(fields[3]).arg(offset);
+ return QString("blt x%1 x%2 %3").arg(fields[3]).arg(fields[2]).arg(offset);
case 0b101: // BGE - signed comparison
- return QString("bge x%1 x%2 %3").arg(fields[2]).arg(fields[3]).arg(offset);
+ return QString("bge x%1 x%2 %3").arg(fields[3]).arg(fields[2]).arg(offset);
case 0b110: // BLTU
- return QString("bltu x%1 x%2 %3").arg(fields[2]).arg(fields[3]).arg(offset);
+ return QString("bltu x%1 x%2 %3").arg(fields[3]).arg(fields[2]).arg(offset);
case 0b111: // BGEU
- return QString("bgeu x%1 x%2 %3").arg(fields[2]).arg(fields[3]).arg(offset);
+ return QString("bgeu x%1 x%2 %3").arg(fields[3]).arg(fields[2]).arg(offset);
default:
return QString();
}

MODIFY
src/processortab.cpp
src/processortab.cpp
@@ -18,22 +18,25 @@ ProcessorTab::ProcessorTab(QWidget* parent) : QWidget(parent), m_ui(new Ui::Proc
});
connect(m_ui->reset, &QPushButton::clicked, [=] { m_ui->start->setChecked(false); });
+}
+
+void ProcessorTab::initRegWidget(std::vector<uint32_t>* regPtr) {
+ // Setup register widget
+ m_ui->registerContainer->setRegPtr(regPtr);
+ m_ui->registerContainer->init();
+}
+void ProcessorTab::initInstructionView(memory* mem, Parser* parser, int textSize) {
// Setup instruction view
- m_instrModel = new InstructionModel();
+ m_instrModel = new InstructionModel(parser);
m_ui->instructionView->setEditTriggers(QAbstractItemView::NoEditTriggers);
+ m_instrModel->setMemory(mem, textSize);
m_ui->instructionView->setModel(m_instrModel);
m_ui->instructionView->horizontalHeader()->setSectionResizeMode(0, QHeaderView::ResizeToContents);
m_ui->instructionView->horizontalHeader()->setSectionResizeMode(1, QHeaderView::ResizeToContents);
m_ui->instructionView->horizontalHeader()->setSectionResizeMode(2, QHeaderView::Stretch);
}
-void ProcessorTab::initRegWidget(std::vector<uint32_t>* regPtr) {
- // Setup register widget
- m_ui->registerContainer->setRegPtr(regPtr);
- m_ui->registerContainer->init();
-}
-
ProcessorTab::~ProcessorTab() {
delete m_ui;
}

MODIFY
src/processortab.h
src/processortab.h
#define PROCESSORTAB_H
#include <QWidget>
+#include "defines.h"
namespace Ui {
class ProcessorTab;
}
class InstructionModel;
+class Parser;
class ProcessorTab : public QWidget {
Q_OBJECT
@@ -17,6 +19,7 @@ public:
~ProcessorTab();
void initRegWidget(std::vector<uint32_t>* regPtr);
+ void initInstructionView(memory* mem, Parser* parser, int textSize);
private slots:
void on_expandView_clicked();

MODIFY
src/runner.cpp
src/runner.cpp
@@ -19,6 +19,9 @@ Runner::Runner(Parser* parser) {
// file parsing
m_parser->parseFile(&m_memory);
+ // Assuming the map was empty when parsing the program into memory, the size of the memory will now equate to the
+ // number of instructions in the text segment
+ m_textSize = m_memory.size();
}
Runner::~Runner() {}

MODIFY
src/runner.h
src/runner.h
@@ -20,6 +20,7 @@ public:
RunnerCache* getRunnerCachePtr() { return &m_cache; }
memory* getMemoryPtr() { return &m_memory; }
std::vector<uint32_t>* getRegPtr() { return &m_reg; }
+ int getTextSize() const { return m_textSize; }
private:
instrState execInstruction(Instruction instr);
@@ -44,7 +45,7 @@ private:
void memWrite(uint32_t address, uint32_t value, int size);
uint32_t memRead(uint32_t address);
- int m_memsize;
+ int m_textSize = 0;
Parser* m_parser;
bool m_running = false; // flag for disabling UI update signals when running simulator

Implement instruction model and work on string representation of instructions