From 507e81b60af88721780a1eb5591d884d1667c4b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karel=20Ko=C4=8D=C3=AD?= Date: Thu, 18 Jan 2018 19:54:00 +0100 Subject: More work on coreview --- qtmips_gui/coreview.cpp | 105 ++++++++++++++--------- qtmips_gui/coreview.h | 20 +++-- qtmips_gui/coreview/logicblock.cpp | 4 +- qtmips_gui/coreview/memory.cpp | 151 ++++++++++++++++++--------------- qtmips_gui/coreview/memory.h | 53 ++++++++---- qtmips_gui/coreview/programcounter.cpp | 8 +- qtmips_gui/coreview/registers.cpp | 15 ++-- qtmips_gui/coreview/registers.h | 2 +- 8 files changed, 210 insertions(+), 148 deletions(-) diff --git a/qtmips_gui/coreview.cpp b/qtmips_gui/coreview.cpp index 3e860cb..ad1572b 100644 --- a/qtmips_gui/coreview.cpp +++ b/qtmips_gui/coreview.cpp @@ -67,54 +67,67 @@ CoreViewScene::CoreViewScene(CoreView *view, machine::QtMipsMachine *machine) : // TODO remove // Elements // - NEW(ProgramCounter, pc.pc, 2, 330, machine); - NEW(Latch, pc.latch, 50, 370, machine, 20); - NEW(Adder, pc.adder, 100, 350); - struct coreview::Latch::ConnectorPair pc_latch_pair = pc.latch->new_connector(10); - NEW_B(Constant, pc.adder_4, pc.adder->connector_in_b(), "4"); - NEW(Junction, pc.junction, 80, pc_latch_pair.out->y()); - NEW(Multiplexer, pc.multiplex, 60, 100, 4); - NEW(LogicBlock, ctl_block, 300, 100, {"CPU", "Control"}); - ctl_block->setSize(35, 70); + // Primary points + NEW(ProgramMemory, mem_program, 90, 240, machine); + NEW(DataMemory, mem_data, 600, 300, machine); + NEW(Registers, regs, 210, 240); + // Fetch stage + NEW(ProgramCounter, ft.pc, 2, 280, machine); + NEW(Latch, ft.latch, 55, 250, machine, 20); + NEW(Adder, ft.adder, 100, 330); + struct coreview::Latch::ConnectorPair pc_latch_pair = ft.latch->new_connector(10); + NEW_B(Constant, ft.adder_4, ft.adder->connector_in_b(), "4"); + NEW(Junction, ft.junction, 80, mem_program->connector_address()->y()); + NEW(Multiplexer, ft.multiplex, 20, 390, 4); + // Decode stage + NEW(LogicBlock, dc.ctl_block, 230, 90, {"Control", "unit"}); + dc.ctl_block->setSize(35, 70); + NEW(LogicBlock, dc.sign_ext, 230, 360, {"Sign", "extension"}); + NEW(LogicBlock, dc.shift2, 290, 390, "<<2"); + NEW(Adder, dc.add, 320, 390); + const coreview::Connector *dc_con_sign_ext = dc.sign_ext->new_connector(1, 0); + NEW(Junction, dc.j_sign_ext, 270, dc_con_sign_ext->y()); + // Execute stage NEW(Alu, alu, 470, 230); - NEW(Memory, mem, 20, 510, machine); - NEW(Registers, regs, 20, 0); + // Memory stage NEW(Multiplexer, mem_or_reg, 570, 180, 2); - NEW_I(instr_fetch, 100, 50, instruction_fetched(const machine::Instruction&)); // Connections // coreview::Connection *con; - new_connection(pc.pc->connector_out(), pc_latch_pair.in); - new_connection(pc_latch_pair.out, pc.junction->new_connector(0)); - new_connection(pc.junction->new_connector(M_PI_2), pc.adder->connector_in_a()); - con = new_connection(pc.junction->new_connector(-M_PI_2), mem->connector_pc()); - con->setAxes({CON_AXIS_X(430)}); - con = new_connection(pc.multiplex->connector_out(), pc.pc->connector_in()); - con->setAxes({CON_AXIS_Y(90), CON_AXIS_X(80)}); - con = new_connection(pc.adder->connector_out(), pc.multiplex->connector_in(3)); - con->setAxes({CON_AXIS_Y(130), CON_AXIS_X(280), CON_AXIS_Y(55)}); + // Fetch stage + new_connection(ft.pc->connector_out(), pc_latch_pair.in); + new_connection(pc_latch_pair.out, ft.junction->new_connector(0)); + new_connection(ft.junction->new_connector(M_PI_2), ft.adder->connector_in_a()); + new_connection(ft.junction->new_connector(M_PI), mem_program->connector_address()); + new_connection(ft.multiplex->connector_out(), ft.pc->connector_in()); + con = new_connection(ft.adder->connector_out(), ft.multiplex->connector_in(0)); + con->setAxes({CON_AXIS_Y(130), CON_AXIS_X(380), CON_AXIS_Y(10)}); + // Decode stage + new_connection(dc_con_sign_ext, dc.j_sign_ext->new_connector(0)); + new_connection(dc.j_sign_ext->new_connector(-M_PI_2), dc.shift2->new_connector(-1, 0)); + new_connection(dc.shift2->new_connector(1, 0), dc.add->connector_in_a()); connect(regs, SIGNAL(open_registers()), this, SIGNAL(request_registers())); - connect(mem, SIGNAL(open_data_mem()), this, SIGNAL(request_data_memory())); - connect(mem, SIGNAL(open_program_mem()), this, SIGNAL(request_program_memory())); + connect(mem_program, SIGNAL(open_mem()), this, SIGNAL(request_program_memory())); + connect(mem_data, SIGNAL(open_mem()), this, SIGNAL(request_data_memory())); } CoreViewScene::~CoreViewScene() { for (int i = 0; i < connections.size(); i++) delete connections[i]; - delete pc.pc; - delete pc.latch; - delete pc.adder; - delete pc.adder_4; - delete pc.junction; - delete pc.multiplex; - delete ctl_block; + delete ft.pc; + delete ft.latch; + delete ft.adder; + delete ft.adder_4; + delete ft.junction; + delete ft.multiplex; + delete dc.ctl_block; delete alu; - delete mem; + delete mem_program; + delete mem_data; delete regs; delete mem_or_reg; - delete instr_fetch; } coreview::Connection *CoreViewScene::new_connection(const coreview::Connector *a, const coreview::Connector *b) { @@ -133,19 +146,28 @@ CoreViewSceneSimple::~CoreViewSceneSimple() { } CoreViewScenePipelined::CoreViewScenePipelined(CoreView *view, machine::QtMipsMachine *machine) : CoreViewScene(view, machine) { - NEW(Latch, latch_if_id, 158, 90, machine, 350); + NEW(Latch, latch_if_id, 158, 90, machine, 400); latch_if_id->setTitle("IF/ID"); - NEW(Latch, latch_id_ex, 392, 90, machine, 350); + NEW(Latch, latch_id_ex, 392, 90, machine, 400); latch_id_ex->setTitle("ID/EX"); - NEW(Latch, latch_ex_mem, 536, 90, machine, 350); + NEW(Latch, latch_ex_mem, 536, 90, machine, 400); latch_ex_mem->setTitle("EX/MEM"); - NEW(Latch, latch_mem_wb, 680, 90, machine, 350); + NEW(Latch, latch_mem_wb, 680, 90, machine, 400); latch_mem_wb->setTitle("MEM/WB"); - NEW_I(inst_dec, 250, 50, instruction_decoded(const machine::Instruction&)); - NEW_I(inst_exec, 400, 50, instruction_executed(const machine::Instruction&)); - NEW_I(inst_mem, 540, 50, instruction_memory(const machine::Instruction&)); - NEW_I(inst_wrb, 670, 50, instruction_writeback(const machine::Instruction&)); + NEW_I(inst_fetch, 100, 2, instruction_fetched(const machine::Instruction&)); + NEW_I(inst_dec, 250, 2, instruction_decoded(const machine::Instruction&)); + NEW_I(inst_exec, 400, 2, instruction_executed(const machine::Instruction&)); + NEW_I(inst_mem, 540, 2, instruction_memory(const machine::Instruction&)); + NEW_I(inst_wrb, 670, 2, instruction_writeback(const machine::Instruction&)); + + if (machine->config().hazard_unit() != machine::MachineConfig::HU_NONE) { + NEW(LogicBlock, hazard_unit, SC_WIDTH/2, SC_HEIGHT - 15, "Hazard Unit"); + hazard_unit->setSize(SC_WIDTH - 100, 12); + } + + struct coreview::Latch::ConnectorPair program_latch_pair = latch_if_id->new_connector(mem_program->connector_instruction()->y() - latch_if_id->y()); + new_connection(mem_program->connector_instruction(), program_latch_pair.in); } CoreViewScenePipelined::~CoreViewScenePipelined() { @@ -153,8 +175,11 @@ CoreViewScenePipelined::~CoreViewScenePipelined() { delete latch_id_ex; delete latch_ex_mem; delete latch_mem_wb; + delete inst_fetch; delete inst_dec; delete inst_exec; delete inst_mem; delete inst_wrb; + if (hazard_unit != nullptr) + delete hazard_unit; } diff --git a/qtmips_gui/coreview.h b/qtmips_gui/coreview.h index 25b96e3..ff2cbe2 100644 --- a/qtmips_gui/coreview.h +++ b/qtmips_gui/coreview.h @@ -40,7 +40,10 @@ signals: void request_data_memory(); void request_program_memory(); -private: +protected: + coreview::ProgramMemory *mem_program; + coreview::DataMemory *mem_data; + coreview::Registers *regs; struct { coreview::ProgramCounter *pc; coreview::Latch *latch; @@ -48,13 +51,14 @@ private: coreview::Constant *adder_4; coreview::Junction *junction; coreview::Multiplexer *multiplex; - } pc; - coreview::LogicBlock *ctl_block; + } ft; + struct { + coreview::LogicBlock *ctl_block, *sign_ext, *shift2; + coreview::Adder *add; + coreview::Junction *j_sign_ext; + } dc; coreview::Alu *alu; - coreview::Memory *mem; - coreview::Registers *regs; coreview::Multiplexer *mem_or_reg; - coreview::InstructionView *instr_fetch; QVector connections; coreview::Connection *new_connection(const coreview::Connector*, const coreview::Connector*); @@ -79,8 +83,8 @@ public: private: coreview::Latch *latch_if_id, *latch_id_ex, *latch_ex_mem, *latch_mem_wb; - coreview::InstructionView *inst_dec, *inst_exec, *inst_mem, *inst_wrb; - // TODO forwarding unit + coreview::InstructionView *inst_fetch, *inst_dec, *inst_exec, *inst_mem, *inst_wrb; + coreview::LogicBlock *hazard_unit; }; #else diff --git a/qtmips_gui/coreview/logicblock.cpp b/qtmips_gui/coreview/logicblock.cpp index 6b5769a..1ee9a18 100644 --- a/qtmips_gui/coreview/logicblock.cpp +++ b/qtmips_gui/coreview/logicblock.cpp @@ -10,9 +10,7 @@ using namespace coreview; #define PENW 1 ////////////////////// -LogicBlock::LogicBlock(QString name) { - LogicBlock({name}); -} +LogicBlock::LogicBlock(QString name) : LogicBlock(QVector({name})) { } LogicBlock::LogicBlock(QVector name) : QGraphicsItem(nullptr) { QFont font; diff --git a/qtmips_gui/coreview/memory.cpp b/qtmips_gui/coreview/memory.cpp index cde1c72..8f1669d 100644 --- a/qtmips_gui/coreview/memory.cpp +++ b/qtmips_gui/coreview/memory.cpp @@ -4,114 +4,127 @@ using namespace coreview; ////////////////////// -#define WIDTH 680 -#define HEIGHT 30 +#define WIDTH 60 +#define HEIGHT 80 +#define CACHE_HEIGHT 50 #define PENW 1 ////////////////////// -Memory::Memory(machine::QtMipsMachine *machine) : QGraphicsObject(nullptr) { - con_pc = new Connector(M_PI_2); - con_inst = new Connector(M_PI_2); - con_address = new Connector(M_PI_2); - con_data_in = new Connector(M_PI_2); - con_data_out = new Connector(M_PI_2); - con_req_write = new Connector(M_PI_2); - con_req_read = new Connector(M_PI_2); - - // TODO cache? - - name = new QGraphicsSimpleTextItem("Memory", this); - QRectF name_box = name->boundingRect(); - name->setPos(WIDTH/2 - name_box.width()/2, HEIGHT/2 - name_box.height()/2); - - // TODO add labels for connections +Memory::Memory(machine::QtMipsMachine *machine) : QGraphicsObject(nullptr), name("Memory", this), type(this) { + cache = false; QFont font; font.setPointSize(7); + name.setFont(font); + type.setFont(font); - // TODO better placement - name_program = new QGraphicsSimpleTextItem("Program", this); - name_box = name_program->boundingRect(); - name_program->setPos(1, HEIGHT - 1 - name_box.height()); - name_program->setFont(font); - - name_data = new QGraphicsSimpleTextItem("Data", this); - name_box = name_data->boundingRect(); - name_data->setPos(WIDTH - 1 - name_box.width(), HEIGHT - 1 - name_box.height()); - name_data->setFont(font); + const QRectF &name_box = name.boundingRect(); + name.setPos(WIDTH/2 - name_box.width()/2, HEIGHT - (HEIGHT - CACHE_HEIGHT)/2); setPos(x(), y()); // set connector's position } -Memory::~Memory() { - delete con_pc; - delete con_inst; - delete con_address; - delete con_data_out; - delete con_data_in; - delete con_req_write; - delete con_req_read; - - delete name; - delete name_program; - delete name_data; -} - QRectF Memory::boundingRect() const { return QRectF(-PENW / 2, -PENW / 2, WIDTH + PENW, HEIGHT + PENW); } void Memory::paint(QPainter *painter, const QStyleOptionGraphicsItem *option __attribute__((unused)), QWidget *widget __attribute__((unused))) { painter->drawRect(0, 0, WIDTH, HEIGHT); - // TODO cache + if (cache) + painter->drawLine(0, CACHE_HEIGHT, WIDTH, CACHE_HEIGHT); } -void Memory::setPos(qreal x, qreal y) { - QGraphicsObject::setPos(x, y); +void Memory::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event) { + QGraphicsObject::mouseDoubleClickEvent(event); + + if (cache && event->pos().y() < HEIGHT/2) + emit open_cache(); + else + emit open_mem(); +} - con_pc->setPos(x + 30, y); - con_inst->setPos(x + 40, y); +void Memory::set_type(const QString &text) { + type.setText(text); + const QRectF &box = type.boundingRect(); + type.setPos(WIDTH/2 - box.width()/2, HEIGHT - (HEIGHT - CACHE_HEIGHT)/2 - box.height()); +} + +ProgramMemory::ProgramMemory(machine::QtMipsMachine *machine) : Memory(machine) { + cache = machine->config().cache_program().enabled(); + set_type("Program"); - con_address->setPos(x + WIDTH - 70, y); - con_data_in->setPos(x + WIDTH - 60, y); - con_req_write->setPos(x + WIDTH- 50, y); - con_req_read->setPos(x + WIDTH - 40, y); - con_data_out->setPos(x + WIDTH - 30, y); + con_address = new Connector(0); + con_inst = new Connector(M_PI); } -const Connector *Memory::connector_pc() const { - return con_pc; +ProgramMemory::~ProgramMemory() { + delete con_address; + delete con_inst; } -const Connector *Memory::connector_inst() const { +void ProgramMemory::setPos(qreal x, qreal y) { + QGraphicsObject::setPos(x, y); + + con_address->setPos(x, y + 20); + con_inst->setPos(x + WIDTH, y + 20); +} + +const Connector *ProgramMemory::connector_address() const { + return con_address; +} + +const Connector *ProgramMemory::connector_instruction() const { return con_inst; } -const Connector *Memory::connector_address() const { +DataMemory::DataMemory(machine::QtMipsMachine *machine) : Memory(machine) { + cache = machine->config().cache_data().enabled(); + set_type("Data"); + + con_address = new Connector(0); + con_data_out = new Connector(M_PI); + con_data_in = new Connector(0); + con_req_write = new Connector(M_PI_2); + con_req_read = new Connector(M_PI_2); +} + +DataMemory::~DataMemory() { + delete con_address; + delete con_data_out; + delete con_data_in; + delete con_req_write; + delete con_req_read; +} + +void DataMemory::setPos(qreal x, qreal y) { + QGraphicsObject::setPos(x, y); + + con_address->setPos(x, y + 20); + con_data_out->setPos(x + WIDTH, y + 20); + if (cache) + con_data_in->setPos(x, y + 40); + else + con_data_in->setPos(x, y + 60); + con_req_write->setPos(x + 40, y); + con_req_read->setPos(x + 50, y); +} + +const Connector *DataMemory::connector_address() const { return con_address; } -const Connector *Memory::connector_data_out() const { +const Connector *DataMemory::connector_data_out() const { return con_data_out; } -const Connector *Memory::connector_data_in() const { +const Connector *DataMemory::connector_data_in() const { return con_data_in; } -const Connector *Memory::connector_req_write() const { +const Connector *DataMemory::connector_req_write() const { return con_req_write; } -const Connector *Memory::connector_req_read() const { +const Connector *DataMemory::connector_req_read() const { return con_req_read; } - -void Memory::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event) { - QGraphicsObject::mouseDoubleClickEvent(event); - - if (event->pos().x() < WIDTH/2) - emit open_program_mem(); - else - emit open_data_mem(); -} diff --git a/qtmips_gui/coreview/memory.h b/qtmips_gui/coreview/memory.h index 067d62f..177dc6d 100644 --- a/qtmips_gui/coreview/memory.h +++ b/qtmips_gui/coreview/memory.h @@ -14,35 +14,56 @@ class Memory : public QGraphicsObject { Q_OBJECT public: Memory(machine::QtMipsMachine *machine); - ~Memory(); QRectF boundingRect() const; void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); +signals: + void open_mem(); + void open_cache(); + +protected: + void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event); + + void set_type(const QString&); + + bool cache; + +private: + QGraphicsSimpleTextItem name, type; +}; + +class ProgramMemory : public Memory { + Q_OBJECT +public: + ProgramMemory(machine::QtMipsMachine *machine); + ~ProgramMemory(); + + void setPos(qreal x, qreal y); + + const Connector *connector_address() const; + const Connector *connector_instruction() const; + +private: + Connector *con_address, *con_inst; +}; + +class DataMemory : public Memory { + Q_OBJECT +public: + DataMemory(machine::QtMipsMachine *machine); + ~DataMemory(); + void setPos(qreal x, qreal y); - const Connector *connector_pc() const; - const Connector *connector_inst() const; + const Connector *connector_address() const; const Connector *connector_data_out() const; const Connector *connector_data_in() const; const Connector *connector_req_write() const; const Connector *connector_req_read() const; - // TODO integrate cache - -signals: - void open_data_mem(); - void open_program_mem(); - -protected: - void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event); private: - // Connectors for instruction memory - Connector *con_pc, *con_inst; - // Connectors for data memory Connector *con_address, *con_data_out, *con_data_in, *con_req_write, *con_req_read; - - QGraphicsSimpleTextItem *name, *name_program, *name_data; }; } diff --git a/qtmips_gui/coreview/programcounter.cpp b/qtmips_gui/coreview/programcounter.cpp index b66d7ac..c43ff6d 100644 --- a/qtmips_gui/coreview/programcounter.cpp +++ b/qtmips_gui/coreview/programcounter.cpp @@ -22,8 +22,8 @@ ProgramCounter::ProgramCounter(machine::QtMipsMachine *machine) : QGraphicsObjec connect(machine->registers(), SIGNAL(pc_update(std::uint32_t)), this, SLOT(pc_update(std::uint32_t))); - con_in = new Connector(M_PI_2); - con_out = new Connector(-M_PI_2); + con_in = new Connector(-M_PI_2); + con_out = new Connector(M_PI_2); setPos(x(), y()); // To set initial connectors positions } @@ -37,8 +37,8 @@ void ProgramCounter::paint(QPainter *painter, const QStyleOptionGraphicsItem *op void ProgramCounter::setPos(qreal x, qreal y) { QGraphicsObject::setPos(x, y); - con_in->setPos(x + WIDTH/2, y); - con_out->setPos(x + WIDTH/2, y + HEIGHT); + con_in->setPos(x + WIDTH/2, y + HEIGHT); + con_out->setPos(x + WIDTH/2, y); } const Connector *ProgramCounter::connector_in() const { diff --git a/qtmips_gui/coreview/registers.cpp b/qtmips_gui/coreview/registers.cpp index 12684e8..87db32e 100644 --- a/qtmips_gui/coreview/registers.cpp +++ b/qtmips_gui/coreview/registers.cpp @@ -4,12 +4,12 @@ using namespace coreview; ////////////////////// -#define WIDTH 680 -#define HEIGHT 30 +#define WIDTH 60 +#define HEIGHT 80 #define PENW 1 ////////////////////// -Registers::Registers() : QGraphicsObject(nullptr) { +Registers::Registers() : QGraphicsObject(nullptr), name("Registers", this) { con_read1 = new Connector(-M_PI_2); con_read1_reg = new Connector(-M_PI_2); con_read2 = new Connector(-M_PI_2); @@ -20,11 +20,12 @@ Registers::Registers() : QGraphicsObject(nullptr) { // TODO do we want to have any hooks on real registers? - // TODO add labels for connections + QFont font; + font.setPointSize(7); + name.setFont(font); - name = new QGraphicsSimpleTextItem("Registers", this); - QRectF name_box = name->boundingRect(); - name->setPos(WIDTH/2 - name_box.width()/2, HEIGHT/2 - name_box.height()/2); + QRectF name_box = name.boundingRect(); + name.setPos(WIDTH/2 - name_box.width()/2, HEIGHT/2 - name_box.height()/2); setPos(x(), y()); // set connector's position } diff --git a/qtmips_gui/coreview/registers.h b/qtmips_gui/coreview/registers.h index ece710d..67f09c5 100644 --- a/qtmips_gui/coreview/registers.h +++ b/qtmips_gui/coreview/registers.h @@ -36,7 +36,7 @@ private: Connector *con_read1, *con_read1_reg, *con_read2, *con_read2_reg; Connector *con_write, *con_write_reg, *con_ctl_write; - QGraphicsSimpleTextItem *name; + QGraphicsSimpleTextItem name; }; } -- cgit v1.2.3