From: stephane Domas <stephane.domas@univ-fcomte.fr> Date: Sun, 14 May 2017 19:45:38 +0000 (+0200) Subject: pattern comput done X-Git-Url: https://bilbo.iut-bm.univ-fcomte.fr/and/gitweb/blast.git/commitdiff_plain/48f48e6a26a54751ecd0ab90b10ab972cc5e89cd?ds=inline;hp=8e89ca269960b7bb43ccc054696dfc28e84d409a pattern comput done --- diff --git a/AbstractBlock.h b/AbstractBlock.h index 88e4cb9..9216212 100644 --- a/AbstractBlock.h +++ b/AbstractBlock.h @@ -36,14 +36,11 @@ public: QList<BlockParameter *> getPortParameters(); QList<BlockParameter *> getWishboneParameters(); inline AbstractBlock* getParent() { return parent; } - inline QList<int> getProductionCounter() { return productionCounter; } - inline int getDelta() { return delta; } + inline bool getPatternComputed() { return patternComputed; } // setters void setName(const QString& str); virtual void setParent(AbstractBlock* _parent); - inline void setProductionCounter(QList<int> pattern) { productionCounter = pattern; } - inline void setDelta(int _delta) { delta = _delta; } inline void setPatternComputed(bool state) { patternComputed = state; } // testers @@ -90,9 +87,7 @@ protected: // others - // patterns - QList<int> productionCounter; //! only usefull for output interfaces - int delta; + // patterns bool patternComputed; // NB: only GroupBlock and FunctionalBlock have a real parent, except sources that have no parents diff --git a/AbstractInterface.cpp b/AbstractInterface.cpp index f57f780..49a937c 100644 --- a/AbstractInterface.cpp +++ b/AbstractInterface.cpp @@ -141,10 +141,17 @@ bool AbstractInterface::setAssociatedIface(AbstractInterface* iface) { int AbstractInterface::getIntDirection(QString str) { if(str == "input") return Input; if(str == "output") return Output; - if(str == "inOut") return InOut; + if(str == "inout") return InOut; return -1; } +int AbstractInterface::getIntPurpose(QString str) { + if(str == "data") return Data; + else if(str == "clock") return Clock; + else if(str == "reset") return Reset; + else if(str == "wishbone") return Wishbone; + return -1; +} QString AbstractInterface::getTypeString() { diff --git a/AbstractInterface.h b/AbstractInterface.h index ac47ca9..2c914d4 100644 --- a/AbstractInterface.h +++ b/AbstractInterface.h @@ -14,6 +14,7 @@ class Exception; #define AI_TO_REF(ptr) ((ReferenceInterface*)ptr) #define AI_TO_FUN(ptr) ((FunctionalInterface*)ptr) #define AI_TO_GRP(ptr) ((GroupInterface*)ptr) +#define AI_TO_CON(ptr) ((ConnectedInterface*)ptr) using namespace std; using namespace Qt; @@ -29,7 +30,8 @@ public : enum IfaceVHDLContext {AnyContext = 0, Entity = 1, Component = 2, Architecture = 3 }; // NB : 3 is when creating an instance of the block that owns this iface enum IfaceVHDLFlags { NoComma = 1 }; - static int getIntDirection(QString str); + static int getIntDirection(QString str); + static int getIntPurpose(QString str); AbstractInterface(AbstractBlock* _owner); AbstractInterface(AbstractBlock* _owner, const QString& _name, const QString& _type, const QString& _width, int _direction, int _purpose); @@ -50,16 +52,6 @@ public : double getDoubleWidth() throw(QException); - inline QList<char> getConsumptionPattern() { return consumptionPattern; } - inline QList<char> getProductionPattern() { return productionPattern; } - inline QList<char> getOutputPattern() { return outputPattern; } - - //virtual QList<AbstractInterface*> getConnectedTo() = 0; - - /* NB: only GroupInterface and FunctionalInterface have a connectedFrom, so - defining getConnectedFrom as pure virtual is normal, usefull even though it is ugly :-) - */ - virtual AbstractInterface* getConnectedFrom() = 0; // setters inline void setOwner(AbstractBlock* _owner) { owner = _owner; } @@ -71,28 +63,14 @@ public : void setDirection(int _direction); bool setAssociatedIface(AbstractInterface* iface); - inline void setConsumptionPattern(QList<char> pattern) { consumptionPattern = pattern; } - inline void setProductionPattern(QList<char> pattern) { productionPattern = pattern; } - inline void setOutputPattern(QList<char> pattern) { outputPattern = pattern; } - // testers virtual bool isReferenceInterface(); virtual bool isFunctionalInterface(); virtual bool isGroupInterface(); - //virtual bool isConnectedTo() = 0; - //virtual bool isConnectedFrom() = 0; - //virtual bool canConnectTo(AbstractInterface* iface) = 0; // returns yes if this can be connected to iface, no if not - //virtual bool canConnectFrom(AbstractInterface* iface) = 0; // returns yes if this can be connected from iface, no if not // others virtual AbstractInterface *clone() = 0; - - //virtual bool addConnectedTo(AbstractInterface *inter) = 0; - //virtual void removeConnectedTo(AbstractInterface *inter) = 0; - //virtual bool setConnectedFrom(AbstractInterface* inter) = 0; - //virtual void clearConnectedTo() = 0; - //virtual void clearConnections() = 0; - //virtual void connectionsValidation(QStack<AbstractInterface*> *interfacetoValidate, QList<AbstractInterface*> *validatedInterfaces) throw(Exception) = 0; + int typeFromString(const QString &_type); QString toVHDL(int context, int flags) throw(Exception); @@ -115,11 +93,7 @@ protected: */ AbstractInterface* associatedIface; - // patterns - QList<char> consumptionPattern; //! only usefull for input interfaces - QList<char> productionPattern; //! only usefull for output interfaces - QList<char> outputPattern; //! only usefull for output interfaces }; diff --git a/ArithmeticEvaluator.cpp b/ArithmeticEvaluator.cpp index dd8081e..54a9596 100644 --- a/ArithmeticEvaluator.cpp +++ b/ArithmeticEvaluator.cpp @@ -22,13 +22,19 @@ ArithmeticEvaluator::ArithmeticEvaluator() { since spaces are removed. Thus, an expression like sin 10 will lead to sin10 after spaces removal, and thus becomes invalid. */ - fctMarkers << "sin" << "cos" << "log10" << "log2" << "log" << "ceil" << "floor" << "round"; + fctMarkers << "sin" << "cos" << "log10" << "log2" << "log" << "ceil" << "floor" << "round"; } ArithmeticEvaluator::ArithmeticEvaluator(const QString& _expression) throw(int) { opMarkers = "+-*/"; varMarkers = "$"; - fctMarkers << "sin" << "cos" << "log10" << "log2" << "log" << "ceil" << "floor" << "round"; + expression = QStringList(); + /* CAUTION : function are mandatory using ( ) to encapsulate the operand + since spaces are removed. Thus, an expression like sin 10 will lead to + sin10 after spaces removal, and thus becomes invalid. + */ + fctMarkers << "sin" << "cos" << "log10" << "log2" << "log" << "ceil" << "floor" << "round"; + try { setExpression(_expression); } @@ -37,7 +43,10 @@ ArithmeticEvaluator::ArithmeticEvaluator(const QString& _expression) throw(int) } } -void ArithmeticEvaluator::setExpression(const QString& _expression) throw(int) { +void ArithmeticEvaluator::setExpression(const QString& _expression) throw(int) { + + setVariableNames(_expression); + try { convert(_expression); } @@ -46,6 +55,28 @@ void ArithmeticEvaluator::setExpression(const QString& _expression) throw(int) { } } +void ArithmeticEvaluator::setVariablesValue(const QHash<QString,double>& _varValues) { + varValues = _varValues; + /* + QHashIterator<QString,double> iterV(varValues); + while (iterV.hasNext()) { + iterV.next(); + cout << "var " << qPrintable(iterV.key()) << " = " << iterV.value() << endl; + } + */ +} + +void ArithmeticEvaluator::setVariableNames(const QString& _expression) { + varNames.clear(); + QRegularExpression re("[$][a-zA-Z0-9_]+"); + QRegularExpressionMatchIterator matcher = re.globalMatch(_expression); + while(matcher.hasNext()) { + QRegularExpressionMatch m = matcher.next(); + QString var = m.captured(0); + varNames.append(var); + } +} + void ArithmeticEvaluator::print() { foreach(QString elt, expression) { cout << qPrintable(elt) << " "; @@ -84,6 +115,7 @@ double ArithmeticEvaluator::evalFunction(int indexFunc, double value) { } double ArithmeticEvaluator::evaluate() throw(int) { + errorMessage = ""; QStack<double> stack; bool ok; double value1,value2; @@ -102,7 +134,11 @@ double ArithmeticEvaluator::evaluate() throw(int) { stack.push(evalFunction(idFunc,value1)); } else if (varMarkers.contains(c)) { - if (!varValues.contains(elt)) throw(-index); + if (!varValues.contains(elt)) { + errorMessage = "cannot find value of "; + errorMessage += qPrintable(elt); + throw(-index); + } stack.push(varValues.value(elt)); } else if (opMarkers.contains(c)) { @@ -166,18 +202,14 @@ double ArithmeticEvaluator::evaluate() throw(int) { void ArithmeticEvaluator::convert(const QString& _expression) throw(int) { - QString expr = _expression; - cout << "converting " << qPrintable(expr) << endl; + QString expr = _expression; QString result=""; - expr.remove(QChar(' '), Qt::CaseInsensitive); - cout << "converting " << qPrintable(expr) << endl; - foreach(QString func, fctMarkers) { - cout << "for " << qPrintable(func) << endl; + expr.remove(QChar(' '), Qt::CaseInsensitive); + foreach(QString func, fctMarkers) { QString rep = QString("\x1b%1").arg(fctMarkers.indexOf(QRegExp(func))); expr.replace(QRegExp(func),rep); - } - cout << "packed expr: " << qPrintable(expr) << endl; + } int offset = 0; try { @@ -379,7 +411,7 @@ QString ArithmeticEvaluator::getVariable(const QString& _expression, int offset, *size = 1; } - while ((_expression[i].isLetterOrNumber()) || (_expression[i] == '-') || (_expression[i] == '_')) { + while ((_expression[i].isLetterOrNumber()) || (_expression[i] == '_')) { number.append(_expression[i]); i += 1; *size += 1; diff --git a/ArithmeticEvaluator.h b/ArithmeticEvaluator.h index f6d478b..67f50a5 100644 --- a/ArithmeticEvaluator.h +++ b/ArithmeticEvaluator.h @@ -30,16 +30,22 @@ public: ArithmeticEvaluator(); ArithmeticEvaluator(const QString& _expression) throw(int); + //getters + inline QList<QString> getVariableNames() { return varNames; } + + // setters void setExpression(const QString& _expression) throw(int); - inline void setVariablesValue(const QHash<QString,double>& _varValues) { varValues = _varValues; } + void setVariablesValue(const QHash<QString,double>& _varValues); inline void setVariableValue(const QString& var, double value) { varValues.insert(var,value); } inline void setVariableMarkers(const QString& _markers) { varMarkers = _markers; } void print(); double evaluate() throw(int); + inline QString getError() { return errorMessage; } protected: QStringList expression; + QList<QString> varNames; // the names of variables that ARE in the expression QHash<QString,double> varValues; QString varMarkers; // a sequence of symbols that are allowed to start a variable. $ is by default QString opMarkers; // a sequence if symbols used as operators. +-*/ is the hard-coded default @@ -54,6 +60,10 @@ protected: bool checkAfterPar(const QString& _expression, int offset); double evalFunction(int indexFunc, double value); + + void setVariableNames(const QString &_expression); + + QString errorMessage; }; diff --git a/BlockImplementation.cpp b/BlockImplementation.cpp index e6b61ca..b751021 100644 --- a/BlockImplementation.cpp +++ b/BlockImplementation.cpp @@ -52,8 +52,9 @@ void BlockImplementation::loadPatterns(QDomElement& root) throw(Exception) { } QDomElement eltProd = eltCons.nextSiblingElement("production"); + productionCounter = eltProd.attribute("counter","none"); - QDomNodeList listNodeOutput = eltCons.elementsByTagName("output"); + QDomNodeList listNodeOutput = eltProd.elementsByTagName("output"); for(int i=0; i<listNodeOutput.size(); i++) { QDomNode node = listNodeOutput.at(i); QDomElement elt = node.toElement(); @@ -62,6 +63,12 @@ void BlockImplementation::loadPatterns(QDomElement& root) throw(Exception) { QString patternStr = elt.attribute("pattern","none"); productionPattern.insert(nameStr,patternStr); } + cout << "patterns summary:" << endl; + QHashIterator<QString,QString> iterP(productionPattern); + while (iterP.hasNext()) { + iterP.next(); + cout << qPrintable(iterP.key()) << " -> " << qPrintable(iterP.value()) << endl; + } cout << "impls patterns read correctly" << endl; } diff --git a/BoxItem.cpp b/BoxItem.cpp index 568e946..c473e6f 100644 --- a/BoxItem.cpp +++ b/BoxItem.cpp @@ -504,6 +504,7 @@ void BoxItem::contextMenuEvent(QGraphicsSceneContextMenuEvent * event) { QAction* showRstClkIface = NULL; QAction* showWishboneIface = NULL; QAction* showParameters = NULL; + QAction* showPatterns = NULL; InterfaceItem* ifaceItem = getInterfaceItemFromCursor(event->pos().x(), event->pos().y()); // menu for interface @@ -550,6 +551,9 @@ void BoxItem::contextMenuEvent(QGraphicsSceneContextMenuEvent * event) { } } } + if ((iface->getAssociatedIface() != NULL) && (iface->getDirection() == AbstractInterface::Output)) { + showPatterns = menu.addAction("Show patterns"); + } } // menu for blocks (group or func) else { @@ -624,13 +628,12 @@ void BoxItem::contextMenuEvent(QGraphicsSceneContextMenuEvent * event) { else if(selectedAction == showWishboneIface) { dispatcher->showWishboneIface(this); } - else if(selectedAction == showParameters) { - if (refBlock->isFunctionalBlock()) { - FunctionalBlock* fun = AB_TO_FUN(refBlock); - fun->createDelta(); - } + else if(selectedAction == showParameters) { new ParametersWindow(refBlock, params, NULL); - } + } + else if(selectedAction == showPatterns) { + dispatcher->showPatterns(ifaceItem); + } } void BoxItem::loadFunctional(QDomElement funcElement) throw(Exception) { @@ -826,7 +829,7 @@ void BoxItem::save(QXmlStreamWriter &writer) { writer.writeAttribute("id",QString::number(id)); writer.writeAttribute("inside_group",QString::number(childGroupItem->getId())); - QString attrPos = QString::number(pos().x()).append(",").append(QString::number(pos().y())); + QString attrPos = QString::number((int)(pos().x())).append(",").append(QString::number((int)(pos().y()))); writer.writeAttribute("position",attrPos); QString attrDim = QString::number(getWidth()).append(",").append(QString::number(getHeight())); writer.writeAttribute("dimension",attrDim); diff --git a/ConnectedInterface.h b/ConnectedInterface.h index cfea68c..84066a6 100644 --- a/ConnectedInterface.h +++ b/ConnectedInterface.h @@ -24,11 +24,14 @@ public : ConnectedInterface(AbstractBlock* _owner); ConnectedInterface(AbstractBlock* _owner, const QString& _name, const QString& _type, const QString& _width, int _direction, int _purpose); + // getters inline QList<ConnectedInterface*> getConnectedTo() { return connectedTo;} inline ConnectedInterface* getConnectedFrom() { return connectedFrom;} + inline QList<char> getOutputPattern() { return outputPattern; } // setters + inline void setOutputPattern(QList<char> pattern) { outputPattern = pattern; } // testers inline bool isConnectedTo(){return connectedTo.length() != 0;} @@ -66,6 +69,9 @@ protected: * this interface. connecteFrom references such an interface if it exists. */ ConnectedInterface* connectedFrom; + + // patterns + QList<char> outputPattern; //! only usefull for output interfaces }; diff --git a/Dispatcher.cpp b/Dispatcher.cpp index 9035183..4cd112d 100644 --- a/Dispatcher.cpp +++ b/Dispatcher.cpp @@ -94,26 +94,12 @@ bool Dispatcher::createConnection(InterfaceItem *iface1, InterfaceItem *iface2) // test the ref1->ref2 connection if ((ref1->canConnectTo(ref2)) && (ref2->canConnectFrom(ref1))) { - ref1->connectTo(ref2); - /* - ref2->connectFrom(ref1); - if ((asso1 != NULL) && (asso2 != NULL)) { - asso1->connectTo(asso2); - asso2->connectFrom(asso1); - } - */ + ref1->connectTo(ref2); ok1 = true; } // if the frist one did not work, test ref2->ref1 if ((ok1 == false) && (ref2->canConnectTo(ref1)) && (ref1->canConnectFrom(ref2))) { - ref2->connectTo(ref1); - /* - ref1->connectFrom(ref2); - if ((asso1 != NULL) && (asso2 != NULL)) { - asso1->connectFrom(asso2); - asso2->connectTo(asso1); - } - */ + ref2->connectTo(ref1); ok2 = true; } if ((ok1 == true) || (ok2 == true)) { @@ -122,6 +108,7 @@ bool Dispatcher::createConnection(InterfaceItem *iface1, InterfaceItem *iface2) unselectAllItems(); params->unsaveModif = true; + cout << "created a connection from " << qPrintable(ref1->getName()) << " to " << qPrintable(ref2->getName()) << endl; return true; } return false; @@ -351,6 +338,18 @@ void Dispatcher::renameInterface(InterfaceItem *item) { item->getOwner()->nameChanged(); } +void Dispatcher::showPatterns(InterfaceItem *item) { + static QString fctName = "Dispatcher::showPatterns()"; +#ifdef DEBUG_FCTNAME + cout << "call to " << qPrintable(fctName) << endl; +#endif + ConnectedInterface* iface = AI_TO_CON(item->refInter->getAssociatedIface()); + foreach(char c, iface->getOutputPattern()) { + cout << (int)c; + } + cout << endl; +} + void Dispatcher::duplicateBoxItem(BoxItem *item){ static QString fctName = "Dispatcher::duplicateBoxItem()"; #ifdef DEBUG_FCTNAME diff --git a/Dispatcher.h b/Dispatcher.h index 3181137..75583d4 100644 --- a/Dispatcher.h +++ b/Dispatcher.h @@ -112,6 +112,7 @@ public slots: void duplicateInterfaceItem(InterfaceItem* item); void showProperties(InterfaceItem *inter); void renameInterface(InterfaceItem* item); + void showPatterns(InterfaceItem* item); // connection ops bool createConnection(InterfaceItem *iface1, InterfaceItem *iface2); diff --git a/FunctionalBlock.cpp b/FunctionalBlock.cpp index 5731794..0db21c4 100644 --- a/FunctionalBlock.cpp +++ b/FunctionalBlock.cpp @@ -5,6 +5,7 @@ #include "FunctionalInterface.h" #include "ReferenceInterface.h" #include "BlockParameter.h" +#include "ArithmeticEvaluator.h" FunctionalBlock::FunctionalBlock(GroupBlock *_parent, ReferenceBlock *_reference) throw(Exception) : AbstractBlock() { @@ -114,82 +115,311 @@ QString FunctionalBlock::getReferenceHashMd5() { } bool FunctionalBlock::createPatterns() { + static QString fctName = "FunctionalBlock::createPatterns()"; +#ifdef DEBUG_FCTNAME + cout << "call to " << qPrintable(fctName) << endl; +#endif + + cout << "create patterns for block " << qPrintable(name) << endl; evaluator = new ArithmeticEvaluator(); bool ok = true; ok = ok & createDelta(); - if (ok) ok = ok & createConsumptionPattern(); - if (ok) ok = ok & createProductionCounter(); + if (! isGeneratorBlock()) { + if (ok) ok = ok & createConsumptionPattern(); + if (ok) ok = ok & createProductionCounter(); + } if (ok) ok = ok & createProductionPattern(); delete evaluator; return ok; } bool FunctionalBlock::createDelta() { - QString delta = implementation->getDelta(); - cout << "delta for " << qPrintable(name) << " = " << qPrintable(delta) << endl; + static QString fctName = "FunctionalBlock::createDelta()"; +#ifdef DEBUG_FCTNAME + cout << "call to " << qPrintable(fctName) << endl; +#endif + + QString deltaStr = implementation->getDelta(); + cout << "delta for " << qPrintable(name) << " = " << qPrintable(deltaStr) << endl; // look for parameter names - QHash<QString,double> vars; - QRegularExpression re("[$][a-zA-Z0-9_]+"); - QRegularExpressionMatchIterator matcher = re.globalMatch(delta); - while(matcher.hasNext()) { - QRegularExpressionMatch m = matcher.next(); - QString var = m.captured(0); - cout << qPrintable(var) << endl; - vars.insert(var,0.0); - } - QHashIterator<QString,double> iterV(vars); - while (iterV.hasNext()) { - iterV.next(); - QString var = iterV.key(); - QString paramName = var.remove(0,1); - BlockParameter* param = reference->getParameterFromName(paramName); - cout << "param = " << qPrintable(param->getStringValue()) << endl; - if (param == NULL) { - cerr << "found an unknown parameter in delta"<< endl; - return false; - } - bool ok; - int val = param->getIntValue(&ok); - vars.insert(var,(double)val); - } - cout << "set expr " << endl; - evaluator->setExpression(delta); - cout << "set vars " << endl; - evaluator->setVariablesValue(vars); - double result = evaluator->evaluate(); - cout << "delta = " << result << endl; + bool ok = true; + double result = evaluateExpression(deltaStr, &ok); + if (!ok) return false; + + delta = result; + cout << "delta = " << delta << endl; return true; } bool FunctionalBlock::createConsumptionPattern() { + static QString fctName = "FunctionalBlock::createConsumptionPattern()"; +#ifdef DEBUG_FCTNAME + cout << "call to " << qPrintable(fctName) << endl; +#endif + + bool ok = true; + QHash<QString,QString> consPattern = implementation->getConsumptionPattern(); + + foreach(AbstractInterface* iface, getControlInputs()) { + FunctionalInterface* connIface = AI_TO_FUN(iface); + QString refName = connIface->getReference()->getName(); + if (! consPattern.contains(refName)) { + cerr << "no consumption pattern for reference interface " << qPrintable(refName) << endl; + return false; + } + QList<char> pattern = expandPattern(consPattern.value(refName),&ok); + + if (!ok) return false; + connIface->setConsumptionPattern(pattern); + cout << qPrintable(refName) << " consumption pattern = "; + foreach(char c, pattern) { + cout << (int)c << " "; + } + cout << endl; + + } return true; } -bool FunctionalBlock::createProductionPattern() { +bool FunctionalBlock::createProductionPattern() { + static QString fctName = "FunctionalBlock::createProductionPattern()"; +#ifdef DEBUG_FCTNAME + cout << "call to " << qPrintable(fctName) << endl; +#endif + + bool ok = true; + QHash<QString,QString> prodPattern = implementation->getProductionPattern(); + + foreach(AbstractInterface* iface, getControlOutputs()) { + FunctionalInterface* connIface = AI_TO_FUN(iface); + QString refName = connIface->getReference()->getName(); + if (! prodPattern.contains(refName)) { + cerr << "no production pattern for reference interface " << qPrintable(refName) << endl; + return false; + } + QList<char> pattern = expandPattern(prodPattern.value(refName),&ok); + if (!ok) return false; + connIface->setProductionPattern(pattern); + cout << qPrintable(refName) << " production pattern = "; + foreach(char c, pattern) { + cout << (int)c << " "; + } + cout << endl; + + } return true; } bool FunctionalBlock::createProductionCounter() { + static QString fctName = "FunctionalBlock::createProductionCounter()"; +#ifdef DEBUG_FCTNAME + cout << "call to " << qPrintable(fctName) << endl; +#endif + + QStringList counterParts = implementation->getProductionCounter().split(","); + foreach(QString s, counterParts) { + cout << "cont part = " << qPrintable(s) << endl; + bool ok; + double val = s.toDouble(&ok); + if (ok) { + productionCounter.append(val); + } + else if (s.at(0) == '{') { + s.remove(0,1); + s.chop(1); + QStringList gen = s.split(":"); + if (gen.size() != 3) return false; + int start = 0; + int nb = 0; + int step = 0; + for(int i=0;i<3;i++) { + bool okVal; + double result = evaluateExpression(gen.at(i),&okVal); + if (!okVal) return false; + if (i==0) start = result; + else if (i==1) nb = result; + else if (i==2) step = result; + } + for(int j=0;j<nb;j++) { + productionCounter.append(start+j*step); + } + } + else { + bool okVal; + double result = evaluateExpression(s,&okVal); + + if (!okVal) return false; + productionCounter.append(result); + } + } + foreach(int val, productionCounter) { + cout << val << ","; + } + cout << endl; + return true; } +QList<char> FunctionalBlock::expandPattern(const QString& pattern, bool* ok) { + static QString fctName = "FunctionalBlock::expandPattern()"; +#ifdef DEBUG_FCTNAME + cout << "call to " << qPrintable(fctName) << endl; +#endif + + QList<char> lst; + QString p = pattern; + p.append(')'); + int offset = 0; + lst = expandPatternRecur(p,&offset,ok); + return lst; +} + +QList<char> FunctionalBlock::expandPatternRecur(const QString& pattern, int *offset, bool *ok) { + + QList<char> currentGroup; + + while ((*offset < pattern.size()) && (pattern.at(*offset) != ')')) { + + QChar c = pattern.at(*offset); + if (c == '(') { + *offset += 1; + currentGroup += expandPatternRecur(pattern,offset, ok); + if (!ok) { + return currentGroup; + } + } + else if (c == '0') { + currentGroup.append(0); + } + else if (c == '1') { + currentGroup.append(1); + } + else if (c == 'X') { + currentGroup.append(-1); + } + else if (c == '{') { + *offset += 1; + QString expr = ""; + while ((*offset < pattern.size()) && (pattern.at(*offset) != '}')) { + expr += pattern.at(*offset); + *offset += 1; + } + if (*offset == pattern.size()) { + *ok = false; + return currentGroup; + } + double repeat = evaluateExpression(expr,ok); + if (!ok) { + return currentGroup; + } + // repeat just the last value in currentGroup + char last = currentGroup.last(); + //cout << "repeat last char " << repeat << " times : " << (int)last << endl; + + for(int i=1;i<(int)repeat;i++) { + currentGroup += last; + } + } + *offset += 1; + } + + // must check if after ), there is a { + if ((*offset < pattern.size()-1) && (pattern.at(*offset+1) == '{')) { + *offset += 2; + QString expr = ""; + while ((*offset < pattern.size()) && (pattern.at(*offset) != '}')) { + expr += pattern.at(*offset); + *offset += 1; + } + if (*offset == pattern.size()) { + *ok = false; + return currentGroup; + } + double repeat = evaluateExpression(expr,ok); + if (!ok) { + return currentGroup; + } + /* + cout << "repeat last group " << repeat << " times : "; + foreach (char c, currentGroup) cout <<(int)c; + cout << endl; + */ + QList<char> single = currentGroup; + for(int i=1;i<(int)repeat;i++) { + currentGroup += single; + } + } + //*offset += 1; + return currentGroup; +} + +double FunctionalBlock::evaluateExpression(const QString& expression, bool* ok) { + static QString fctName = "FunctionalBlock::evaluateExpression()"; +#ifdef DEBUG_FCTNAME + cout << "call to " << qPrintable(fctName) << endl; +#endif + + *ok = true; + QHash<QString,double> vars; + evaluator->setExpression(expression); + QList<QString> varNames = evaluator->getVariableNames(); + foreach (QString name, varNames) { + QString paramName = name; + paramName.remove(0,1); + BlockParameter* param = reference->getParameterFromName(paramName); + if (param == NULL) { + cerr << "found an unknown parameter in delta"<< endl; + *ok = false; + return 0.0; + } + bool okVal; + int val = param->getDoubleValue(&okVal); + if (!okVal) { + cerr << "cannot obtain double value of paramter " << qPrintable(paramName) << endl; + *ok = false; + return 0.0; + } + vars.insert(name,(double)val); + } + evaluator->setVariablesValue(vars); + double result; + try { + result = evaluator->evaluate(); + } + catch(int index) { + cerr << "Error at index " << index << ": " << qPrintable(evaluator->getError()) << endl; + *ok = false; + return 0.0; + } + return result; +} + bool FunctionalBlock::computeOutputPattern(int nbExec) { + static QString fctName = "FunctionalBlock::computeOutputPattern()"; +#ifdef DEBUG_FCTNAME + cout << "call to " << qPrintable(fctName) << endl; +#endif /* case 1: the block is a generator for which output pattern must be computed for a nbExec following executions */ + if (nbExec > 0) { + cout << "computing output pattern of " << qPrintable(name) << " for " << nbExec << " executions" << endl; foreach(AbstractInterface* iface, getControlOutputs()) { + FunctionalInterface* connIface = AI_TO_FUN(iface); QList<char> pattern; - for(int i=0;i<nbExec;i++) pattern += iface->getProductionPattern(); - iface->setOutputPattern(pattern); + for(int i=0;i<nbExec;i++) pattern += connIface->getProductionPattern(); + connIface->setOutputPattern(pattern); } } else { - // initialize consumption and production patterns + cout << "computing output pattern of " << qPrintable(name) << endl; + + // initialize consumption and production patterns initConsumptionPattern(); initProductionPattern(); @@ -199,7 +429,8 @@ bool FunctionalBlock::computeOutputPattern(int nbExec) { inputPattern = new char*[nbConsumingPorts]; int minLen = -1; foreach(AbstractInterface* iface, getControlInputs()) { - QList<char> in = iface->getConnectedFrom()->getOutputPattern(); + ConnectedInterface* connIface = AI_TO_CON(iface); + QList<char> in = connIface->getConnectedFrom()->getOutputPattern(); if (minLen == -1) { minLen = in.size(); } @@ -224,22 +455,26 @@ bool FunctionalBlock::computeOutputPattern(int nbExec) { delete [] inputPattern; return false; } + cout << "input pattern array initialized with min. len " << minLen << endl; // initialize the output pattern char** outputPattern = NULL; outputPattern = new char*[nbProducingPorts]; int lengthOP = 0; idIface = 0; foreach(AbstractInterface* iface, getControlOutputs()) { - lengthOP = minLen+iface->getProductionPattern().size(); + FunctionalInterface* connIface = AI_TO_FUN(iface); + lengthOP = minLen+connIface->getProductionPattern().size(); outputPattern[idIface] = new char[lengthOP]; memset(outputPattern[idIface],0,lengthOP); idIface += 1; } + cout << "output pattern array initialized" << endl; int clock = 0; nbExec = 0; // search for the beginning of the first execution. - while (! isValidDataGroup(inputPattern,nbConsumingPorts,clock)) clock++; + while ((clock < minLen) && (! isValidDataGroup(inputPattern,nbConsumingPorts,clock))) clock++; + cout << "found 1st exec clock: " << clock << endl; while (clock < minLen) { // initialize counters for current execution. @@ -274,7 +509,7 @@ bool FunctionalBlock::computeOutputPattern(int nbExec) { // search for PC(m) valid input group in IP while (ncp < productionCounter.at(m)) { - if (isValidDataGroup(consumptionPattern,nbConsumingPorts,ccp)) cip += 1; + if (isValidDataGroup(consumptionPattern,nbConsumingPorts,ccp)) ncp += 1; ccp += 1; gap -= 1; } @@ -300,12 +535,15 @@ bool FunctionalBlock::computeOutputPattern(int nbExec) { // find the last valid output data group while(! isValidDataGroup(outputPattern,nbProducingPorts,lengthOP-1)) lengthOP -= 1; + //for(int i=0;i<lengthOP;i++) cout << (int)(outputPattern[0][i]); + //cout << endl; // copy back outputPattern info each interface idIface = 0; foreach(AbstractInterface* iface, getControlOutputs()) { + ConnectedInterface* connIface = AI_TO_CON(iface); QList<char> pattern; for(int i=0;i<lengthOP;i++) pattern.append(outputPattern[idIface][i]); - iface->setOutputPattern(pattern); + connIface->setOutputPattern(pattern); idIface += 1; } @@ -358,14 +596,19 @@ void FunctionalBlock::clearProductionPattern() { } void FunctionalBlock::initConsumptionPattern() { + static QString fctName = "FunctionalBlock::initConsumptionPattern()"; +#ifdef DEBUG_FCTNAME + cout << "call to " << qPrintable(fctName) << endl; +#endif + if (consumptionPattern != NULL) clearConsumptionPattern(); nbConsumingPorts = getControlInputs().size(); int idIface = 0; consumptionPattern = new char*[nbConsumingPorts]; foreach(AbstractInterface* iface, getControlInputs()) { - - QList<char> in = iface->getConsumptionPattern(); + FunctionalInterface* connIface = AI_TO_FUN(iface); + QList<char> in = connIface->getConsumptionPattern(); lengthCP = in.size(); // normally, all inputs have the same lenght for CP consumptionPattern[idIface] = new char[lengthCP]; int i = 0; @@ -375,14 +618,19 @@ void FunctionalBlock::initConsumptionPattern() { } void FunctionalBlock::initProductionPattern() { + static QString fctName = "FunctionalBlock::initProductionPattern()"; +#ifdef DEBUG_FCTNAME + cout << "call to " << qPrintable(fctName) << endl; +#endif + if (productionPattern != NULL) clearProductionPattern(); nbProducingPorts = getControlOutputs().size(); int idIface = 0; productionPattern = new char*[nbProducingPorts]; foreach(AbstractInterface* iface, getControlOutputs()) { - - QList<char> in = iface->getProductionPattern(); + FunctionalInterface* connIface = AI_TO_FUN(iface); + QList<char> in = connIface->getProductionPattern(); lengthPP = in.size(); // normally, all inputs have the same lenght for PP productionPattern[idIface] = new char[lengthPP]; int i = 0; diff --git a/FunctionalBlock.h b/FunctionalBlock.h index f898990..b6ac65f 100644 --- a/FunctionalBlock.h +++ b/FunctionalBlock.h @@ -30,9 +30,14 @@ public: // getters inline ReferenceBlock* getReference() { return reference; } - + inline QList<int> getProductionCounter() { return productionCounter; } + inline int getDelta() { return delta; } + // setters inline void setImplementation(BlockImplementation* impl) { implementation = impl; } + inline void setProductionCounter(QList<int> pattern) { productionCounter = pattern; } + inline void setDelta(int _delta) { delta = _delta; } + // testers bool isFunctionalBlock(); @@ -56,11 +61,14 @@ public: void initProductionPattern(); // initialize a char** from patterns defined for each interface void clearConsumptionPattern(); void clearProductionPattern(); + bool computeOutputPattern(int nbExec = -1); private: - // patterns - bool computeOutputPattern(int nbExec = -1); + // patterns bool isValidDataGroup(char** pattern, int nbPorts, int clock); + double evaluateExpression(const QString& expression, bool* ok); + QList<char> expandPattern(const QString& pattern, bool* ok); + QList<char> expandPatternRecur(const QString& pattern, int* offset, bool* ok); /*! * \brief combinePatterns * \param patternSrc the pattern that must be combined with patternDest (patternDest = patternDest OR patternSrc) @@ -74,6 +82,9 @@ private: */ void combinePatterns(char** patternSrc, int srcCol, char** patternDest, int destCol, int nbCols, int nbPorts ); + QList<int> productionCounter; //! only usefull for output interfaces + int delta; + char** consumptionPattern; int nbConsumingPorts; int lengthCP; diff --git a/FunctionalInterface.cpp b/FunctionalInterface.cpp index 495d60e..145b86a 100644 --- a/FunctionalInterface.cpp +++ b/FunctionalInterface.cpp @@ -101,7 +101,8 @@ bool FunctionalInterface::canConnectTo(AbstractInterface *iface) { */ if (direction == Input) return false; if (iface->isReferenceInterface()) return false; - if (iface->getConnectedFrom() != NULL) return false; + ConnectedInterface* connIface = AI_TO_CON(iface); + if (connIface->getConnectedFrom() != NULL) return false; // first case: interface of blocks within the same group if (getOwner()->getParent() == iface->getOwner()->getParent()) { diff --git a/FunctionalInterface.h b/FunctionalInterface.h index 1dfa726..b87e2c7 100644 --- a/FunctionalInterface.h +++ b/FunctionalInterface.h @@ -35,8 +35,12 @@ public : // getters inline ReferenceInterface* getReference() { return reference; } + inline QList<char> getConsumptionPattern() { return consumptionPattern; } + inline QList<char> getProductionPattern() { return productionPattern; } // setters + inline void setConsumptionPattern(QList<char> pattern) { consumptionPattern = pattern; } + inline void setProductionPattern(QList<char> pattern) { productionPattern = pattern; } // testers bool isFunctionalInterface(); @@ -53,7 +57,10 @@ public : private: ReferenceInterface* reference; - + + //patterns + QList<char> consumptionPattern; //! only usefull for input interfaces + QList<char> productionPattern; //! only usefull for output interfaces }; #endif // __FUNCTIONALINTERFACE_H__ diff --git a/Graph.cpp b/Graph.cpp index d3fd276..999e72a 100644 --- a/Graph.cpp +++ b/Graph.cpp @@ -141,3 +141,34 @@ void Graph::resetPatternComputed() { } } } + +bool Graph::computeOutputPatterns(int nbExec) { + + createPatterns(); + resetPatternComputed(); + // search for all block that are generators. + QList<FunctionalBlock*> generators; + generators.append(sources); + foreach(AbstractBlock* block, groups) { + GroupBlock* group = AB_TO_GRP(block); + foreach(AbstractBlock* inBlock, group->getBlocks()) { + FunctionalBlock* funBlock = AB_TO_FUN(inBlock); + if ((inBlock->isFunctionalBlock()) && (inBlock->isGeneratorBlock())) { + generators.append(funBlock); + } + } + } + // search for maximum delta + int maxDelta = 0; + foreach(FunctionalBlock* block, generators) { + if (block->getDelta() > maxDelta) maxDelta = block->getDelta(); + } + // compute output for generators + int maxExecLen = maxDelta*nbExec; + foreach(FunctionalBlock* block, generators) { + int d = block->getDelta(); + block->computeOutputPattern((maxExecLen+d-1)/d); + } + // compute output for top group + topGroup->computeOutputPattern(); +} diff --git a/Graph.h b/Graph.h index b2b8078..f3e9923 100644 --- a/Graph.h +++ b/Graph.h @@ -52,6 +52,7 @@ public: */ bool createPatterns(); void resetPatternComputed(); + bool computeOutputPatterns(int nbExec); private: diff --git a/GroupBlock.cpp b/GroupBlock.cpp index a8a06e6..474d5dc 100644 --- a/GroupBlock.cpp +++ b/GroupBlock.cpp @@ -107,20 +107,29 @@ void GroupBlock::removeGenericParameter(QString name) { void GroupBlock::initInputPattern() { foreach(AbstractInterface* iface, getControlInputs()) { - iface->setOutputPattern(iface->getConnectedFrom()->getOutputPattern()); + ConnectedInterface* connIface = AI_TO_CON(iface); + connIface->setOutputPattern(connIface->getConnectedFrom()->getOutputPattern()); } } bool GroupBlock::computeOutputPattern(int nbExec) { + + static QString fctName = "GroupBlock::computeOutputPattern()"; +#ifdef DEBUG_FCTNAME + cout << "call to " << qPrintable(fctName) << endl; +#endif + + cout << "computing output pattern of group " << qPrintable(name) << endl; bool canCompute = true; // get the input pattern on each inputs initInputPattern(); + cout << "Input pattern OK" << endl; // find blocks that are connected to that inputs and generators QList<AbstractBlock*> fifo; foreach(AbstractBlock* block, blocks) { - + bool addIt = false; // if a block is a generator and has control outputs, add it if (block->isGeneratorBlock()) { @@ -129,19 +138,27 @@ bool GroupBlock::computeOutputPattern(int nbExec) { else { // if the block has a control input connected from an intput of the group, add it too foreach(AbstractInterface* iface, block->getControlInputs()) { - ConnectedInterface* conn = (ConnectedInterface*)iface; - ConnectedInterface* groupIface = conn->getConnectionFromParentGroup(); - if (groupIface != NULL) { + //cout << qPrintable(iface->getName()) << " of " << qPrintable(iface->getOwner()->getName()) << " connected to " << endl; + ConnectedInterface* connFrom = ((ConnectedInterface*)iface)->getConnectedFrom(); + //cout << qPrintable(connFrom->getName()) << " of " << qPrintable(connFrom->getOwner()->getName()) << endl; + + if (connFrom->getOwner() == this) { addIt = true; break; } } } - if (addIt) fifo.append(block); + if (addIt) { + cout << "adding " << qPrintable(block->getName()) << " to initialize the FIFO" << endl; + fifo.append(block); + } } + while (!fifo.isEmpty()) { AbstractBlock* block = fifo.takeFirst(); - cout << "computing pattern for " << qPrintable(block->getName()) << endl; + + if (block->getPatternComputed()) continue; // block has laready been processed + canCompute = block->computeOutputPattern(); if (!canCompute) { cout << "cannot finalize output pattern computation of " << qPrintable(block->getName()) << endl; @@ -167,7 +184,8 @@ bool GroupBlock::computeOutputPattern(int nbExec) { if (canCompute) { foreach(AbstractInterface* iface, getControlOutputs()) { - iface->setOutputPattern(iface->getConnectedFrom()->getOutputPattern()); + ConnectedInterface* connIface = AI_TO_CON(iface); + connIface->setOutputPattern(connIface->getConnectedFrom()->getOutputPattern()); } setPatternComputed(true); } diff --git a/GroupBlock.h b/GroupBlock.h index 547159e..593b854 100644 --- a/GroupBlock.h +++ b/GroupBlock.h @@ -42,6 +42,7 @@ public: // public attributes static int counter; + bool computeOutputPattern(int nbExec = -1); private: // patterns @@ -52,7 +53,7 @@ private: * found by taking the output pattern of the connectedFrom interface. */ void initInputPattern(); - bool computeOutputPattern(int nbExec = -1); + bool topGroup; QList<AbstractBlock*> blocks; // contains instances of FunctionalBlock or GroupBlock that are children of this group diff --git a/GroupInterface.cpp b/GroupInterface.cpp index 934ad08..ecc6ba7 100644 --- a/GroupInterface.cpp +++ b/GroupInterface.cpp @@ -41,7 +41,8 @@ bool GroupInterface::canConnectTo(AbstractInterface *iface) { */ if (iface->isReferenceInterface()) return false; - if (iface->getConnectedFrom() != NULL) return false; + ConnectedInterface* connIface = AI_TO_CON(iface); + if (connIface->getConnectedFrom() != NULL) return false; if (this->getOwner() == iface->getOwner()->getParent()) { if ((direction == Input) && (iface->getDirection() == Input)) return true; diff --git a/GroupItem.cpp b/GroupItem.cpp index 38d70eb..3286c14 100644 --- a/GroupItem.cpp +++ b/GroupItem.cpp @@ -22,7 +22,7 @@ GroupItem::GroupItem(BoxItem *_parentItem, parentItem = _parentItem; if (parentItem != NULL) { - parentItem->setChildGroupItem(this); + parentItem->setChildGroupItem(this); } /* @@ -618,7 +618,7 @@ void GroupItem::load(QDomElement groupElement) throw(Exception) { if(!ok) throw(Exception(PROJECTFILE_CORRUPTED)); QString nameStr = groupElement.attribute("name","none"); - if(nameStr == "none") throw(Exception(PROJECTFILE_CORRUPTED)); + if(nameStr == "none") throw(Exception(PROJECTFILE_CORRUPTED)); QStringList positionStr = groupElement.attribute("position","none").split(","); if(positionStr.length() != 2) throw(Exception(PROJECTFILE_CORRUPTED)); @@ -651,6 +651,10 @@ void GroupItem::load(QDomElement groupElement) throw(Exception) { QString name = currentInterfaceNode.attribute("name","none"); if(name == "none") throw(Exception(PROJECTFILE_CORRUPTED)); + QString purposeStr = currentInterfaceNode.attribute("purpose","none"); + int purpose = AbstractInterface::getIntPurpose(purposeStr); + if(purpose == -1) throw(Exception(PROJECTFILE_CORRUPTED)); + QString directionStr = currentInterfaceNode.attribute("direction","none"); int direction = AbstractInterface::getIntDirection(directionStr); if(direction == -1) throw(Exception(PROJECTFILE_CORRUPTED)); @@ -661,13 +665,16 @@ void GroupItem::load(QDomElement groupElement) throw(Exception) { double position = currentInterfaceNode.attribute("position","none").toDouble(&ok); if(!ok) throw(Exception(PROJECTFILE_CORRUPTED)); - - GroupInterface *groupInterface = new GroupInterface(groupBlock,name,direction,AbstractInterface::Data); - - InterfaceItem *interfaceItem = new InterfaceItem(position,orientation,groupInterface,this,params); + + GroupInterface *groupIface = new GroupInterface(groupBlock,name,direction,purpose); + GroupInterface *groupCtlIface = new GroupInterface(groupBlock,name+"_enb",direction,AbstractInterface::Control); + groupCtlIface->setAssociatedIface(groupIface); + + InterfaceItem *interfaceItem = new InterfaceItem(position,orientation,groupIface,this,params); interfaceItem->setId(id); - groupBlock->addInterface(groupInterface); + groupBlock->addInterface(groupIface); + groupBlock->addInterface(groupCtlIface); addInterfaceItem(interfaceItem, false); cout << "interface add to " << groupBlock->getName().toStdString() << endl; } @@ -703,6 +710,7 @@ void GroupItem::save(QXmlStreamWriter &writer) { writer.writeAttribute("id",QString::number(item->getId())); writer.writeAttribute("name",item->getName()); + writer.writeAttribute("purpose",QString(item->refInter->getPurposeString())); writer.writeAttribute("direction",QString(item->refInter->getDirectionString())); writer.writeAttribute("orientation",item->getStrOrientation()); writer.writeAttribute("position",QString::number(item->getPositionRatio())); diff --git a/GroupScene.cpp b/GroupScene.cpp index 7fddacd..48de27e 100644 --- a/GroupScene.cpp +++ b/GroupScene.cpp @@ -61,6 +61,11 @@ QList<BoxItem *> GroupScene::getSelectedBlocks() { int GroupScene::setItemsId(int countInit) { int counter = countInit; groupItem->setId(counter++); + if (isTopScene()) { + foreach(SourceItem *item, sourceItems){ + item->setId(counter++); + } + } foreach(BoxItem *item, boxItems){ item->setId(counter++); } @@ -72,6 +77,13 @@ int GroupScene::setInterfacesId(int countInit) { foreach(InterfaceItem* inter, groupItem->getInterfaces()){ inter->setId(counter++); } + if (isTopScene()) { + foreach(SourceItem *item, sourceItems){ + foreach(InterfaceItem* inter, item->getInterfaces()){ + inter->setId(counter++); + } + } + } foreach(BoxItem *item, boxItems){ foreach(InterfaceItem* inter, item->getInterfaces()){ inter->setId(counter++); @@ -129,6 +141,9 @@ SourceItem *GroupScene::createSourceItem(AbstractBlock *block) { } void GroupScene::addSourceItem(SourceItem* item) { + // adding item to the scene + addItem(item); + item->setZValue(1); // add item from the QList sourceItems.append(item); } diff --git a/GroupWidget.cpp b/GroupWidget.cpp index 0705632..318e596 100644 --- a/GroupWidget.cpp +++ b/GroupWidget.cpp @@ -165,7 +165,7 @@ void GroupWidget::createToolbar() { toolbarEditMode->addWidget(butAddConnection); toolbarEditMode->addWidget(butEdit); - toolbarAdd->addAction(copyBlockAct); + //toolbarAdd->addAction(copyBlockAct); toolbarAdd->addAction(newEmptyGroupAct); toolbarAdd->addAction(newGroupAct); diff --git a/MainWindow.cpp b/MainWindow.cpp index 4be284b..877e9ac 100644 --- a/MainWindow.cpp +++ b/MainWindow.cpp @@ -373,7 +373,8 @@ void MainWindow::slotOpenBlockLibrary() { void MainWindow::slotGraphValidation() { - params->parametersValidation(); + params->getGraph()->computeOutputPatterns(5); + //params->parametersValidation(); } void MainWindow::addTopGroup(GroupWidget *_topGroup) { diff --git a/Parameters.cpp b/Parameters.cpp index 3cc8c14..322046d 100644 --- a/Parameters.cpp +++ b/Parameters.cpp @@ -9,6 +9,7 @@ #include "GroupScene.h" #include "GroupItem.h" #include "BoxItem.h" +#include "SourceItem.h" #include "InterfaceItem.h" #include "ConnectionItem.h" @@ -232,6 +233,7 @@ GroupWidget *Parameters::loadProject(QDomElement root) throw(Exception) { if (idUpperScene != -1) { groupWidget->setWindowTitle(groupBlock->getName()); groupWidget->show(); + cout << qPrintable(groupItem->getRefBlock()->getName()) << " has upper box item in " << qPrintable(groupItem->getParentItem()->getScene()->getGroupItem()->getRefBlock()->getName()) << endl; } } dispatcher->setSceneCounter(maxIdScene+1); @@ -249,7 +251,29 @@ GroupWidget *Parameters::loadProject(QDomElement root) throw(Exception) { GroupScene *currentScene = searchSceneById(idScene,topScene); if(currentScene == NULL) throw(Exception(PROJECTFILE_CORRUPTED)); - + /********************************************************** + 2.1 : getting sources if it is top scene + ***********************************************************/ + if (currentScene->isTopScene()) { + QDomNodeList sourceNodes = currentSceneNode.elementsByTagName("source_item"); + cout << "top scene has " << sourceNodes.length() << " sources" << endl; + for(int j=0; j<sourceNodes.length(); j++) { + QDomElement currentSBNode = sourceNodes.at(j).toElement(); + SourceItem* sourceItem = new SourceItem(dispatcher,this); + try { + sourceItem->load(currentSBNode); + } + catch(Exception err) { + throw(err); + } + cout << "source item has been read, add it to the scene" << endl; + // add the block to the GroupScene + currentScene->addSourceItem(sourceItem); + } + } + /********************************************************** + 2.2 : getting functional blocks + ***********************************************************/ QDomNodeList functionalBlockNodes = currentSceneNode.elementsByTagName("bi_functional"); for(int j=0; j<functionalBlockNodes.length(); j++) { @@ -306,7 +330,7 @@ GroupWidget *Parameters::loadProject(QDomElement root) throw(Exception) { // get the GroupItem already created and set at phase 1 GroupItem *insideGroup = searchGroupItemById(idGroup, topScene); BoxItem* upperItem = NULL; - if(insideGroup == NULL) cout << "group null" << endl; + if(insideGroup == NULL) cout << "group null" << endl; // now search within the scene which BoxItem has a childItem that is = to insideGroup QList<BoxItem *> lst = currentScene->getBoxItems(); foreach(BoxItem* item, lst) { @@ -1022,6 +1046,15 @@ InterfaceItem* Parameters::searchInterfaceItemById(int id, GroupScene* scene) { return item; } } + if (scene->isTopScene()) { + foreach(SourceItem *block, scene->getSourceItems()){ + foreach(InterfaceItem *item, block->getInterfaces()){ + if(item->getId() == id){ + return item; + } + } + } + } foreach(BoxItem *block, scene->getBoxItems()){ foreach(InterfaceItem *item, block->getInterfaces()){ if(item->getId() == id){ diff --git a/ParametersWindow.cpp b/ParametersWindow.cpp index 182460d..ee98880 100644 --- a/ParametersWindow.cpp +++ b/ParametersWindow.cpp @@ -60,8 +60,7 @@ void ParametersWindow::updateData() type->setText(param->getTypeString()); } -void ParametersWindow::save() -{ +void ParametersWindow::save() { BlockParameter *param = block->getParameters().at(comboBox->currentIndex()); param->setValue(value->text()); diff --git a/ReferenceInterface.h b/ReferenceInterface.h index 9ea4b23..d5219b6 100644 --- a/ReferenceInterface.h +++ b/ReferenceInterface.h @@ -22,8 +22,7 @@ public : ReferenceInterface(AbstractBlock* _owner, const QString& _name, const QString& _type, const QString& _width, int _direction, int _purpose, int _multiplicity=1) throw (Exception); // getters - inline int getMultiplicity() { return multiplicity; } - inline AbstractInterface* getConnectedFrom() { return NULL; } + inline int getMultiplicity() { return multiplicity; } // setters void setMultiplicity(int _multiplicity); diff --git a/SourceItem.cpp b/SourceItem.cpp index 27db2a3..ca252c1 100644 --- a/SourceItem.cpp +++ b/SourceItem.cpp @@ -603,10 +603,9 @@ void SourceItem::load(QDomElement funcElement) throw(Exception) { else { reference = referenceMd5; } - - GroupBlock* parentGroupBlock = AB_TO_GRP(((GroupItem *)parentItem())->getRefBlock()); - FunctionalBlock* functionalBlock = params->getGraph()->createFunctionalBlock(parentGroupBlock, reference); - /* NB: addFunctionalBlock creates all interfaces from the reference, which is annoying when + + FunctionalBlock* functionalBlock = params->getGraph()->createSourceBlock(reference); + /* NB: createSourceBlock creates all interfaces from the reference, which is annoying when reading bif_iface tags. Thus interface are all removed. */ functionalBlock->setName(name); @@ -617,7 +616,7 @@ void SourceItem::load(QDomElement funcElement) throw(Exception) { setId(id); - QDomNodeList blockParamNodes = funcElement.elementsByTagName("bif_parameter"); + QDomNodeList blockParamNodes = funcElement.elementsByTagName("source_parameter"); // setting parameters value for(int i=0; i<blockParamNodes.length(); i++){ QDomElement currentBlockParamNode = blockParamNodes.at(i).toElement(); @@ -636,7 +635,7 @@ void SourceItem::load(QDomElement funcElement) throw(Exception) { // recreate all (non-control) interfaces because of some may have a multiplicity>1 with several examplars functionalBlock->removeAllInterfaces(); - QDomNodeList interfaceNodes = funcElement.elementsByTagName("bif_iface"); + QDomNodeList interfaceNodes = funcElement.elementsByTagName("source_iface"); // setting interfaces (user name, and for multiplicity>1 may be create some new ones) for(int i=0; i<interfaceNodes.length(); i++) { diff --git a/blast.creator.user b/blast.creator.user index a4cb21c..d213478 100755 --- a/blast.creator.user +++ b/blast.creator.user @@ -1,10 +1,10 @@ <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE QtCreatorProject> -<!-- Written by QtCreator 3.2.1, 2017-05-12T16:46:10. --> +<!-- Written by QtCreator 3.2.1, 2017-05-14T21:44:23. --> <qtcreator> <data> <variable>EnvironmentId</variable> - <value type="QByteArray">{1d077e47-e3a1-47fd-8b12-4de650e39df5}</value> + <value type="QByteArray">{c8006d66-d34f-42be-ad10-d0207752286d}</value> </data> <data> <variable>ProjectExplorer.Project.ActiveTarget</variable> @@ -60,12 +60,12 @@ <valuemap type="QVariantMap"> <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Desktop</value> <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Desktop</value> - <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">{451ee8a3-56ff-4aba-8a8e-3da882cc142e}</value> + <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">{2c9bf876-3476-44eb-8065-1f0844704dda}</value> <value type="int" key="ProjectExplorer.Target.ActiveBuildConfiguration">0</value> <value type="int" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value> <value type="int" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value> <valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0"> - <value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/localhome/sdomas/Projet/Blast/code/blast</value> + <value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/sdomas/Projet/Blast/code/blast</value> <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0"> <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0"> <valuelist type="QVariantList" key="GenericProjectManager.GenericMakeStep.BuildTargets"> diff --git a/lib/implementations/average-Nx3_impl.xml b/lib/implementations/average-Nx3_impl.xml index de874d1..4c1457d 100644 --- a/lib/implementations/average-Nx3_impl.xml +++ b/lib/implementations/average-Nx3_impl.xml @@ -26,10 +26,10 @@ <patterns> <delta value="$nb_data" /> <consumption> - <input name="data_i" pattern="(1){$nb_data}" /> + <input name="data_i_enb" pattern="1{$nb_data}" /> </consumption> - <production counter="{2:$nb_data+2:1}"> - <output name="data_o" pattern="00{$nb_data}" /> + <production counter="{2:$nb_data:1}"> + <output name="data_o_enb" pattern="0001{$nb_data}" /> </production> </patterns> </block_impl> diff --git a/lib/implementations/decimator-N_impl.xml b/lib/implementations/decimator-N_impl.xml new file mode 100644 index 0000000..f68c396 --- /dev/null +++ b/lib/implementations/decimator-N_impl.xml @@ -0,0 +1,35 @@ +<?xml version="1.0" encoding="UTF-8" standalone="yes" ?> +<block_impl ref_name="decimator-N.xml" ref_md5=""> + <comments> + <author firstname="stephane" lastname="Domas" mail="sdomas@univ-fcomte.fr" /> + <date creation="2015-04-27" /> + <related_files list=""/> + <description> + This component is a decimator of N-1 values out of N + </description> + <notes> + No notes + </notes> + </comments> + + <libraries> + <library name="IEEE"> + <package name="std_logic_1164" use="all"/> + <package name="numeric_std" use="all"/> + </library> + </libraries> + + <architecture> + + </architecture> + + <patterns> + <delta value="$nb_deci+1" /> + <consumption> + <input name="data_i_enb" pattern="1{$nb_deci+1}" /> + </consumption> + <production counter="1"> + <output name="data_o_enb" pattern="010{$nb_deci}" /> + </production> + </patterns> +</block_impl> diff --git a/lib/implementations/generator-cst_impl.xml b/lib/implementations/generator-cst_impl.xml index 10b4299..0c94e16 100644 --- a/lib/implementations/generator-cst_impl.xml +++ b/lib/implementations/generator-cst_impl.xml @@ -28,7 +28,7 @@ <consumption> </consumption> <production counter=""> - <output name="data_o" pattern="1{$seq_length}X{$idle_length}" /> + <output name="data_o_enb" pattern="1{$seq_length}X{$idle_length}" /> </production> </patterns> </block_impl> diff --git a/lib/implementations/generator-img_impl.xml b/lib/implementations/generator-img_impl.xml new file mode 100644 index 0000000..d5f66f3 --- /dev/null +++ b/lib/implementations/generator-img_impl.xml @@ -0,0 +1,36 @@ +<?xml version="1.0" encoding="UTF-8" standalone="yes" ?> +<block_impl ref_name="generator-img.xml" ref_md5=""> + <comments> + <author firstname="stephane" lastname="Domas" mail="sdomas@univ-fcomte.fr" /> + <date creation="2015-05-10" /> + <related_files list=""/> + <description> + This component is a generator of a RGB image, read in a CSV file + </description> + <notes> + No notes + </notes> + </comments> + + <libraries> + <library name="IEEE"> + <package name="std_logic_1164" use="all"/> + <package name="numeric_std" use="all"/> + </library> + </libraries> + + <architecture> + + </architecture> + + <patterns> + <delta value="($img_width+$row_idle)*$img_height" /> + <consumption> + </consumption> + <production counter="1"> + <output name="r_o_enb" pattern="(1{$img_width}0{$row_idle}){$img_height}" /> + <output name="g_o_enb" pattern="(1{$img_width}0{$row_idle}){$img_height}" /> + <output name="b_o_enb" pattern="(1{$img_width}0{$row_idle}){$img_height}" /> + </production> + </patterns> +</block_impl> diff --git a/lib/implementations/impls.bmf b/lib/implementations/impls.bmf index 15dfac4..d43a935 100644 Binary files a/lib/implementations/impls.bmf and b/lib/implementations/impls.bmf differ diff --git a/lib/implementations/rgb216bits_impl.xml b/lib/implementations/rgb216bits_impl.xml new file mode 100644 index 0000000..d5203d5 --- /dev/null +++ b/lib/implementations/rgb216bits_impl.xml @@ -0,0 +1,37 @@ +<?xml version="1.0" encoding="UTF-8" standalone="yes" ?> +<block_impl ref_name="rgb216bits.xml" ref_md5=""> + <comments> + <author firstname="stephane" lastname="Domas" mail="sdomas@univ-fcomte.fr" /> + <date creation="2015-04-27" /> + <related_files list=""/> + <description> + This component converts a RGB pixel into a 16 bits pixel + </description> + <notes> + No notes + </notes> + </comments> + + <libraries> + <library name="IEEE"> + <package name="std_logic_1164" use="all"/> + <package name="numeric_std" use="all"/> + </library> + </libraries> + + <architecture> + + </architecture> + + <patterns> + <delta value="1" /> + <consumption> + <input name="r_i_enb" pattern="1" /> + <input name="g_i_enb" pattern="1" /> + <input name="b_i_enb" pattern="1" /> + </consumption> + <production counter="1"> + <output name="pix_o_enb" pattern="01" /> + </production> + </patterns> +</block_impl> diff --git a/lib/implementations/scatter_impl.xml b/lib/implementations/scatter_impl.xml new file mode 100644 index 0000000..e214f6a --- /dev/null +++ b/lib/implementations/scatter_impl.xml @@ -0,0 +1,35 @@ +<?xml version="1.0" encoding="UTF-8" standalone="yes" ?> +<block_impl ref_name="scatter.xml" ref_md5=""> + <comments> + <author firstname="stephane" lastname="Domas" mail="sdomas@univ-fcomte.fr" /> + <date creation="2015-04-27" /> + <related_files list=""/> + <description> + This component scatters an input over X outputs + </description> + <notes> + No notes + </notes> + </comments> + + <libraries> + <library name="IEEE"> + <package name="std_logic_1164" use="all"/> + <package name="numeric_std" use="all"/> + </library> + </libraries> + + <architecture> + </architecture> + + <patterns> + <delta value="1" /> + <consumption> + <input name="data_i_enb" pattern="1" /> + </consumption> + <production counter="1"> + <output name="data_o_enb" pattern="01" /> + </production> + </patterns> + +</block_impl> diff --git a/lib/references/average-Nx3.xml b/lib/references/average-Nx3.xml index 063ec2a..24e96a3 100644 --- a/lib/references/average-Nx3.xml +++ b/lib/references/average-Nx3.xml @@ -16,8 +16,8 @@ </informations> <parameters> - <parameter name="data_width" type="string" value="0" context="user"/> - <parameter name="nb_data" type="string" value="20" context="user"/> + <parameter name="data_width" type="positive" value="8" context="user"/> + <parameter name="nb_data" type="positive" value="10" context="user"/> </parameters> <interfaces> diff --git a/lib/references/decimator-N.xml b/lib/references/decimator-N.xml new file mode 100644 index 0000000..b008aa2 --- /dev/null +++ b/lib/references/decimator-N.xml @@ -0,0 +1,36 @@ +<?xml version="1.0" encoding="UTF-8" standalone="yes" ?> +<block> + <informations> + <name> + parametrized deicmator + </name> + <category ids="4" /> + <description> + <brief> + This block does a decimation of N-1 inputs overs N + </brief> + <detailed> + This block does a decimation of N-1 inputs overs N + </detailed> + </description> + </informations> + + <parameters> + <parameter name="data_width" type="positive" value="8" context="user"/> + <parameter name="nb_deci" type="positive" value="1" context="user"/> + </parameters> + + <interfaces> + <inputs> + <input name="clk" type="boolean" width="1" purpose="clock" /> + <input name="rst" type="boolean" width="1" purpose="reset" /> + <input name="data_i" type="expression" width="$data_width" /> + <control iface="data_i" /> + </inputs> + <outputs> + <output name="data_o" type="expression" width="$data_width" multiplicity="1"/> + <control iface="data_o" /> + </outputs> + </interfaces> + +</block> diff --git a/lib/references/generator-cst.xml b/lib/references/generator-cst.xml index d67b7ca..8522dd1 100644 --- a/lib/references/generator-cst.xml +++ b/lib/references/generator-cst.xml @@ -19,6 +19,7 @@ <parameter name="data_width" type="positive" value="8" context="user"/> <parameter name="seq_length" type="positive" value="10" context="user"/> <parameter name="idle_length" type="positive" value="5" context="user"/> + <parameter name="fixed_value" type="integer" value="666" context="user"/> </parameters> <interfaces> diff --git a/lib/references/generator-img.xml b/lib/references/generator-img.xml new file mode 100644 index 0000000..55a5cee --- /dev/null +++ b/lib/references/generator-img.xml @@ -0,0 +1,40 @@ +<?xml version="1.0" encoding="UTF-8" standalone="yes" ?> +<block> + <informations> + <name> + generator-img + </name> + <category ids="6" /> + <description> + <brief> + generates a RGB image, reading if from a csv file + </brief> + <detailed> + generates a RGB image, reading if from a csv file + </detailed> + </description> + </informations> + + <parameters> + <parameter name="img_file" type="string" value="nofile.csv" context="user"/> + <parameter name="img_width" type="positive" value="8" context="user"/> + <parameter name="img_height" type="positive" value="8" context="user"/> + <parameter name="row_idle" type="natural" value="2" context="user"/> + </parameters> + + <interfaces> + <inputs> + <input name="clk" width="1" purpose="clock" /> + <input name="rst" width="1" purpose="reset" /> + </inputs> + <outputs> + <output name="r_o" width="8"/> + <output name="g_o" width="8"/> + <output name="b_o" width="8"/> + <control iface="r_o"/> + <control iface="g_o"/> + <control iface="b_o"/> + </outputs> + </interfaces> + +</block> diff --git a/lib/references/references.bmf b/lib/references/references.bmf index 60ea249..8ec5506 100644 Binary files a/lib/references/references.bmf and b/lib/references/references.bmf differ diff --git a/lib/references/rgb216bits.xml b/lib/references/rgb216bits.xml new file mode 100644 index 0000000..6898880 --- /dev/null +++ b/lib/references/rgb216bits.xml @@ -0,0 +1,38 @@ +<?xml version="1.0" encoding="UTF-8" standalone="yes" ?> +<block> + <informations> + <name> + RGB to 16 bits + </name> + <category ids="4" /> + <description> + <brief> + This block does a conversion of an RGB pixel into a 16 bits value + </brief> + <detailed> + This block does a conversion of an RGB pixel into a 16 bits value + </detailed> + </description> + </informations> + + <parameters> + </parameters> + + <interfaces> + <inputs> + <input name="clk" type="boolean" width="1" purpose="clock" /> + <input name="rst" type="boolean" width="1" purpose="reset" /> + <input name="r_i" type="natural" width="8" /> + <input name="g_i" type="natural" width="8" /> + <input name="b_i" type="natural" width="8" /> + <control iface="r_i" /> + <control iface="g_i" /> + <control iface="b_i" /> + </inputs> + <outputs> + <output name="pix_o" type="natural" width="16" multiplicity="1"/> + <control iface="pix_o" /> + </outputs> + </interfaces> + +</block> diff --git a/lib/references/scatter.xml b/lib/references/scatter.xml new file mode 100644 index 0000000..ce9e2ef --- /dev/null +++ b/lib/references/scatter.xml @@ -0,0 +1,35 @@ +<?xml version="1.0" encoding="UTF-8" standalone="yes" ?> +<block> + <informations> + <name> + scatter + </name> + <category ids="1,5" /> + <description> + <brief> + This block replicates the input over X outputs, the outputs being created at will. + </brief> + <detailed> + This block replicates the input over X outputs, the outputs being created at will. + </detailed> + </description> + </informations> + + <parameters> + <parameter name="data_width" type="positive" value="16" context="user"/> + </parameters> + + <interfaces> + <inputs> + <input name="clk" type="boolean" width="1" purpose="clock" /> + <input name="rst" type="boolean" width="1" purpose="reset" /> + <input name="data_i" type="expression" width="$data_width" /> + <control iface="data_i" /> + </inputs> + <outputs> + <output name="data_o" type="expression" width="$data_width" multiplicity="*"/> + <control iface="data_o" /> + </outputs> + </interfaces> + +</block> diff --git a/projectfile.xsd b/projectfile.xsd index 8fdab46..811beb2 100644 --- a/projectfile.xsd +++ b/projectfile.xsd @@ -2,333 +2,448 @@ <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> - <!-- déclaration des groupes d'attributs --> - - <xs:attributeGroup name="group_itemAttrGroup"> - <xs:attribute ref="id"/> - <xs:attribute ref="name"/> - <xs:attribute ref="upper_group"/> - <xs:attribute ref="upper_item"/> - <xs:attribute ref="position"/> - <xs:attribute ref="dimension"/> - </xs:attributeGroup> - - <xs:attributeGroup name="group_ifaceAttrGroup"> - <xs:attribute ref="id"/> - <xs:attribute ref="name"/> - <xs:attribute ref="direction"/> - <xs:attribute ref="orientation"/> - <xs:attribute ref="position"/> - </xs:attributeGroup> - - <xs:attributeGroup name="block_itemsAttrGroup"> - <xs:attribute ref="functional_count" /> - <xs:attribute ref="group_count" /> - </xs:attributeGroup> - - <xs:attributeGroup name="bi_functionalAttrGroup"> - <xs:attribute ref="id" /> - <xs:attribute ref="ref_xml" /> - <xs:attribute ref="ref_md5" /> - <xs:attribute ref="name" /> - <xs:attribute ref="position" /> - <xs:attribute ref="dimension" /> - </xs:attributeGroup> - - <xs:attributeGroup name="bif_parameterAttrGroup"> - <xs:attribute ref="name" /> - <xs:attribute ref="value" /> - <xs:attribute ref="context" /> - <xs:attribute ref="type" /> - - </xs:attributeGroup> - - <xs:attributeGroup name="bif_ifaceAttrGroup"> - <xs:attribute ref="id" /> - <xs:attribute ref="name" /> - <xs:attribute ref="ref_name" /> - <xs:attribute ref="orientation" /> - <xs:attribute ref="position" /> - </xs:attributeGroup> - - <xs:attributeGroup name="bi_groupAttrGroup"> - <xs:attribute ref="id" /> - <xs:attribute ref="inside_group" /> - <xs:attribute ref="position" /> - <xs:attribute ref="dimension" /> - </xs:attributeGroup> - - <xs:attributeGroup name="big_ifaceAttrGroup"> - <xs:attribute ref="id" /> - <xs:attribute ref="ref_name" /> - <xs:attribute ref="orientation" /> - <xs:attribute ref="position" /> - </xs:attributeGroup> - - <xs:attributeGroup name="connectionAttrGroup"> - <xs:attribute ref="from" /> - <xs:attribute ref="to" /> - </xs:attributeGroup> - - - <!-- déclaration des attributs --> - - <xs:attribute name="count"> - <xs:simpleType> - <xs:restriction base="xs:nonNegativeInteger"> - <xs:minInclusive value="0"/> - </xs:restriction> - </xs:simpleType> - </xs:attribute> - - <xs:attribute name="id"> - <xs:simpleType> - <xs:restriction base="xs:nonNegativeInteger"> - <xs:minInclusive value="0"/> - </xs:restriction> - </xs:simpleType> - </xs:attribute> - - <xs:attribute name="upper_scene"> - <xs:simpleType> - <xs:restriction base="xs:integer"> - <xs:minInclusive value="-1"/> - </xs:restriction> - </xs:simpleType> - </xs:attribute> - - <xs:attribute name="upper_group"> - <xs:simpleType> - <xs:restriction base="xs:integer"> - <xs:minInclusive value="-1"/> - </xs:restriction> - </xs:simpleType> - </xs:attribute> - - <xs:attribute name="upper_item"> - <xs:simpleType> - <xs:restriction base="xs:integer"> - <xs:minInclusive value="-1"/> - </xs:restriction> - </xs:simpleType> - </xs:attribute> - - <xs:attribute name="inside_group"> - <xs:simpleType> - <xs:restriction base="xs:nonNegativeInteger"> - <xs:minInclusive value="0"/> - </xs:restriction> - </xs:simpleType> - </xs:attribute> - - <xs:attribute name="functional_count"> - <xs:simpleType> - <xs:restriction base="xs:nonNegativeInteger"> - <xs:minInclusive value="0"/> - </xs:restriction> - </xs:simpleType> - </xs:attribute> - - <xs:attribute name="group_count"> - <xs:simpleType> - <xs:restriction base="xs:nonNegativeInteger"> - <xs:minInclusive value="0"/> - </xs:restriction> - </xs:simpleType> - </xs:attribute> - - <xs:attribute name="value" type="xs:string"/> - - <xs:attribute name="from"> - <xs:simpleType> - <xs:restriction base="xs:nonNegativeInteger"> - <xs:minInclusive value="0"/> - </xs:restriction> - </xs:simpleType> - </xs:attribute> - - <xs:attribute name="to"> - <xs:simpleType> - <xs:restriction base="xs:nonNegativeInteger"> - <xs:minInclusive value="0"/> - </xs:restriction> - </xs:simpleType> - </xs:attribute> - - <xs:attribute name="position" type="xs:string"/> - <xs:attribute name="dimension" type="xs:string"/> - <xs:attribute name="direction" type="xs:string"/> - <xs:attribute name="orientation" type="xs:string"/> - <xs:attribute name="name" type="xs:string"/> - <xs:attribute name="ref_name" type="xs:string"/> - <xs:attribute name="ref_xml" type="xs:string"/> - <xs:attribute name="ref_md5" type="xs:string"/> - <xs:attribute name="context" type="xs:string"/> - <xs:attribute name="type" type="xs:string"/> - - - <!-- déclaration des groupes d'éléments --> - - <xs:group name="rootElmtGroup"> - <xs:sequence> - <xs:element ref="scenes"/> - <xs:element ref="connections"/> - </xs:sequence> - </xs:group> - - <xs:group name="sceneElmtGroup"> - <xs:sequence> - <xs:element ref="group_item"/> - <xs:element ref="block_items"/> - </xs:sequence> - </xs:group> - - <xs:group name="block_itemsElmtGroup"> + <!-- déclaration des groupes d'attributs --> + + <xs:attributeGroup name="group_itemAttrGroup"> + <xs:attribute ref="id"/> + <xs:attribute ref="name"/> + <xs:attribute ref="upper_group"/> + <xs:attribute ref="upper_item"/> + <xs:attribute ref="position"/> + <xs:attribute ref="dimension"/> + </xs:attributeGroup> + + <xs:attributeGroup name="group_ifaceAttrGroup"> + <xs:attribute ref="id"/> + <xs:attribute ref="name"/> + <xs:attribute ref="purpose"/> + <xs:attribute ref="direction"/> + <xs:attribute ref="orientation"/> + <xs:attribute ref="position"/> + </xs:attributeGroup> + + <xs:attributeGroup name="source_itemsAttrGroup"> + <xs:attribute ref="count" /> + </xs:attributeGroup> + + <xs:attributeGroup name="block_itemsAttrGroup"> + <xs:attribute ref="functional_count" /> + <xs:attribute ref="group_count" /> + </xs:attributeGroup> + + <xs:attributeGroup name="source_itemAttrGroup"> + <xs:attribute ref="id" /> + <xs:attribute ref="ref_xml" /> + <xs:attribute ref="ref_md5" /> + <xs:attribute ref="name" /> + <xs:attribute ref="position" /> + <xs:attribute ref="dimension" /> + </xs:attributeGroup> + + <xs:attributeGroup name="bi_functionalAttrGroup"> + <xs:attribute ref="id" /> + <xs:attribute ref="ref_xml" /> + <xs:attribute ref="ref_md5" /> + <xs:attribute ref="name" /> + <xs:attribute ref="position" /> + <xs:attribute ref="dimension" /> + </xs:attributeGroup> + + <xs:attributeGroup name="source_parameterAttrGroup"> + <xs:attribute ref="name" /> + <xs:attribute ref="value" /> + <xs:attribute ref="context" /> + <xs:attribute ref="type" /> + </xs:attributeGroup> + + <xs:attributeGroup name="bif_parameterAttrGroup"> + <xs:attribute ref="name" /> + <xs:attribute ref="value" /> + <xs:attribute ref="context" /> + <xs:attribute ref="type" /> + </xs:attributeGroup> + + <xs:attributeGroup name="source_ifaceAttrGroup"> + <xs:attribute ref="id" /> + <xs:attribute ref="name" /> + <xs:attribute ref="ref_name" /> + <xs:attribute ref="orientation" /> + <xs:attribute ref="position" /> + </xs:attributeGroup> + + <xs:attributeGroup name="bif_ifaceAttrGroup"> + <xs:attribute ref="id" /> + <xs:attribute ref="name" /> + <xs:attribute ref="ref_name" /> + <xs:attribute ref="orientation" /> + <xs:attribute ref="position" /> + </xs:attributeGroup> + + <xs:attributeGroup name="bi_groupAttrGroup"> + <xs:attribute ref="id" /> + <xs:attribute ref="inside_group" /> + <xs:attribute ref="position" /> + <xs:attribute ref="dimension" /> + </xs:attributeGroup> + + <xs:attributeGroup name="big_ifaceAttrGroup"> + <xs:attribute ref="id" /> + <xs:attribute ref="ref_name" /> + <xs:attribute ref="orientation" /> + <xs:attribute ref="position" /> + </xs:attributeGroup> + + <xs:attributeGroup name="connectionAttrGroup"> + <xs:attribute ref="from" /> + <xs:attribute ref="to" /> + </xs:attributeGroup> + + + <!-- déclaration des attributs --> + + <xs:attribute name="count"> + <xs:simpleType> + <xs:restriction base="xs:nonNegativeInteger"> + <xs:minInclusive value="0"/> + </xs:restriction> + </xs:simpleType> + </xs:attribute> + + <xs:attribute name="id"> + <xs:simpleType> + <xs:restriction base="xs:nonNegativeInteger"> + <xs:minInclusive value="0"/> + </xs:restriction> + </xs:simpleType> + </xs:attribute> + + <xs:attribute name="upper_scene"> + <xs:simpleType> + <xs:restriction base="xs:integer"> + <xs:minInclusive value="-1"/> + </xs:restriction> + </xs:simpleType> + </xs:attribute> + + <xs:attribute name="upper_group"> + <xs:simpleType> + <xs:restriction base="xs:integer"> + <xs:minInclusive value="-1"/> + </xs:restriction> + </xs:simpleType> + </xs:attribute> + + <xs:attribute name="upper_item"> + <xs:simpleType> + <xs:restriction base="xs:integer"> + <xs:minInclusive value="-1"/> + </xs:restriction> + </xs:simpleType> + </xs:attribute> + + <xs:attribute name="inside_group"> + <xs:simpleType> + <xs:restriction base="xs:nonNegativeInteger"> + <xs:minInclusive value="0"/> + </xs:restriction> + </xs:simpleType> + </xs:attribute> + + <xs:attribute name="functional_count"> + <xs:simpleType> + <xs:restriction base="xs:nonNegativeInteger"> + <xs:minInclusive value="0"/> + </xs:restriction> + </xs:simpleType> + </xs:attribute> + + <xs:attribute name="group_count"> + <xs:simpleType> + <xs:restriction base="xs:nonNegativeInteger"> + <xs:minInclusive value="0"/> + </xs:restriction> + </xs:simpleType> + </xs:attribute> + + <xs:attribute name="value" type="xs:string"/> + + <xs:attribute name="from"> + <xs:simpleType> + <xs:restriction base="xs:nonNegativeInteger"> + <xs:minInclusive value="0"/> + </xs:restriction> + </xs:simpleType> + </xs:attribute> + + <xs:attribute name="to"> + <xs:simpleType> + <xs:restriction base="xs:nonNegativeInteger"> + <xs:minInclusive value="0"/> + </xs:restriction> + </xs:simpleType> + </xs:attribute> + + <xs:attribute name="purpose"> + <xs:simpleType> + <xs:restriction base="xs:string"> + <xs:enumeration value="data"/> + <xs:enumeration value="clock"/> + <xs:enumeration value="reset"/> + <xs:enumeration value="wishbone"/> + </xs:restriction> + </xs:simpleType> + </xs:attribute> + + <xs:attribute name="direction"> + <xs:simpleType> + <xs:restriction base="xs:string"> + <xs:enumeration value="input"/> + <xs:enumeration value="output"/> + <xs:enumeration value="inout"/> + </xs:restriction> + </xs:simpleType> + </xs:attribute> + + <xs:attribute name="orientation"> + <xs:simpleType> + <xs:restriction base="xs:string"> + <xs:enumeration value="west"/> + <xs:enumeration value="east"/> + <xs:enumeration value="north"/> + <xs:enumeration value="south"/> + </xs:restriction> + </xs:simpleType> + </xs:attribute> + + <xs:attribute name="position" type="xs:string"/> + <xs:attribute name="dimension" type="xs:string"/> + <xs:attribute name="name" type="xs:string"/> + <xs:attribute name="ref_name" type="xs:string"/> + <xs:attribute name="ref_xml" type="xs:string"/> + <xs:attribute name="ref_md5" type="xs:string"/> + <xs:attribute name="context" type="xs:string"/> + <xs:attribute name="type" type="xs:string"/> + + + <!-- déclaration des groupes d'éléments --> + + <xs:group name="rootElmtGroup"> + <xs:sequence> + <xs:element ref="scenes"/> + <xs:element ref="connections"/> + </xs:sequence> + </xs:group> + + <xs:group name="sceneElmtGroup"> + <xs:sequence> + <xs:element ref="group_item"/> + <xs:element ref="source_items" minOccurs="0" maxOccurs="unbounded"/> + <xs:element ref="block_items"/> + </xs:sequence> + </xs:group> + + <xs:group name="source_itemsElmtGroup"> + <xs:sequence> + <xs:element ref="source_item" minOccurs="0" maxOccurs="unbounded"/> + </xs:sequence> + </xs:group> + + <xs:group name="block_itemsElmtGroup"> + <xs:sequence> + <xs:element ref="bi_functional" minOccurs="0" maxOccurs="unbounded"/> + <xs:element ref="bi_group" minOccurs="0" maxOccurs="unbounded"/> + </xs:sequence> + </xs:group> + + <xs:group name="source_itemElmtGroup"> + <xs:sequence> + <xs:element ref="source_parameters"/> + <xs:element ref="source_ifaces"/> + </xs:sequence> + </xs:group> + + <xs:group name="bi_functionalElmtGroup"> + <xs:sequence> + <xs:element ref="bif_parameters"/> + <xs:element ref="bif_ifaces"/> + </xs:sequence> + </xs:group> + + + <!-- déclaration des éléments --> + + <xs:element name="scenes"> + <xs:complexType> <xs:sequence> - <xs:element ref="bi_group" minOccurs="0" maxOccurs="unbounded"/> - <xs:element ref="bi_functional" minOccurs="0" maxOccurs="unbounded"/> - </xs:sequence> - </xs:group> - - <xs:group name="bi_functionalElmtGroup"> - <xs:sequence> - <xs:element ref="bif_parameters"/> - <xs:element ref="bif_ifaces"/> - </xs:sequence> - </xs:group> - - - <!-- déclaration des éléments --> - - <xs:element name="scenes"> - <xs:complexType> - <xs:sequence> - <xs:element ref="scene" maxOccurs="unbounded" /> - </xs:sequence> - <xs:attribute ref="count"/> - </xs:complexType> - </xs:element> - - <xs:element name="scene"> - <xs:complexType> - <xs:group ref="sceneElmtGroup"/> - <xs:attribute ref="id"/> - <xs:attribute ref="upper_scene"/> - </xs:complexType> - </xs:element> - - <xs:element name="group_item"> - <xs:complexType> - <xs:sequence> - <xs:element ref="group_ifaces" maxOccurs="unbounded" /> - </xs:sequence> - <xs:attributeGroup ref="group_itemAttrGroup"/> - </xs:complexType> - </xs:element> - - <xs:element name="group_ifaces"> - <xs:complexType> - <xs:sequence> - <xs:element ref="group_iface" minOccurs="0" maxOccurs="unbounded"/> - </xs:sequence> - <xs:attribute ref="count"/> - </xs:complexType> - </xs:element> - - <xs:element name="group_iface"> - <xs:complexType> - <xs:attributeGroup ref="group_ifaceAttrGroup"/> - </xs:complexType> - </xs:element> - - <xs:element name="block_items"> - <xs:complexType> - <xs:group ref="block_itemsElmtGroup"/> - <xs:attributeGroup ref="block_itemsAttrGroup"/> - </xs:complexType> - </xs:element> - - <xs:element name="bi_functional"> - <xs:complexType> - <xs:group ref="bi_functionalElmtGroup"/> - <xs:attributeGroup ref="bi_functionalAttrGroup"/> - </xs:complexType> - </xs:element> - - <xs:element name="bif_parameters"> - <xs:complexType> - <xs:sequence> - <xs:element ref="bif_parameter" minOccurs="0" maxOccurs="unbounded" /> - </xs:sequence> - </xs:complexType> - </xs:element> - - <xs:element name="bif_parameter"> - <xs:complexType> - <xs:attributeGroup ref="bif_parameterAttrGroup"/> - </xs:complexType> - </xs:element> - - <xs:element name="bif_ifaces"> - <xs:complexType> - <xs:sequence> - <xs:element ref="bif_iface" minOccurs="0" maxOccurs="unbounded" /> - </xs:sequence> - <xs:attribute ref="count"/> - </xs:complexType> - </xs:element> - - <xs:element name="bif_iface"> - <xs:complexType> - <xs:attributeGroup ref="bif_ifaceAttrGroup"/> - </xs:complexType> - </xs:element> - - <xs:element name="bi_group"> - <xs:complexType> - <xs:sequence> - <xs:element ref="big_ifaces"/> - </xs:sequence> - <xs:attributeGroup ref="bi_groupAttrGroup"/> - </xs:complexType> - </xs:element> - - <xs:element name="big_ifaces"> - <xs:complexType> - <xs:sequence> - <xs:element ref="big_iface" minOccurs="0" maxOccurs="unbounded" /> - </xs:sequence> - <xs:attribute ref="count" /> - </xs:complexType> - </xs:element> - - <xs:element name="big_iface"> - <xs:complexType> - <xs:attributeGroup ref="big_ifaceAttrGroup" /> - </xs:complexType> - </xs:element> - - <xs:element name="connections"> - <xs:complexType> - <xs:sequence> - <xs:element ref="connection" minOccurs="0" maxOccurs="unbounded"/> - </xs:sequence> - <xs:attribute ref="count" /> - </xs:complexType> - </xs:element> - - <xs:element name="connection"> - <xs:complexType> - <xs:attributeGroup ref="connectionAttrGroup"/> - </xs:complexType> - </xs:element> - - <!-- racine du document --> - - <xs:element name="blast_project"> - <xs:complexType> - <xs:group ref="rootElmtGroup"/> - </xs:complexType> - </xs:element> + <xs:element ref="scene" maxOccurs="unbounded" /> + </xs:sequence> + <xs:attribute ref="count"/> + </xs:complexType> + </xs:element> + + <xs:element name="scene"> + <xs:complexType> + <xs:group ref="sceneElmtGroup"/> + <xs:attribute ref="id"/> + <xs:attribute ref="upper_scene"/> + </xs:complexType> + </xs:element> + + <xs:element name="group_item"> + <xs:complexType> + <xs:sequence> + <xs:element ref="group_ifaces" maxOccurs="unbounded" /> + </xs:sequence> + <xs:attributeGroup ref="group_itemAttrGroup"/> + </xs:complexType> + </xs:element> + + <xs:element name="group_ifaces"> + <xs:complexType> + <xs:sequence> + <xs:element ref="group_iface" minOccurs="0" maxOccurs="unbounded"/> + </xs:sequence> + <xs:attribute ref="count"/> + </xs:complexType> + </xs:element> + + <xs:element name="group_iface"> + <xs:complexType> + <xs:attributeGroup ref="group_ifaceAttrGroup"/> + </xs:complexType> + </xs:element> + + <xs:element name="source_items"> + <xs:complexType> + <xs:group ref="source_itemsElmtGroup"/> + <xs:attributeGroup ref="source_itemsAttrGroup"/> + </xs:complexType> + </xs:element> + + <xs:element name="block_items"> + <xs:complexType> + <xs:group ref="block_itemsElmtGroup"/> + <xs:attributeGroup ref="block_itemsAttrGroup"/> + </xs:complexType> + </xs:element> + + <xs:element name="source_item"> + <xs:complexType> + <xs:group ref="source_itemElmtGroup"/> + <xs:attributeGroup ref="source_itemAttrGroup"/> + </xs:complexType> + </xs:element> + + <xs:element name="bi_functional"> + <xs:complexType> + <xs:group ref="bi_functionalElmtGroup"/> + <xs:attributeGroup ref="bi_functionalAttrGroup"/> + </xs:complexType> + </xs:element> + + <xs:element name="source_parameters"> + <xs:complexType> + <xs:sequence> + <xs:element ref="source_parameter" minOccurs="0" maxOccurs="unbounded" /> + </xs:sequence> + </xs:complexType> + </xs:element> + + <xs:element name="source_parameter"> + <xs:complexType> + <xs:attributeGroup ref="source_parameterAttrGroup"/> + </xs:complexType> + </xs:element> + + <xs:element name="bif_parameters"> + <xs:complexType> + <xs:sequence> + <xs:element ref="bif_parameter" minOccurs="0" maxOccurs="unbounded" /> + </xs:sequence> + </xs:complexType> + </xs:element> + + <xs:element name="bif_parameter"> + <xs:complexType> + <xs:attributeGroup ref="bif_parameterAttrGroup"/> + </xs:complexType> + </xs:element> + + <xs:element name="source_ifaces"> + <xs:complexType> + <xs:sequence> + <xs:element ref="source_iface" minOccurs="0" maxOccurs="unbounded" /> + </xs:sequence> + <xs:attribute ref="count"/> + </xs:complexType> + </xs:element> + + <xs:element name="source_iface"> + <xs:complexType> + <xs:attributeGroup ref="source_ifaceAttrGroup"/> + </xs:complexType> + </xs:element> + + <xs:element name="bif_ifaces"> + <xs:complexType> + <xs:sequence> + <xs:element ref="bif_iface" minOccurs="0" maxOccurs="unbounded" /> + </xs:sequence> + <xs:attribute ref="count"/> + </xs:complexType> + </xs:element> + + <xs:element name="bif_iface"> + <xs:complexType> + <xs:attributeGroup ref="bif_ifaceAttrGroup"/> + </xs:complexType> + </xs:element> + + <xs:element name="bi_group"> + <xs:complexType> + <xs:sequence> + <xs:element ref="big_ifaces"/> + </xs:sequence> + <xs:attributeGroup ref="bi_groupAttrGroup"/> + </xs:complexType> + </xs:element> + + <xs:element name="big_ifaces"> + <xs:complexType> + <xs:sequence> + <xs:element ref="big_iface" minOccurs="0" maxOccurs="unbounded" /> + </xs:sequence> + <xs:attribute ref="count" /> + </xs:complexType> + </xs:element> + + <xs:element name="big_iface"> + <xs:complexType> + <xs:attributeGroup ref="big_ifaceAttrGroup" /> + </xs:complexType> + </xs:element> + + <xs:element name="connections"> + <xs:complexType> + <xs:sequence> + <xs:element ref="connection" minOccurs="0" maxOccurs="unbounded"/> + </xs:sequence> + <xs:attribute ref="count" /> + </xs:complexType> + </xs:element> + + <xs:element name="connection"> + <xs:complexType> + <xs:attributeGroup ref="connectionAttrGroup"/> + </xs:complexType> + </xs:element> + + <!-- racine du document --> + + <xs:element name="blast_project"> + <xs:complexType> + <xs:group ref="rootElmtGroup"/> + </xs:complexType> + </xs:element> </xs:schema> diff --git a/reference.xsd b/reference.xsd index 3fa3faa..b219bfa 100644 --- a/reference.xsd +++ b/reference.xsd @@ -4,8 +4,8 @@ <!-- déclaration des groupes d'attributs --> <xs:attributeGroup name="parameterAttrGroup"> - <xs:attribute ref="name" use="required"/> - <xs:attribute ref="type" use="required"/> + <xs:attribute ref="name" use="required"/> + <xs:attribute name="type" type="typeparam" use="required"/> <xs:attribute ref="wishbone" use="optional"/> <xs:attribute ref="value" use="optional"/> <xs:attribute ref="iface" use="optional"/> @@ -16,7 +16,7 @@ <xs:attributeGroup name="inOutAttrGroup"> <xs:attribute ref="name" use="required"/> <xs:attribute ref="width" use="required"/> - <xs:attribute ref="type"/> + <xs:attribute name="type" type="typeiface"/> <xs:attribute ref="purpose"/> <xs:attribute ref="multiplicity"/> </xs:attributeGroup> @@ -26,7 +26,28 @@ <xs:attribute name="ids" type="xs:string"/> <xs:attribute name="name" type="xs:string"/> - <xs:attribute name="type" type="xs:string"/> + + <xs:simpleType name="typeparam"> + <xs:restriction base="xs:string"> + <xs:enumeration value="string"/> + <xs:enumeration value="expression"/> + <xs:enumeration value="boolean"/> + <xs:enumeration value="integer"/> + <xs:enumeration value="natural"/> + <xs:enumeration value="positive"/> + <xs:enumeration value="real"/> + <xs:enumeration value="time"/> + </xs:restriction> + </xs:simpleType> + + <xs:simpleType name="typeiface"> + <xs:restriction base="xs:string"> + <xs:enumeration value="expression"/> + <xs:enumeration value="boolean"/> + <xs:enumeration value="natural"/> + </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" />