Init work on string generation from instruction parsing
MODIFY
RISC-V-sim.pro
RISC-V-sim.pro
@@ -36,7 +36,8 @@ SOURCES += src/main.cpp \
src/graphics/pipelinewidget.cpp \
src/registercontainerwidget.cpp \
src/aboutwidget.cpp \
- src/graphics/backgrounditems.cpp
+ src/graphics/backgrounditems.cpp \
+ src/instructionmodel.cpp
HEADERS += \
src/parser.h \
@@ -68,7 +69,8 @@ HEADERS += \
src/graphics/pipelinewidget.h \
src/registercontainerwidget.h \
src/aboutwidget.h \
- src/graphics/backgrounditems.h
+ src/graphics/backgrounditems.h \
+ src/instructionmodel.h
FORMS += \
src/mainwindow.ui \

ADD
src/instructionmodel.cpp
+#include "instructionmodel.h"
+
+#include <QHeaderView>
+
+InstructionModel::InstructionModel(QObject *parent) : QStandardItemModel(parent)
+{
+
+ setItem(0,2, new QStandardItem());
+ setHeaderData(0, Qt::Horizontal, "PC");
+ setHeaderData(1, Qt::Horizontal, "Stage");
+ setHeaderData(2, Qt::Horizontal, "Instruction");
+}

ADD
src/instructionmodel.h
+#ifndef INSTRUCTIONMODEL_H
+#define INSTRUCTIONMODEL_H
+
+#include <QStandardItemModel>
+
+class InstructionModel : public QStandardItemModel
+{
+ Q_OBJECT
+public:
+ explicit InstructionModel(QObject *parent = nullptr);
+
+signals:
+
+public slots:
+};
+
+#endif // INSTRUCTIONMODEL_H

MODIFY
src/parser.cpp
src/parser.cpp
#include "parser.h"
+#include <assert.h>
#include <iostream>
-Parser::Parser() {}
+Parser::Parser() {
+
+ // generate word parser functors
+ decodeRInstr = generateWordParser(vector<int>{5, 3, 5, 5, 7}); // from LSB to MSB
+ decodeIInstr = generateWordParser(vector<int>{5, 3, 5, 12});
+ decodeSInstr = generateWordParser(vector<int>{5, 3, 5, 5, 7});
+ decodeBInstr = generateWordParser(vector<int>{1, 4, 3, 5, 5, 6, 1});
+ decodeUInstr = generateWordParser(vector<int>{5, 20});
+ decodeJInstr = generateWordParser(vector<int>{5, 8, 1, 10, 1});
+}
bool Parser::init(char* filename) {
// Open binary file
@@ -34,3 +44,58 @@ void Parser::parseFile(memory* memoryPtr) {
m_fileIter++;
}
}
+
+namespace {
+uint32_t generateBitmask(int n) {
+ // Generate bitmask. There might be a smarter way to do this
+ uint32_t mask = 0;
+ for (int i = 0; i < n - 1; i++) {
+ mask |= 0b1;
+ mask <<= 1;
+ }
+ mask |= 0b1;
+ return mask;
+}
+
+uint32_t bitcount(int n) {
+ int count = 0;
+ while (n > 0) {
+ count += 1;
+ n = n & (n - 1);
+ }
+ return count;
+}
+}
+
+decode_functor Parser::generateWordParser(std::vector<int> bitFields) {
+ // Generates functors that can decode a binary number based on the input
+ // vector which is supplied upon generation
+
+ // Assert that total bitField size is (32-7)=25-bit. Subtract 7 for op-code
+ int tot = 0;
+ for (const auto& field : bitFields) {
+ tot += field;
+ }
+ assert(tot == 25 && "Requested word parsing format is not 32-bit in length");
+
+ // Generate vector of <fieldsize,bitmask>
+ std::vector<std::pair<uint32_t, uint32_t>> parseVector;
+
+ // Generate bit masks and fill parse vector
+ for (const auto& field : bitFields) {
+ parseVector.push_back(std::pair<uint32_t, uint32_t>(field, generateBitmask(field)));
+ }
+
+ // Create parse functor
+ decode_functor wordParser = [=](uint32_t word) {
+ word = word >> 7; // remove OpCode
+ std::vector<uint32_t> parsedWord;
+ for (const auto& field : parseVector) {
+ parsedWord.insert(parsedWord.begin(), word & field.second);
+ word = word >> field.first;
+ }
+ return parsedWord;
+ };
+
+ return wordParser;
+}

MODIFY
src/parser.h
src/parser.h
#ifndef PARSER_H
#define PARSER_H
-#include "defines.h"
#include <fstream>
+#include <functional>
#include <unordered_map>
#include <vector>
+#include "defines.h"
using namespace std;
+typedef std::function<std::vector<uint32_t>(uint32_t)> decode_functor;
+
class Parser {
public:
@@ -23,6 +26,15 @@ private:
ifstream m_fileStream;
istreambuf_iterator<char> m_fileIter;
int m_fileSize;
+
+ // Instruction decode functions; runtime generated
+ decode_functor generateWordParser(std::vector<int> bitFields);
+ decode_functor decodeUInstr;
+ decode_functor decodeJInstr;
+ decode_functor decodeIInstr;
+ decode_functor decodeSInstr;
+ decode_functor decodeRInstr;
+ decode_functor decodeBInstr;
};
#endif // PARSER_H

MODIFY
src/processortab.cpp
src/processortab.cpp
#include "processortab.h"
+#include "instructionmodel.h"
#include "ui_processortab.h"
#include "runner.h"
@@ -17,6 +18,14 @@ ProcessorTab::ProcessorTab(QWidget* parent) : QWidget(parent), m_ui(new Ui::Proc
});
connect(m_ui->reset, &QPushButton::clicked, [=] { m_ui->start->setChecked(false); });
+
+ // Setup instruction view
+ m_instrModel = new InstructionModel();
+ m_ui->instructionView->setEditTriggers(QAbstractItemView::NoEditTriggers);
+ 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) {

MODIFY
src/processortab.h
src/processortab.h
@@ -7,6 +7,8 @@ namespace Ui {
class ProcessorTab;
}
+class InstructionModel;
+
class ProcessorTab : public QWidget {
Q_OBJECT
@@ -21,6 +23,7 @@ private slots:
private:
Ui::ProcessorTab* m_ui;
+ InstructionModel* m_instrModel;
};
#endif // PROCESSORTAB_H

MODIFY
src/processortab.ui
src/processortab.ui
</property>
<layout class="QGridLayout" name="gridLayout_3">
<item row="0" column="0">
- <widget class="QTableView" name="tableView">
+ <widget class="QTableView" name="instructionView">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Expanding">
<horstretch>0</horstretch>

Init work on string generation from instruction parsing