aboutsummaryrefslogtreecommitdiff
path: root/qtmips_gui
diff options
context:
space:
mode:
Diffstat (limited to 'qtmips_gui')
-rw-r--r--qtmips_gui/coreview.cpp105
-rw-r--r--qtmips_gui/coreview.h20
-rw-r--r--qtmips_gui/coreview/logicblock.cpp4
-rw-r--r--qtmips_gui/coreview/memory.cpp151
-rw-r--r--qtmips_gui/coreview/memory.h53
-rw-r--r--qtmips_gui/coreview/programcounter.cpp8
-rw-r--r--qtmips_gui/coreview/registers.cpp15
-rw-r--r--qtmips_gui/coreview/registers.h2
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<coreview::Connection*> 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<QString>({name})) { }
LogicBlock::LogicBlock(QVector<QString> 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;
};
}