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();
263 
269  GraphicsScene* scene() const;
270 
273 
279 
280  NetLayoutPoint positonForNode(const Node& nd) const;
281  Node nodeAtPosition(const QPoint& p) const;
282 
283  QPoint gridPointByItem(GraphicsNode* item) const;
284 
285  void dumpNodePositions(const QPoint& search) const;
286 
287  void updatePlacement(const GridPlacement& plc);
288 
289  void setNodePosition(const Node& n, const QPoint& p);
290  void swapNodePositions(const Node& n1, const Node& n2);
291  void removeNodeFromMaps(const Node& n);
292 
293  int minXIndex() const;
294  int minYIndex() const;
295 
296  bool done() const;
297 
298  bool dumpJunctionEnabled();
299  void setDumpJunctionEnabled(bool enabled);
300 
301  QVector<qreal> xValues() const;
302  QVector<qreal> yValues() const;
303 
304  qreal maxNodeWidth() const;
305  qreal maxNodeHeight() const;
306 
307  qreal defaultGridWidth() const;
308  qreal defaultGridHeight() const;
309 
310  qreal gridXposition(int ix) const;
311  qreal gridYposition(int iy) const;
312 
313  const NodeBoxes& boxes() const
314  {
315  return mBoxes;
316  }
317 
318  void prepareRollback();
319  bool canRollback() const;
320  bool rollback();
321 
322  protected:
328 
329  private Q_SLOTS:
330  void handleDrawNetThreadFinished();
331  void handleJunctionThreadFinished();
332 
333  private:
334  void clearLayoutData();
335  void clearComments();
336  void createBoxes();
337  void getWireHash();
338  void findMaxBoxDimensions();
339  void findMaxChannelLanes();
340  void calculateJunctionMinDistance();
341  void calculateGateOffsets();
342  void placeGates();
343  void drawNets();
344  void drawComments();
345  void drawNetsIsolated(u32 id, Net* n, const EndpointList& epl);
346  void updateSceneRect();
347  static bool verifyModulePort(Net* n, const Node& modNode, bool isModInput);
348  void handleCommentAboutToDeleted(CommentEntry* entry);
349  void handleCommentAdded(CommentEntry* entry);
350 
351  bool boxExists(const int x, const int y) const;
352 
353  bool hRoadJumpPossible(const int x, const int y1, const int y2) const;
354  bool hRoadJumpPossible(const Road* const r1, const Road* const r2) const;
355 
356  bool vRoadJumpPossible(const int x1, const int x2, const int y) const;
357  bool vRoadJumpPossible(const Road* const r1, const Road* const r2) const;
358 
359  qreal hRoadHeight(const unsigned int mLanes) const;
360  qreal vRoadWidth(const unsigned int mLanes) const;
361 
362  static bool isConstNet(const Net* n);
363 
364  NodeBoxes mBoxes;
365 
366  QMap<int, qreal> mMaxNodeWidthForX;
367  QMap<int, qreal> mMaxNodeHeightForY;
368 
369  QMap<int, qreal> mNodeOffsetForX;
370  QMap<int, qreal> mNodeOffsetForY;
371 
372  QMap<int, qreal> mMaxLeftIoPaddingForChannelX;
373  QMap<int, qreal> mMaxRightIoPaddingForChannelX;
374 
375  QSet<u32> mViewInput;
376  QSet<u32> mViewOutput;
377 
378  int mMinXIndex;
379  int mMinYIndex;
380 
381  int mMaxXIndex;
382  int mMaxYIndex;
383 
384  QVector<qreal> mXValues;
385  QVector<qreal> mYValues;
386 
387  qreal mMaxNodeWidth;
388  qreal mMaxNodeHeight;
389 
390  bool mDone;
391  int mRollbackStatus;
392 
393  QRect mNodeBoundingBox;
394  NetLayoutConnectionMetric mConnectionMetric;
399  QHash<NetLayoutPoint, float> mSpaceSeparatedOutputs;
400  NetLayoutJunctionHash mJunctionHash;
403  QMap<int, float> mJunctionMinDistanceY;
404  QHash<u32, EndpointList> mWireEndpoint;
405  QHash<u32, int> mGlobalInputHash;
406  QHash<u32, int> mGlobalOutputHash;
407 
408  bool mDumpJunctions;
409  QList<CommentSpeechBubble*> mCommentBubbles;
410  QSet<u32> mNetsToDraw;
411  QSet<u32>::const_iterator mNetIterator;
412  QList<DrawNetThread*> mDrawNetThreads;
413  QList<JunctionThread*> mJunctionThreads;
415 
416  SceneCoordinateArray* mCoordArrayX;
417  SceneCoordinateArray* mCoordArrayY;
418  };
419 
420  class DrawNetThread : public QThread
421  {
422  Q_OBJECT
423  u32 mId;
424  GraphLayouter* mLayouter;
425  void drawJunction();
426  void drawEndpoint();
427  public:
430  DrawNetThread(u32 id, GraphLayouter* parent) : QThread(parent), mId(id), mLayouter(parent) {;}
431  u32 id() const { return mId; }
432  void run() override;
433  };
434 
435  class JunctionThread : public QThread
436  {
437  Q_OBJECT
438  public:
443  : mNetLayoutPoint(nlp), mEntries(entr), mJunction(nullptr) {;}
444  void run() override;
445  };
446 } // 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
void updatePlacement(const GridPlacement &plc)
Abstract base class for nodes (e.g. gates, modules)
Definition: graphics_node.h:42
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:211
n
Definition: test.py:6
quint32 u32
Q_OBJECTQ_OBJECT
Q_SLOTSQ_SLOTS
QObject * parent() const const