aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--qtmips_gui/coreview.cpp33
-rw-r--r--qtmips_gui/coreview.h1
-rw-r--r--qtmips_gui/coreview/registers.cpp1
-rw-r--r--qtmips_gui/coreview/value.cpp51
-rw-r--r--qtmips_gui/coreview/value.h30
-rw-r--r--qtmips_gui/qtmips_gui.pro6
-rw-r--r--qtmips_machine/core.cpp29
-rw-r--r--qtmips_machine/core.h13
-rw-r--r--qtmips_machine/qtmips_machine.pro3
-rw-r--r--qtmips_machine/utils.cpp5
-rw-r--r--qtmips_machine/utils.h4
11 files changed, 168 insertions, 8 deletions
diff --git a/qtmips_gui/coreview.cpp b/qtmips_gui/coreview.cpp
index 5652a21..b2d9b7d 100644
--- a/qtmips_gui/coreview.cpp
+++ b/qtmips_gui/coreview.cpp
@@ -19,10 +19,13 @@
NEW(InstructionView, VAR, X, Y); \
connect(machine->core(), SIGNAL(SIG), VAR, SLOT(instruction_update(const machine::Instruction&))); \
} while(false)
+#define NEW_V(X, Y, ...) NEW(Value, val, X, Y, __VA_ARGS__)
CoreViewScene::CoreViewScene(machine::QtMipsMachine *machine) : QGraphicsScene() {
setSceneRect(0, 0, SC_WIDTH, SC_HEIGHT);
+ coreview::Value *val;
+
// Elements //
// Primary points
NEW(ProgramMemory, mem_program, 90, 240, machine);
@@ -93,6 +96,36 @@ CoreViewScene::CoreViewScene(machine::QtMipsMachine *machine) : QGraphicsScene()
con = new_bus(wb.mem_or_reg->connector_out(), regs->connector_write());
con->setAxes({CON_AXIS_Y(710), CON_AXIS_X(510), CON_AXIS_Y(172)});
+ // Decode stage values
+ NEW_V(200, 200); // Instruction
+ connect(machine->core(), SIGNAL(decode_instruction_value(std::uint32_t)), val, SLOT(value_update(std::uint32_t)));
+ NEW_V(360, 250); // Register output 1
+ connect(machine->core(), SIGNAL(decode_reg1_value(std::uint32_t)), val, SLOT(value_update(std::uint32_t)));
+ NEW_V(360, 270); // Register output 2
+ connect(machine->core(), SIGNAL(decode_reg2_value(std::uint32_t)), val, SLOT(value_update(std::uint32_t)));
+ NEW_V(335, 415); // Sign extended immediate value
+ connect(machine->core(), SIGNAL(decode_immediate_value(std::uint32_t)), val, SLOT(value_update(std::uint32_t)));
+ // Execute stage
+ NEW_V(430, 250); // Register 1
+ connect(machine->core(), SIGNAL(execute_reg1_value(std::uint32_t)), val, SLOT(value_update(std::uint32_t)));
+ NEW_V(420, 310, true); // Register 2
+ connect(machine->core(), SIGNAL(execute_reg2_value(std::uint32_t)), val, SLOT(value_update(std::uint32_t)));
+ NEW_V(520, 280, true); // Alu output
+ connect(machine->core(), SIGNAL(execute_alu_value(std::uint32_t)), val, SLOT(value_update(std::uint32_t)));
+ NEW_V(430, 415); // Immediate value
+ connect(machine->core(), SIGNAL(execute_immediate_value(std::uint32_t)), val, SLOT(value_update(std::uint32_t)));
+ // Memory stage
+ NEW_V(560, 275, true); // Alu output
+ connect(machine->core(), SIGNAL(memory_alu_value(std::uint32_t)), val, SLOT(value_update(std::uint32_t)));
+ NEW_V(560, 345, true); // rt
+ connect(machine->core(), SIGNAL(memory_rt_value(std::uint32_t)), val, SLOT(value_update(std::uint32_t)));
+ NEW_V(650, 290, true); // Memory output
+ connect(machine->core(), SIGNAL(memory_mem_value(std::uint32_t)), val, SLOT(value_update(std::uint32_t)));
+ // Write back stage
+ NEW_V(710, 330, true); // Write back value
+ connect(machine->core(), SIGNAL(writeback_value(std::uint32_t)), val, SLOT(value_update(std::uint32_t)));
+
+
connect(regs, SIGNAL(open_registers()), this, SIGNAL(request_registers()));
connect(mem_program, SIGNAL(open_mem()), this, SIGNAL(request_program_memory()));
connect(mem_data, SIGNAL(open_mem()), this, SIGNAL(request_data_memory()));
diff --git a/qtmips_gui/coreview.h b/qtmips_gui/coreview.h
index b2668c1..e4885d8 100644
--- a/qtmips_gui/coreview.h
+++ b/qtmips_gui/coreview.h
@@ -18,6 +18,7 @@
#include "coreview/constant.h"
#include "coreview/logicblock.h"
#include "coreview/and.h"
+#include "coreview/value.h"
class CoreViewScene : public QGraphicsScene {
Q_OBJECT
diff --git a/qtmips_gui/coreview/registers.cpp b/qtmips_gui/coreview/registers.cpp
index ba46f53..e4515c0 100644
--- a/qtmips_gui/coreview/registers.cpp
+++ b/qtmips_gui/coreview/registers.cpp
@@ -46,7 +46,6 @@ QRectF Registers::boundingRect() const {
void Registers::paint(QPainter *painter, const QStyleOptionGraphicsItem *option __attribute((unused)), QWidget *widget __attribute((unused))) {
painter->drawRect(0, 0, WIDTH, HEIGHT);
- // TODO anything else?
}
void Registers::setPos(qreal x, qreal y) {
diff --git a/qtmips_gui/coreview/value.cpp b/qtmips_gui/coreview/value.cpp
new file mode 100644
index 0000000..557abfe
--- /dev/null
+++ b/qtmips_gui/coreview/value.cpp
@@ -0,0 +1,51 @@
+#include "value.h"
+
+using namespace coreview;
+
+#define HEIGHT 8
+#define LETWIDTH 7
+
+// TODO orientation
+Value::Value(bool vertical, unsigned width, std::uint32_t init_val) : QGraphicsObject(nullptr) {
+ wid = width;
+ val = init_val;
+ this->vertical = vertical;
+}
+
+QRectF Value::boundingRect() const {
+ if (vertical)
+ return QRectF(-LETWIDTH/2 - 1, -HEIGHT*(int)wid/2 - 1, LETWIDTH + 2, HEIGHT*wid + 2);
+ else
+ return QRectF(-(LETWIDTH*(int)wid)/2 - 1, -HEIGHT/2 - 1, LETWIDTH*wid + 2, HEIGHT + 2);
+}
+
+void Value::paint(QPainter *painter, const QStyleOptionGraphicsItem *option __attribute__((unused)), QWidget *widget __attribute__((unused))){
+ QFont f;
+ f.setPointSize(7);
+ painter->setFont(f);
+
+ QRectF rect;
+ if (vertical)
+ rect = QRectF(-LETWIDTH/2 - 0.5, -(HEIGHT*(int)wid)/2 - 0.5, LETWIDTH + 1, HEIGHT*wid + 1);
+ else
+ rect = QRectF(-(LETWIDTH*(int)wid)/2 - 0.5, -HEIGHT/2 - 0.5, LETWIDTH*wid + 1, HEIGHT + 1);
+ painter->setBrush(QBrush(QColor(Qt::white)));
+ painter->setBackgroundMode(Qt::OpaqueMode);
+ painter->drawRect(rect);
+ painter->setBackgroundMode(Qt::TransparentMode);
+ QString str = QString("%1").arg(val, wid, 16, QChar('0'));
+ if (vertical) {
+ rect.setHeight(HEIGHT + 1);
+ for (unsigned i = 0; i < wid; i++) {
+ painter->drawText(rect, Qt::AlignCenter, QString(str[i]));
+ // TODO this is probably broken (it is offseted)
+ rect.setY(rect.y() + HEIGHT + 8);
+ }
+ } else
+ painter->drawText(rect, Qt::AlignCenter, str);
+}
+
+void Value::value_update(std::uint32_t val) {
+ this->val = val;
+ update();
+}
diff --git a/qtmips_gui/coreview/value.h b/qtmips_gui/coreview/value.h
new file mode 100644
index 0000000..c454024
--- /dev/null
+++ b/qtmips_gui/coreview/value.h
@@ -0,0 +1,30 @@
+#ifndef VALUE_H
+#define VALUE_H
+
+#include <QGraphicsObject>
+#include <QPainter>
+
+namespace coreview {
+
+class Value : public QGraphicsObject {
+ Q_OBJECT
+public:
+ Value(bool vertical = false, unsigned width = 8, unsigned init_val = 0); // width is for number of character to be shown from number
+
+ QRectF boundingRect() const;
+ void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
+
+public slots:
+ void value_update(std::uint32_t);
+
+protected:
+ std::uint32_t val;
+
+private:
+ unsigned wid;
+ bool vertical;
+};
+
+}
+
+#endif // VALUE_H
diff --git a/qtmips_gui/qtmips_gui.pro b/qtmips_gui/qtmips_gui.pro
index eb5f392..e7736f9 100644
--- a/qtmips_gui/qtmips_gui.pro
+++ b/qtmips_gui/qtmips_gui.pro
@@ -38,7 +38,8 @@ SOURCES += \
statictable.cpp \
cacheview.cpp \
cachedock.cpp \
- graphicsview.cpp
+ graphicsview.cpp \
+ coreview/value.cpp
HEADERS += \
mainwindow.h \
@@ -64,7 +65,8 @@ HEADERS += \
statictable.h \
cacheview.h \
cachedock.h \
- graphicsview.h
+ graphicsview.h \
+ coreview/value.h
FORMS += \
NewDialog.ui \
diff --git a/qtmips_machine/core.cpp b/qtmips_machine/core.cpp
index 6315a0d..481190b 100644
--- a/qtmips_machine/core.cpp
+++ b/qtmips_machine/core.cpp
@@ -1,5 +1,6 @@
#include "core.h"
#include "programloader.h"
+#include "utils.h"
using namespace machine;
@@ -125,6 +126,14 @@ struct Core::dtDecode Core::decode(const struct dtFetch &dt) {
if (!(dec.flags & DM_SUPPORTED))
throw QTMIPS_EXCEPTION(UnsupportedInstruction, "Instruction with following opcode is not supported", QString::number(dt.inst.opcode(), 16));
+ std::uint32_t val_rs = regs->read_gp(dt.inst.rs());
+ std::uint32_t val_rt = regs->read_gp(dt.inst.rt());
+
+ emit decode_instruction_value(dt.inst.data());
+ emit decode_reg1_value(val_rs);
+ emit decode_reg2_value(val_rt);
+ emit decode_immediate_value(sign_extend(dt.inst.immediate()));
+
return {
.inst = dt.inst,
.memread = dec.flags & DM_MEMREAD,
@@ -134,8 +143,8 @@ struct Core::dtDecode Core::decode(const struct dtFetch &dt) {
.regwrite = dec.flags & DM_REGWRITE,
.aluop = dt.inst.opcode() == 0 ? (enum AluOp)dt.inst.funct() : dec.alu,
.memctl = dec.mem_ctl,
- .val_rs = regs->read_gp(dt.inst.rs()),
- .val_rt = regs->read_gp(dt.inst.rt()),
+ .val_rs = val_rs,
+ .val_rt = val_rt,
};
}
@@ -149,7 +158,14 @@ struct Core::dtExecute Core::execute(const struct dtDecode &dt) {
std::uint32_t alu_sec = dt.val_rt;
if (dt.alusrc)
- alu_sec = ((dt.inst.immediate() & 0x8000) ? 0xFFFF0000 : 0) | (dt.inst.immediate()); // Sign extend to 32bit
+ alu_sec = sign_extend(dt.inst.immediate()); // Sign extend to 32bit
+
+ std::uint32_t alu_val = alu_operate(dt.aluop, dt.val_rs, alu_sec, dt.inst.shamt(), regs);
+
+ emit execute_alu_value(alu_val);
+ emit execute_reg1_value(dt.val_rs);
+ emit execute_reg2_value(dt.val_rt);
+ emit execute_immediate_value(sign_extend(dt.inst.immediate()));
return {
.inst = dt.inst,
@@ -159,7 +175,7 @@ struct Core::dtExecute Core::execute(const struct dtDecode &dt) {
.memctl = dt.memctl,
.val_rt = dt.val_rt,
.rwrite = dt.regd ? dt.inst.rd() : dt.inst.rt(),
- .alu_val = alu_operate(dt.aluop, dt.val_rs, alu_sec, dt.inst.shamt(), regs),
+ .alu_val = alu_val,
};
}
@@ -172,6 +188,10 @@ struct Core::dtMemory Core::memory(const struct dtExecute &dt) {
else if (dt.memread)
towrite_val = mem_data->read_ctl(dt.memctl, dt.alu_val);
+ emit memory_alu_value(dt.alu_val);
+ emit memory_rt_value(dt.val_rt);
+ emit memory_mem_value(dt.memread ? towrite_val : 0);
+
return {
.inst = dt.inst,
.regwrite = dt.regwrite,
@@ -182,6 +202,7 @@ struct Core::dtMemory Core::memory(const struct dtExecute &dt) {
void Core::writeback(const struct dtMemory &dt) {
emit instruction_writeback(dt.inst);
+ emit writeback_value(dt.towrite_val);
if (dt.regwrite)
regs->write_gp(dt.rwrite, dt.towrite_val);
}
diff --git a/qtmips_machine/core.h b/qtmips_machine/core.h
index 3ea18ec..64fe409 100644
--- a/qtmips_machine/core.h
+++ b/qtmips_machine/core.h
@@ -29,6 +29,19 @@ signals:
void instruction_writeback(const machine::Instruction &inst);
void instruction_program_counter(const machine::Instruction &inst);
+ void decode_instruction_value(std::uint32_t);
+ void decode_reg1_value(std::uint32_t);
+ void decode_reg2_value(std::uint32_t);
+ void decode_immediate_value(std::uint32_t);
+ void execute_alu_value(std::uint32_t);
+ void execute_reg1_value(std::uint32_t);
+ void execute_reg2_value(std::uint32_t);
+ void execute_immediate_value(std::uint32_t);
+ void memory_alu_value(std::uint32_t);
+ void memory_rt_value(std::uint32_t);
+ void memory_mem_value(std::uint32_t);
+ void writeback_value(std::uint32_t);
+
protected:
virtual void do_step() = 0;
virtual void do_reset() = 0;
diff --git a/qtmips_machine/qtmips_machine.pro b/qtmips_machine/qtmips_machine.pro
index bdce148..503832e 100644
--- a/qtmips_machine/qtmips_machine.pro
+++ b/qtmips_machine/qtmips_machine.pro
@@ -22,7 +22,8 @@ SOURCES += \
programloader.cpp \
cache.cpp \
alu.cpp \
- machineconfig.cpp
+ machineconfig.cpp \
+ utils.cpp
HEADERS += \
qtmipsmachine.h \
diff --git a/qtmips_machine/utils.cpp b/qtmips_machine/utils.cpp
new file mode 100644
index 0000000..070dc2e
--- /dev/null
+++ b/qtmips_machine/utils.cpp
@@ -0,0 +1,5 @@
+#include "utils.h"
+
+std::uint32_t sign_extend(std::uint16_t v) {
+ return ((v & 0x8000) ? 0xFFFF0000 : 0) | v;
+}
diff --git a/qtmips_machine/utils.h b/qtmips_machine/utils.h
index 7d30364..4aa615a 100644
--- a/qtmips_machine/utils.h
+++ b/qtmips_machine/utils.h
@@ -1,10 +1,14 @@
#ifndef UTILS_H
#define UTILS_H
+#include <cstdint>
+
#if __GNUC__ >= 7
#define FALLTROUGH __attribute__((fallthrough));
#else
#define FALLTROUGH
#endif
+std::uint32_t sign_extend(std::uint16_t);
+
#endif // UTILS_H