]> AND Private Git Repository - blast.git/commitdiff
Logo AND Algorithmique Numérique Distribuée

Private GIT Repository
adding link between ifaces and clk
authorstephane Domas <stephane.domas@univ-fcomte.fr>
Fri, 27 Apr 2018 14:44:07 +0000 (16:44 +0200)
committerstephane Domas <stephane.domas@univ-fcomte.fr>
Fri, 27 Apr 2018 14:44:07 +0000 (16:44 +0200)
22 files changed:
AbstractBoxItem.cpp
AbstractBoxItem.h
AbstractInterface.cpp
AbstractInterface.h
BoxItem.cpp
BoxItem.h
Dispatcher.cpp
GroupBlock.cpp
GroupItem.cpp
GroupItem.h
GroupScene.cpp
GroupScene.h
InterfaceItem.cpp
InterfaceItem.h
NewProjectDialog.cpp
ReferenceBlock.cpp
SourceItem.cpp
blast.creator.user
lib/implementations/impls.bmf
lib/references/apf27-wb-master.xml
lib/references/references.bmf
reference.xsd

index 9fafc8fbc4b5b7dea39e0675b5c20913af3fdd0e..911a790d6da0cf18d84de16eda232f5da1103833 100644 (file)
 #include "AbstractInterface.h"
 #include "ConnectedInterface.h"
 
+int AbstractBoxItem::NoLock = 0;
+int AbstractBoxItem::Position = 1;
+int AbstractBoxItem::Dimension = 2;
+int AbstractBoxItem::Interfaces = 4;
+int AbstractBoxItem::Names = 8;
 
