#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;
// 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;
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;
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);
*/
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;
}
class Dispatcher;
class InterfaceItem;
+#include "Parameters.h"
class Parameters;
class AbstractBlock;
class GroupScene;
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();
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);
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; }
InterfaceItem *searchInterfaceItemByRef(ConnectedInterface* ref);
InterfaceItem* getInterfaceItemFromCursor(qreal x, qreal y);
+ QRectF boundingRect() const;
+
protected:
Dispatcher *dispatcher;
Parameters *params;
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);
};
type = Boolean;
endianess = LittleEndian;
associatedIface = NULL;
+ clkIface = "";
+ clkIfaceType = 0;
}
type = typeFromString(_type);
endianess = _endianess;
associatedIface = NULL;
+ clkIface = "";
+ clkIfaceType = 0;
}
AbstractInterface::AbstractInterface(AbstractInterface* other) {
purpose = other->purpose;
endianess = LittleEndian;
associatedIface = NULL;
+ clkIface = other->clkIface;
+ clkIfaceType = other->clkIfaceType;
}
void AbstractInterface::setName(const QString& _name) {
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;
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);
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);
void setPurpose(int _purpose);
void setDirection(int _direction);
bool setAssociatedIface(AbstractInterface* iface);
+ bool setClockIface(QString name);
// testers
virtual bool isReferenceInterface();
* (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
};
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
if (_refBlock->isReferenceBlock()) throw(Exception(BLOCK_INVALID_TYPE));
span = _span;
- hPos = _hPos;
- vPos = _vPos;
+ position = _position;
childGroupItem = NULL;
//boxWidth = params->defaultBlockWidth;
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;
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;
+ }
}
}
//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;
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();
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;
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);
+ }
}
}
}
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();
}
}
}
- //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);
+ }
+ }
+ }
}
}
// creating InterfaceItem
- initInterfaceItems();
+ createInterfaceItems();
// setting them with saved values
for(int i=0; i<interfaceNodes.length(); i++){
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();
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);
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;
// 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);
}
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() {
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;
}
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;
}
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;
// 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();
+ }
}
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)) {
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 {
setCursor(Qt::ArrowCursor);
}
}
- }
- //QGraphicsItem::hoverMoveEvent(event);
- event->ignore();
+ }
}
void GroupItem::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) {
// 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);
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);
};
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;
QPointF newPos(x,y);
newPos = newPos-item->getOriginPoint();
item->moveTo(newPos);
-
+*/
return item;
}
// 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);
int _orientation,
ConnectedInterface *_refInter,
AbstractBoxItem* _owner,
- Parameters* _params) {
+ Parameters* _params, bool forceVisible) {
positionRatio = _position;
orientation = _orientation;
refInter = _refInter;
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 {
int _orientation,
ConnectedInterface* _refInter,
AbstractBoxItem* _owner,
- Parameters* _params);
+ Parameters* _params, bool forceVisible = false);
InterfaceItem();
QRectF boundingRect() const;
void paint(QPainter *painter);
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;
QString widthStr;
QString endianStr;
QString purposeStr;
+ QString clockStr;
int purpose;
QString multStr;
int mult;
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");
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;
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
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;
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);
}
}
}
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) {
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();
toWrite << iface->getPurpose();
toWrite << iface->getDirection();
toWrite << iface->getMultiplicity();
+ toWrite << iface->getClockIfaceType();
+ toWrite << iface->getClockIface();
}
}
// secondly, write other ifaces
toWrite << iface->getPurpose();
toWrite << iface->getDirection();
toWrite << iface->getMultiplicity();
+ toWrite << iface->getClockIfaceType();
+ toWrite << iface->getClockIface();
}
}
toWrite << b.bidirs.size();
toWrite << iface->getPurpose();
toWrite << iface->getDirection();
toWrite << iface->getMultiplicity();
+ toWrite << iface->getClockIfaceType();
+ toWrite << iface->getClockIface();
}
out << blockData;
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;
}
}
}
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";
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);
}
setZValue(100);
setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemSendsGeometryChanges);
- initInterfaceItems();
+ createInterfaceItems();
updateGeometry(InterfaceMove);
resetInterfaceItemsPosition();
QPointF initPos = QPointF(0.0,0.0) - originPoint;
}
// creating InterfaceItem
- initInterfaceItems();
+ createInterfaceItems();
// setting them with saved values
for(int i=0; i<interfaceNodes.length(); i++){
<?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>
</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" />
<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>
<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" />