Draw state seperation lines and instruction text
MODIFY
RISC-V-sim.pro
RISC-V-sim.pro
@@ -35,7 +35,8 @@ SOURCES += src/main.cpp \
src/graphics/connection.cpp \
src/graphics/pipelinewidget.cpp \
src/registercontainerwidget.cpp \
- src/aboutwidget.cpp
+ src/aboutwidget.cpp \
+ src/graphics/backgrounditems.cpp
HEADERS += \
src/parser.h \
@@ -66,7 +67,8 @@ HEADERS += \
src/graphics/connection.h \
src/graphics/pipelinewidget.h \
src/registercontainerwidget.h \
- src/aboutwidget.h
+ src/aboutwidget.h \
+ src/graphics/backgrounditems.h
FORMS += \
src/mainwindow.ui \

ADD
src/graphics/backgrounditems.cpp
+#include "backgrounditems.h"
+#include "defines.h"
+#include "shape.h"
+
+#include <QFont>
+#include <QFontMetrics>
+#include <QPainter>
+#include <QRectF>
+
+namespace Graphics {
+
+DashLine::DashLine(Shape* reg) { m_regPtr = reg; }
+
+QRectF DashLine::boundingRect() const {
+ auto regRect = m_regPtr->sceneBoundingRect();
+ return QRectF(QPointF(regRect.left(), regRect.top() - dashHeight),
+ QPointF(regRect.right(), regRect.bottom() + dashHeight));
+}
+
+void DashLine::paint(QPainter* painter, const QStyleOptionGraphicsItem*,
+ QWidget*) {
+ QPen pen(Qt::DashLine);
+ pen.setColor(Colors::FoundersRock);
+ pen.setWidth(2);
+ painter->setPen(pen);
+ auto regRect = m_regPtr->sceneBoundingRect();
+ painter->drawLine(
+ QPointF(regRect.left() + (regRect.width() / 2),
+ regRect.top() - dashHeight),
+ QPointF(regRect.left() + (regRect.width() / 2), regRect.top()));
+
+ painter->drawLine(
+ QPointF(regRect.left() + (regRect.width() / 2), regRect.bottom()),
+ QPointF(regRect.left() + (regRect.width() / 2),
+ regRect.bottom() + dashHeight));
+}
+
+Text::Text(QPointF pos) {
+ m_pos = pos;
+ m_font = QFont("Monospace");
+ m_font.setStyleHint(QFont::Monospace);
+ m_font.setPointSize(12);
+}
+
+QRectF Text::boundingRect() const {
+ QFontMetrics obj(m_font);
+ auto rect = obj.boundingRect(*m_text);
+ rect.moveTo(m_pos.toPoint());
+ return rect;
+}
+
+void Text::paint(QPainter* painter, const QStyleOptionGraphicsItem*, QWidget*) {
+ QFontMetrics obj(m_font);
+ QRectF rect = obj.boundingRect(*m_text);
+ rect.moveTo(m_pos.toPoint());
+ rect.translate(-rect.width() / 2, -rect.height() / 2);
+ painter->setFont(m_font);
+ painter->drawText(rect, Qt::AlignCenter, *m_text);
+}
+
+} // namespace Graphics

ADD
src/graphics/backgrounditems.h
+#ifndef BACKGROUNDITEMS_H
+#define BACKGROUNDITEMS_H
+
+#include <QFont>
+#include <QGraphicsItem>
+
+namespace Graphics {
+class Shape;
+
+class DashLine : public QGraphicsItem {
+ public:
+ DashLine(Shape* reg);
+ QRectF boundingRect() const;
+ void paint(QPainter* painter, const QStyleOptionGraphicsItem* option,
+ QWidget* widget);
+
+ private:
+ Shape* m_regPtr;
+ constexpr static int dashHeight = 100;
+};
+
+class Text : public QGraphicsItem {
+ public:
+ Text(QPointF pos);
+ void setTextPtr(QString* text) { m_text = text; }
+ QRectF boundingRect() const;
+ void paint(QPainter* painter, const QStyleOptionGraphicsItem* option,
+ QWidget* widget);
+
+ private:
+ QString* m_text;
+ QFont m_font;
+ QPointF m_pos;
+};
+
+} // namespace Graphics
+
+#endif // BACKGROUNDITEMS_H

