Implement immediate generation in Pipeline
MODIFY
RISC-V-sim.pro
RISC-V-sim.pro
@@ -37,7 +37,8 @@ SOURCES += src/main.cpp \
src/registercontainerwidget.cpp \
src/aboutwidget.cpp \
src/graphics/backgrounditems.cpp \
- src/instructionmodel.cpp
+ src/instructionmodel.cpp \
+ src/pipeline.cpp
HEADERS += \
src/parser.h \
@@ -72,7 +73,8 @@ HEADERS += \
src/graphics/backgrounditems.h \
src/instructionmodel.h \
src/binutils.h \
- src/pipelineobjects.h
+ src/pipelineobjects.h \
+ src/pipeline.h
FORMS += \
src/mainwindow.ui \

MODIFY
src/binutils.h
src/binutils.h
@@ -35,14 +35,14 @@ constexpr uint32_t bitcount(int n) {
inline uint32_t accBVec(std::vector<bool> v) {
uint32_t r = 0;
- for (size_t i = 0; i < v.size(); i++) {
+ for (uint32_t i = 0; i < v.size(); i++) {
r |= v[i] << i;
}
return r;
}
inline void buildVec(std::vector<bool>& v, uint32_t n) {
- for (size_t i = 0; i < v.size(); i++) {
+ for (uint32_t i = 0; i < v.size(); i++) {
v[i] = n & 0b1;
n >>= 1;
}

ADD
src/pipeline.cpp
+#include "pipeline.h"
+
+Pipeline::Pipeline() {}
+
+void Pipeline::immGen() {
+ // Generates an immediate value on the basis of an instruction opcode
+ // Opcode bits 5 and 6 can define the required fields for generating the immediate
+ switch ((r_IFID.value() & 0b1100000) >> 5) {
+ case 0b00: {
+ // Load instruction, sign extend bits 31:20
+ imm = Signal<64>(signextend<int32_t, 12>((r_IFID.value() >> 20)));
+ break;
+ }
+ case 0b01: {
+ // Store instruction
+ uint32_t v = r_IFID.value();
+ imm = Signal<64>(signextend<int32_t, 12>(((v & 0xfe000000)) >> 20) | ((v & 0xf80) >> 7));
+ break;
+ }
+ default: {
+ // Conditional branch instructions
+ uint32_t v = r_IFID.value();
+ imm = Signal<64>(signextend<int32_t, 13>(((v & 0x80000000)) >> 20) | ((v & 0x7e) >> 20) |
+ ((v & 0xf00) >> 7) | ((v & 0x80) << 6));
+ break;
+ }
+ }
+}

ADD
src/pipeline.h
+#ifndef PIPELINE_H
+#define PIPELINE_H
+
+#include "pipelineobjects.h"
+
+class Pipeline {
+public:
+ Pipeline();
+
+private:
+ void immGen();
+
+ // Signals
+ Signal<64> imm;
+
+ // Registers
+ Reg<32> r_IFID;
+};
+
+#endif // PIPELINE_H

MODIFY
src/pipelineobjects.h
src/pipelineobjects.h
// Signal class
// A boolean vector of immutable size
// Can be cast to booleans, u/integers etc.
-#define ASSERT_SIZE static_assert(n >= 1 && n <= 32, "n = [1;32]");
+#define ASSERT_SIZE static_assert(n >= 1 && n <= 64, "n = [1;64]");
#define CREATE_VEC m_value = std::vector<bool>(n);
template <int n>
@@ -66,6 +66,7 @@ class Reg {
public:
Reg() { ASSERT_SIZE }
void clock() { m_current = *m_next; }
+ uint32_t value() const { return (uint32_t)m_current; }
// Signal assignment operator
void connect(Reg<n>& r) { setInput(&r.m_current); }

Implement immediate generation in Pipeline