diff options
-rw-r--r-- | qtmips_gui/coreview.cpp | 3 | ||||
-rw-r--r-- | qtmips_gui/coreview.h | 2 | ||||
-rw-r--r-- | qtmips_gui/coreview/logicblock.cpp | 99 | ||||
-rw-r--r-- | qtmips_gui/coreview/logicblock.h | 44 | ||||
-rw-r--r-- | qtmips_gui/qtmips_gui.pro | 6 |
5 files changed, 152 insertions, 2 deletions
diff --git a/qtmips_gui/coreview.cpp b/qtmips_gui/coreview.cpp index 8fe7432..3e860cb 100644 --- a/qtmips_gui/coreview.cpp +++ b/qtmips_gui/coreview.cpp @@ -74,6 +74,8 @@ CoreViewScene::CoreViewScene(CoreView *view, machine::QtMipsMachine *machine) : 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); NEW(Alu, alu, 470, 230); NEW(Memory, mem, 20, 510, machine); NEW(Registers, regs, 20, 0); @@ -107,6 +109,7 @@ CoreViewScene::~CoreViewScene() { delete pc.adder_4; delete pc.junction; delete pc.multiplex; + delete ctl_block; delete alu; delete mem; delete regs; diff --git a/qtmips_gui/coreview.h b/qtmips_gui/coreview.h index 8adf302..25b96e3 100644 --- a/qtmips_gui/coreview.h +++ b/qtmips_gui/coreview.h @@ -15,6 +15,7 @@ #include "coreview/instructionview.h" #include "coreview/junction.h" #include "coreview/constant.h" +#include "coreview/logicblock.h" class CoreView : public QGraphicsView { public: @@ -48,6 +49,7 @@ private: coreview::Junction *junction; coreview::Multiplexer *multiplex; } pc; + coreview::LogicBlock *ctl_block; coreview::Alu *alu; coreview::Memory *mem; coreview::Registers *regs; diff --git a/qtmips_gui/coreview/logicblock.cpp b/qtmips_gui/coreview/logicblock.cpp new file mode 100644 index 0000000..6b5769a --- /dev/null +++ b/qtmips_gui/coreview/logicblock.cpp @@ -0,0 +1,99 @@ +#include "logicblock.h" +#include <cmath> + +using namespace coreview; + +////////////////////// +#define GAP 3 +#define RADIUS GAP +#define LINE_OFFSET 1 +#define PENW 1 +////////////////////// + +LogicBlock::LogicBlock(QString name) { + LogicBlock({name}); +} + +LogicBlock::LogicBlock(QVector<QString> name) : QGraphicsItem(nullptr) { + QFont font; + font.setPointSize(7); + + qreal h = 0, w = 0; + for (int i = 0; i < name.size(); i++) { + QGraphicsSimpleTextItem *t = new QGraphicsSimpleTextItem(name[i], this); + t->setFont(font); + text.append(t); + QRectF t_box = t->boundingRect(); + t->setPos(-t_box.width()/2, h + LINE_OFFSET); + h += t_box.height() + LINE_OFFSET; + if (w < t_box.width()) + w = t_box.width(); + } + + box = QRectF(-w/2 - GAP, -GAP, w + (2*GAP), h + (2*GAP)); +} + +LogicBlock::~LogicBlock() { + for (int i = 0; i < connectors.size(); i++) + delete connectors[i].con; + for (int i = 0; i < text.size(); i++) + delete text[i]; +} + +QRectF LogicBlock::boundingRect() const { + return QRectF(box.x() - PENW/2, box.y() - PENW/2, box.width() + PENW, box.height() + PENW); +} + +void LogicBlock::paint(QPainter *painter, const QStyleOptionGraphicsItem *option __attribute__((unused)), QWidget *widget __attribute__((unused))) { + painter->drawRoundedRect(box, RADIUS, RADIUS); +} + +void LogicBlock::setPos(qreal x, qreal y) { + QGraphicsItem::setPos(x, y); + for (int i = 0; i < connectors.size(); i++) { + struct Con &c = connectors[i]; + c.con->setPos(x + c.p.x(), y + c.p.y()); + } +} + +void LogicBlock::setSize(qreal width, qreal height) { + box.setX(-width/2 - GAP); + box.setWidth(width + (2*GAP)); + box.setHeight(height + (2*GAP)); + for (int i = 0; i < connectors.size(); i++) { // Update point for all connectors + struct Con &c = connectors[i]; + c.p = con_pos(c.x, c.y); + } + setPos(x(), y()); +} + +static qreal sign(qreal v) { + // This intentionally doesn't return 0 on v == 0 + return (0 <= v) - (0 > v); +} + +const Connector *LogicBlock::new_connector(qreal x, qreal y) { + // stick to closest edge + if (fabs(x) > fabs(y)) + x = sign(x); + else + y = sign(y); + + // Note: we are using here that 0 and M_PI is same angle but different orientation (but we ignore orientation for now) + Connector *c = new Connector(fabs(x) > fabs(y) ? 0 : M_PI_2); + connectors.append({ + .con = c, + .x = x, + .y = y, + .p = con_pos(x, y) + }); + setPos(this->x(), this->y()); // Update connector position + return c; +} + +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)); + return QPointF(px, py); +} diff --git a/qtmips_gui/coreview/logicblock.h b/qtmips_gui/coreview/logicblock.h new file mode 100644 index 0000000..4c1310c --- /dev/null +++ b/qtmips_gui/coreview/logicblock.h @@ -0,0 +1,44 @@ +#ifndef LOGICBLOCK_H +#define LOGICBLOCK_H + +#include <QGraphicsItem> +#include <QPainter> +#include <QGraphicsSimpleTextItem> +#include <QVector> +#include "connection.h" + +namespace coreview { + +class LogicBlock : public QGraphicsItem { +public: + LogicBlock(QString name); + LogicBlock(QVector<QString> name); + ~LogicBlock(); + + QRectF boundingRect() const; + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); + + void setPos(qreal x, qreal y); + void setSize(qreal width, qreal height); + + // This creates new connector + // Position is determined by x and y in 0 to 1 range and is mapped to real size of this block + // Using x=y and x=-y coordinates is not supported + const Connector *new_connector(qreal x, qreal y); + +private: + QVector<QGraphicsSimpleTextItem*> text; + QRectF box; + + struct Con { + Connector *con; + qreal x, y; + QPointF p; + }; + QVector<struct Con> connectors; + QPointF con_pos(qreal x, qreal y); +}; + +} + +#endif // LOGICBLOCK_H diff --git a/qtmips_gui/qtmips_gui.pro b/qtmips_gui/qtmips_gui.pro index 921bb2d..a71509e 100644 --- a/qtmips_gui/qtmips_gui.pro +++ b/qtmips_gui/qtmips_gui.pro @@ -31,7 +31,8 @@ SOURCES += \ coreview/registers.cpp \ coreview/adder.cpp \ coreview/constant.cpp \ - coreview/junction.cpp + coreview/junction.cpp \ + coreview/logicblock.cpp HEADERS += \ mainwindow.h \ @@ -51,7 +52,8 @@ HEADERS += \ coreview/registers.h \ coreview/adder.h \ coreview/constant.h \ - coreview/junction.h + coreview/junction.h \ + coreview/logicblock.h FORMS += \ NewDialog.ui \ |