diff options
-rw-r--r-- | qtmips_gui/coreview.cpp | 33 | ||||
-rw-r--r-- | qtmips_gui/coreview.h | 1 | ||||
-rw-r--r-- | qtmips_gui/coreview/registers.cpp | 1 | ||||
-rw-r--r-- | qtmips_gui/coreview/value.cpp | 51 | ||||
-rw-r--r-- | qtmips_gui/coreview/value.h | 30 | ||||
-rw-r--r-- | qtmips_gui/qtmips_gui.pro | 6 | ||||
-rw-r--r-- | qtmips_machine/core.cpp | 29 | ||||
-rw-r--r-- | qtmips_machine/core.h | 13 | ||||
-rw-r--r-- | qtmips_machine/qtmips_machine.pro | 3 | ||||
-rw-r--r-- | qtmips_machine/utils.cpp | 5 | ||||
-rw-r--r-- | qtmips_machine/utils.h | 4 |
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 |