-AbstractBoxItem::  AbstractBoxItem(AbstractBlock *_refBlock, Dispatcher *_dispatcher, Parameters *_params, LockType _lock, QGraphicsItem *parent) : QGraphicsItem(parent) {
+AbstractBoxItem::AbstractBoxItem(AbstractBlock *_refBlock, Dispatcher *_dispatcher, Parameters *_params, int _lock, QGraphicsItem *parent) : QGraphicsItem(parent) {
   dispatcher = _dispatcher;
   params = _params;
   refBlock = _refBlock;  
@@ -44,7 +49,7 @@ AbstractBoxItem::  AbstractBoxItem(AbstractBlock *_refBlock, Dispatcher *_dispat
   // NOTE : initInterfaces() is only called in subclasses
 }
 
-AbstractBoxItem::AbstractBoxItem(Dispatcher *_dispatcher, Parameters *_params, LockType _lock, QGraphicsItem* parent) : QGraphicsItem(parent) {
+AbstractBoxItem::AbstractBoxItem(Dispatcher *_dispatcher, Parameters *_params, int _lock, QGraphicsItem* parent) : QGraphicsItem(parent) {
   dispatcher = _dispatcher;
   params = _params;  
   refBlock = NULL;
@@ -130,7 +135,7 @@ void AbstractBoxItem::setRefBlock(AbstractBlock* _refBlock) {
   nameHeight = fmId.height();
 }
 
-void AbstractBoxItem::initInterfaceItems() {
+void AbstractBoxItem::createInterfaceItems(Parameters::Direction posInputs, Parameters::Direction posOutputs, Parameters::Direction posBidirs) {
   /* TO DO : creating all needed InterfaceItem, with by default, input at west and output at east */
   int orientation = Parameters::West;
 
@@ -141,11 +146,11 @@ void AbstractBoxItem::initInterfaceItems() {
     if (inter->getPurpose() != AbstractInterface::Control) {
       InterfaceItem *item;
       if(inter->getDirection() == AbstractInterface::Input){
-        orientation = Parameters::West;
+        orientation = posInputs;
       } else if(inter->getDirection() == AbstractInterface::Output){
-        orientation = Parameters::East;
+        orientation = posOutputs;
       } else if(inter->getDirection() == AbstractInterface::InOut){
-        orientation = Parameters::North;
+        orientation = posBidirs;
       }
       item = new InterfaceItem(0.0 , orientation, (ConnectedInterface *)inter, this, params);
       interfaces.append(item);        
@@ -297,7 +302,7 @@ QRectF AbstractBoxItem::boundingRectInScene() {
 */
 bool AbstractBoxItem::isInterfaces(int orientation) const {
   foreach(InterfaceItem* inter, interfaces) {
-    if (inter->getOrientation() == orientation) return true;
+    if ((inter->visible) && (inter->getOrientation() == orientation)) return true;
   }
   return false;
 }
index 84a4fbc354fc4fb22f39db2d2dbea76253a5facf..e490088f956e91b19e36ff84207580e887359138 100644 (file)
@@ -9,6 +9,7 @@
 
 class Dispatcher;
 class InterfaceItem;
+#include "Parameters.h"
 class Parameters;
 class AbstractBlock;
 class GroupScene;
@@ -23,11 +24,16 @@ class AbstractBoxItem : public QGraphicsItem {
 public:  
 
   enum BorderType { NoBorder = 0, BorderEast, BorderNorth, BorderWest, BorderSouth, CornerSouthEast, Title};
-  enum ChangeType { Resize = 0, InterfaceMove };
-  enum LockType { NoLock = 0, Position = 1, Dimension = 2, Interfaces = 4, Names = 8};
+  enum ChangeType { Creation = 0, Resize, InterfaceMove };
 
-  AbstractBoxItem(AbstractBlock *_refBlock, Dispatcher *_dispatcher, Parameters *_params, LockType _lock = NoLock, QGraphicsItem* parent = Q_NULLPTR);
-  AbstractBoxItem(Dispatcher *_dispatcher, Parameters *_params, LockType _lock = NoLock, QGraphicsItem* parent = Q_NULLPTR);
+  static int NoLock;
+  static int Position;
+  static int Dimension;
+  static int Interfaces;
+  static int Names;
+
+  AbstractBoxItem(AbstractBlock *_refBlock, Dispatcher *_dispatcher, Parameters *_params, int _lock = NoLock, QGraphicsItem* parent = Q_NULLPTR);
+  AbstractBoxItem(Dispatcher *_dispatcher, Parameters *_params, int _lock = NoLock, QGraphicsItem* parent = Q_NULLPTR);
 
   virtual ~AbstractBoxItem();
 
@@ -44,6 +50,8 @@ public:
   inline int getIfaceMargin() { return ifaceMargin; }
   inline int getNameMargin() { return nameMargin; }
   inline QPointF getOriginPoint() { return originPoint; }
+  inline int getMinimumBoxWidth() { return minimumBoxWidth; }
+  inline int getMinimumBoxHeight() { return minimumBoxHeight; }
 
   // setters
   void setRefBlock(AbstractBlock* _refBlock);
@@ -52,6 +60,8 @@ public:
   void setRstClkVisible(bool b);
   void setWishboneVisible(bool b);
   void setDimension(int x, int y);
+  inline void setWidth(int width) { boxWidth = width; }
+  inline void setHeight(int height) {boxHeight = height; }
   inline void setCurrentInterface(InterfaceItem* iface) { currentInterface = iface; }
   inline void setLock(int _lock) { lock = _lock; }
   inline void lockPosition() { lock = lock | Position; }
@@ -109,6 +119,8 @@ public:
   InterfaceItem *searchInterfaceItemByRef(ConnectedInterface* ref);
   InterfaceItem* getInterfaceItemFromCursor(qreal x, qreal y);  
 
+  QRectF boundingRect() const;
+
 protected: 
   Dispatcher *dispatcher;
   Parameters *params;
@@ -146,13 +158,13 @@ protected:
   virtual void updateMinimumSize() = 0; // modify the minimum size
   virtual bool updateGeometry(ChangeType type) = 0; // modify the originPoint and the total dimension
 
-  QRectF boundingRect() const;
+
   /* pure virtual method inherited from QGraphicsItem :
     virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0) =0;
     virtual QRectF boundingRect() const =0;
   */   
   
-  void initInterfaceItems();
+  void createInterfaceItems(Parameters::Direction posInputs = Parameters::West, Parameters::Direction posOutputs = Parameters::East, Parameters::Direction posBidirs = Parameters::South);
   int nbInterfacesByOrientation(int orientation);
 };
 
index 6b3d0092da463c1ec849cc05aa39d4c53feeb3c2..03a1a986e4cd35757cdfd4a337f460de6523958b 100644 (file)
@@ -13,6 +13,8 @@ AbstractInterface::AbstractInterface(AbstractBlock* _owner) {
   type = Boolean;
   endianess = LittleEndian;
   associatedIface = NULL;
+  clkIface = "";
+  clkIfaceType = 0;
 
 }
 
@@ -26,6 +28,8 @@ AbstractInterface::AbstractInterface(AbstractBlock* _owner, const QString& _name
   type = typeFromString(_type);
   endianess = _endianess;
   associatedIface = NULL;
+  clkIface = "";
+  clkIfaceType = 0;
 }
 
 AbstractInterface::AbstractInterface(AbstractInterface* other) {
@@ -37,6 +41,8 @@ AbstractInterface::AbstractInterface(AbstractInterface* other) {
   purpose = other->purpose;
   endianess = LittleEndian;
   associatedIface = NULL;
+  clkIface = other->clkIface;
+  clkIfaceType = other->clkIfaceType;
 }
 
 void AbstractInterface::setName(const QString& _name) {
@@ -237,6 +243,46 @@ bool AbstractInterface::setAssociatedIface(AbstractInterface* iface) {
   return true;
 }
 
+bool AbstractInterface::setClockIface(QString name) {
+  /* 2 cases :
+   *  - this is a Data interface
+   *  - this is a Clock output (from a clkrstgen)
+   *
+   *   iface must correspond to an existing clock interface name
+   * or a user parameter prepend with a $.
+   */
+  if ((purpose == Data) || ((purpose == Clock) && (direction == Output))) {
+    if (name.at(0) == '$') {
+      name.remove(0,1);
+      QList<BlockParameter* > params = owner->getUserParameters();
+      foreach(BlockParameter* p, params) {
+        if (p->getName() == name) {
+          clkIface = name;
+          clkIfaceType = ParameterName;
+          return true;
+        }
+      }
+      // error case: cannot found the input clock
+      return false;
+    }
+    else {
+      QList<AbstractInterface*> clocks = owner->getInterfaces(Input, Clock);
+      foreach(AbstractInterface* iface, clocks) {
+        if (iface->getName() == name) {
+          clkIface = name;
+          clkIfaceType = ClockName;
+          return true;
+        }
+      }
+      // error case: cannot found the user paramter
+      return false;
+    }
+  }
+  clkIface = "";
+  clkIfaceType = NoName;
+  return true;
+}
+
 
 int AbstractInterface::getIntDirection(QString str) {
     if(str == "input") return Input;
index 166fdbeb9d313b876ba33304aff88648b3dede5f..0e167dbc0039d992d4b7ec81a3ecaa6f51fcc655 100644 (file)
@@ -30,6 +30,7 @@ public :
   enum IfaceDirection { AnyDirection = 0, Input = 1, Output = 2, InOut = 3 };  
   enum IfaceVHDLContext {AnyContext = 0, Entity = 1, Component = 2, Instance = 3, Signal = 4 };
   enum IfaceVHDLFlags { NoComma = 1 };
+  enum IfaceClockName { NoName = 0, ClockName, ParameterName };
 
   static int getIntDirection(QString str);
   static int getIntPurpose(QString str);
@@ -53,6 +54,9 @@ public :
   QString getDirectionString();  
   inline AbstractBlock *getOwner() { return owner;}
   inline AbstractInterface* getAssociatedIface() { return associatedIface; }
+  inline QString getClockIface() { return clkIface; }
+  inline int getClockIfaceType() { return clkIfaceType; }
+
 
   double getDoubleWidth() throw(QException);
   
@@ -67,6 +71,7 @@ public :
   void setPurpose(int _purpose);
   void setDirection(int _direction);
   bool setAssociatedIface(AbstractInterface* iface);
+  bool setClockIface(QString name);
   
   // testers
   virtual bool isReferenceInterface();
@@ -99,6 +104,17 @@ protected:
    * (NB: a test is done in the method to prevent the other case).
    */
   AbstractInterface* associatedIface;
+  /*!
+   * \brief clkIface represents the clock interface that is used in processes modifying this interface. It is only relevant for
+   * Data interfaces and clock outputs (that comes from a clkrstgen). Since Control interfaces are automatically associated to a
+   * Data interface, clkIface is "" for them. Wishbone interfaces
+   * In general, blocks have a single
+   * clock interface which is by default automatically connected to the main clock dispatched by the clkrstgen block in top group.
+   * Nevertheless, the designer has the possibility to connect the block taht owns this interface to another clkrstgen block.  Moreover,
+   * some blocks may have several clocks, e.g. dual port RAMs, FIFOs.
+   */
+  QString clkIface;
+  int clkIfaceType; // 0 for not affected, 1 for clock input name, 2 for user param name
   
   
 };
index a7e11812a6a084683f6273901f66bfba1dec0f6f..deee2cc81ca24a010da7603730b6cacde075e13e 100644 (file)
@@ -17,7 +17,7 @@
 
 BoxItem::BoxItem(AbstractBlock *_refBlock,
                      Dispatcher *_dispatcher,
-                     Parameters *_params, GroupItem *parent, LockType _lock, SpanType _span, Position _hPos, Position _vPos) throw(Exception) : AbstractBoxItem( _refBlock, _dispatcher, _params, _lock, parent) {
+                     Parameters *_params, GroupItem *parent, int _lock, SpanType _span, Position _position) throw(Exception) : AbstractBoxItem( _refBlock, _dispatcher, _params, _lock, parent) {
 
   /*  NOTE :
      _refBlock : mandatory a FunctionalBlock or a GroupBlock
@@ -25,8 +25,7 @@ BoxItem::BoxItem(AbstractBlock *_refBlock,
   if (_refBlock->isReferenceBlock()) throw(Exception(BLOCK_INVALID_TYPE));  
 
   span = _span;
-  hPos = _hPos;
-  vPos = _vPos;
+  position = _position;
 
   childGroupItem = NULL;
   //boxWidth = params->defaultBlockWidth;
@@ -38,26 +37,145 @@ BoxItem::BoxItem(AbstractBlock *_refBlock,
   QGraphicsItem::GraphicsItemFlags flags = QGraphicsItem::ItemIsSelectable;
   if (!isPositionLock()) {
     flags |= QGraphicsItem::ItemIsMovable;
+    cout << "item " << qPrintable(refBlock->getName()) << "is movable" << endl;
   }
   if (!isDimensionLock()) {
     flags |= QGraphicsItem::ItemSendsGeometryChanges;
+    cout << "item " << qPrintable(refBlock->getName()) << "is resizable" << endl;
   }
   setFlags(flags);
 
-  initInterfaceItems();
-  updateGeometry(InterfaceMove);
-  resetInterfaceItemsPosition();
-  QPointF initPos = QPointF(0.0,0.0) - originPoint;
+  bool freeBorder[4]; // 0 = east, 1 = north, 2 = west, 3 = south
+  Parameters::Direction dirs[4];
+  for(int i=0;i<4;i++) {
+    freeBorder[i] = true;
+  }
+  dirs[0] = Parameters::East;
+  dirs[1] = Parameters::North;
+  dirs[2] = Parameters::West;
+  dirs[3] = Parameters::South;
+
+
+  if (position == Top) {
+    freeBorder[1] = false;
+  }
+  if (position == Bottom) {
+    freeBorder[3] = false;
+  }
+  if (position == Left) {
+    freeBorder[2] = false;
+  }
+  if (position == Right) {
+    freeBorder[0] = false;
+  }
+  if (span == HSpan) {
+    freeBorder[2] = false;
+    freeBorder[0] = false;
+  }
+  if (span == VSpan) {
+    freeBorder[1] = false;
+    freeBorder[3] = false;
+  }
+  Parameters::Direction dIn = Parameters::West;
+  Parameters::Direction dOut = Parameters::East;
+  Parameters::Direction dBi = Parameters::South;
+  if (freeBorder[2] == false) {
+    int i=3;
+    while (freeBorder[i] == false) {
+      i = (i+1)%4;
+    }
+    dIn = dirs[i];
+  }
+  if (freeBorder[0] == false) {
+    int i=1;
+    while (freeBorder[i] == false) {
+      i = (i+1)%4;
+    }
+    dOut = dirs[i];
+  }
+  if (freeBorder[3] == false) {
+    int i=0;
+    while (freeBorder[i] == false) {
+      i = (i+1)%4;
+    }
+    dBi = dirs[i];
+  }
+
+  createInterfaceItems(dIn,dOut,dBi);
+  updateGeometry(Creation);
+
+  // position the item
+  int groupWidth = getScene()->getGroupItem()->getWidth();
+  int groupHeight = getScene()->getGroupItem()->getHeight();
+  double xx = 0.0,yy = 0.0;
+  if ((position == BoxItem::Left) || (position == BoxItem::TopLeft) || (position == BoxItem::BottomLeft)) {
+    xx = 0;
+    if ((span == VSpan) || (position == BoxItem::TopLeft)) {
+      yy = 0;
+    }
+    else if (position == BoxItem::BottomLeft) {
+      yy = groupHeight-totalHeight;
+    }
+    else {
+      yy = (groupHeight-totalHeight)/2.0;
+    }
+  }
+  else if ((position == BoxItem::Right) || (position == BoxItem::TopRight) || (position == BoxItem::BottomRight)) {
+    xx = groupWidth-totalWidth;
+    if (xx < 0) xx = 0;
+    if ((span == VSpan) || (position == BoxItem::TopRight)) {
+      yy = 0;
+    }
+    else if (position == BoxItem::BottomRight) {
+      yy = groupHeight-totalHeight;
+    }
+    else {
+      yy = (groupHeight-totalHeight)/2.0;
+    }
+  }
+  else if ((position == BoxItem::Top) || (position == BoxItem::TopLeft) || (position == BoxItem::TopRight)) {
+    yy = 0;
+    if ((span == HSpan) || (position == BoxItem::TopLeft)) {
+      xx = 0;
+    }
+    else if (position == BoxItem::TopRight) {
+      xx = groupWidth-totalWidth;
+    }
+    else {
+      xx = (groupWidth-totalWidth)/2.0;
+    }    
+  }
+  else if ((position == BoxItem::Bottom) || (position == BoxItem::BottomLeft) || (position == BoxItem::BottomRight)) {
+    yy = groupHeight-totalHeight;
+    if ((span == HSpan) || (position == BoxItem::BottomLeft)) {
+      xx = 0;
+    }
+    else if (position == BoxItem::BottomRight) {
+      xx = groupWidth-totalWidth;
+    }
+    else {
+      xx = (groupWidth-totalWidth)/2.0;
+    }    
+  }
+  else {
+    int marginConn = 2*(params->arrowWidth+params->arrowLineLength);
+    xx = (groupWidth-totalWidth)/2.0;
+    if (xx < marginConn) xx = marginConn;
+    yy = (groupHeight-totalHeight)/2.0;
+    if (yy < marginConn) yy = marginConn;
+  }
+  cout << "setting raw pos to " << xx << "," << yy << endl;
+  QPointF initPos(xx,yy);
+  initPos = initPos-originPoint;
   setPos(initPos);
-  //cout << "total size of block: " << totalWidth << "," << totalHeight << endl;
-  //cout << "pos in group: " << x() << "," << y() << endl;
+  cout << "total size of block: " << totalWidth << "," << totalHeight << endl;
+  cout << "pos in group: " << x() << "," << y() << endl;
 }
 
-BoxItem::BoxItem(Dispatcher *_dispatcher, Parameters *_params, GroupItem *parent, LockType _lock, SpanType _span, Position _hPos, Position _vPos) throw(Exception) : AbstractBoxItem(_dispatcher, _params, _lock, parent) {
+BoxItem::BoxItem(Dispatcher *_dispatcher, Parameters *_params, GroupItem *parent, int _lock, SpanType _span, Position _position) throw(Exception) : AbstractBoxItem(_dispatcher, _params, _lock, parent) {
 
   span = _span;
-  hPos = _hPos;
-  vPos = _vPos;
+  position = _position;
 
   refBlock = NULL;
   childGroupItem = NULL;
@@ -133,19 +251,22 @@ void BoxItem::updateMinimumSize() {
   int ifaceHeight = 0;
 
   foreach(InterfaceItem* iface, interfaces) {
-    ifaceWidth = iface->getNameWidth();
-    ifaceHeight = iface->getNameHeight();
-    if (iface->getOrientation() == Parameters::South) {
-      if (ifaceWidth > maxSouth) maxSouth = ifaceWidth;
-    }
-    else if (iface->getOrientation() == Parameters::North) {
-      if (ifaceWidth > maxNorth) maxNorth = ifaceWidth;
-    }
-    else if (iface->getOrientation() == Parameters::East) {
-      if (ifaceWidth > maxEast) maxEast = ifaceWidth;
-    }
-    else if (iface->getOrientation() == Parameters::West) {
-      if (ifaceWidth > maxWest) maxWest = ifaceWidth;
+
+    if (iface->visible) {
+      ifaceWidth = iface->getNameWidth();
+      ifaceHeight = iface->getNameHeight();
+      if (iface->getOrientation() == Parameters::South) {
+        if (ifaceWidth > maxSouth) maxSouth = ifaceWidth;
+      }
+      else if (iface->getOrientation() == Parameters::North) {
+        if (ifaceWidth > maxNorth) maxNorth = ifaceWidth;
+      }
+      else if (iface->getOrientation() == Parameters::East) {
+        if (ifaceWidth > maxEast) maxEast = ifaceWidth;
+      }
+      else if (iface->getOrientation() == Parameters::West) {
+        if (ifaceWidth > maxWest) maxWest = ifaceWidth;
+      }
     }
   }
 
@@ -173,34 +294,58 @@ bool BoxItem::updateGeometry(ChangeType type) {
   //cout << "current pos of block: " << currentPosition.x() << "," << currentPosition.y() << endl;
   QPointF oldOrigin = originPoint;
   QSize oldSize(totalWidth,totalHeight);
-
   bool boxSizeChanged = false;
 
   // whatever the change, the minimum size may have changed
   updateMinimumSize();
 
-  if (type == Resize) {
+  int groupWidth = getScene()->getGroupItem()->getWidth();
+  int groupHeight = getScene()->getGroupItem()->getHeight();
+
+  cout << "minimum box size is " << minimumBoxWidth << "x" << minimumBoxHeight << endl;
+  cout << "group size is " << groupWidth << "x" << groupHeight << endl;
+
+  if (type == Creation) {
+
+    boxSizeChanged = true;
+    boxWidth = minimumBoxWidth;
+    boxHeight = minimumBoxHeight;
+    /* reset and update interfaces positions
+     * in case of spanning, the interface are positionned
+     * only on free borders.
+     */
+    resetInterfaceItemsPosition();
+    /* must test if the GroupItem must be resized */
+    if ((span == HSpan) && (boxWidth < groupWidth)) {
+      boxWidth = groupWidth; // no interfaces in east/west (done in constructor)
+    }
+    else if ((span == VSpan) && (boxHeight < groupHeight)) {
+      boxHeight = groupHeight;
+    }
+  }
+  else if (type == Resize) {
     // resize implies to move interfaces and to update connections
     boxSizeChanged = true;
+    updateInterfaceAndConnectionItems();
   }
   else if (type == InterfaceMove) {
     // if an interface moves, it may change the box size
     if (boxWidth < minimumBoxWidth) {
       boxWidth = minimumBoxWidth;
       boxSizeChanged = true;
+      updateInterfaceAndConnectionItems();
     }
     if (boxHeight < minimumBoxHeight) {
       boxHeight = minimumBoxHeight;
       boxSizeChanged = true;
+      updateInterfaceAndConnectionItems();
     }
   }
-  if (boxSizeChanged) {
-    updateInterfaceAndConnectionItems();
-  }
-
 
+  // update total size
   double x = 0.0;
   double y = 0.0;
+
   totalWidth = boxWidth;
   totalHeight = boxHeight;
 
@@ -221,6 +366,9 @@ bool BoxItem::updateGeometry(ChangeType type) {
   QSizeF newSize(totalWidth,totalHeight);
   originPoint.setX(x);
   originPoint.setY(y);
+  cout << "change orig pos of " << qPrintable(refBlock->getName()) << "to " << x << "," << y << endl;
+  cout << "box size is " << boxWidth << "x" << boxHeight << endl;
+  cout << "total size is " << totalWidth << "x" << totalHeight << endl;
 
   if ((boxSizeChanged) || (newSize != oldSize) || (originPoint != oldOrigin)) {
     prepareGeometryChange();
@@ -246,37 +394,48 @@ void BoxItem::nameChanged() {
 void BoxItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) {
 
   if(params->editState == Parameters::EditBlockMove) {
+
+    if (isPositionLock()) return;
     QPointF absPos = currentPosition + originPoint;
     int marginConn = 2*(params->arrowWidth+params->arrowLineLength);
     int gapX = event->scenePos().x() - cursorPosition.x();
     int gapY = event->scenePos().y() - cursorPosition.y();
+    // update cursor position
+    cursorPosition = event->scenePos();
 
     //cout << "block abs. pos: " << absPos.x() << "," << absPos.y() << " | ";
     //cout << "block current. pos: " << currentPosition.x() << "," << currentPosition.y() << " | ";
 
-    if (absPos.x()+gapX < marginConn) {
+    if ((gapX < 0) && (absPos.x() == marginConn)) {
+      gapX = 0;
+    }
+    else if (absPos.x()+gapX < marginConn) {
       gapX = marginConn-absPos.x();
     }
-    if (absPos.y()+gapY < marginConn) {
+    if ((gapY < 0) && (absPos.y() == marginConn)) {
+      gapY = 0;
+    }
+    else if (absPos.y()+gapY < marginConn) {
       gapY = marginConn-absPos.y();
     }
     //cout << "gap: " << gapX << "," << gapY << endl;
-    QPointF gap(gapX,gapY);
-    currentPosition = currentPosition+gap;
-    setPos(currentPosition);
-    // update all connections from/to this block
-    foreach(ConnectionItem *item, getScene()->getConnectionItems()){
-      if ((item->getFromInterfaceItem()->getOwner() == this) || (item->getToInterfaceItem()->getOwner() == this)) {
-        item->setPath();
+    if ((gapX != 0) || (gapY != 0)) {
+      QPointF gap(gapX,gapY);
+      currentPosition = currentPosition+gap;
+      setPos(currentPosition);
+      // update all connections from/to this block
+      foreach(ConnectionItem *item, getScene()->getConnectionItems()){
+        if ((item->getFromInterfaceItem()->getOwner() == this) || (item->getToInterfaceItem()->getOwner() == this)) {
+          item->setPath();
+        }
       }
+      // udpate the groupitem
+      (getScene()->getGroupItem())->updateShape();
     }
-    cursorPosition = event->scenePos();
-
-    // udpate the groupitem
-    (getScene()->getGroupItem())->updateShape();
   }
   else if(params->editState == Parameters::EditBlockResize) {
 
+    if (isDimensionLock()) return;
     int gapX = event->scenePos().x() - cursorPosition.x();
     int gapY = event->scenePos().y() - cursorPosition.y();
     //cout << "gap: " << gapX << "," << gapY << endl;
@@ -395,9 +554,16 @@ void BoxItem::mousePressEvent(QGraphicsSceneMouseEvent *event) {
       update();
     }
     else if (params->cursorState == Parameters::CursorOnBorder) {
-      setFlag(ItemIsMovable, false);
-      cursorPosition = event->scenePos();
-      params->setEditState(Parameters::EditBlockResize);
+      if (isDimensionLock()) {
+        if ((position == Bottom)||(position == Right)) {
+          event->ignore();
+        }
+      }
+      else {
+        setFlag(ItemIsMovable, false);
+        cursorPosition = event->scenePos();
+        params->setEditState(Parameters::EditBlockResize);
+      }
     }
   }
 }
@@ -453,9 +619,9 @@ void BoxItem::mouseReleaseEvent(QGraphicsSceneMouseEvent  *event) {
 
 void BoxItem::hoverMoveEvent(QGraphicsSceneHoverEvent * event) {
 
-  QPointF pos = event->pos();
-  qreal x = pos.x();
-  qreal y = pos.y();
+  QPointF evPos = event->pos();
+  qreal x = evPos.x();
+  qreal y = evPos.y();
   currentBorder = NoBorder;
   int mode = getScene()->getEditionMode();
 
@@ -516,8 +682,14 @@ void BoxItem::hoverMoveEvent(QGraphicsSceneHoverEvent * event) {
       }
     }
   }
-  //QGraphicsItem::hoverMoveEvent(event);
-  event->ignore();
+  if (params->cursorState == Parameters::CursorOnBorder) {
+    if (isDimensionLock()) {
+      if ((position == Bottom)||(position == Right)) {
+        event->setPos(evPos+pos());
+        getScene()->getGroupItem()->hoverMoveEvent(event);
+      }
+    }
+  }
 }
 
 
@@ -826,7 +998,7 @@ void BoxItem::loadFunctional(QDomElement funcElement) throw(Exception) {
   }
   
   // creating InterfaceItem
-  initInterfaceItems();
+  createInterfaceItems();
   // setting them with saved values
   for(int i=0; i<interfaceNodes.length(); i++){
 
index 4ab2022ed8bf47d8712428654265273eb2426b1f..ee4070a71163f762a99f79dfec667d41c87052e2 100644 (file)
--- a/BoxItem.h
+++ b/BoxItem.h
@@ -31,20 +31,24 @@ class BoxItem : public AbstractBoxItem {
 
 public:
 
-  enum Position { Left = 1, Right, Top, Bottom, Center};
+  enum Position { Free = 0, Left , Right, Top, Bottom, TopLeft, BottomLeft, TopRight, BottomRight }; // if not Free, glue the box to the desired border
   enum SpanType { NoSpan = 0, HSpan = 1, VSpan = 2 };
 
-  BoxItem(AbstractBlock *_refBlock, Dispatcher *_dispatcher, Parameters *_params, GroupItem* parent, LockType _lock = NoLock, SpanType _span = NoSpan, Position _hPos = Center, Position _vPos = Center) throw(Exception);
-  BoxItem(Dispatcher *_dispatcher, Parameters *_params, GroupItem* parent, LockType _lock = NoLock, SpanType _span = NoSpan, Position _hPos = Center, Position _vPos = Center) throw(Exception);
+  BoxItem(AbstractBlock *_refBlock, Dispatcher *_dispatcher, Parameters *_params, GroupItem* parent, int _lock = NoLock, SpanType _span = NoSpan, Position _position = Free) throw(Exception);
+  BoxItem(Dispatcher *_dispatcher, Parameters *_params, GroupItem* parent, int _lock = NoLock, SpanType _span = NoSpan, Position _position = Free) throw(Exception);
   ~BoxItem();
 
   void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);  
 
   // getters
   inline GroupItem *getChildGroupItem() { return childGroupItem; }
+  inline Position getPosition() { return position; }
+  inline SpanType getSpan() { return span; }
 
   // setters
   inline void setChildGroupItem(GroupItem* item) { childGroupItem = item; }
+  inline void setPosition(Position _position) { position = _position; }
+  inline void setSpan(SpanType _span) { span = _span; }
 
   // testers
   bool isBoxItem();
@@ -55,14 +59,13 @@ public:
   void loadFunctional(QDomElement funcElement) throw(Exception);
   void save(QXmlStreamWriter& writer);
 
+  void updateMinimumSize(); // modify the minimum size
+  bool updateGeometry(ChangeType type); // modify the originPoint and the total dimension
+
 protected:
 
   SpanType span;
-  Position hPos;
-  Position vPos;
-
-  void updateMinimumSize(); // modify the minimum size
-  bool updateGeometry(ChangeType type); // modify the originPoint and the total dimension
+  Position position;
 
   void mousePressEvent(QGraphicsSceneMouseEvent *event);
   void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
index da4bae2b5ad8a3c4e0d0e4bb2bcebec0d565892c..8d1164964036eb4af1ede213cb1e7325ed9c9b0a 100644 (file)
@@ -111,7 +111,7 @@ bool Dispatcher::createConnection(Context context, InterfaceItem *iface1, Interf
     ref1->connectTo(ref2);    
     ok1 = true;
   }
-  // if the frist one did not work, test ref2->ref1
+  // if the first one did not work, test ref2->ref1
   if ((ok1 == false) && (ref2->canConnectTo(ref1)) && (ref1->canConnectFrom(ref2))) {  
     ref2->connectTo(ref1);    
     ok2 = true;
@@ -693,15 +693,29 @@ GroupWidget *Dispatcher::createTopScene(Context context){
     // creating the clkrstgen block
     ReferenceBlock* ref = params->getHiddenReferenceBlock("clkrstgen");
     FunctionalBlock* newOne = params->getGraph()->createFunctionalBlock(topBlock, ref, true);
-    ConnectedInterface* fromIface = AI_TO_CON(topBlock->getIfaceFromName("ext_clk"));
-    ConnectedInterface* toIface = AI_TO_CON(newOne->getIfaceFromName("ext_clk"));
-    fromIface->connectTo(toIface);
-    fromIface = AI_TO_CON(topBlock->getIfaceFromName("ext_reset"));
-    toIface = AI_TO_CON(newOne->getIfaceFromName("ext_reset"));
-    fromIface->connectTo(toIface);
-    // create the clkrstgen boxitem
-    BoxItem* item = scene->createBoxItem(newOne, GroupScene::Left, GroupScene::Top, AbstractBoxItem::Position, BoxItem::HSpan);
-    params->blockToItem.insert(newOne,item);
+    // creating the clkrstgen item
+    BoxItem* clkResetItem = scene->createBoxItem(newOne, BoxItem::TopLeft, AbstractBoxItem::Position | AbstractBoxItem::Dimension, BoxItem::NoSpan);
+    params->blockToItem.insert(newOne,clkResetItem);
+    // creating top group ext_clk iface item
+    ConnectedInterface* fromIfaceClk = AI_TO_CON(topBlock->getIfaceFromName("ext_clk"));
+    InterfaceItem* fromIfaceItemClk = new InterfaceItem(0.5 , Parameters::West, fromIfaceClk, group, params, true);
+    group->addInterfaceItem(fromIfaceItemClk,true);
+    // creating top group ext_reset iface item
+    ConnectedInterface* fromIfaceReset = AI_TO_CON(topBlock->getIfaceFromName("ext_reset"));
+    InterfaceItem* fromIfaceItemReset = new InterfaceItem(0.5 , Parameters::West, fromIfaceReset, group, params, false);
+    group->addInterfaceItem(fromIfaceItemReset,true);
+    // connecting ext_clk iface items
+    InterfaceItem* toIfaceItemClk = clkResetItem->searchInterfaceItemByName("ext_clk");
+    if (toIfaceItemClk == NULL) {
+      cerr << "Abnormal case while connecting top group ext_clk to clkrstgen" << endl;
+    }
+    createConnection(context,fromIfaceItemClk, toIfaceItemClk, false);
+    // connecting ext_reset iface items
+    InterfaceItem* toIfaceItemReset = clkResetItem->searchInterfaceItemByName("ext_reset");
+    if (toIfaceItemReset == NULL) {
+      cerr << "Abnormal case while connecting top group ext_reset to clkrstgen" << endl;
+    }
+    createConnection(context,fromIfaceItemReset, toIfaceItemReset, false);
   }
 
 
index 7945ee75e0c8f991538f07eecb732dc9adc78428..ea7f2f7e7b7cc01c8709df86a557162f835e098b 100644 (file)
@@ -43,20 +43,10 @@ GroupBlock::GroupBlock(GroupBlock *_parent, bool createIfaces) throw(Exception)
     addInterface(clk);
     addInterface(rst);
     // creating clkrstgen block and connecting it to this: done in Dispatcher since this has no access to library
+    cout << "created ext_clk and reset ifaces for top group" << endl;
   }
   parent = _parent;
 
-  if (_parent != NULL) {
-    try {
-      connectClkReset();
-    }
-    catch(Exception e) {
-      AbstractBlock* source = (AbstractBlock *)(e.getSource());
-      cerr << qPrintable(source->getName()) << ":" << qPrintable(e.getMessage()) << endl;
-      throw(e);
-    }
-  }
-
 }
 
 GroupBlock::~GroupBlock() {
index ebef87ca47501f5b8d3bc6d3bae616bbcbdc5844..c165d029c214f3301c090fb0125ac1aa667d69de 100644 (file)
@@ -25,28 +25,29 @@ GroupItem::GroupItem(BoxItem *_parentItem,
     parentItem->setChildGroupItem(this);    
   }
 
-  /*
-  minimumBoxWidth = nameWidth+2*nameMargin;
-  minimumBoxHeight = 100;
-  boxHeight = minimumBoxHeight;
-  boxWidth = minimumBoxWidth;
-  */
+  boxHeight = 1;
+  boxWidth = 1;
   rectTitle = QRectF(0,-(nameHeight+2*nameMargin),nameWidth+2*nameMargin,nameHeight+2*nameMargin);
+
+  /* NB: boxPoint represent the position in scene of the top-left corner of the box, thus
+   * without taking into account the interfaces. It is also the reference position to draw the item.
+   * Nevertheless, in order to place sources in the scene, the real bouding box of the group is determined
+   * from originPoint and totalWidth/totalheight.
+   * */
+  boxPoint = QPointF(0,0);
   /*
   totalHeight = boxHeight + rectTitle.height();
   totalWidth = boxWidth;
 */
   selected = false;
 
-
   setZValue(100);
 
   setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemSendsGeometryChanges);  
 
 
-  updateGeometry(InterfaceMove);
-  QPointF initPos = QPointF(0.0,0.0) - originPoint;
-  setPos(initPos);
+  updateGeometry(Creation);
+  setPos(boxPoint);
   cout << "total size of group: " << totalWidth << "," << totalHeight << endl;
   cout << "pos in scene: " << x() << "," << y() << endl;
 }
@@ -125,62 +126,155 @@ void GroupItem::updateMinimumSize() {
   minimumBoxHeight = 2*marginConn;
 
   if (getScene() == NULL) return;
-
   QList<BoxItem *> blocks = getScene()->getBoxItems();
-  if(blocks.length() > 0) {
-    // first, search for blocks that are at (0,0)
-    int xMaxZero = 0;
-    int yMaxZero = 0;
-    int xMax = 0;
-    int yMax = 0;
-    bool isZeroBlocks = false;
-    bool isOtherBlocks = false;
-    foreach(BoxItem* item, blocks) {
-      QPointF p = item->pos() + item->getOriginPoint();
-      if ((p.x()==0.0) && (p.y()==0.0)) {
-        isZeroBlocks = true;
-        if (item->getTotalWidth() > xMaxZero) {
-          xMaxZero = item->getTotalWidth();
+  if(blocks.length() == 0) return; // no blocks within, keep the miniumum computed before.
+
+  QRectF boxFree; // the bounding box of free blocks.
+  foreach(BoxItem* item, blocks) {
+    QRectF boxItem = item->boundingRect();
+    if (item->getPosition() == BoxItem::Free) {
+      boxItem.translate(item->pos());
+      if (item->getSpan() == BoxItem::NoSpan) {
+        boxFree = boxFree.united(boxItem);
+      }
+      else if (item->getSpan() == BoxItem::HSpan) {
+        QRectF r(boxFree.left()+boxFree.width()/2.0,boxItem.top(),1,boxItem.height());
+        boxFree = boxFree.united(r);
+      }
+      else if (item->getSpan() == BoxItem::VSpan) {
+        QRectF r(boxItem.left(),boxFree.top()+boxFree.height()/2.0,boxItem.width(),1);
+        boxFree = boxFree.united(r);
+      }
+    }
+  }
+  // find the move to apply to freely located items
+  double gapXLeft = 0.0;
+  double gapYTop = 0.0;
+  if (boxFree.left() < marginConn) {
+    gapXLeft = boxFree.left() - marginConn;
+  }
+  if (boxFree.top() < marginConn) {
+    gapYTop = boxFree.top() - marginConn;
+  }
+  // translate the box
+  boxFree.translate(-gapXLeft,-gapYTop);
+  minimumBoxWidth = boxFree.right() + marginConn;
+  minimumBoxHeight = boxFree.bottom() + marginConn;
+
+  // find the highest/largest item stick on top/bottom/left/right
+
+  qreal topHighest = 0.0;
+  qreal bottomHighest = 0.0;
+  qreal leftLargest = 0.0;
+  qreal rightLargest = 0.0;
+
+  foreach(BoxItem* item, blocks) {
+    QRectF boxItem = item->boundingRect();
+
+    if (item->getPosition() == BoxItem::Top) {
+
+      if (item->getSpan() == BoxItem::VSpan) {
+        if (item->getMinimumBoxHeight() > topHighest) {
+          topHighest = item->getMinimumBoxHeight();
         }
-        if (item->getTotalHeight() > yMaxZero) {
-          yMaxZero = item->getTotalHeight();
+      }
+      else {
+        if (boxItem.height()+marginConn > topHighest) {
+          topHighest = boxItem.height()+marginConn;
+        }
+      }
+      if (item->getSpan() == BoxItem::HSpan) {
+        if (item->getMinimumBoxWidth() > leftLargest) {
+          leftLargest = item->getMinimumBoxWidth();
+        }
+      }
+    }
+
+    if (item->getPosition() == BoxItem::Bottom) {
+
+      if (item->getSpan() == BoxItem::VSpan) {
+        if (item->getMinimumBoxHeight() > bottomHighest) {
+          bottomHighest = item->getMinimumBoxHeight();
         }
       }
       else {
-        isOtherBlocks = true;
-        if(p.x()+item->getTotalWidth() > xMax) {
-          xMax = p.x()+item->getTotalWidth();
+        if (boxItem.height()+marginConn > bottomHighest) {
+          bottomHighest = boxItem.height()+marginConn;
         }
-        if(p.y()+item->getTotalHeight() > yMax) {
-          yMax = p.y()+item->getTotalHeight();
+      }
+      if (item->getSpan() == BoxItem::HSpan) {
+        if (item->getMinimumBoxWidth() > leftLargest) {
+          leftLargest = item->getMinimumBoxWidth();
         }
       }
     }
-    if (isZeroBlocks) {
-      if (!isOtherBlocks) {
-        minimumBoxWidth = xMaxZero+2*marginConn;
-        minimumBoxHeight = yMaxZero+2*marginConn;
+
+    if (item->getPosition() == BoxItem::Left) {
+
+      if (item->getSpan() == BoxItem::HSpan) {
+        if (item->getMinimumBoxWidth() > leftLargest) {
+          leftLargest = item->getMinimumBoxWidth();
+        }
       }
       else {
-        if (xMaxZero+marginConn > xMax) {
-          minimumBoxWidth = xMaxZero+2*marginConn;
+        if (boxItem.width()+marginConn > leftLargest) {
+          leftLargest = boxItem.width()+marginConn;
         }
-        else {
-          minimumBoxWidth = xMax+marginConn;
+      }
+      if (item->getSpan() == BoxItem::VSpan) {
+        if (item->getMinimumBoxHeight() > topHighest) {
+          topHighest = item->getMinimumBoxHeight();
         }
-        if (yMaxZero+marginConn > yMax) {
-          minimumBoxHeight = yMaxZero+2*marginConn;
+      }
+    }
+
+    if (item->getPosition() == BoxItem::Right) {
+
+      if (item->getSpan() == BoxItem::HSpan) {
+        if (item->getMinimumBoxWidth() > rightLargest) {
+          rightLargest = item->getMinimumBoxWidth();
         }
-        else {
-          minimumBoxHeight = yMax+marginConn;
+      }
+      else {
+        if (boxItem.width()+marginConn > rightLargest) {
+          rightLargest = boxItem.width()+marginConn;
+        }
+      }
+      if (item->getSpan() == BoxItem::VSpan) {
+        if (item->getMinimumBoxHeight() > topHighest) {
+          topHighest = item->getMinimumBoxHeight();
         }
       }
     }
-    else {
-      minimumBoxWidth = xMax+marginConn;
-      minimumBoxHeight = yMax+marginConn;
+  }
+
+  if (leftLargest > minimumBoxWidth) {
+    minimumBoxWidth = leftLargest;
+  }
+  if (rightLargest > minimumBoxWidth) {
+    minimumBoxWidth = rightLargest;
+  }
+  if (topHighest > minimumBoxHeight) {
+    minimumBoxHeight = topHighest;
+  }
+  if (bottomHighest > minimumBoxHeight) {
+    minimumBoxHeight = bottomHighest;
+  }
+  // must move all free boxitem within of -gapXLeft,-gapYTop
+  foreach(BoxItem* item, blocks) {
+    if (item->getPosition() == BoxItem::Free) {
+      if (item->getSpan() == BoxItem::HSpan) {
+        item->moveBy(0,-gapYTop);
+      }
+      if (item->getSpan() == BoxItem::VSpan) {
+        item->moveBy(-gapXLeft,0);
+      }
+      else {
+        item->moveBy(-gapXLeft,-gapYTop);
+      }
     }
   }
+
   //cout << "min group size: " << minimumBoxWidth << "," << minimumBoxHeight << endl;
 }
 
@@ -188,6 +282,35 @@ void GroupItem::updateShape() {
   updateGeometry(InterfaceMove);
 }
 
+void GroupItem::updateBorderSpanItems() {
+  QList<BoxItem *> blocks = getScene()->getBoxItems();
+  bool changed = false;
+  foreach(BoxItem* item, blocks) {
+    changed = false;
+    if (item->getPosition() == BoxItem::Bottom) {
+      changed = true;
+      QPointF pos = item->pos();
+      item->moveTo(QPointF(pos.x(),boxHeight-item->getTotalHeight()));
+    }
+    else if (item->getPosition() == BoxItem::Right) {
+      changed = true;
+      QPointF pos = item->pos();
+      item->moveTo(QPointF(boxWidth-item->getTotalWidth(),pos.y()));
+    }
+    if (item->getSpan() == BoxItem::HSpan) {
+      changed = true;
+      item->setWidth(boxWidth);
+    }
+    else if (item->getSpan() == BoxItem::VSpan) {
+      changed = true;
+      item->setHeight(boxHeight);
+    }
+    if (changed) {
+      item->updateGeometry(Resize);
+    }
+  }
+}
+
 bool GroupItem::updateGeometry(ChangeType type) {
 
   QPointF oldOrigin = originPoint;
@@ -198,21 +321,35 @@ bool GroupItem::updateGeometry(ChangeType type) {
   // whatever the change, the minimum size may have changed
   updateMinimumSize();
 
-  if (type == Resize) {
+  if (type == Creation) {
     boxSizeChanged = true;
-  }
-  // if an internal block has moved, the actual box size may be inadequate
-  if (boxWidth < minimumBoxWidth) {
     boxWidth = minimumBoxWidth;
-    boxSizeChanged = true;
-  }
-  if (boxHeight < minimumBoxHeight) {
     boxHeight = minimumBoxHeight;
-    boxSizeChanged = true;
+    /* reset and update interfaces positions
+     * in case of spanning, the interface are positionned
+     * only on free borders.
+     */
+    resetInterfaceItemsPosition();
   }
-
-  if (boxSizeChanged) {
+  else if (type == Resize) {
+    boxSizeChanged = true;
     updateInterfaceAndConnectionItems();
+    updateBorderSpanItems();
+  }  
+  else if (type == InterfaceMove) {
+    // if an internal block has moved, the actual box size may be inadequate
+    if (boxWidth < minimumBoxWidth) {
+      boxWidth = minimumBoxWidth;
+      boxSizeChanged = true;
+      updateInterfaceAndConnectionItems();
+      updateBorderSpanItems();
+    }
+    if (boxHeight < minimumBoxHeight) {
+      boxHeight = minimumBoxHeight;
+      boxSizeChanged = true;
+      updateInterfaceAndConnectionItems();
+      updateBorderSpanItems();
+    }
   }
 
 
@@ -506,11 +643,11 @@ void GroupItem::hoverMoveEvent(QGraphicsSceneHoverEvent *event) {
 
       if ((y>boxHeight-2*marginS)&&(y<boxHeight)) {
         currentBorder = CornerSouthEast;
-        setCursor(Qt::SizeFDiagCursor);
+        setCursor(Qt::SizeFDiagCursor);        
       }
       else {
         currentBorder = BorderEast;
-        setCursor(Qt::SizeHorCursor);
+        setCursor(Qt::SizeHorCursor);        
       }
     }
     else if ((y>boxHeight-marginS)&&(y<boxHeight)) {
@@ -519,11 +656,11 @@ void GroupItem::hoverMoveEvent(QGraphicsSceneHoverEvent *event) {
 
       if ((x>boxWidth-2*marginE)&&(x<boxWidth)) {
         currentBorder = CornerSouthEast;
-        setCursor(Qt::SizeFDiagCursor);
+        setCursor(Qt::SizeFDiagCursor);        
       }
       else {
         currentBorder = BorderSouth;
-        setCursor(Qt::SizeVerCursor);
+        setCursor(Qt::SizeVerCursor);        
       }
     }
     else {
@@ -536,9 +673,7 @@ void GroupItem::hoverMoveEvent(QGraphicsSceneHoverEvent *event) {
         setCursor(Qt::ArrowCursor);
       }
     }
-  }
-  //QGraphicsItem::hoverMoveEvent(event);
-  event->ignore();
+  }  
 }
 
 void GroupItem::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) {
index 8ab486ad64731b6fcba927e2df692258946171c4..a7613e7c941461083f6135aea108b1388436c4ff 100644 (file)
@@ -48,20 +48,24 @@ public:
 
   // others  
   void nameChanged();
-  void updateShape();
+
   void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);  
   void load(QDomElement groupElement) throw(Exception);
   void save(QXmlStreamWriter& writer);
 
-protected:
-
+  void updateShape();
   void updateMinimumSize(); // modify the minimum size
   bool updateGeometry(ChangeType type);
+  void updateBorderSpanItems();
+
+   void hoverMoveEvent(QGraphicsSceneHoverEvent *event);
+   void mousePressEvent(QGraphicsSceneMouseEvent *event);
+   void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
+   void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
+
+protected:
+
 
-  void mousePressEvent(QGraphicsSceneMouseEvent *event);
-  void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
-  void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
-  void hoverMoveEvent(QGraphicsSceneHoverEvent *event);
   void contextMenuEvent(QGraphicsSceneContextMenuEvent *event);
 
 
@@ -71,8 +75,8 @@ private:
   in the top scene
   */
   BoxItem* parentItem;
-  QRectF rectTitle;  
-
+  QRectF rectTitle;
+  QPointF boxPoint; // the coordinates of the top-left corner of the box (without ifaces)
 
   InterfaceItem *isHoverInterface(QPointF point);
 };
index 0eaa8a1dc8435587cbd5d4ebe70da8e921ab71b1..05d7c4c61cb96ba3d163270ea44d9c734884fc1a 100644 (file)
@@ -103,15 +103,17 @@ int GroupScene::setInterfacesId(int countInit) {
   return counter;
 }
 
-BoxItem *GroupScene::createBoxItem(AbstractBlock *block, BoxItem::Position hPos, BoxItem::Position vPos, AbstractBoxItem::LockType lock, BoxItem::SpanType span) {
+BoxItem *GroupScene::createBoxItem(AbstractBlock *block, BoxItem::Position position, int lock, BoxItem::SpanType span) {
 
-  BoxItem* item = new BoxItem(block,dispatcher,params,groupItem, lock, span);
+  BoxItem* item = new BoxItem(block,dispatcher,params,groupItem, lock, span, position);
   item->setZValue(1);
   // add item from the QList
   boxItems.append(item);
   // repainting the group
   groupItem->updateShape();
-  // center the new block
+
+/*
+  // position the new block
   double x,y;
   if (hPos == BoxItem::Left) {
     x = 0;
@@ -134,7 +136,7 @@ BoxItem *GroupScene::createBoxItem(AbstractBlock *block, BoxItem::Position hPos,
   QPointF newPos(x,y);
   newPos = newPos-item->getOriginPoint();
   item->moveTo(newPos);
-
+*/
   return item;
 }
 
index bcaa79904765642a563ded9aff6bb6d10a822035..211d9d7937519151e861cbae245c2b82b0c62f75 100644 (file)
@@ -76,7 +76,7 @@ public:
   // others  
   
   // BoxItem related
-  BoxItem* createBoxItem(AbstractBlock* block, BoxItem::Position hPos = Center, BoxItem::Position vPos = Center, AbstractBoxItem::LockType lock = AbstractBoxItem::NoLock, BoxItem::SpanType span = BoxItem::NoSpan); //! create a new BoxItem and place it at the center of the scene
+  BoxItem* createBoxItem(AbstractBlock* block, BoxItem::Position position = BoxItem::Free, int lock = AbstractBoxItem::NoLock, BoxItem::SpanType span = BoxItem::NoSpan); //! create a new BoxItem and place it at the center of the scene
   void addBoxItem(BoxItem* item); //! add an already configured BoxItem in the scene.
   void removeBoxItem(BoxItem* item);
   
index 18397f33cd0564239b9003e980bbec8d47630b22..1ef3aae76b5c3de65eeb940cb3dc78c958da847e 100644 (file)
@@ -11,7 +11,7 @@ InterfaceItem::InterfaceItem(double _position,
                              int _orientation,
                              ConnectedInterface *_refInter,
                              AbstractBoxItem* _owner,
-                             Parameters* _params) {
+                             Parameters* _params, bool forceVisible) {
   positionRatio = _position;
   orientation = _orientation;
   refInter = _refInter;
@@ -24,7 +24,7 @@ InterfaceItem::InterfaceItem(double _position,
   nameWidth = fmName.width(refInter->getName());
   nameHeight = fmName.height();
   // by default, only data interface are visible
-  if (refInter->getPurpose() == AbstractInterface::Data) {
+  if ((forceVisible) || (refInter->getPurpose() == AbstractInterface::Data)) {
     visible = true;
   }
   else {
index 77ddf72d06334fd8bc8265f76d043c8d3dbfef25..26f9dd9aff6659a198a8a7f572e2e88308ebc11d 100644 (file)
@@ -23,7 +23,7 @@ public:
                   int _orientation,
                   ConnectedInterface* _refInter,
                   AbstractBoxItem* _owner,
-                  Parameters* _params);
+                  Parameters* _params, bool forceVisible = false);
   InterfaceItem();
   QRectF boundingRect() const;
   void paint(QPainter *painter);
index d98d04aeac9b7ae574805b7aedf5d01e5aa776d2..beed4278fdc4064b0d871643db86c75ed4c1b1e8 100644 (file)
@@ -35,7 +35,8 @@ NewProjectDialog::NewProjectDialog(Parameters *_params, QWidget *parent) : Custo
 
   QHBoxLayout *layAuto = new QHBoxLayout;
   autoConnClkCheck = new QCheckBox("Auto-connect blocks to main clock");
-  autoConnClkCheck->setChecked(true);
+  autoConnClkCheck->setChecked(true);  
+  layAuto->addWidget(autoConnClkCheck);
 
 
   QVBoxLayout *layAll = new QVBoxLayout;
index e0edd969b1b475fa454eb82ec5603a652a3a36db..7e697eb1baabb7bb5cf997543abf403a6ae35611 100644 (file)
@@ -223,6 +223,7 @@ void ReferenceBlock::loadInterfaces(QDomElement &elt) throw(Exception) {
   QString widthStr;
   QString endianStr;
   QString purposeStr;
+  QString clockStr;
   int purpose;
   QString multStr;
   int mult;
@@ -233,33 +234,59 @@ void ReferenceBlock::loadInterfaces(QDomElement &elt) throw(Exception) {
   QDomElement eltInputs = elt.firstChildElement("inputs");
   // getting each input
   QDomNodeList listNodeInputs = eltInputs.elementsByTagName("input");
+
+  // find all input clocks
+  QList<AbstractInterface*> clocks;
   for(int i=0;i<listNodeInputs.size();i++) {
     QDomNode node = listNodeInputs.at(i);
     QDomElement eltInput = node.toElement();
-    nameStr = eltInput.attribute("name","none");
-    typeStr = eltInput.attribute("type","none");
-    widthStr = eltInput.attribute("width","none");
-    endianStr = eltInput.attribute("endian","none");
-    int endianess;
-    if ((endianStr == "none") || (endianStr == "little")) {
-      endianess = AbstractInterface::LittleEndian;
-    }
-    else if (endianStr == "big") {
-      endianess = AbstractInterface::BigEndian;
-    }
-    else {
-      throw (Exception(BLOCKFILE_CORRUPTED));
+    purposeStr = eltInput.attribute("purpose","none");
+    if (purposeStr == "clock") {
+      nameStr = eltInput.attribute("name","none");
+      inter = new ReferenceInterface(this,nameStr,AbstractInterface::Input, AbstractInterface::Clock, "boolean", "1", AbstractInterface::LittleEndian, 1);
+      inputs.append(inter);
+      clocks.append(inter);
     }
+  }
+  cout << "number of clocks: " << clocks.size() << endl;
+
+  // find inputs
+  for(int i=0;i<listNodeInputs.size();i++) {
+    QDomNode node = listNodeInputs.at(i);
+    QDomElement eltInput = node.toElement();
     purposeStr = eltInput.attribute("purpose","none");
-    cout << "block : " << this->getName().toStdString() << endl;
-    cout << "purpose for " << nameStr.toStdString() << " : " << purposeStr.toStdString() << endl;
     purpose = ReferenceInterface::translatePurpose(purposeStr);
-    cout << "translated purpose : " << purpose << endl;
-    multStr = eltInput.attribute("multiplicity","none");
-    mult = ReferenceInterface::translateMultiplicity(multStr);
+    if (purpose != AbstractInterface::Clock) {
+      cout << "translated purpose : " << purpose << endl;
+      nameStr = eltInput.attribute("name","none");
+      typeStr = eltInput.attribute("type","none");
+      widthStr = eltInput.attribute("width","none");
+      endianStr = eltInput.attribute("endian","none");
+      clockStr = eltInput.attribute("clock","none");
+      int endianess;
+      if ((endianStr == "none") || (endianStr == "little")) {
+        endianess = AbstractInterface::LittleEndian;
+      }
+      else if (endianStr == "big") {
+        endianess = AbstractInterface::BigEndian;
+      }
+      else {
+        throw (Exception(BLOCKFILE_CORRUPTED));
+      }
 
-    inter = new ReferenceInterface(this,nameStr,AbstractInterface::Input, purpose, typeStr, widthStr, endianess, mult);
-    inputs.append(inter);
+      multStr = eltInput.attribute("multiplicity","none");
+      mult = ReferenceInterface::translateMultiplicity(multStr);
+
+      inter = new ReferenceInterface(this,nameStr, AbstractInterface::Input, purpose, typeStr, widthStr, endianess, mult);
+      if (clockStr == "none") {
+        // no clock given, take the first one (hope that there is a single one !)
+        clockStr = clocks.at(0)->getName();
+      }
+      if (! inter->setClockIface(clockStr)) {
+        throw (Exception(BLOCKFILE_CORRUPTED));
+      }
+      inputs.append(inter);
+    }
   }
   // getting each control
   QDomNodeList listNodeInCtl = eltInputs.elementsByTagName("control");
@@ -282,10 +309,12 @@ void ReferenceBlock::loadInterfaces(QDomElement &elt) throw(Exception) {
   for(int i=0;i<listNodeOutputs.size();i++) {
     QDomNode node = listNodeOutputs.at(i);
     QDomElement eltOutput = node.toElement();
+
     nameStr = eltOutput.attribute("name","none");
     typeStr = eltOutput.attribute("type","none");
     widthStr = eltOutput.attribute("width","none");
     endianStr = eltOutput.attribute("endian","none");
+    clockStr = eltOutput.attribute("clock","none");
     int endianess;
     if ((endianStr == "none") || (endianStr == "little")) {
       endianess = AbstractInterface::LittleEndian;
@@ -302,6 +331,13 @@ void ReferenceBlock::loadInterfaces(QDomElement &elt) throw(Exception) {
     mult = ReferenceInterface::translateMultiplicity(multStr);
 
     inter = new ReferenceInterface(this,nameStr,AbstractInterface::Output, purpose,typeStr,widthStr, endianess, mult);
+    if (clockStr == "none") {
+      // no clock given, take the first one (hope that there is a single one !)
+      clockStr = clocks.at(0)->getName();
+    }
+    if (! inter->setClockIface(clockStr)) {
+      throw (Exception(BLOCKFILE_CORRUPTED));
+    }
     outputs.append(inter);
   }
   // getting each control
@@ -330,6 +366,7 @@ void ReferenceBlock::loadInterfaces(QDomElement &elt) throw(Exception) {
     typeStr = eltBidir.attribute("type","none");
     widthStr = eltBidir.attribute("width","none");
     endianStr = eltBidir.attribute("endian","none");
+    clockStr = eltBidir.attribute("clock","none");
     int endianess;
     if ((endianStr == "none") || (endianStr == "little")) {
       endianess = AbstractInterface::LittleEndian;
@@ -346,6 +383,13 @@ void ReferenceBlock::loadInterfaces(QDomElement &elt) throw(Exception) {
     mult = ReferenceInterface::translateMultiplicity(multStr);
 
     inter = new ReferenceInterface(this,nameStr,AbstractInterface::InOut, purpose,typeStr,widthStr, endianess, mult);
+    if (clockStr == "none") {
+      // no clock given, take the first one (hope that there is a single one !)
+      clockStr = clocks.at(0)->getName();
+    }
+    if (! inter->setClockIface(clockStr)) {
+      throw (Exception(BLOCKFILE_CORRUPTED));
+    }
     bidirs.append(inter);
   }
 }
@@ -418,7 +462,21 @@ QDataStream& operator<<(QDataStream &out, const ReferenceBlock &b) {
   }
 
   toWrite << b.inputs.size();
-  // firstly write control ifaces
+  // firstly write clock ifaces
+  for(int i=0; i<b.inputs.size(); i++){
+    ReferenceInterface *iface = (ReferenceInterface *)(b.inputs.at(i));
+    if (iface->getPurpose() == AbstractInterface::Clock) {
+      toWrite << iface->getName();
+      toWrite << iface->getType();
+      toWrite << iface->getWidthString();
+      toWrite << iface->getPurpose();
+      toWrite << iface->getDirection();
+      toWrite << iface->getMultiplicity();
+      toWrite << iface->getClockIfaceType();
+      toWrite << iface->getClockIface();
+    }
+  }
+  // secondly write control ifaces
   for(int i=0; i<b.inputs.size(); i++){
     ReferenceInterface *iface = (ReferenceInterface *)(b.inputs.at(i));
     if (iface->getPurpose() == AbstractInterface::Control) {
@@ -428,18 +486,22 @@ QDataStream& operator<<(QDataStream &out, const ReferenceBlock &b) {
       toWrite << iface->getPurpose();
       toWrite << iface->getDirection();    
       toWrite << iface->getMultiplicity();
+      toWrite << iface->getClockIfaceType();
+      toWrite << iface->getClockIface();
     }
   }
   // secondly, write other ifaces
   for(int i=0; i<b.inputs.size(); i++){
     ReferenceInterface *iface = (ReferenceInterface *)(b.inputs.at(i));
-    if (iface->getPurpose() != AbstractInterface::Control) {
+    if ((iface->getPurpose() != AbstractInterface::Control) && (iface->getPurpose() != AbstractInterface::Clock)) {
       toWrite << iface->getName();
       toWrite << iface->getType();
       toWrite << iface->getWidthString();
       toWrite << iface->getPurpose();
       toWrite << iface->getDirection();    
       toWrite << iface->getMultiplicity();
+      toWrite << iface->getClockIfaceType();
+      toWrite << iface->getClockIface();
     }
   }
   toWrite << b.outputs.size();
@@ -453,6 +515,8 @@ QDataStream& operator<<(QDataStream &out, const ReferenceBlock &b) {
       toWrite << iface->getPurpose();
       toWrite << iface->getDirection();    
       toWrite << iface->getMultiplicity();
+      toWrite << iface->getClockIfaceType();
+      toWrite << iface->getClockIface();
     }
   }
   // secondly, write other ifaces
@@ -465,6 +529,8 @@ QDataStream& operator<<(QDataStream &out, const ReferenceBlock &b) {
       toWrite << iface->getPurpose();
       toWrite << iface->getDirection();    
       toWrite << iface->getMultiplicity();
+      toWrite << iface->getClockIfaceType();
+      toWrite << iface->getClockIface();
     }
   }
   toWrite << b.bidirs.size();
@@ -476,6 +542,8 @@ QDataStream& operator<<(QDataStream &out, const ReferenceBlock &b) {
     toWrite << iface->getPurpose();
     toWrite << iface->getDirection();    
     toWrite << iface->getMultiplicity();
+    toWrite << iface->getClockIfaceType();
+    toWrite << iface->getClockIface();
   }
 
   out << blockData;
@@ -557,13 +625,24 @@ QDataStream& operator>>(QDataStream &in, ReferenceBlock &b) {
     iface->setDirection(val);    
     in >> val;
     iface->setMultiplicity(val);
+    int clkType;
+    QString clk;
+    in >> clkType;
+    in >> clk;
+    if (clkType == AbstractInterface::ParameterName) {
+      clk = "$"+clk;
+    }
+    if (! iface->setClockIface(clk)) {
+      cerr << "Abnormal case while reading a reference block in library: cannot set ref clock for an interface" << endl;
+    }
+
     b.inputs.append(iface);
     if (iface->getPurpose() == AbstractInterface::Data) {
       QString ctlRefName = iface->getName()+"_enb";
       ReferenceInterface* ctlRefIface = AI_TO_REF(b.getIfaceFromName(ctlRefName));      
       if (ctlRefIface != NULL) {        
         if (! ctlRefIface->setAssociatedIface(iface)) {
-          cerr << "Abnormal case while reading a reference block in library" << endl;
+          cerr << "Abnormal case while reading a reference block in library: cannot set associated control interface for data interface" << endl;
         }      
       }        
     }    
@@ -586,6 +665,16 @@ QDataStream& operator>>(QDataStream &in, ReferenceBlock &b) {
     iface->setDirection(val);
     in >> val;   
     iface->setMultiplicity(val);
+    int clkType;
+    QString clk;
+    in >> clkType;
+    in >> clk;
+    if (clkType == AbstractInterface::ParameterName) {
+      clk = "$"+clk;
+    }
+    if (! iface->setClockIface(clk)) {
+      cerr << "Abnormal case while reading a reference block in library: cannot set ref clock for an interface" << endl;
+    }
     b.outputs.append(iface);
     if (iface->getPurpose() == AbstractInterface::Data) {
       QString ctlRefName = iface->getName()+"_enb";      
@@ -615,6 +704,16 @@ QDataStream& operator>>(QDataStream &in, ReferenceBlock &b) {
     iface->setDirection(val);
     in >> val;    
     iface->setMultiplicity(val);
+    int clkType;
+    QString clk;
+    in >> clkType;
+    in >> clk;
+    if (clkType == AbstractInterface::ParameterName) {
+      clk = "$"+clk;
+    }
+    if (! iface->setClockIface(clk)) {
+      cerr << "Abnormal case while reading a reference block in library: cannot set ref clock for an interface" << endl;
+    }
     b.bidirs.append(iface);
   }
 
index d12284774bd426cddd9279284340bffef9384a11..0229e7f2d7117972b752f9cd0ba83883c940693e 100644 (file)
@@ -30,7 +30,7 @@ SourceItem::SourceItem(AbstractBlock *_refBlock,
   setZValue(100);
   setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemSendsGeometryChanges);
 
-  initInterfaceItems();
+  createInterfaceItems();
   updateGeometry(InterfaceMove);
   resetInterfaceItemsPosition();
   QPointF initPos = QPointF(0.0,0.0) - originPoint;
@@ -679,7 +679,7 @@ void SourceItem::load(QDomElement funcElement) throw(Exception) {
   }
   
   // creating InterfaceItem
-  initInterfaceItems();
+  createInterfaceItems();
   // setting them with saved values
   for(int i=0; i<interfaceNodes.length(); i++){
 
index 0cdb79801a825344f8ab50e1961273ded5b5fb3c..6a8ea4d52a1f32b4521c55a1a00360fa70fa871f 100644 (file)
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!DOCTYPE QtCreatorProject>
-<!-- Written by QtCreator 4.2.0, 2018-04-20T16:47:23. -->
+<!-- Written by QtCreator 4.2.0, 2018-04-27T16:43:37. -->
 <qtcreator>
  <data>
   <variable>EnvironmentId</variable>
index 3399923c5382b5f4eb3bad6138dfb3fea748e67d..f2e8067992b095109f2ed871e487eeba2bcc0b83 100644 (file)
Binary files a/lib/implementations/impls.bmf and b/lib/implementations/impls.bmf differ
index 777424e857baaabd2629ee20e47e190f7054e2c2..32255bae20bbd00275e88a2a27d457237aee8d26 100644 (file)
@@ -16,6 +16,7 @@
   </informations>
 
   <parameters>
+    <parameter name="imx_clk" type="positive" value="133" context="user"/>
   </parameters>
 
   <interfaces>
       <input name="clk" type="boolean" width="1" purpose="clock" />
       <input name="rst" type="boolean" width="1" purpose="reset" />
       
-      <input name="imx_addr" type="expression" width="$wb_addr_width" />
-      <input name="imx_cs_n" type="boolean" width="1" />
-      <input name="imx_oe_n" type="boolean" width="1" />
-      <input name="imx_eb3_n" type="boolean" width="1" />
+      <input name="imx_addr" type="expression" width="$wb_addr_width" clock="$imx_clk" />
+      <input name="imx_data" type="expression" width="$wb_data_width" clock="$imx_clk" />      
+      <input name="imx_cs_n" type="boolean" width="1" clock="$imx_clk" />
+      <input name="imx_oe_n" type="boolean" width="1" clock="$imx_clk"/>
+      <input name="imx_eb3_n" type="boolean" width="1" clock="$imx_clk"/>
       
       <input name="ack_i" type="boolean" width="1" purpose="wb" />
       <input name="dat_i" width="$wb_data_width" purpose="wb" />
index 9dc64827d332272ef420c0b5703ffef094d0c4cd..67e76eea9b6b68bd9b036454f0151a154c32ccdc 100644 (file)
Binary files a/lib/references/references.bmf and b/lib/references/references.bmf differ
index 29f5d2821f7270e09ee8af42cd7b74732fe4c173..bf87cb8f6f78f2ae20def03619274482e78baae2 100644 (file)
        <xs:attribute ref="value" use="optional"/>
        <xs:attribute ref="iface" use="optional"/>
        <xs:attribute ref="width" use="optional"/>      
-       <xs:attribute ref="context" use="required"/>
+       <xs:attribute name="context" type="typecontext" use="required"/>
     </xs:attributeGroup>
 
     <xs:attributeGroup name="inOutAttrGroup">
        <xs:attribute ref="name" use="required"/>
        <xs:attribute ref="width" use="required"/>
        <xs:attribute name="type" type="typeiface"/>
-       <xs:attribute ref="purpose"/>
+       <xs:attribute name="purpose" type="typepurpose" use="optional"/>
        <xs:attribute ref="multiplicity"/>
-       <xs:attribute name="endian" type="typeendian" use="optional"/>  
+       <xs:attribute name="endian" type="typeendian" use="optional"/>
+       <xs:attribute ref="clock" use="optional"/>
     </xs:attributeGroup>
 
 
@@ -27,6 +28,7 @@
 
     <xs:attribute name="ids" type="xs:string"/>
     <xs:attribute name="name" type="xs:string"/>
+    <xs:attribute name="clock" type="xs:string"/>
 
     <xs:simpleType name="typeparam">
       <xs:restriction base="xs:string">
        <xs:enumeration value="big"/>
       </xs:restriction>
     </xs:simpleType>
-      
+
+    <xs:simpleType name="typecontext">
+      <xs:restriction base="xs:string">
+       <xs:enumeration value="generic"/>
+       <xs:enumeration value="user"/>
+       <xs:enumeration value="wb"/>
+       <xs:enumeration value="port"/>
+      </xs:restriction>
+    </xs:simpleType>
+
+    <xs:simpleType name="typepurpose">
+      <xs:restriction base="xs:string">
+       <xs:enumeration value="data"/>
+       <xs:enumeration value="clock"/>
+       <xs:enumeration value="reset"/>
+       <xs:enumeration value="wb"/>    
+      </xs:restriction>
+    </xs:simpleType>
+    
     <xs:attribute name="wishbone" type="xs:string"/>
-    <xs:attribute name="context" type="xs:string" />
     <xs:attribute name="multiplicity" type="xs:string" />
     <xs:attribute name="width" type="xs:string"/>
-    <xs:attribute name="purpose" type="xs:string"/>
     <xs:attribute name="value" type="xs:string"/>
     <xs:attribute name="iface" type="xs:string"/>
     <xs:attribute name="path" type="xs:string" />