From 7af5c69c22148510cf8f042552018c9b966860cd Mon Sep 17 00:00:00 2001 From: stephane Domas <stephane.domas@univ-fcomte.fr> Date: Thu, 18 May 2017 17:01:11 +0200 Subject: [PATCH 1/1] modified pattern to use only QMap --- ConnectedInterface.cpp | 16 +- ConnectedInterface.h | 9 +- Dispatcher.cpp | 2 +- FunctionalBlock.cpp | 355 +++++++++++------------ FunctionalBlock.h | 85 ++++-- FunctionalInterface.h | 13 +- GroupBlock.cpp | 6 +- GroupBlock.h | 7 + blast.creator.user | 8 +- lib/implementations/average-Nx3_impl.xml | 2 +- lib/implementations/impls.bmf | Bin 2886 -> 2912 bytes 11 files changed, 285 insertions(+), 218 deletions(-) diff --git a/ConnectedInterface.cpp b/ConnectedInterface.cpp index c053aad..948388a 100644 --- a/ConnectedInterface.cpp +++ b/ConnectedInterface.cpp @@ -6,15 +6,25 @@ ConnectedInterface::ConnectedInterface(AbstractBlock* _owner) : AbstractInterface(_owner) { connectedFrom = NULL; + outputPattern = NULL; + } ConnectedInterface::ConnectedInterface(AbstractBlock* _owner, const QString& _name, const QString& _type, const QString& _width, int _direction, int _purpose) : AbstractInterface(_owner, _name, _type, _width, _direction, _purpose) { connectedFrom = NULL; + outputPattern = NULL; } +ConnectedInterface::~ConnectedInterface() { + if (outputPattern != NULL) delete outputPattern; +} + +/* NB/ became useless since disconnectTo does the job + void ConnectedInterface::removeConnectedTo(ConnectedInterface *iface) { - connectedTo.removeOne(iface); + connectedTo.removeAll(iface); } +*/ void ConnectedInterface::clearConnections() { connectedFrom = NULL; @@ -25,6 +35,10 @@ void ConnectedInterface::clearConnectedTo() { connectedTo.clear(); } +void ConnectedInterface::setOutputPattern(QList<char>* pattern) { + if (outputPattern != NULL) delete outputPattern; + outputPattern = pattern; +} void ConnectedInterface::connectTo(ConnectedInterface *iface) { connectedTo.append(iface); diff --git a/ConnectedInterface.h b/ConnectedInterface.h index 84066a6..7866a8f 100644 --- a/ConnectedInterface.h +++ b/ConnectedInterface.h @@ -24,14 +24,15 @@ public : ConnectedInterface(AbstractBlock* _owner); ConnectedInterface(AbstractBlock* _owner, const QString& _name, const QString& _type, const QString& _width, int _direction, int _purpose); + ~ConnectedInterface(); // getters inline QList<ConnectedInterface*> getConnectedTo() { return connectedTo;} inline ConnectedInterface* getConnectedFrom() { return connectedFrom;} - inline QList<char> getOutputPattern() { return outputPattern; } + inline QList<char>* getOutputPattern() { return outputPattern; } // setters - inline void setOutputPattern(QList<char> pattern) { outputPattern = pattern; } + void setOutputPattern(QList<char>* pattern); // testers inline bool isConnectedTo(){return connectedTo.length() != 0;} @@ -47,7 +48,7 @@ public : ConnectedInterface* getConnectionFromParentGroup(); virtual AbstractInterface *clone() = 0; - void removeConnectedTo(ConnectedInterface *inter); + //void removeConnectedTo(ConnectedInterface *inter); virtual void clearConnectedTo(); inline void clearConnectedFrom() { connectedFrom = NULL; } @@ -71,7 +72,7 @@ protected: ConnectedInterface* connectedFrom; // patterns - QList<char> outputPattern; //! only usefull for output interfaces + QList<char>* outputPattern; //! only usefull for output interfaces }; diff --git a/Dispatcher.cpp b/Dispatcher.cpp index 4cd112d..ee72743 100644 --- a/Dispatcher.cpp +++ b/Dispatcher.cpp @@ -344,7 +344,7 @@ void Dispatcher::showPatterns(InterfaceItem *item) { cout << "call to " << qPrintable(fctName) << endl; #endif ConnectedInterface* iface = AI_TO_CON(item->refInter->getAssociatedIface()); - foreach(char c, iface->getOutputPattern()) { + foreach(char c, *(iface->getOutputPattern())) { cout << (int)c; } cout << endl; diff --git a/FunctionalBlock.cpp b/FunctionalBlock.cpp index 0db21c4..23d43b9 100644 --- a/FunctionalBlock.cpp +++ b/FunctionalBlock.cpp @@ -14,12 +14,7 @@ FunctionalBlock::FunctionalBlock(GroupBlock *_parent, ReferenceBlock *_reference reference = _reference; parent = _parent; name = reference->getName(); - consumptionPattern = NULL; - lengthCP = 0; - nbConsumingPorts = 0; - productionPattern = NULL; - lengthPP = 0; - nbProducingPorts = 0; + if (reference->getImplementations().isEmpty()) { implementation = NULL; cout << "block has no implementation" << endl; @@ -169,16 +164,10 @@ bool FunctionalBlock::createConsumptionPattern() { cerr << "no consumption pattern for reference interface " << qPrintable(refName) << endl; return false; } - QList<char> pattern = expandPattern(consPattern.value(refName),&ok); + 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; - + consumptionPattern.insert(connIface,pattern); } return true; } @@ -199,15 +188,9 @@ bool FunctionalBlock::createProductionPattern() { cerr << "no production pattern for reference interface " << qPrintable(refName) << endl; return false; } - QList<char> pattern = expandPattern(prodPattern.value(refName),&ok); + 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; - + productionPattern.insert(connIface,pattern); } return true; } @@ -262,97 +245,96 @@ bool FunctionalBlock::createProductionCounter() { return true; } -QList<char> FunctionalBlock::expandPattern(const QString& pattern, bool* ok) { +QList<char>* FunctionalBlock::expandPattern(const QString& patternIn, bool* ok) { static QString fctName = "FunctionalBlock::expandPattern()"; #ifdef DEBUG_FCTNAME cout << "call to " << qPrintable(fctName) << endl; #endif QList<char> lst; - QString p = pattern; + QString p = patternIn; p.append(')'); int offset = 0; - lst = expandPatternRecur(p,&offset,ok); - return lst; + QList<char>* patternOut = new QList<char>(); + expandPatternRecur(p,&offset,ok,patternOut); + return patternOut; } -QList<char> FunctionalBlock::expandPatternRecur(const QString& pattern, int *offset, bool *ok) { - - QList<char> currentGroup; +void FunctionalBlock::expandPatternRecur(const QString& patternIn, int *offset, bool *ok, QList<char>* patternOut) { - while ((*offset < pattern.size()) && (pattern.at(*offset) != ')')) { + while ((*offset < patternIn.size()) && (patternIn.at(*offset) != ')')) { - QChar c = pattern.at(*offset); + QChar c = patternIn.at(*offset); if (c == '(') { *offset += 1; - currentGroup += expandPatternRecur(pattern,offset, ok); + expandPatternRecur(patternIn,offset, ok, patternOut); if (!ok) { - return currentGroup; + return; } } else if (c == '0') { - currentGroup.append(0); + patternOut->append(0); } else if (c == '1') { - currentGroup.append(1); + patternOut->append(1); } else if (c == 'X') { - currentGroup.append(-1); + patternOut->append(-1); } else if (c == '{') { *offset += 1; QString expr = ""; - while ((*offset < pattern.size()) && (pattern.at(*offset) != '}')) { - expr += pattern.at(*offset); + while ((*offset < patternIn.size()) && (patternIn.at(*offset) != '}')) { + expr += patternIn.at(*offset); *offset += 1; } - if (*offset == pattern.size()) { + if (*offset == patternIn.size()) { *ok = false; - return currentGroup; + return; } double repeat = evaluateExpression(expr,ok); if (!ok) { - return currentGroup; + return; } // repeat just the last value in currentGroup - char last = currentGroup.last(); + char last = patternOut->last(); //cout << "repeat last char " << repeat << " times : " << (int)last << endl; for(int i=1;i<(int)repeat;i++) { - currentGroup += last; + patternOut->append(last); } } *offset += 1; } // must check if after ), there is a { - if ((*offset < pattern.size()-1) && (pattern.at(*offset+1) == '{')) { + if ((*offset < patternIn.size()-1) && (patternIn.at(*offset+1) == '{')) { *offset += 2; QString expr = ""; - while ((*offset < pattern.size()) && (pattern.at(*offset) != '}')) { - expr += pattern.at(*offset); + while ((*offset < patternIn.size()) && (patternIn.at(*offset) != '}')) { + expr += patternIn.at(*offset); *offset += 1; } - if (*offset == pattern.size()) { + if (*offset == patternIn.size()) { *ok = false; - return currentGroup; + return; } double repeat = evaluateExpression(expr,ok); if (!ok) { - return currentGroup; + return; } /* cout << "repeat last group " << repeat << " times : "; foreach (char c, currentGroup) cout <<(int)c; cout << endl; */ - QList<char> single = currentGroup; + QList<char> single = *patternOut; for(int i=1;i<(int)repeat;i++) { - currentGroup += single; + patternOut->append(single); } } //*offset += 1; - return currentGroup; + return; } double FunctionalBlock::evaluateExpression(const QString& expression, bool* ok) { @@ -382,7 +364,8 @@ double FunctionalBlock::evaluateExpression(const QString& expression, bool* ok) return 0.0; } vars.insert(name,(double)val); - } + } + evaluator->setVariablesValue(vars); double result; try { @@ -411,69 +394,72 @@ bool FunctionalBlock::computeOutputPattern(int nbExec) { 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 += connIface->getProductionPattern(); + // create output pattern + QList<char>* pp = productionPattern.value(connIface); + QList<char>* pattern = new QList<char>(*pp); + for(int i=1;i<nbExec;i++) pattern->append(*pp); + // assign pattern to interface connIface->setOutputPattern(pattern); - } + // store it in QMap + outputPattern.insert(connIface,pattern); + } } else { cout << "computing output pattern of " << qPrintable(name) << endl; - // initialize consumption and production patterns - initConsumptionPattern(); - initProductionPattern(); - - // collect the input patterns for each input - char** inputPattern = NULL; - int idIface = 0; - inputPattern = new char*[nbConsumingPorts]; + // collect the input patterns for each input + QMap<AbstractInterface*,QList<char>* > inputPattern; int minLen = -1; foreach(AbstractInterface* iface, getControlInputs()) { ConnectedInterface* connIface = AI_TO_CON(iface); - QList<char> in = connIface->getConnectedFrom()->getOutputPattern(); + QList<char>* out = connIface->getConnectedFrom()->getOutputPattern(); if (minLen == -1) { - minLen = in.size(); + minLen = out->size(); } else { - if (in.size() < minLen) minLen = in.size(); + if (out->size() < minLen) minLen = out->size(); } - if (in.size() > 0) { - inputPattern[idIface] = new char[in.size()]; - int i = 0; - foreach(char c, in) inputPattern[idIface][i++] = c; + if (out->size() > 0) { + QList<char>* in = new QList<char>(*out); + foreach(char c, *in) { + cout << (int)c; + } + cout << endl; + + inputPattern.insert(connIface,in); } else { - inputPattern[idIface] = NULL; - } - idIface += 1; + inputPattern.insert(connIface,NULL); + } } - // if some patterns are not available, ens now, returning false + // if some patterns are not available, end now, returning false if (minLen == 0) { - for(int i=0;i<nbConsumingPorts; i++) { - if (inputPattern[i] != NULL) delete [] inputPattern[i]; - } - delete [] inputPattern; + QMapIterator<AbstractInterface*,QList<char>* > iterI(inputPattern); + while (iterI.hasNext()) { + iterI.next(); + QList<char>* pattern = iterI.value(); + if (pattern != NULL) delete pattern; + } 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()) { - FunctionalInterface* connIface = AI_TO_FUN(iface); - lengthOP = minLen+connIface->getProductionPattern().size(); - outputPattern[idIface] = new char[lengthOP]; - memset(outputPattern[idIface],0,lengthOP); - idIface += 1; + FunctionalInterface* connIface = AI_TO_FUN(iface); + lengthOP = minLen+productionPattern.value(connIface)->size(); + QList<char>* pattern = new QList<char>(); + for(int i=0;i<lengthOP;i++) pattern->append(0); + connIface->setOutputPattern(pattern); + outputPattern.insert(connIface,pattern); } cout << "output pattern array initialized" << endl; int clock = 0; nbExec = 0; // search for the beginning of the first execution. - while ((clock < minLen) && (! isValidDataGroup(inputPattern,nbConsumingPorts,clock))) clock++; + while ((clock < minLen) && (! isValidDataGroup(inputPattern,clock))) clock++; cout << "found 1st exec clock: " << clock << endl; while (clock < minLen) { @@ -487,7 +473,7 @@ bool FunctionalBlock::computeOutputPattern(int nbExec) { bool cannotCompleteExec = false; for(int m=0;m<productionCounter.size();m++) { // search for the first production in PP - while (!isValidDataGroup(productionPattern,nbProducingPorts,p)) { + while (!isValidDataGroup(productionPattern,p)) { p += 1; o += 1; } @@ -495,7 +481,7 @@ bool FunctionalBlock::computeOutputPattern(int nbExec) { // search for PC(m) valid input group in IP while (nip < productionCounter.at(m)) { if (clock+cip < minLen) { - if (isValidDataGroup(inputPattern,nbConsumingPorts,clock+cip)) nip += 1; + if (isValidDataGroup(inputPattern,clock+cip)) nip += 1; cip += 1; gap += 1; } @@ -503,18 +489,18 @@ bool FunctionalBlock::computeOutputPattern(int nbExec) { cannotCompleteExec = true; break; } - } + } if (cannotCompleteExec) break; // no need to go further since the next search of input data group will lead to go outside inputPattern // search for PC(m) valid input group in IP while (ncp < productionCounter.at(m)) { - if (isValidDataGroup(consumptionPattern,nbConsumingPorts,ccp)) ncp += 1; + if (isValidDataGroup(consumptionPattern,ccp)) ncp += 1; ccp += 1; gap -= 1; } o += gap; // to take into acocunt of extra null columns - combinePatterns(productionPattern,p,outputPattern,clock+o,1,nbProducingPorts); + combinePatterns(productionPattern,p,outputPattern,clock+o); p += 1; o += 1; } @@ -528,113 +514,126 @@ bool FunctionalBlock::computeOutputPattern(int nbExec) { clock += 1; nip = 0; while ((clock < minLen) && (nip < delta)) { - if (isValidDataGroup(inputPattern,nbConsumingPorts,clock)) nip += 1; + if (isValidDataGroup(inputPattern,clock)) nip += 1; if (nip < delta) clock += 1; } + cout << "found exec " << nbExec << " at clock: " << clock << endl; } // 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]); - connIface->setOutputPattern(pattern); - idIface += 1; - } - - // clear inputPattern and outputPattern - for(int i=0;i<nbConsumingPorts; i++) { - delete [] inputPattern[i]; - } - delete [] inputPattern; - for(int i=0;i<nbProducingPorts; i++) { - delete [] outputPattern[i]; + while(! isValidDataGroup(outputPattern,lengthOP-1)) { + removeDataGroup(outputPattern,lengthOP-1); + lengthOP -= 1; } - delete [] outputPattern; + + // clear input pattern + QMapIterator<AbstractInterface*,QList<char>* > iterI(inputPattern); + while (iterI.hasNext()) { + iterI.next(); + QList<char>* pattern = iterI.value(); + if (pattern != NULL) delete pattern; + } } return true; } -bool FunctionalBlock::isValidDataGroup(char** pattern, int nbPorts, int clock) { - - for(int i=0;i<nbPorts;i++) { - if (pattern[i][clock] == 1) return true; +bool FunctionalBlock::canCombinePatterns(const QMap<AbstractInterface*, QList<char>* >& patternSrc, int srcCol, QMap<AbstractInterface*, QList<char>* > patternDest, int destCol) { + if (patternSrc.size() != patternDest.size()) return false; + QMapIterator<AbstractInterface*, QList<char>* > iterSrc(patternSrc); + QMapIterator<AbstractInterface*, QList<char>* > iterDest(patternDest); + while (iterSrc.hasNext()) { + iterSrc.next(); + iterDest.next(); + QList<char>* srcPat = iterSrc.value(); + QList<char>* destPat = iterDest.value(); + if (srcCol >= srcPat->size()) return false; + if (destCol >= destPat->size()) return false; + if ((srcPat->at(srcCol) == -1) && (destPat->at(destCol) == 1)) return false; + if ((srcPat->at(srcCol) == 1) && (destPat->at(destCol) == -1)) return false; } - return false; + return true; } -void FunctionalBlock::combinePatterns(char** patternSrc, int srcCol, char** patternDest, int destCol, int nbCols, int nbPorts ) { - - for (int i=0;i<nbCols;i++) { - for(int j=0;j<nbPorts;j++) { - patternDest[j][destCol+i] = patternDest[j][destCol+i] | patternSrc[j][srcCol+i]; +void FunctionalBlock::combinePatterns(const QMap<AbstractInterface*, QList<char>* >& patternSrc, int srcCol, QMap<AbstractInterface*, QList<char>* > patternDest, int destCol) { + if (patternSrc.size() != patternDest.size()) return; + QMapIterator<AbstractInterface*, QList<char>* > iterSrc(patternSrc); + QMapIterator<AbstractInterface*, QList<char>* > iterDest(patternDest); + while (iterSrc.hasNext()) { + iterSrc.next(); + iterDest.next(); + QList<char>* srcPat = iterSrc.value(); + QList<char>* destPat = iterDest.value(); + if (srcCol >= srcPat->size()) return; + if (destCol >= destPat->size()) return; + if ((srcPat->at(srcCol) == -1) && (destPat->at(destCol) == 1)) return; + if ((srcPat->at(srcCol) == 1) && (destPat->at(destCol) == -1)) return; + destPat->replace(destCol,destPat->at(destCol) | srcPat->at(srcCol)); + } +} + +void FunctionalBlock::appendToPattern(const QMap<AbstractInterface*, QList<char>* >& patternSrc, int srcCol, QMap<AbstractInterface*, QList<char>* > patternDest, int nbCols) { + if (patternSrc.size() != patternDest.size()) return; + QMapIterator<AbstractInterface*, QList<char>* > iterSrc(patternSrc); + QMapIterator<AbstractInterface*, QList<char>* > iterDest(patternDest); + while (iterSrc.hasNext()) { + iterSrc.next(); + iterDest.next(); + QList<char>* srcPat = iterSrc.value(); + QList<char>* destPat = iterDest.value(); + int i=0; + while ((srcCol+i < srcPat->size()) && (i<nbCols)) { + destPat->append(srcPat->at(srcCol+i)); + i++; } - } - + } } -void FunctionalBlock::clearConsumptionPattern() { - if (consumptionPattern == NULL) return; - - for(int i=0;i<nbConsumingPorts; i++) { - delete [] consumptionPattern[i]; +void FunctionalBlock::removeDataGroup(QMap<AbstractInterface *, QList<char> *> &pattern, int offset) { + QMapIterator<AbstractInterface*, QList<char>* > iterSrc(pattern); + while (iterSrc.hasNext()) { + iterSrc.next(); + QList<char>* srcPat = iterSrc.value(); + if (offset < srcPat->size()) { + srcPat->removeAt(offset); + } } - delete [] consumptionPattern; } -void FunctionalBlock::clearProductionPattern() { - if (productionPattern == NULL) return; - for(int i=0;i<nbProducingPorts;i++) { - delete [] productionPattern[i]; +bool FunctionalBlock::isValidDataGroup(const QMap<AbstractInterface *, QList<char> *> &pattern, int offset) { + QMapIterator<AbstractInterface*, QList<char>* > iterSrc(pattern); + while (iterSrc.hasNext()) { + iterSrc.next(); + QList<char>* srcPat = iterSrc.value(); + if (offset >= srcPat->size()) return false; + if (srcPat->at(offset) == 1) return true; } - delete [] productionPattern; + return false; } -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()) { - 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; - foreach(char c, in) consumptionPattern[idIface][i++] = c; - idIface += 1; +bool FunctionalBlock::isOnlyXDataGroup(const QMap<AbstractInterface *, QList<char> *> &pattern, int offset) { + QMapIterator<AbstractInterface*, QList<char>* > iterSrc(pattern); + while (iterSrc.hasNext()) { + iterSrc.next(); + QList<char>* srcPat = iterSrc.value(); + if (offset >= srcPat->size()) return false; + if (srcPat->at(offset) != -1) return false; } + return true; } -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()) { - 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; - foreach(char c, in) productionPattern[idIface][i++] = c; - idIface += 1; +void FunctionalBlock::clearConsumptionPattern() { + QMapIterator<AbstractInterface*, QList<char>* > iterP(consumptionPattern); + while (iterP.hasNext()) { + iterP.next(); + QList<char>* pattern = iterP.value(); + if (pattern != NULL) delete pattern; } -} +} + +void FunctionalBlock::clearProductionPattern() { + QMapIterator<AbstractInterface*, QList<char>* > iterP(productionPattern); + while (iterP.hasNext()) { + iterP.next(); + QList<char>* pattern = iterP.value(); + if (pattern != NULL) delete pattern; + } +} diff --git a/FunctionalBlock.h b/FunctionalBlock.h index b6ac65f..2cf9a5a 100644 --- a/FunctionalBlock.h +++ b/FunctionalBlock.h @@ -57,40 +57,83 @@ public: bool createConsumptionPattern(); // initialize a QList<char> for each interface from patterns defined in implementation bool createProductionPattern(); // initialize a QList<char> for each interface from patterns defined in implementation bool createProductionCounter(); // initialize a QList<int> from counter defined in implementation - void initConsumptionPattern(); // initialize a char** from patterns defined for each interface - void initProductionPattern(); // initialize a char** from patterns defined for each interface void clearConsumptionPattern(); void clearProductionPattern(); bool computeOutputPattern(int nbExec = -1); private: - // patterns - bool isValidDataGroup(char** pattern, int nbPorts, int clock); + // patterns 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); + QList<char>* expandPattern(const QString& patternIn, bool* ok); + void expandPatternRecur(const QString& patternIn, int* offset, bool* ok, QList<char> *patternOut); + /*! + * \brief canCombinePatterns + * \param patternSrc the pattern that must be combined with patternDest (patternDest = patternDest OR patternSrc) + * \param srcCol the column index within patternSrc + * \param patternDest the pattern that is modified by the combination (patternDest = patternDest OR patternSrc) + * \param destCol the column index within patternDest + * \return true if the combination is possible, and false else (e.g. when X1 must be combined with 11) + * NB: if src/destCol are outside the range of the list, false is returned. + */ + bool canCombinePatterns(const QMap<AbstractInterface*, QList<char>* >& patternSrc, int srcCol, QMap<AbstractInterface*, QList<char>* > patternDest, int destCol); /*! * \brief combinePatterns * \param patternSrc the pattern that must be combined with patternDest (patternDest = patternDest OR patternSrc) * \param srcCol the column index within patternSrc * \param patternDest the pattern that is modified by the combination (patternDest = patternDest OR patternSrc) - * \param destClock the column index within patternDest - * \param nbCols the numer of columns to combine - * \param nbPorts the number of rows in both patterns - * BEWARE: no check is done if nbCols is consistent with the real length of both patterns, thus an access outside - * the patterns is possible. + * \param destCol the column index within patternDest + * BEWARE: this method returns as soons as there is an acces problem (i.e. out of list range, impossible combine, ...) + leaving the dest pattern in an inconsistent state. Thus, it is a good idea to call canCombine before. */ - void combinePatterns(char** patternSrc, int srcCol, char** patternDest, int destCol, int nbCols, int nbPorts ); - - QList<int> productionCounter; //! only usefull for output interfaces - int delta; + void combinePatterns(const QMap<AbstractInterface*, QList<char>* >& patternSrc, int srcCol, QMap<AbstractInterface*, QList<char>* > patternDest, int destCol); + /*! + * \brief appendToPattern + * \param patternSrc the pattern that must be appended to patternDest + * \param srcCol the column index within patternSrc + * \param patternDest the pattern that is modified by the append + * \param nbCols the numer of columns to append + * BEWARE: if nbCols is not consistent with the real length of src pattern, there may be less that nbCols + * that will be appended + */ + void appendToPattern(const QMap<AbstractInterface*, QList<char>* >& patternSrc, int srcCol, QMap<AbstractInterface*, QList<char>* > patternDest, int nbCols); + /*! + * \brief removeDataGroup + * \param pattern the pattern for which a column is removed + * \param offset the index of the column to remove + */ + void removeDataGroup(QMap<AbstractInterface*, QList<char>* >& pattern, int offset); + /*! + * \brief isValidGroup + * \param pattern the pattern to test + * \param offset the column to test + * isValidGroup checks if there is at least one 1 in the column offset of pattern. + */ + bool isValidDataGroup(const QMap<AbstractInterface*, QList<char>* >& pattern, int offset); + /*! + * \brief isOnlyXGroup + * \param pattern the pattern to test + * \param offset the column to test + * isOnlyXGroup checks if there is only X in the column offset of pattern. + */ + bool isOnlyXDataGroup(const QMap<AbstractInterface*, QList<char>* >& pattern, int offset); + /*! + * \brief shifRightPattern + * \param pattern the pattern to shift + * \param offset the column where to shift + * shiftRightPattern insert a null colmun in pattern, which leads to shift right the pattern at offset. + * this method is used during admittance generation + */ + void shiftRightPattern(const QMap<AbstractInterface*, QList<char>* >& pattern, int offset); + + QMap<AbstractInterface*, QList<char>* > consumptionPattern; + QMap<AbstractInterface*, QString > admittance; // the admittance expressed as prologue-cyclic part-eppilogue + QMap<AbstractInterface*, QList<char>* > admittanceExpanded; // the admittance expanded by taking into account nb exec. + QMap<AbstractInterface*, QList<char>* > productionPattern; + QMap<AbstractInterface*, QList<char>* > outputPattern; // CAUTION: the QList<char>* must also be stored in the outputPattern attributes of AbstractInterface + QList<int> productionCounter; //! only usefull for control output interfaces - char** consumptionPattern; - int nbConsumingPorts; - int lengthCP; - char** productionPattern; - int nbProducingPorts; - int lengthPP; + int delta; + ArithmeticEvaluator* evaluator; ReferenceBlock* reference; diff --git a/FunctionalInterface.h b/FunctionalInterface.h index b87e2c7..43f31c3 100644 --- a/FunctionalInterface.h +++ b/FunctionalInterface.h @@ -35,12 +35,12 @@ public : // getters inline ReferenceInterface* getReference() { return reference; } - inline QList<char> getConsumptionPattern() { return consumptionPattern; } - inline QList<char> getProductionPattern() { return productionPattern; } + //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; } + //inline void setConsumptionPattern(QList<char>* pattern) { consumptionPattern = pattern; } + //inline void setProductionPattern(QList<char>* pattern) { productionPattern = pattern; } // testers bool isFunctionalInterface(); @@ -59,8 +59,9 @@ private: ReferenceInterface* reference; //patterns - QList<char> consumptionPattern; //! only usefull for input interfaces - QList<char> productionPattern; //! only usefull for output interfaces + //QList<char>* consumptionPattern; //! only usefull for input interfaces + //QList<char>* productionPattern; //! only usefull for output interfaces + //QString admittance; //! only usefull for input interfaces }; #endif // __FUNCTIONALINTERFACE_H__ diff --git a/GroupBlock.cpp b/GroupBlock.cpp index 474d5dc..2fc3012 100644 --- a/GroupBlock.cpp +++ b/GroupBlock.cpp @@ -108,7 +108,8 @@ void GroupBlock::removeGenericParameter(QString name) { void GroupBlock::initInputPattern() { foreach(AbstractInterface* iface, getControlInputs()) { ConnectedInterface* connIface = AI_TO_CON(iface); - connIface->setOutputPattern(connIface->getConnectedFrom()->getOutputPattern()); + QList<char>* pattern = new QList<char>(*(connIface->getConnectedFrom()->getOutputPattern())); + connIface->setOutputPattern(pattern); } } @@ -185,7 +186,8 @@ bool GroupBlock::computeOutputPattern(int nbExec) { if (canCompute) { foreach(AbstractInterface* iface, getControlOutputs()) { ConnectedInterface* connIface = AI_TO_CON(iface); - connIface->setOutputPattern(connIface->getConnectedFrom()->getOutputPattern()); + QList<char>* pattern = new QList<char>(*(connIface->getConnectedFrom()->getOutputPattern())); + connIface->setOutputPattern(pattern); } setPatternComputed(true); } diff --git a/GroupBlock.h b/GroupBlock.h index 593b854..4a147ab 100644 --- a/GroupBlock.h +++ b/GroupBlock.h @@ -46,6 +46,13 @@ public: private: // patterns + /* NB: in opposition to FunctionalBlock, the input pattern and output pattern of a block + is not computed but just deduced from the output pattern of functional interfaces that + are connected to some block interfaces. Thus, there is no need to have an outputPattern QMap linking + interfaces and patterns as in FunctionalBlock. + Thus, the output patterns are directly set/retrieved from interfaces. + + */ /*! * \brief initInputPattern * Since input GroupInterface are just tunnels to input interfaces of inner blocks, they must diff --git a/blast.creator.user b/blast.creator.user index d213478..dc3af4e 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-14T21:44:23. --> +<!-- Written by QtCreator 3.2.1, 2017-05-18T16:26:09. --> <qtcreator> <data> <variable>EnvironmentId</variable> - <value type="QByteArray">{c8006d66-d34f-42be-ad10-d0207752286d}</value> + <value type="QByteArray">{1d077e47-e3a1-47fd-8b12-4de650e39df5}</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">{2c9bf876-3476-44eb-8065-1f0844704dda}</value> + <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">{451ee8a3-56ff-4aba-8a8e-3da882cc142e}</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">/home/sdomas/Projet/Blast/code/blast</value> + <value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/localhome/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 4c1457d..981529b 100644 --- a/lib/implementations/average-Nx3_impl.xml +++ b/lib/implementations/average-Nx3_impl.xml @@ -28,7 +28,7 @@ <consumption> <input name="data_i_enb" pattern="1{$nb_data}" /> </consumption> - <production counter="{2:$nb_data:1}"> + <production counter="{2:$nb_data-1:1},$nb_data-1"> <output name="data_o_enb" pattern="0001{$nb_data}" /> </production> </patterns> diff --git a/lib/implementations/impls.bmf b/lib/implementations/impls.bmf index d43a935111c63cb5fee4e6a04d0c141242216977..f108eac57120f7b7bb773d4b8eb71ec7ea70fa2d 100644 GIT binary patch delta 86 zcmX>m_CSn<fq^?_BFlT$76t}}SrY|HC+9L=F*jqVW-wx~Vo+hoV@P6%XGmd4WGDe* VT?Rv-s3AiwgAO*i&2daGH~?@K643wv delta 60 zcmaDLc1(<gfq~m;BFlT$ECvRKSrY|HC+9L=k(FVnW-wx~Vo+hoV@P6%XGmd4WGDe* OD+WV`+RYVAFE{|s3=XaU -- 2.39.5