From 6a0ffdb10d7344d99e04c5518fca2b8295df94be Mon Sep 17 00:00:00 2001 From: stephane Domas Date: Fri, 27 Apr 2018 16:44:07 +0200 Subject: [PATCH] adding link between ifaces and clk --- AbstractBoxItem.cpp | 19 +- AbstractBoxItem.h | 24 ++- AbstractInterface.cpp | 46 +++++ AbstractInterface.h | 16 ++ BoxItem.cpp | 278 +++++++++++++++++++++++------ BoxItem.h | 19 +- Dispatcher.cpp | 34 ++-- GroupBlock.cpp | 12 +- GroupItem.cpp | 263 ++++++++++++++++++++------- GroupItem.h | 22 ++- GroupScene.cpp | 10 +- GroupScene.h | 2 +- InterfaceItem.cpp | 4 +- InterfaceItem.h | 2 +- NewProjectDialog.cpp | 3 +- ReferenceBlock.cpp | 145 ++++++++++++--- SourceItem.cpp | 4 +- blast.creator.user | 2 +- lib/implementations/impls.bmf | Bin 6865 -> 6865 bytes lib/references/apf27-wb-master.xml | 10 +- lib/references/references.bmf | Bin 23200 -> 25136 bytes reference.xsd | 30 +++- 22 files changed, 732 insertions(+), 213 deletions(-) diff --git a/AbstractBoxItem.cpp b/AbstractBoxItem.cpp index 9fafc8f..911a790 100644 --- a/AbstractBoxItem.cpp +++ b/AbstractBoxItem.cpp @@ -12,8 +12,13 @@ #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; } diff --git a/AbstractBoxItem.h b/AbstractBoxItem.h index 84a4fbc..e490088 100644 --- a/AbstractBoxItem.h +++ b/AbstractBoxItem.h @@ -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); }; diff --git a/AbstractInterface.cpp b/AbstractInterface.cpp index 6b3d009..03a1a98 100644 --- a/AbstractInterface.cpp +++ b/AbstractInterface.cpp @@ -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 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 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; diff --git a/AbstractInterface.h b/AbstractInterface.h index 166fdbe..0e167db 100644 --- a/AbstractInterface.h +++ b/AbstractInterface.h @@ -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 }; diff --git a/BoxItem.cpp b/BoxItem.cpp index a7e1181..deee2cc 100644 --- a/BoxItem.cpp +++ b/BoxItem.cpp @@ -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; iconnectTo(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); } diff --git a/GroupBlock.cpp b/GroupBlock.cpp index 7945ee7..ea7f2f7 100644 --- a/GroupBlock.cpp +++ b/GroupBlock.cpp @@ -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() { diff --git a/GroupItem.cpp b/GroupItem.cpp index ebef87c..c165d02 100644 --- a/GroupItem.cpp +++ b/GroupItem.cpp @@ -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 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 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)&&(yboxHeight-marginS)&&(yboxWidth-2*marginE)&&(xignore(); + } } void GroupItem::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) { diff --git a/GroupItem.h b/GroupItem.h index 8ab486a..a7613e7 100644 --- a/GroupItem.h +++ b/GroupItem.h @@ -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); }; diff --git a/GroupScene.cpp b/GroupScene.cpp index 0eaa8a1..05d7c4c 100644 --- a/GroupScene.cpp +++ b/GroupScene.cpp @@ -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; } diff --git a/GroupScene.h b/GroupScene.h index bcaa799..211d9d7 100644 --- a/GroupScene.h +++ b/GroupScene.h @@ -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); diff --git a/InterfaceItem.cpp b/InterfaceItem.cpp index 18397f3..1ef3aae 100644 --- a/InterfaceItem.cpp +++ b/InterfaceItem.cpp @@ -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 { diff --git a/InterfaceItem.h b/InterfaceItem.h index 77ddf72..26f9dd9 100644 --- a/InterfaceItem.h +++ b/InterfaceItem.h @@ -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); diff --git a/NewProjectDialog.cpp b/NewProjectDialog.cpp index d98d04a..beed427 100644 --- a/NewProjectDialog.cpp +++ b/NewProjectDialog.cpp @@ -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; diff --git a/ReferenceBlock.cpp b/ReferenceBlock.cpp index e0edd96..7e697eb 100644 --- a/ReferenceBlock.cpp +++ b/ReferenceBlock.cpp @@ -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 clocks; for(int i=0;igetName().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;igetName(); + } + 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; igetPurpose() == 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; igetPurpose() == 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; igetPurpose() != 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); } diff --git a/SourceItem.cpp b/SourceItem.cpp index d122847..0229e7f 100644 --- a/SourceItem.cpp +++ b/SourceItem.cpp @@ -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 - + EnvironmentId diff --git a/lib/implementations/impls.bmf b/lib/implementations/impls.bmf index 3399923c5382b5f4eb3bad6138dfb3fea748e67d..f2e8067992b095109f2ed871e487eeba2bcc0b83 100644 GIT binary patch delta 72 zcmV-O0Js0qHPJP&69$tv1}2je1|+jx2GRzTgAE{)PYntIGm`-X6O(NX7L!>GAhV+l e + @@ -23,10 +24,11 @@ - - - - + + + + + diff --git a/lib/references/references.bmf b/lib/references/references.bmf index 9dc64827d332272ef420c0b5703ffef094d0c4cd..67e76eea9b6b68bd9b036454f0151a154c32ccdc 100644 GIT binary patch delta 2188 zcmbVNZ)jUp6hH61Bwf?wWlh>NN&l>&-Lm{?Ufay(CALjx#sZUO9TlQ7m~E|_+te_J z?8BfknV{(CdcO3FwXiP=73wbS+*I5LQIINAK@fEeQIsKbGLSLFdEd>w@12|ch5cNcTN^pq~(t#7r7i$CjX3K9p&k-Z@PP;s$!!$)1fD}wX8v3B0>eKKPJP8?U*#SD$ zb^2zg*A!iypl?65O;O7<&ek`3RCpSmffI0m+GsR*wXvnaL6K7Q1*pfxyvW=?aiMj) z3;4Uu;a&f9v&e;gC5%Z9{r-uJrP3s44t%mQf?g+1+OWnz}J!*k#XH46gD*SGm zT9aoh_Z#r+!PS5&+cuF?o(nRb%Xf+uZy(pJTUMB&;?LeBU)$^(G73>o6QdlXpAdfU zYehvrN`COIN>y;P%>wRnUIZljql`V8zn8=9_s2~NenDRI->rs-B~#qZf>=mCXb@4d zVejJ)@YTb?G}jh_EIRxym=LhGPlzits^BZ_+qlzGdz5Rn4*0V@j;GrLSjzUBpe=Z$ z!%wYEhDA9}Uheo(=8KPnHLkrFjxbKElzk`QxXGr=`7O;d-DmK<>QR0qSHg`-%?2II zX3Vo&G2+`ME~C6fX1A99chw9~n|wYhDIDIabVnk?8oZRqvf1!@B71L#DxZ;$*suh4N;)lgW=NlJQ)pTSEA(Zt(mz{^AlH zb6Xd2#4D@rFH?n?FX2*8&UiKxMRU|WL876Q!X>`$M zX_9MnD(42d@0sBiR7S+e_m8C6WkyHxPH}Bph|G=j2?AI_{*)K>3G8B3sdG>wKL-c# zMldJ>qoh5#t3ft$V1}f^F}xWOd0g7PKEu|E#kIjg7t6zeLMM|mOnUKLA;GV)R)~rt z>kg4Sg%x|%WLX*&W5I%KE5;2dIu;fSno%_NbmQ8?K|EXR=CJ3B5d&6gWAY1Yt)4-b#_k`R~0yQW~n!$z^h?^mcVTRu@0|n8>fi4&Kl8D*dyb Trf(UqWwy|auO~4Zz7qTkzA)eR delta 1231 zcma)6T}TvB6uvWew^di#Rm^sC${k%zx5f5nTDNUnl{8UY3sQ^)&5cR~7b7G3r6i)) z>I;I95_&00DsB=+MNy$aRKE095tO|I74=XLQD>&MmXc^L=iEDYzH{z9-#KS4-;>5B zqv-Y^bYZB~NF@5MR!el|c@bbKXgu{NOG zuA88%;+1vkZ%_kyikW~x@ib>L8<1sfnHAgZR=GaNG!|k38Y#Aw1zDJ_WVN)jncf1V zBQ)32yoK}%S{ta9q%|5_SQPE;%P_OdgT(wMNDdzwNk$xg+;w>I&Jo87XA?%8aZEYA z_()P(P=?lm7MVX3V+Ge_pr;0owmhUQ#ipMRJu&cTD4Pu)5f>LU%C;i5jSa9}=nF0V zWg_BUTmH}ehGZ!&xHPR-sOfV6W;kJ+BeB)EOBky?%`3DOQ=xC0ve|7MLq~qle!h zRf#dpE!J0jlCzR+cuFfS9O*61B%BWlrMmn7*q9d6euKBQ92e6S~?*IS* diff --git a/reference.xsd b/reference.xsd index 29f5d28..bf87cb8 100644 --- a/reference.xsd +++ b/reference.xsd @@ -10,16 +10,17 @@ - + - + - + + @@ -27,6 +28,7 @@ + @@ -55,12 +57,28 @@ - + + + + + + + + + + + + + + + + + + + - - -- 2.39.5