MODIFY
src/graphics/pipelinewidget.cpp
src/graphics/pipelinewidget.cpp
#include "pipelinewidget.h"
+#include "backgrounditems.h"
#include "connection.h"
#include "defines.h"
#include "shape.h"
@@ -13,22 +14,15 @@ PipelineWidget::PipelineWidget(QWidget* parent) : QGraphicsView(parent) {
QGraphicsScene* scene = new QGraphicsScene(this);
scene->setItemIndexMethod(QGraphicsScene::NoIndex);
setScene(scene);
- setCacheMode(CacheBackground);
+ // setCacheMode(CacheBackground);
setRenderHint(QPainter::Antialiasing);
setRenderHint(QPainter::TextAntialiasing);
setDragMode(QGraphicsView::ScrollHandDrag);
- // Create some temporary instructions to draw
- if_instr = new QString("and x12, x2, x5");
- id_instr = new QString("beq x1, x3, 16");
- ex_instr = new QString("sub x10, x4, x8");
- mem_instr = new QString("nop");
- wb_instr = new QString("rd x10 24 x2");
-
// ------------ Create pipeline objects ---------------
// Registers memory
- Graphics::Shape* registers = new Graphics::Shape(Graphics::ShapeType::Block,
- Graphics::Stage::ID, 10, 15);
+ Graphics::Shape* registers = new Graphics::Shape(
+ Graphics::ShapeType::Block, Graphics::Stage::ID, 10, 15);
registers->addInput(QStringList() << "Read\nregister 1"
<< "Read\nregister 2"
<< "Write\nregister"
@@ -38,16 +32,16 @@ PipelineWidget::PipelineWidget(QWidget* parent) : QGraphicsView(parent) {
registers->setName("Registers");
// Data memory
- Graphics::Shape* data_mem = new Graphics::Shape(Graphics::ShapeType::Block,
- Graphics::Stage::MEM, 50, 5);
+ Graphics::Shape* data_mem = new Graphics::Shape(
+ Graphics::ShapeType::Block, Graphics::Stage::MEM, 50, 5);
data_mem->addInput(QStringList() << "Address"
<< "Write\ndata");
data_mem->addOutput(QStringList() << "Read\ndata");
data_mem->setName("Data\nmemory");
// Instruction memory
- Graphics::Shape* instr_mem = new Graphics::Shape(Graphics::ShapeType::Block,
- Graphics::Stage::IF, 60, 0);
+ Graphics::Shape* instr_mem = new Graphics::Shape(
+ Graphics::ShapeType::Block, Graphics::Stage::IF, 60, 0);
instr_mem->addInput(QStringList() << "Read\naddress");
instr_mem->addOutput(QStringList() << "Instruction");
instr_mem->setName("Instruction\nmemory");
@@ -98,8 +92,8 @@ PipelineWidget::PipelineWidget(QWidget* parent) : QGraphicsView(parent) {
alu3->addOutput("");
// State registers
- ifid = new Graphics::Shape(Graphics::ShapeType::Block, Graphics::Stage::ID, 0,
- 10);
+ ifid = new Graphics::Shape(Graphics::ShapeType::Block, Graphics::Stage::ID,
+ 0, 10);
ifid->setName("IF/ID");
ifid->setFixedHeight(true, stateRegHeight);
for (int i = 0; i < 2; i++) {
@@ -107,8 +101,8 @@ PipelineWidget::PipelineWidget(QWidget* parent) : QGraphicsView(parent) {
ifid->addOutput("");
}
- idex = new Graphics::Shape(Graphics::ShapeType::Block, Graphics::Stage::EX, 0,
- 10);
+ idex = new Graphics::Shape(Graphics::ShapeType::Block, Graphics::Stage::EX,
+ 0, 10);
idex->setName("ID/EX");
idex->setFixedHeight(true, stateRegHeight);
for (int i = 0; i < 9; i++) {
@@ -208,7 +202,8 @@ PipelineWidget::PipelineWidget(QWidget* parent) : QGraphicsView(parent) {
createConnection(idex, 6, mux2, 1);
// MEM
connPtr = createConnection(exmem, 0, mux1, 1);
- connPtr->setFeedbackSettings(false, minConnectionLen - 20, minConnectionLen);
+ connPtr->setFeedbackSettings(false, minConnectionLen - 20,
+ minConnectionLen);
connPtr->setKinkBias(70);
createConnection(exmem, 1, data_mem, 0);
@@ -229,7 +224,6 @@ PipelineWidget::PipelineWidget(QWidget* parent) : QGraphicsView(parent) {
// other
// items position relative to these
- int spaceBetweenStateRegs = 300;
// Position state registers
ifid->moveBy(0, 0);
idex->moveBy(spaceBetweenStateRegs * 1, 0);
@@ -266,6 +260,50 @@ PipelineWidget::PipelineWidget(QWidget* parent) : QGraphicsView(parent) {
// position WB stage
moveToIO(mux3, memwb, mux3->getInputPoint(0), memwb->getOutputPoint(0),
-minConnectionLen);
+
+ // ----------- Create Etc. objects -----------
+ Graphics::DashLine* dash1 = new Graphics::DashLine(ifid);
+ Graphics::DashLine* dash2 = new Graphics::DashLine(idex);
+ Graphics::DashLine* dash3 = new Graphics::DashLine(exmem);
+ Graphics::DashLine* dash4 = new Graphics::DashLine(memwb);
+
+ scene->addItem(dash1);
+ scene->addItem(dash2);
+ scene->addItem(dash3);
+ scene->addItem(dash4);
+
+ int textPad = 20;
+ Graphics::Text* if_instr = new Graphics::Text(QPointF(
+ -dash1->sceneBoundingRect().left() +
+ dash1->sceneBoundingRect().width() / 2 + -spaceBetweenStateRegs / 2,
+ dash1->sceneBoundingRect().top() + textPad));
+ Graphics::Text* id_instr = new Graphics::Text(QPointF(
+ dash1->sceneBoundingRect().left() +
+ dash1->sceneBoundingRect().width() / 2 + spaceBetweenStateRegs / 2,
+ dash1->sceneBoundingRect().top() + textPad));
+ Graphics::Text* ex_instr = new Graphics::Text(QPointF(
+ dash2->sceneBoundingRect().left() +
+ dash2->sceneBoundingRect().width() / 2 + spaceBetweenStateRegs / 2,
+ dash2->sceneBoundingRect().top() + textPad));
+ Graphics::Text* mem_instr = new Graphics::Text(QPointF(
+ dash3->sceneBoundingRect().left() +
+ dash3->sceneBoundingRect().width() / 2 + spaceBetweenStateRegs / 2,
+ dash3->sceneBoundingRect().top() + textPad));
+ Graphics::Text* wb_instr = new Graphics::Text(
+ QPointF(dash4->sceneBoundingRect().left() + spaceBetweenStateRegs / 3,
+ dash4->sceneBoundingRect().top() + textPad));
+
+ if_instr->setTextPtr(new QString("and x12, x2, x5"));
+ id_instr->setTextPtr(new QString("beq x1, x3, 16"));
+ ex_instr->setTextPtr(new QString("sub x10, x4, x8"));
+ mem_instr->setTextPtr(new QString("nop"));
+ wb_instr->setTextPtr(new QString("rd x10 24 x2"));
+
+ scene->addItem(if_instr);
+ scene->addItem(id_instr);
+ scene->addItem(ex_instr);
+ scene->addItem(mem_instr);
+ scene->addItem(wb_instr);
}
void PipelineWidget::moveToIO(Graphics::Shape* source, Graphics::Shape* dest,
@@ -344,5 +382,3 @@ void PipelineWidget::scaleView(qreal scaleFactor) {
scale(scaleFactor, scaleFactor);
}
-
-void drawBackground(QPainter* painter, const QRectF& rect) {}

MODIFY
src/graphics/pipelinewidget.h
src/graphics/pipelinewidget.h
@@ -20,9 +20,6 @@ class PipelineWidget : public QGraphicsView {
Qt::KeepAspectRatio);
}
- protected:
- void drawBackground(QPainter* painter, const QRectF& rect) override;
-
private:
void scaleView(qreal scaleFactor);
void adjustPositioning();
@@ -41,19 +38,14 @@ class PipelineWidget : public QGraphicsView {
QList<QGraphicsItem*> filterAllowedItems(Graphics::Shape* shape,
QList<QGraphicsItem*> items);
- qreal shapeMargin = 15; // Minimum distance between two shapes
- qreal stateRegHeight = 500;
+ constexpr static qreal shapeMargin =
+ 15; // Minimum distance between two shapes
+ constexpr static qreal stateRegHeight = 500;
+ constexpr static qreal spaceBetweenStateRegs = 350;
constexpr static qreal minConnectionLen = 30;
QList<Graphics::Connection*> m_connections;
- // Stage instructions
- QString* if_instr;
- QString* id_instr;
- QString* ex_instr;
- QString* mem_instr;
- QString* wb_instr;
-
// Shape pointers
Graphics::Shape* ifid;
Graphics::Shape* idex;

MODIFY
src/graphics/shape.h
src/graphics/shape.h
#include <QPainterPath>
#include <QPen>
-#include "pipelinewidget.h"
-
namespace Graphics {
class Connection;
enum class ShapeType { Block, ALU, MUX, Static };

Draw state seperation lines and instruction text