diff options
Diffstat (limited to 'qtmips_gui')
| -rw-r--r-- | qtmips_gui/coreview.cpp | 129 | ||||
| -rw-r--r-- | qtmips_gui/coreview.h | 14 | ||||
| -rw-r--r-- | qtmips_gui/coreview/connection.cpp | 52 | ||||
| -rw-r--r-- | qtmips_gui/coreview/connection.h | 12 | ||||
| -rw-r--r-- | qtmips_gui/coreview/logicblock.cpp | 8 | ||||
| -rw-r--r-- | qtmips_gui/coreview/registers.cpp | 26 | 
6 files changed, 180 insertions, 61 deletions
| diff --git a/qtmips_gui/coreview.cpp b/qtmips_gui/coreview.cpp index 6b85cfe..0fb5e76 100644 --- a/qtmips_gui/coreview.cpp +++ b/qtmips_gui/coreview.cpp @@ -59,18 +59,21 @@ CoreViewScene::CoreViewScene(CoreView *view, machine::QtMipsMachine *machine) :      setSceneRect(0, 0, SC_WIDTH, SC_HEIGHT);      // Identification cross (TODO remove) +    /*      QPen pen;      pen.setBrush(QBrush(QColor(220, 220, 220)));      addLine(width()/2, 0, width()/2, height(), pen);      addLine(0, height()/2, width(), height()/2, pen);      addRect(0.5, 0.5, width() - 0.5, height() - 0.5, pen); +    */      // TODO remove      // Elements //      // Primary points      NEW(ProgramMemory, mem_program, 90, 240, machine); -    NEW(DataMemory, mem_data, 600, 300, machine); -    NEW(Registers, regs, 210, 240); +    NEW(DataMemory, mem_data, 580, 265, machine); +    NEW(Registers, regs, 230, 240); +    NEW(Alu, alu, 470, 225);      // Fetch stage      NEW(ProgramCounter, ft.pc, 2, 280, machine);      NEW(Latch, ft.latch, 55, 250, machine, 20); @@ -83,20 +86,23 @@ CoreViewScene::CoreViewScene(CoreView *view, machine::QtMipsMachine *machine) :      // 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); +    NEW(LogicBlock, dc.sign_ext, 250, 400, {"Sign", "extension"}); +    NEW(LogicBlock, dc.shift2, 310, 428, "<<2"); +    NEW(Adder, dc.add, 340, 428);      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()); +    NEW(Junction, dc.j_sign_ext, 290, dc_con_sign_ext->y());      NEW(LogicBlock, dc.cmp, 320, 200, "=");      NEW(And, dc.and_branch, 350, 190);      dc.cmp->setSize(24, 12); -    NEW(Junction, dc.j_inst_up, 180, 126); -    NEW(Junction, dc.j_inst_down, 180, dc_con_sign_ext->y()); +    NEW(Junction, dc.j_inst_up, 190, 126); +    NEW(Junction, dc.j_inst_down, 190, dc_con_sign_ext->y());      // Execute stage -    NEW(Alu, alu, 470, 230); -    // Memory stage -    NEW(Multiplexer, mem_or_reg, 570, 180, 2); +    NEW(Junction, ex.j_mux, 420, 316); +    NEW(Multiplexer, ex.mux_imm, 450, 306, 2); +    // Memory +    NEW(Junction, mm.j_addr, 570, mem_data->connector_address()->y()); +    // WriteBack stage +    NEW(Multiplexer, wb.mem_or_reg, 690, 252, 2);      // Connections //      coreview::Connection *con; @@ -120,11 +126,21 @@ CoreViewScene::CoreViewScene(CoreView *view, machine::QtMipsMachine *machine) :      dc.instr_bus = new_bus(dc.j_inst_up->new_connector(coreview::Connector::AX_Y), dc.j_inst_down->new_connector(coreview::Connector::AX_Y));      new_bus(dc.j_inst_up->new_connector(coreview::Connector::AX_X), dc.ctl_block->new_connector(-1, 0), 2);      new_bus(dc.j_inst_down->new_connector(coreview::Connector::AX_X), dc.sign_ext->new_connector(-1, 0), 2); +    new_bus(dc.instr_bus->new_connector(regs->connector_read1_reg()->point()), regs->connector_read1_reg(), 2); +    new_bus(dc.instr_bus->new_connector(regs->connector_read2_reg()->point()), regs->connector_read2_reg(), 2); +    // Execute stage +    new_bus(ex.j_mux->new_connector(CON_AX_X), ex.mux_imm->connector_in(0)); +    new_bus(ex.mux_imm->connector_out(), alu->connector_in_b()); +    // Memory stage +    new_bus(mm.j_addr->new_connector(CON_AX_X), mem_data->connector_address());      // From decode stage to fetch stage      con = new_signal(dc.and_branch->connector_out(), ft.multiplex->connector_ctl());      con->setAxes({CON_AXIS_Y(365), CON_AXIS_X(490)});      con = new_bus(dc.add->connector_out(), ft.multiplex->connector_in(1)); -    con->setAxes({CON_AXIS_Y(340), CON_AXIS_X(480), CON_AXIS_Y(10)}); +    con->setAxes({CON_AXIS_Y(360), CON_AXIS_X(480), CON_AXIS_Y(10)}); +    // From write back stage to decode stage +    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)});      connect(regs, SIGNAL(open_registers()), this, SIGNAL(request_registers()));      connect(mem_program, SIGNAL(open_mem()), this, SIGNAL(request_program_memory())); @@ -132,54 +148,55 @@ CoreViewScene::CoreViewScene(CoreView *view, machine::QtMipsMachine *machine) :  }  CoreViewScene::~CoreViewScene() { -    for (int i = 0; i < connections.size(); i++) -        delete connections[i]; - -    delete ft.pc; -    delete ft.latch; -    delete ft.adder; -    delete ft.adder_4; -    delete ft.junc_pc; -    delete ft.junc_pc_4; -    delete ft.multiplex; -    delete dc.ctl_block; -    delete dc.sign_ext; -    delete dc.shift2; -    delete dc.cmp; -    delete dc.add; -    delete dc.j_sign_ext; -    delete dc.and_branch; -    delete alu; -    delete mem_program; -    delete mem_data; -    delete regs; -    delete mem_or_reg; +    // We add all items to scene and they are removed in QGraphicsScene descructor so we don't have to care about them here  }  coreview::Connection *CoreViewScene::new_connection(const coreview::Connector *a, const coreview::Connector *b) {      coreview::Connection *c = new coreview::Connection(a, b); -    connections.append(c);      addItem(c); +    c->setZValue(-1); // hide connections under neath the items      return c;  }  coreview::Bus *CoreViewScene::new_bus(const coreview::Connector *a, const coreview::Connector *b, unsigned width) {      coreview::Bus *c = new coreview::Bus(a, b, width); -    connections.append(c);      addItem(c); +    c->setZValue(-2); // hide connections under neath the items      return c;  }  coreview::Signal *CoreViewScene::new_signal(const coreview::Connector *a, const coreview::Connector *b) {      coreview::Signal *c = new coreview::Signal(a, b); -    connections.append(c);      addItem(c); -    c->setZValue(-1); // hide connections under neath the items +    c->setZValue(-3); // hide connections under neath the items      return c;  }  CoreViewSceneSimple::CoreViewSceneSimple(CoreView *view, machine::QtMipsMachine *machine) : CoreViewScene(view, machine) { -    NEW(Latch, delay_slot_latch, 160, 50, machine, 150); +    NEW(Latch, delay_slot_latch, 55, 460, machine, 50); + +    coreview::Connection *con; +    // Fetch stage +    new_bus(mem_program->connector_instruction(), dc.instr_bus->new_connector(mem_program->connector_instruction()->point())); +    con = new_bus(ft.junc_pc_4->new_connector(coreview::Connector::AX_Y), dc.add->connector_in_b()); +    con->setAxes({CON_AXIS_Y(270)}); +    // Decode stage +    con = new_bus(regs->connector_read1(), alu->connector_in_a()); +    con->setAxes({CON_AXIS_Y(445)}); +    con = new_bus(regs->connector_read2(), ex.mux_imm->connector_in(0)); +    con->setAxes({CON_AXIS_Y(420)}); +    con = new_bus(dc.j_sign_ext->new_connector(coreview::Connector::AX_X), ex.mux_imm->connector_in(1)); +    con->setAxes({CON_AXIS_Y(440)}); +    // Execute +    new_bus(alu->connector_out(), mm.j_addr->new_connector(CON_AX_X)); +    con = new_bus(ex.j_mux->new_connector(CON_AX_Y), mem_data->connector_data_in()); +    con->setAxes({CON_AXIS_X(360), CON_AXIS_Y(560)}); +    // Memory +    con = new_bus(mm.j_addr->new_connector(CON_AX_Y), wb.mem_or_reg->connector_in(0)); +    con->setAxes({CON_AXIS_X(250), CON_AXIS_Y(678)}); +    con = new_bus(mem_data->connector_data_out(), wb.mem_or_reg->connector_in(1)); +    con->setAxes({CON_AXIS_Y(678)}); +    // WriteBack  }  CoreViewSceneSimple::~CoreViewSceneSimple() { @@ -193,7 +210,7 @@ CoreViewScenePipelined::CoreViewScenePipelined(CoreView *view, machine::QtMipsMa      latch_id_ex->setTitle("ID/EX");      NEW(Latch, latch_ex_mem, 536, 90, machine, 380);      latch_ex_mem->setTitle("EX/MEM"); -    NEW(Latch, latch_mem_wb, 680, 90, machine, 380); +    NEW(Latch, latch_mem_wb, 660, 90, machine, 380);      latch_mem_wb->setTitle("MEM/WB");      NEW_I(inst_fetch, 100, 2, instruction_fetched(const machine::Instruction&)); @@ -214,9 +231,39 @@ CoreViewScenePipelined::CoreViewScenePipelined(CoreView *view, machine::QtMipsMa      struct coreview::Latch::ConnectorPair lp_ft_pc = latch_if_id->new_connector(370);      new_bus(ft.junc_pc_4->new_connector(coreview::Connector::AX_Y), lp_ft_pc.in);      // Decode stage -    //new_bus(lp_ft_inst.out, dc.instr_bus->new_connector(lp_ft_inst.out->point())); +    new_bus(lp_ft_inst.out, dc.instr_bus->new_connector(lp_ft_inst.out->point()));      con = new_bus(lp_ft_pc.out, dc.add->connector_in_b());      con->setAxes({CON_AXIS_Y(270)}); +    struct coreview::Latch::ConnectorPair lp_dc_rs = latch_id_ex->new_connector(regs->connector_read1()->y() - latch_id_ex->y()); +    struct coreview::Latch::ConnectorPair lp_dc_rt = latch_id_ex->new_connector(regs->connector_read2()->y() - latch_id_ex->y()); +    new_bus(regs->connector_read1(), lp_dc_rs.in); +    new_bus(regs->connector_read2(), lp_dc_rt.in); +    struct coreview::Latch::ConnectorPair lp_dc_immed = latch_id_ex->new_connector(dc.j_sign_ext->y() - latch_id_ex->y()); +    new_bus(dc.j_sign_ext->new_connector(coreview::Connector::AX_X), lp_dc_immed.in); +    // Execute +    con = new_bus(lp_dc_rs.out, alu->connector_in_a()); +    con->setAxes({CON_AXIS_Y(445)}); +    con = new_bus(lp_dc_rt.out, ex.mux_imm->connector_in(0)); +    con->setAxes({CON_AXIS_Y(420)}); +    con = new_bus(lp_dc_immed.out, ex.mux_imm->connector_in(1)); +    con->setAxes({CON_AXIS_Y(440)}); +    struct coreview::Latch::ConnectorPair lp_ex_alu = latch_ex_mem->new_connector(alu->connector_out()->y() - latch_ex_mem->y()); +    struct coreview::Latch::ConnectorPair lp_ex_dt = latch_ex_mem->new_connector(270); +    new_bus(alu->connector_out(), lp_ex_alu.in); +    new_bus(ex.j_mux->new_connector(CON_AX_Y), lp_ex_dt.in); +    // Memory +    new_bus(lp_ex_alu.out, mm.j_addr->new_connector(CON_AX_X)); +    con = new_bus(lp_ex_dt.out, mem_data->connector_data_in()); +    con->setAxes({CON_AXIS_Y(560)}); +    struct coreview::Latch::ConnectorPair lp_mem_alu = latch_mem_wb->new_connector(160); +    struct coreview::Latch::ConnectorPair lp_mem_mem = latch_mem_wb->new_connector(mem_data->connector_data_out()->y() - latch_mem_wb->y()); +    new_bus(mm.j_addr->new_connector(CON_AX_Y), lp_mem_alu.in); +    new_bus(mem_data->connector_data_out(), lp_mem_mem.in); +    // WriteBack +    con = new_bus(lp_mem_alu.out, wb.mem_or_reg->connector_in(0)); +    con->setAxes({CON_AXIS_Y(678)}); +    con = new_bus(lp_mem_mem.out, wb.mem_or_reg->connector_in(1)); +    con->setAxes({CON_AXIS_Y(678)});  }  CoreViewScenePipelined::~CoreViewScenePipelined() { diff --git a/qtmips_gui/coreview.h b/qtmips_gui/coreview.h index edc970c..ed8a8ad 100644 --- a/qtmips_gui/coreview.h +++ b/qtmips_gui/coreview.h @@ -45,6 +45,7 @@ protected:      coreview::ProgramMemory *mem_program;      coreview::DataMemory *mem_data;      coreview::Registers *regs; +    coreview::Alu *alu;      struct {          coreview::ProgramCounter *pc;          coreview::Latch *latch; @@ -61,10 +62,17 @@ protected:          coreview::Junction *j_inst_up, *j_inst_down;          coreview::Bus *instr_bus;      } dc; -    coreview::Alu *alu; -    coreview::Multiplexer *mem_or_reg; +    struct { +        coreview::Junction *j_mux; +        coreview::Multiplexer *mux_imm; +    } ex; +    struct { +        coreview::Junction *j_addr; +    } mm; +    struct { +        coreview::Multiplexer *mem_or_reg; +    } wb; -    QVector<coreview::Connection*> connections;      coreview::Connection *new_connection(const coreview::Connector*, const coreview::Connector*);      coreview::Bus *new_bus(const coreview::Connector*, const coreview::Connector*, unsigned width = 4);      coreview::Signal *new_signal(const coreview::Connector*, const coreview::Connector*); diff --git a/qtmips_gui/coreview/connection.cpp b/qtmips_gui/coreview/connection.cpp index 3355eed..31d93e5 100644 --- a/qtmips_gui/coreview/connection.cpp +++ b/qtmips_gui/coreview/connection.cpp @@ -1,4 +1,5 @@  #include "connection.h" +#include <qtmipsexception.h>  #include <cmath>  using namespace coreview; @@ -14,6 +15,10 @@ void Connector::setPos(qreal x, qreal y) {      emit updated(vector());  } +void Connector::setPos(const QPointF &p) { +    setPos(p.x(), p.y()); +} +  enum Connector::Axis Connector::axis() const {      return ax;  } @@ -42,6 +47,7 @@ QLineF Connector::vector() const {      case AX_MXY:          return QLineF(p, p + QPoint(1, -1));      } +    throw QTMIPS_EXCEPTION(Sanity, "Connection::vector() unknown axes set", QString::number(ax));  }  Connection::Connection(const Connector *a, const Connector *b) : QGraphicsObject(nullptr) { @@ -134,13 +140,23 @@ Bus::Bus(const Connector *start, const Connector *end, unsigned width) : Connect      pen_width = width;  } +Bus::~Bus() { +    for (int i = 0; i < conns.size(); i++) +        delete conns[i].c; +} + +void Bus::setAxes(QVector<QLineF> axes) { +    Connection::setAxes(axes); +    conns_update(); +} +  const Connector *Bus::new_connector(qreal x, qreal y, enum Connector::Axis axis) {      Connector *c = new Connector(axis);      conns.append({          .c = c,          .p = QPoint(x, y)       }); -    // TODO update positions +    conns_update();      return c;  } @@ -148,6 +164,40 @@ const Connector *Bus::new_connector(const QPointF &p, enum Connector::Axis axis)      return new_connector(p.x(), p.y(), axis);  } +// Calculate closes point to given line. We do it by calculating rectangular intersection between given line and imaginary line crossing given point. +static qreal cu_closest(const QLineF &l, const QPointF &p, QPointF *intersec) { +    // Closest point is on normal vector +    QLineF normal = l.normalVector(); +    // Now move normal vector to 0,0 and then to p +    QLineF nline = normal.translated(-normal.p1()).translated(p); +    // And now found intersection +    SANITY_ASSERT(l.intersect(nline, intersec) != QLineF::NoIntersection, "We are calculating intersection with normal vector and that should always have intersection"); +    // Now check if that point belongs to given line +    // We know that this is intersection so just check if we are not outside of line limits +    // TODO replace intersec if it's outside of given line with one of corner points + +    return (p - *intersec).manhattanLength(); // return length from each other +} + +void Bus::conns_update() { +    for (int i = 0; i < conns.size(); i++) { +        QPointF closest; +        qreal closest_range = 0; // Just to suppress warning. On first check the closest is null so we set it later on + +        QPointF inter; +        qreal range; +        for (int y = 0; y < (points.size() - 1); y++) { +            range = cu_closest(QLineF(points[y], points[y+1]), QPointF(conns[i].p), &inter); +            if (closest.isNull() || closest_range > range) { +                closest = inter; +                closest_range = range; +            } +        } + +        conns[i].c->setPos(closest); +    } +} +  Signal::Signal(const Connector *start, const Connector *end) : Connection(start, end) {      color = QColor(0, 0, 255);  } diff --git a/qtmips_gui/coreview/connection.h b/qtmips_gui/coreview/connection.h index 88ad1da..fa40d95 100644 --- a/qtmips_gui/coreview/connection.h +++ b/qtmips_gui/coreview/connection.h @@ -20,6 +20,7 @@ public:      Connector(enum Axis axis = AX_X);      void setPos(qreal x, qreal y); +    void setPos(const QPointF&);      enum Axis axis() const;      qreal x() const; @@ -48,7 +49,7 @@ public:      void setHasText(bool has);      void setText(QString val); -    void setAxes(QVector<QLineF>); +    virtual void setAxes(QVector<QLineF>);  private slots:      void moved_start(QLineF); @@ -71,6 +72,9 @@ protected:  class Bus : public Connection {  public:      Bus(const Connector *start, const Connector *end, unsigned width = 4); +    ~Bus(); + +    void setAxes(QVector<QLineF>);      // This creates connector snapped to closes point to x,y that is on bus      const Connector *new_connector(qreal x, qreal y, enum Connector::Axis = Connector::AX_X); @@ -82,6 +86,7 @@ protected:          QPointF p;      };      QVector<struct con_pos> conns; +    void conns_update();      // TODO because of this we have to overload setAxis function and update that in there  }; @@ -90,6 +95,11 @@ public:      Signal(const Connector *start, const Connector *end);  }; +#define CON_AX_X (coreview::Connector::AX_X) +#define CON_AX_Y (coreview::Connector::AX_Y) +#define CON_AX_XY (coreview::Connector::AX_XY) +#define CON_AX_MXY (coreview::Connector::AX_MXY) +  #define CON_AXIS_X(Y) QLineF(QPointF(0, Y), QPointF(1, Y))  #define CON_AXIS_Y(X) QLineF(QPointF(X, 0), QPointF(X, 1)) diff --git a/qtmips_gui/coreview/logicblock.cpp b/qtmips_gui/coreview/logicblock.cpp index 2e74a77..35ff0c4 100644 --- a/qtmips_gui/coreview/logicblock.cpp +++ b/qtmips_gui/coreview/logicblock.cpp @@ -91,7 +91,11 @@ const Connector *LogicBlock::new_connector(qreal x, qreal y) {  QPointF LogicBlock::con_pos(qreal x, qreal y) {      qreal px, py; -    px = (box.right() - GAP) * x + (GAP * sign(x)); -    py = (box.bottom()/2 - GAP) * (y + 1) + (GAP * sign(y)); +    px = (box.right() - GAP) * x; +    py = (box.bottom()/2 - GAP) * (y + 1) + GAP; +    if (fabs(x) == 1) +        px += GAP * sign(x); +    if (fabs(y) == 1) +        py += GAP * sign(y);      return QPointF(px, py);  } diff --git a/qtmips_gui/coreview/registers.cpp b/qtmips_gui/coreview/registers.cpp index 9a4fcff..2b1c1b5 100644 --- a/qtmips_gui/coreview/registers.cpp +++ b/qtmips_gui/coreview/registers.cpp @@ -10,12 +10,12 @@ using namespace coreview;  //////////////////////  Registers::Registers() : QGraphicsObject(nullptr), name("Registers", this) { -    con_read1 = new Connector(Connector::AX_Y); -    con_read1_reg = new Connector(Connector::AX_Y); -    con_read2 = new Connector(Connector::AX_Y); -    con_read2_reg = new Connector(Connector::AX_Y); -    con_write = new Connector(Connector::AX_Y); -    con_write_reg = new Connector(Connector::AX_Y); +    con_read1 = new Connector(Connector::AX_X); +    con_read1_reg = new Connector(Connector::AX_X); +    con_read2 = new Connector(Connector::AX_X); +    con_read2_reg = new Connector(Connector::AX_X); +    con_write = new Connector(Connector::AX_X); +    con_write_reg = new Connector(Connector::AX_X);      con_ctl_write = new Connector(Connector::AX_Y);      // TODO do we want to have any hooks on real registers? @@ -52,14 +52,14 @@ void Registers::paint(QPainter *painter, const QStyleOptionGraphicsItem *option  void Registers::setPos(qreal x, qreal y) {      QGraphicsObject::setPos(x, y); -    con_read1_reg->setPos(x + 30, y + HEIGHT); -    con_read2_reg->setPos(x + 40, y + HEIGHT); -    con_read1->setPos(x + 60, y + HEIGHT); -    con_read2->setPos(x + 70, y + HEIGHT); +    con_read1_reg->setPos(x, y + 10); +    con_read2_reg->setPos(x, y + 30); +    con_read1->setPos(x + WIDTH, y + 10); +    con_read2->setPos(x + WIDTH, y + 30); -    con_write_reg->setPos(x + WIDTH - 40, y + HEIGHT); -    con_write->setPos(x + WIDTH - 30, y + HEIGHT); -    con_ctl_write->setPos(x + WIDTH - 20, y + HEIGHT); +    con_write_reg->setPos(x + WIDTH/2, y); +    con_write->setPos(x, y + HEIGHT - 10); +    con_ctl_write->setPos(x, y + HEIGHT - 20);  }  const Connector *Registers::connector_read1() const { | 
