HAL
graph_layouter.h
Go to the documentation of this file.
1 // MIT License
2 //
3 // Copyright (c) 2019 Ruhr University Bochum, Chair for Embedded Security. All Rights reserved.
4 // Copyright (c) 2019 Marc Fyrbiak, Sebastian Wallat, Max Hoffmann ("ORIGINAL AUTHORS"). All rights reserved.
5 // Copyright (c) 2021 Max Planck Institute for Security and Privacy. All Rights reserved.
6 // Copyright (c) 2021 Jörn Langheinrich, Julian Speith, Nils Albartus, René Walendy, Simon Klix ("ORIGINAL AUTHORS"). All Rights reserved.
7 //
8 // Permission is hereby granted, free of charge, to any person obtaining a copy
9 // of this software and associated documentation files (the "Software"), to deal
10 // in the Software without restriction, including without limitation the rights
11 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 // copies of the Software, and to permit persons to whom the Software is
13 // furnished to do so, subject to the following conditions:
14 //
15 // The above copyright notice and this permission notice shall be included in all
16 // copies or substantial portions of the Software.
17 //
18 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24 // SOFTWARE.
25 
26 #pragma once
27 
33 #include "gui/gui_def.h"
35 #include "hal_core/defines.h"
36 #include "hal_core/netlist/gate.h"
37 #include "hal_core/netlist/net.h"
38 
39 #include <QMap>
40 #include <QMultiHash>
41 #include <QObject>
42 #include <QPoint>
43 #include <QRect>
44 #include <QSet>
45 #include <QVector>
46 #include <QThread>
47 
48 namespace hal
49 {
50  class GraphContext;
51  class GraphicsGate;
52  class GraphicsItem;
53  class GraphicsNet;
54  class GraphicsNode;
55  class GraphicsScene;
56  class SeparatedGraphicsNet;
57  class StandardGraphicsNet;
58 
59  class NetLayoutJunctionHash;
60  class NetLayoutJunctionEntries;
61  class CommentSpeechBubble;
62  class CommentEntry;
63  class JunctionThread;
64  class DrawNetThread;
65 
77  class GraphLayouter : public QObject
78  {
79  Q_OBJECT
80 
81  friend class DrawNetThread;
82 
83  class SceneCoordinate
84  {
85  int minLane;
86  int maxLane;
87  float mOffset;
88  float mPadding;
89 
90  public:
91  SceneCoordinate() : minLane(0), maxLane(0), mOffset(0), mPadding(0)
92  {
93  ;
94  }
95  void testMinMax(int ilane);
96  void setOffset(float off)
97  {
98  mOffset = off;
99  }
100  void setPadding(float pad)
101  {
102  mPadding = pad;
103  }
104  void setOffsetYje(const SceneCoordinate& previous, float minimumJunction);
105  void setOffsetYej(const SceneCoordinate& previous, float maximumBlock, float minimumJunction);
106  void setOffsetX(const SceneCoordinate& previous, float maximumBlock, float sepOut, float sepInp);
107  float lanePosition(int ilane) const;
108  int preLanes() const
109  {
110  return -minLane;
111  }
112  float junctionEntry() const
113  {
114  return lanePosition(minLane);
115  }
116  float junctionExit() const
117  {
118  return lanePosition(maxLane - 1);
119  }
120  float xBoxOffset() const;
121  };
122 
123  class SceneCoordinateArray
124  {
125  float* mArray;
126  int mFirstIndex;
127  public:
128  SceneCoordinateArray(const QMap<int,SceneCoordinate>& inputMap);
129  ~SceneCoordinateArray();
130  float lanePosition(int igrid, int ilane) const;
131  };
132 
133  class EndpointCoordinate
134  {
135  float mYoffset;
136  float mXoutput;
137  float mXinput;
138  float mPinDistance;
139  float mTopPin;
140  int mNumberPins;
141  QMultiHash<u32, int> mInputHash;
142  QMultiHash<u32, int> mOutputHash;
143 
144  public:
145  EndpointCoordinate();
146  void setInputPosition(QPointF p0pos);
147  void setOutputPosition(QPointF p0pos);
148  float lanePosition(int ilane, bool absolute) const;
149  float xInput() const
150  {
151  return mXinput;
152  }
153  float xOutput() const
154  {
155  return mXoutput;
156  }
157  void setInputPins(const QList<u32>& pinList, float p0dist, float pdist);
158  void setOutputPins(const QList<u32>& pinList, float p0dist, float pdist);
159  int numberPins() const;
160  QList<int> inputPinIndex(u32 id) const;
161  QList<int> outputPinIndex(u32 id) const;
162  };
163 
164  class EndpointList : public QList<NetLayoutPoint>
165  {
166  public:
167  enum EndpointType
168  {
169  NoEndpoint = 0,
170  SingleSource = 1,
171  SingleDestination = 2,
172  SourceAndDestination = 3,
173  ConstantLevel = 4,
174  HasGlobalEndpoint = 5
175  };
176  EndpointList()
177  : mNetType(NoEndpoint), mInputArrow(false), mOutputArrow(false)
178  {;}
179  void addSource(const NetLayoutPoint& pnt);
180  void addDestination(const NetLayoutPoint& pnt);
181  void setNetType(EndpointType tp) { mNetType = tp; }
182  EndpointType netType() const { return mNetType; }
183  bool isInput(int index) const { return mPointIsInput.at(index); }
184  void setInputArrow() { mInputArrow = true; }
185  bool hasInputArrow() const { return mInputArrow; }
186  void setOutputArrow() { mOutputArrow = true; }
187  bool hasOutputArrow() const { return mOutputArrow; }
188 
189  private:
190  EndpointType mNetType;
191  QList<bool> mPointIsInput;
192  bool mInputArrow;
193  bool mOutputArrow;
194  };
195 
196  class SeparatedNetWidth
197  {
198  public:
199  float mInputSpace;
200  float mOutputSpace;
201  SeparatedNetWidth() : mInputSpace(0), mOutputSpace(0)
202  {
203  ;
204  }
205  void requireInputSpace(float spc);
206  void requireOutputSpace(float spc);
207  };
208 
209  struct Road
210  {
211  Road(const int x_coordinate, const int y_coordinate) : x(x_coordinate), y(y_coordinate), mLanes(0)
212  {
213  }
214 
215  int x;
216  int y;
217 
218  unsigned int mLanes = 0;
219  };
220 
221  struct UsedPaths
222  {
223  QSet<Road*> mHRoads;
224  QSet<Road*> mVRoads;
225  };
226 
227  public:
234  explicit GraphLayouter(GraphContext *context, QObject* parent = nullptr);
235 
239  ~GraphLayouter();
240 
246  virtual QString name() const = 0;
247 
253  virtual QString mDescription() const = 0;
254 
255  virtual void add(const QSet<u32> modules, const QSet<u32> gates, const QSet<u32> nets, PlacementHint placement = PlacementHint()) = 0;
256 
257  virtual void remove(const QSet<u32> modules, const QSet<u32> gates, const QSet<u32> nets) = 0;
258 
262  void layout();
264 
270  GraphicsScene* scene() const;
271 
274 
280 
281  NetLayoutPoint positonForNode(const Node& nd) const;
282  Node nodeAtPosition(const QPoint& p) const;
283 
284  QPoint gridPointByItem(GraphicsNode* item) const;
285 
286  void dumpNodePositions(const QPoint& search) const;
287 
288  void setNodePosition(const Node& n, const QPoint& p);
289  void swapNodePositions(const Node& n1, const Node& n2);
290  void removeNodeFromMaps(const Node& n);
291 
292  int minXIndex() const;
293  int minYIndex() const;
294 
295  bool done() const;
296 
297  bool dumpJunctionEnabled();
298  void setDumpJunctionEnabled(bool enabled);
299 
300  QVector<qreal> xValues() const;
301  QVector<qreal> yValues() const;
302 
303  qreal maxNodeWidth() const;
304  qreal maxNodeHeight() const;
305 
306  qreal defaultGridWidth() const;
307  qreal defaultGridHeight() const;
308 
309  qreal gridXposition(int ix) const;
310  qreal gridYposition(int iy) const;
311 
312  const NodeBoxes& boxes() const
313  {
314  return mBoxes;
315  }
316 
317  void prepareRollback();
318  bool canRollback() const;
319  bool rollback();
320 
321  protected:
327 
328  private Q_SLOTS:
329  void handleDrawNetThreadFinished();
330  void handleJunctionThreadFinished();
331 
332  private:
333  void clearLayoutData();
334  void clearComments();
335  void createBoxes();
336  void getWireHash();
337  void findMaxBoxDimensions();
338  void findMaxChannelLanes();
339  void calculateJunctionMinDistance();
340  void calculateGateOffsets();
341  void placeGates();
342  void drawNets();
343  void drawComments();
344  void drawNetsIsolated(u32 id, Net* n, const EndpointList& epl);
345  void updateSceneRect();
346  static bool verifyModulePort(Net* n, const Node& modNode, bool isModInput);
347  void handleCommentAboutToDeleted(CommentEntry* entry);
348  void handleCommentAdded(CommentEntry* entry);
349 
350  bool boxExists(const int x, const int y) const;
351 
352  bool hRoadJumpPossible(const int x, const int y1, const int y2) const;
353  bool hRoadJumpPossible(const Road* const r1, const Road* const r2) const;
354 
355  bool vRoadJumpPossible(const int x1, const int x2, const int y) const;
356  bool vRoadJumpPossible(const Road* const r1, const Road* const r2) const;
357 
358  qreal hRoadHeight(const unsigned int mLanes) const;
359  qreal vRoadWidth(const unsigned int mLanes) const;
360 
361  static bool isConstNet(const Net* n);
362 
363  NodeBoxes mBoxes;
364 
365  QMap<int, qreal> mMaxNodeWidthForX;
366  QMap<int, qreal> mMaxNodeHeightForY;
367 
368  QMap<int, qreal> mNodeOffsetForX;
369  QMap<int, qreal> mNodeOffsetForY;
370 
371  QMap<int, qreal> mMaxLeftIoPaddingForChannelX;
372  QMap<int, qreal> mMaxRightIoPaddingForChannelX;
373 
374  QSet<u32> mViewInput;
375  QSet<u32> mViewOutput;
376 
377  int mMinXIndex;
378  int mMinYIndex;
379 
380  int mMaxXIndex;
381  int mMaxYIndex;
382 
383  QVector<qreal> mXValues;
384  QVector<qreal> mYValues;
385 
386  qreal mMaxNodeWidth;
387  qreal mMaxNodeHeight;
388 
389  bool mDone;
390  int mRollbackStatus;
391 
392  QRect mNodeBoundingBox;
393  NetLayoutConnectionMetric mConnectionMetric;
398  QHash<NetLayoutPoint, float> mSpaceSeparatedOutputs;
399  NetLayoutJunctionHash mJunctionHash;
402  QMap<int, float> mJunctionMinDistanceY;
403  QHash<u32, EndpointList> mWireEndpoint;
404  QHash<u32, int> mGlobalInputHash;
405  QHash<u32, int> mGlobalOutputHash;
406 
407  bool mDumpJunctions;
408  QList<CommentSpeechBubble*> mCommentBubbles;
409  QSet<u32> mNetsToDraw;
410  QSet<u32>::const_iterator mNetIterator;
411  QList<DrawNetThread*> mDrawNetThreads;
412  QList<JunctionThread*> mJunctionThreads;
414 
415  SceneCoordinateArray* mCoordArrayX;
416  SceneCoordinateArray* mCoordArrayY;
417  };
418 
419  class DrawNetThread : public QThread
420  {
421  Q_OBJECT
422  u32 mId;
423  GraphLayouter* mLayouter;
424  void drawJunction();
425  void drawEndpoint();
426  public:
429  DrawNetThread(u32 id, GraphLayouter* parent) : QThread(parent), mId(id), mLayouter(parent) {;}
430  u32 id() const { return mId; }
431  void run() override;
432  };
433 
434  class JunctionThread : public QThread
435  {
436  Q_OBJECT
437  public:
442  : mNetLayoutPoint(nlp), mEntries(entr), mJunction(nullptr) {;}
443  void run() override;
444  };
445 } // namespace hal
The CommentEntry class encapsulated information related to a comment.
Definition: comment_entry.h:43
void run() override
DrawNetThread(u32 id, GraphLayouter *parent)
StandardGraphicsNet::Lines mLines
QList< QPointF > mKnots
Logical container for modules, gates, and nets.
Definition: graph_context.h:55
Base class for all specific layouters.
QVector< qreal > yValues() const
qreal gridXposition(int ix) const
virtual void remove(const QSet< u32 > modules, const QSet< u32 > gates, const QSet< u32 > nets)=0
void setNodePosition(const Node &n, const QPoint &p)
void removeNodeFromMaps(const Node &n)
virtual QString mDescription() const =0
QVector< qreal > xValues() const
QMap< Node, QPoint > mNodeToPositionRollback
qreal defaultGridHeight() const
void setDumpJunctionEnabled(bool enabled)
void swapNodePositions(const Node &n1, const Node &n2)
QMap< QPoint, Node > mPositionToNodeMap
virtual void add(const QSet< u32 > modules, const QSet< u32 > gates, const QSet< u32 > nets, PlacementHint placement=PlacementHint())=0
const QMap< QPoint, Node > positionToNodeMap() const
NetLayoutPoint positonForNode(const Node &nd) const
GraphLayouter(GraphContext *context, QObject *parent=nullptr)
GraphicsScene * mScene
void dumpNodePositions(const QPoint &search) const
const QMap< Node, QPoint > nodeToPositionMap() const
qreal maxNodeWidth() const
qreal gridYposition(int iy) const
qreal maxNodeHeight() const
Node nodeAtPosition(const QPoint &p) const
GridPlacement * gridPlacementFactory() const
GraphicsScene * scene() const
bool canRollback() const
qreal defaultGridWidth() const
QPoint gridPointByItem(GraphicsNode *item) const
virtual QString name() const =0
GraphContext * mParentContext
QMap< Node, QPoint > mNodeToPositionMap
const NodeBoxes & boxes() const
Abstract base class for nodes (e.g. gates, modules)
Definition: graphics_node.h:41
Container for a GraphGraphicsView containing gates, nets, and modules.
NetLayoutPoint mNetLayoutPoint
NetLayoutJunction * mJunction
JunctionThread(const NetLayoutPoint &nlp, const NetLayoutJunctionEntries &entr)
NetLayoutJunctionEntries mEntries
Definition: net.h:58
The NodeBoxes class owns all NodeBox'es from hal view.
Definition: node_box.h:150
The Node class object represents a module or a gate.
Definition: gui_def.h:61
The PlacementHint class object provides hints for the layouter how new box objects are placed on a vi...
Definition: gui_def.h:196
n
Definition: test.py:6
quint32 u32
Q_OBJECTQ_OBJECT
Q_SLOTSQ_SLOTS
QObject * parent() const const