From 5d4e709cb8d460b2efc083e6e7999f1c3a0eb602 Mon Sep 17 00:00:00 2001 From: stephane Domas Date: Fri, 12 May 2017 16:46:45 +0200 Subject: [PATCH] started adding delta comput --- AbstractBlock.cpp | 75 +++++++++++------- AbstractBlock.h | 8 +- AbstractInterface.h | 6 +- ArithmeticEvaluator.cpp | 8 +- BlockImplementation.cpp | 90 +++++++++++++++++----- BlockImplementation.h | 14 +++- BlockParameter.cpp | 31 ++++++++ BlockParameter.h | 4 + BlockParameterUser.cpp | 4 +- BlockParameterUser.h | 2 +- BoxItem.cpp | 6 +- FunctionalBlock.cpp | 93 +++++++++++++++++++++-- FunctionalBlock.h | 13 +++- Graph.cpp | 34 +++++++++ Graph.h | 10 ++- GroupBlock.cpp | 61 ++++++++++++++- GroupBlock.h | 2 +- Parameters.cpp | 22 ++++-- ReferenceBlock.cpp | 7 +- ReferenceBlock.h | 2 +- blast.creator.user | 8 +- implementation.xsd | 2 +- lib/implementations/average-Nx3_impl.xml | 4 +- lib/implementations/impls.bmf | Bin 784 -> 1214 bytes lib/references/references.bmf | Bin 7216 -> 8102 bytes 25 files changed, 417 insertions(+), 89 deletions(-) diff --git a/AbstractBlock.cpp b/AbstractBlock.cpp index c71b2e0..66c8f37 100644 --- a/AbstractBlock.cpp +++ b/AbstractBlock.cpp @@ -51,11 +51,12 @@ bool AbstractBlock::isTopGroupBlock() { bool AbstractBlock::isSourceBlock() { return false; } - +/* NB: a generator is a block that has no data inputs + * and has at least one data output. + */ bool AbstractBlock::isGeneratorBlock() { - foreach(AbstractInterface* iface, inputs) { - if (iface->getPurpose() == AbstractInterface::Data) return false; - } + if (getDataInputs().size() > 0) return false; + return true; } @@ -126,42 +127,58 @@ void AbstractBlock::defineBlockParam(BlockParameter *param) param->setValue(value); } -QList AbstractBlock::getInterfaces() { +QList AbstractBlock::getInterfaces(int direction, int purpose) { QList list; - list.append(inputs); - list.append(outputs); - list.append(bidirs); + bool selIn = false; + bool selOut = false; + bool selInOut = false; + + if (direction == AbstractInterface::AnyDirection) { + selIn = true; + selOut = true; + selInOut = true; + } + else if (direction == AbstractInterface::Input) { + selIn = true; + } + else if (direction == AbstractInterface::Output) { + selOut = true; + } + else if (direction == AbstractInterface::InOut) { + selInOut = true; + } + if (selIn) { + foreach(AbstractInterface* iface, inputs) { + if ((iface->getPurpose() == purpose) || (purpose == AbstractInterface::AnyPurpose)) list.append(iface); + } + } + if (selOut) { + foreach(AbstractInterface* iface, outputs) { + if ((iface->getPurpose() == purpose) || (purpose == AbstractInterface::AnyPurpose)) list.append(iface); + } + } + if (selInOut) { + foreach(AbstractInterface* iface, bidirs) { + if ((iface->getPurpose() == purpose) || (purpose == AbstractInterface::AnyPurpose)) list.append(iface); + } + } return list; } QList AbstractBlock::getDataInputs() { - QList list; - foreach(AbstractInterface* iface, inputs) { - if (iface->getPurpose() == AbstractInterface::Data) { - list.append(iface); - } - } - return list; + return getInterfaces(AbstractInterface::Input, AbstractInterface::Data); +} + +QList AbstractBlock::getDataOutputs() { + return getInterfaces(AbstractInterface::Output, AbstractInterface::Data); } QList AbstractBlock::getControlInputs() { - QList list; - foreach(AbstractInterface* iface, inputs) { - if (iface->getPurpose() == AbstractInterface::Control) { - list.append(iface); - } - } - return list; + return getInterfaces(AbstractInterface::Input, AbstractInterface::Control); } QList AbstractBlock::getControlOutputs() { - QList list; - foreach(AbstractInterface* iface, outputs) { - if (iface->getPurpose() == AbstractInterface::Control) { - list.append(iface); - } - } - return list; + return getInterfaces(AbstractInterface::Output, AbstractInterface::Control); } AbstractInterface* AbstractBlock::getIfaceFromName(QString name) { diff --git a/AbstractBlock.h b/AbstractBlock.h index c8aa023..88e4cb9 100644 --- a/AbstractBlock.h +++ b/AbstractBlock.h @@ -5,6 +5,7 @@ #include +#include "AbstractInterface.h" class AbstractInterface; class BlockParameter; @@ -43,6 +44,7 @@ public: virtual void setParent(AbstractBlock* _parent); inline void setProductionCounter(QList pattern) { productionCounter = pattern; } inline void setDelta(int _delta) { delta = _delta; } + inline void setPatternComputed(bool state) { patternComputed = state; } // testers virtual bool isReferenceBlock(); @@ -62,15 +64,16 @@ public: void removeAllInterfaces(); void defineBlockParam(BlockParameter *param); - QList getInterfaces(); //! return all interfaces + QList getInterfaces(int direction = AbstractInterface::AnyDirection, int purpose = AbstractInterface::AnyPurpose); QList getDataInputs(); //! return all inputs of type data + QList getDataOutputs(); //! return all inputs of type data QList getControlInputs(); //! return all inputs of type control QList getControlOutputs(); //! return all outputs of type control AbstractInterface* getIfaceFromName(QString name); BlockParameter* getParameterFromName(QString name); // patterns - virtual void computeOutputPattern(int nbExec = -1) = 0; + virtual bool computeOutputPattern(int nbExec = -1) = 0; protected: @@ -90,6 +93,7 @@ protected: // patterns QList productionCounter; //! only usefull for output interfaces int delta; + bool patternComputed; // NB: only GroupBlock and FunctionalBlock have a real parent, except sources that have no parents AbstractBlock* parent; diff --git a/AbstractInterface.h b/AbstractInterface.h index e26f5c5..ac47ca9 100644 --- a/AbstractInterface.h +++ b/AbstractInterface.h @@ -24,9 +24,9 @@ class AbstractInterface { public : enum IfaceWidthType { Expression = 1, Boolean, Natural, Inherited}; //! Inherited is only for Group interface - enum IfacePurpose { Data = 1, Control, Clock, Reset, Wishbone }; - enum IfaceDirection { Input = 1, Output = 2, InOut = 3 }; - enum IfaceVHDLContext { Entity = 1, Component = 2, Architecture = 3 }; // NB : 3 is when creating an instance of the block that owns this iface + enum IfacePurpose { AnyPurpose = 0, Data = 1, Control, Clock, Reset, Wishbone }; + enum IfaceDirection { AnyDirection = 0, Input = 1, Output = 2, InOut = 3 }; + 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); diff --git a/ArithmeticEvaluator.cpp b/ArithmeticEvaluator.cpp index 60db08e..dd8081e 100644 --- a/ArithmeticEvaluator.cpp +++ b/ArithmeticEvaluator.cpp @@ -165,15 +165,19 @@ double ArithmeticEvaluator::evaluate() throw(int) { */ void ArithmeticEvaluator::convert(const QString& _expression) throw(int) { - QString expr = _expression; + + QString expr = _expression; + cout << "converting " << qPrintable(expr) << endl; QString result=""; expr.remove(QChar(' '), Qt::CaseInsensitive); + cout << "converting " << qPrintable(expr) << endl; foreach(QString func, fctMarkers) { + cout << "for " << qPrintable(func) << endl; QString rep = QString("\x1b%1").arg(fctMarkers.indexOf(QRegExp(func))); expr.replace(QRegExp(func),rep); } - //cout << "packed expr: " << qPrintable(expr) << endl; + cout << "packed expr: " << qPrintable(expr) << endl; int offset = 0; try { diff --git a/BlockImplementation.cpp b/BlockImplementation.cpp index af06ef3..e6b61ca 100644 --- a/BlockImplementation.cpp +++ b/BlockImplementation.cpp @@ -5,10 +5,13 @@ #include "ReferenceInterface.h" #include "FunctionalInterface.h" #include "BlockParameter.h" +#include BlockImplementation::BlockImplementation(const QString& _xmlFile) { - xmlFile = _xmlFile; + xmlFile = _xmlFile; + productionCounter = ""; + delta = ""; evaluator = new ArithmeticEvaluator; evaluator->setVariableMarkers("@$"); @@ -16,32 +19,69 @@ BlockImplementation::BlockImplementation(const QString& _xmlFile) { BlockImplementation::BlockImplementation(const QString& _xmlFile, const QString &_referenceXml, const QString &_referenceMd5) { xmlFile = _xmlFile; + productionCounter = ""; + delta = ""; referenceXml = _referenceXml; referenceMd5 = _referenceMd5; } -void BlockImplementation::assignPatterns(FunctionalBlock *_block) throw(Exception) { +void BlockImplementation::loadPatterns(QDomElement& root) throw(Exception) { + + QDomNodeList patternNode = root.elementsByTagName("patterns"); - block = _block; - - QFile implFile(xmlFile); - - // reading in into QDomDocument - QDomDocument document("implFile"); - - if (!implFile.open(QIODevice::ReadOnly)) { - throw(Exception(IMPLFILE_NOACCESS)); - } - if (!document.setContent(&implFile)) { - implFile.close(); - throw(Exception(IMPLFILE_NOACCESS)); + if (patternNode.isEmpty()) { + cout << "impl has no patterns" << endl; + return; } - implFile.close(); - QDomElement impl = document.documentElement(); - QDomNodeList patternNode = impl.elementsByTagName("patterns"); - if (patternNode.isEmpty()) return; + QDomElement patternElt = patternNode.at(0).toElement(); + QDomElement eltDelta = patternElt.firstChildElement("delta"); + delta = eltDelta.attribute("value","none"); + + QDomElement eltCons = eltDelta.nextSiblingElement("consumption"); + + QDomNodeList listNodeInput = eltCons.elementsByTagName("input"); + for(int i=0; i iterI(consumptionPattern); + while (iterI.hasNext()) { + iterI.next(); + iface = reference->getIfaceFromName(iterI.key()); + if (iface == NULL) return false; + } + QHashIterator iterO(productionPattern); + while (iterO.hasNext()) { + iterO.next(); + iface = reference->getIfaceFromName(iterO.key()); + if (iface == NULL) return false; + } + return true; } void BlockImplementation::generateVHDL(FunctionalBlock* _block, const QString &path) throw(Exception) { @@ -527,7 +567,12 @@ QDataStream& operator<<(QDataStream &out, const BlockImplementation &impl) { toWrite << impl.xmlFile; toWrite << impl.referenceXml; toWrite << impl.referenceMd5; - + // saving patterns + toWrite << impl.delta; + toWrite << impl.consumptionPattern; + toWrite << impl.productionPattern; + toWrite << impl.productionCounter; + out << blockData; return out; @@ -544,6 +589,11 @@ QDataStream& operator>>(QDataStream &in, BlockImplementation &impl) { in >> impl.xmlFile; in >> impl.referenceXml; in >> impl.referenceMd5; + // loading patterns + in >> impl.delta; + in >> impl.consumptionPattern; + in >> impl.productionPattern; + in >> impl.productionCounter; return in; } diff --git a/BlockImplementation.h b/BlockImplementation.h index 852cc63..4866e85 100644 --- a/BlockImplementation.h +++ b/BlockImplementation.h @@ -28,9 +28,16 @@ public: BlockImplementation(const QString& _xmlFile); BlockImplementation(const QString& _xmlFile, const QString& _referenceXml, const QString& _referenceMd5); + // getters inline QString getXmlFile() { return xmlFile; } inline QString getReferenceXml() { return referenceXml; } inline QString getReferenceMd5() { return referenceMd5; } + inline QString getDelta() { return delta; } + inline QHash getConsumptionPattern() { return consumptionPattern; } + inline QHash getProductionPattern() { return productionPattern; } + inline QString getProductionCounter() { return productionCounter; } + // setters + QString eval(QString line, QTextStream& out); QString evalComplex(QString line, int num); QString evalString(QString s); @@ -40,7 +47,8 @@ public: inline void setReference(ReferenceBlock* _reference) { reference = _reference; } - void assignPatterns(FunctionalBlock* _block) throw(Exception); // called during output pattern computation + void loadPatterns(QDomElement &root) throw(Exception); + bool checkPatterns(); void generateVHDL(FunctionalBlock* _block, const QString& path) throw(Exception); // main entry to generate the VHDL code @@ -53,6 +61,10 @@ private: ArithmeticEvaluator* evaluator; ReferenceBlock* reference; FunctionalBlock* block; // the current functional block for which this implementation is used. + QString delta; + QHash consumptionPattern; // key = reference interface name, value = pattern expression + QHash productionPattern; // key = reference interface name, value = pattern expression + QString productionCounter; void generateComments(QDomElement &elt,QString coreFile, QTextStream& out) throw(Exception); // generates comments from element void generateLibraries(QDomElement &elt, QTextStream& out) throw(Exception); // generates libraries from element diff --git a/BlockParameter.cpp b/BlockParameter.cpp index f8dfcd7..6207148 100644 --- a/BlockParameter.cpp +++ b/BlockParameter.cpp @@ -22,6 +22,37 @@ QVariant BlockParameter::getValue() { return defaultValue; } +bool BlockParameter::getBooleanValue(bool* ok) { + if (type == Boolean) { + *ok = true; + return getValue().toBool(); + } + *ok = false; + return false; +} + +int BlockParameter::getIntValue(bool* ok) { + if ((type == Natural) || (type == Positive) || (type == Integer)) { + *ok = true; + return getValue().toInt(); + } + *ok = false; + return 0; +} + +double BlockParameter::getDoubleValue(bool* ok) { + if ((type == Real) || (type == Natural) || (type == Positive) || (type == Integer)) { + *ok = true; + return getValue().toDouble(); + } + *ok = false; + return 0.0; +} + +QString BlockParameter::getStringValue() { + return getValue().toString(); +} + bool BlockParameter::isUserParameter() { return false; diff --git a/BlockParameter.h b/BlockParameter.h index adc8c5d..e8068d4 100644 --- a/BlockParameter.h +++ b/BlockParameter.h @@ -44,6 +44,10 @@ public : inline int getType() { return type; } QString getTypeString(); virtual QVariant getValue(); // may be overriden + int getIntValue(bool* ok); + double getDoubleValue(bool* ok); + bool getBooleanValue(bool* ok); + QString getStringValue(); virtual QString getContext() = 0; // setters diff --git a/BlockParameterUser.cpp b/BlockParameterUser.cpp index d0d870f..b6665fa 100644 --- a/BlockParameterUser.cpp +++ b/BlockParameterUser.cpp @@ -4,7 +4,7 @@ BlockParameterUser::BlockParameterUser() : BlockParameter() { userValue = defaultValue; } -BlockParameterUser::BlockParameterUser(AbstractBlock* _owner, const QString &_name, const QString &_value) : BlockParameter(_owner, _name, "string", _value) { +BlockParameterUser::BlockParameterUser(AbstractBlock* _owner, const QString &_name, const QString &_type, const QString &_value) : BlockParameter(_owner, _name, _type, _value) { userValue = defaultValue; } @@ -30,7 +30,7 @@ bool BlockParameterUser::isDefaultValue() { } BlockParameter* BlockParameterUser::clone() { - BlockParameter* block = new BlockParameterUser(owner,name,defaultValue.toString()); + BlockParameter* block = new BlockParameterUser(owner,name,getTypeString(), defaultValue.toString()); return block; } diff --git a/BlockParameterUser.h b/BlockParameterUser.h index 3da12a3..5958981 100644 --- a/BlockParameterUser.h +++ b/BlockParameterUser.h @@ -29,7 +29,7 @@ class BlockParameterUser : public BlockParameter { public : BlockParameterUser(); - BlockParameterUser(AbstractBlock* _owner, const QString& _name, const QString& _value); + BlockParameterUser(AbstractBlock* _owner, const QString& _name, const QString& _type, const QString& _value); // getters QVariant getValue(); diff --git a/BoxItem.cpp b/BoxItem.cpp index 92f89b8..568e946 100644 --- a/BoxItem.cpp +++ b/BoxItem.cpp @@ -624,7 +624,11 @@ void BoxItem::contextMenuEvent(QGraphicsSceneContextMenuEvent * event) { else if(selectedAction == showWishboneIface) { dispatcher->showWishboneIface(this); } - else if(selectedAction == showParameters){ + else if(selectedAction == showParameters) { + if (refBlock->isFunctionalBlock()) { + FunctionalBlock* fun = AB_TO_FUN(refBlock); + fun->createDelta(); + } new ParametersWindow(refBlock, params, NULL); } } diff --git a/FunctionalBlock.cpp b/FunctionalBlock.cpp index 93e8377..5731794 100644 --- a/FunctionalBlock.cpp +++ b/FunctionalBlock.cpp @@ -18,7 +18,14 @@ FunctionalBlock::FunctionalBlock(GroupBlock *_parent, ReferenceBlock *_reference nbConsumingPorts = 0; productionPattern = NULL; lengthPP = 0; - nbProducingPorts = 0; + nbProducingPorts = 0; + if (reference->getImplementations().isEmpty()) { + implementation = NULL; + cout << "block has no implementation" << endl; + } + else { + implementation = reference->getImplementations().at(0); + } } @@ -106,7 +113,69 @@ QString FunctionalBlock::getReferenceHashMd5() { return ((ReferenceBlock *)reference)->getHashMd5(); } -void FunctionalBlock::computeOutputPattern(int nbExec) { +bool FunctionalBlock::createPatterns() { + evaluator = new ArithmeticEvaluator(); + bool ok = true; + ok = ok & createDelta(); + 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; + + // look for parameter names + QHash 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 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; + + return true; +} + +bool FunctionalBlock::createConsumptionPattern() { + return true; +} + +bool FunctionalBlock::createProductionPattern() { + return true; +} + +bool FunctionalBlock::createProductionCounter() { + return true; +} + +bool FunctionalBlock::computeOutputPattern(int nbExec) { /* case 1: the block is a generator for which output pattern must be computed for a nbExec following executions @@ -137,11 +206,24 @@ void FunctionalBlock::computeOutputPattern(int nbExec) { else { if (in.size() < minLen) minLen = in.size(); } - inputPattern[idIface] = new char[in.size()]; - int i = 0; - foreach(char c, in) inputPattern[idIface][i++] = c; + if (in.size() > 0) { + inputPattern[idIface] = new char[in.size()]; + int i = 0; + foreach(char c, in) inputPattern[idIface][i++] = c; + } + else { + inputPattern[idIface] = NULL; + } idIface += 1; } + // if some patterns are not available, ens now, returning false + if (minLen == 0) { + for(int i=0;i for each interface from patterns defined in implementation + bool createProductionPattern(); // initialize a QList for each interface from patterns defined in implementation + bool createProductionCounter(); // initialize a QList 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(); @@ -50,7 +59,7 @@ public: private: // patterns - void computeOutputPattern(int nbExec = -1); + bool computeOutputPattern(int nbExec = -1); bool isValidDataGroup(char** pattern, int nbPorts, int clock); /*! * \brief combinePatterns @@ -71,8 +80,10 @@ private: char** productionPattern; int nbProducingPorts; int lengthPP; + ArithmeticEvaluator* evaluator; ReferenceBlock* reference; + BlockImplementation* implementation; }; diff --git a/Graph.cpp b/Graph.cpp index a4dd676..d3fd276 100644 --- a/Graph.cpp +++ b/Graph.cpp @@ -107,3 +107,37 @@ bool Graph::removeSourceBlock(FunctionalBlock *block) { sources.removeAll(block); return true; } + +bool Graph::createPatterns() { + bool ok = true; + foreach(AbstractBlock* block, sources) { + FunctionalBlock* funBlock = AB_TO_FUN(block); + ok = funBlock->createPatterns(); + if (!ok) return false; + } + + foreach(AbstractBlock* block, groups) { + GroupBlock* group = AB_TO_GRP(block); + foreach(AbstractBlock* inBlock, group->getBlocks()) { + if (inBlock->isFunctionalBlock()) { + FunctionalBlock* funBlock = AB_TO_FUN(inBlock); + ok = funBlock->createPatterns(); + if (!ok) return false; + } + } + } + return true; +} + +void Graph::resetPatternComputed() { + foreach(AbstractBlock* block, sources) { + block->setPatternComputed(false); + } + foreach(AbstractBlock* block, groups) { + GroupBlock* group = AB_TO_GRP(block); + group->setPatternComputed(false); + foreach(AbstractBlock* inBlock, group->getBlocks()) { + inBlock->setPatternComputed(false); + } + } +} diff --git a/Graph.h b/Graph.h index 7be35c2..b2b8078 100644 --- a/Graph.h +++ b/Graph.h @@ -43,7 +43,15 @@ public: bool removeSourceBlock(FunctionalBlock* block); // others - QList getOutsideInterfaces(); + QList getOutsideInterfaces(); + /*! + * \brief initPatterns + * initPatterns() crosses the graph and for each functional block, it computes + * the consumptionPattern, the productionPattern, the production counter and delta + * using the parameters fo the block. + */ + bool createPatterns(); + void resetPatternComputed(); private: diff --git a/GroupBlock.cpp b/GroupBlock.cpp index 716cea6..a8a06e6 100644 --- a/GroupBlock.cpp +++ b/GroupBlock.cpp @@ -1,6 +1,7 @@ #include "GroupBlock.h" #include "BlockParameterGeneric.h" #include "AbstractInterface.h" +#include "ConnectedInterface.h" #include "string.h" #include @@ -110,13 +111,65 @@ void GroupBlock::initInputPattern() { } } -void GroupBlock::computeOutputPattern(int nbExec) { +bool GroupBlock::computeOutputPattern(int nbExec) { + bool canCompute = true; // get the input pattern on each inputs initInputPattern(); - // find blocks that are connected to that inputs - foreach(AbstractInterface* iface, getControlOutputs()) { - iface->setOutputPattern(iface->getConnectedFrom()->getOutputPattern()); + // find blocks that are connected to that inputs and generators + QList fifo; + foreach(AbstractBlock* block, blocks) { + + bool addIt = false; + // if a block is a generator and has control outputs, add it + if (block->isGeneratorBlock()) { + if (block->getControlOutputs().size() > 0) addIt = true; + } + 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) { + addIt = true; + break; + } + } + } + if (addIt) fifo.append(block); + } + while (!fifo.isEmpty()) { + AbstractBlock* block = fifo.takeFirst(); + cout << "computing pattern for " << qPrintable(block->getName()) << endl; + canCompute = block->computeOutputPattern(); + if (!canCompute) { + cout << "cannot finalize output pattern computation of " << qPrintable(block->getName()) << endl; + break; + } + block->setPatternComputed(true); + // add other blocks connected from block to the fifo + foreach(AbstractInterface* iface, block->getControlOutputs()) { + ConnectedInterface* conn = (ConnectedInterface*)iface; + foreach(ConnectedInterface* connTo, conn->getConnectedTo()) { + /* if connTo is owned by a functional block + or by a group block that is within this, add the block to the fifo. + */ + if (connTo->getOwner()->isFunctionalBlock()) { + fifo.append(connTo->getOwner()); + } + else if (connTo->getOwner() != this) { + fifo.append(connTo->getOwner()); + } + } + } + } + + if (canCompute) { + foreach(AbstractInterface* iface, getControlOutputs()) { + iface->setOutputPattern(iface->getConnectedFrom()->getOutputPattern()); + } + setPatternComputed(true); } + return canCompute; } diff --git a/GroupBlock.h b/GroupBlock.h index 0aeb006..547159e 100644 --- a/GroupBlock.h +++ b/GroupBlock.h @@ -52,7 +52,7 @@ private: * found by taking the output pattern of the connectedFrom interface. */ void initInputPattern(); - void computeOutputPattern(int nbExec = -1); + bool computeOutputPattern(int nbExec = -1); bool topGroup; QList blocks; // contains instances of FunctionalBlock or GroupBlock that are children of this group diff --git a/Parameters.cpp b/Parameters.cpp index c12fead..3cc8c14 100644 --- a/Parameters.cpp +++ b/Parameters.cpp @@ -683,6 +683,12 @@ void Parameters::loadImplementationsFromXml() throw(Exception) { QString refXml = implRoot.attribute("ref_name","none"); QString refMd5 = implRoot.attribute("ref_md5","none"); BlockImplementation* impl = new BlockImplementation(fileName,refXml,refMd5); + try { + impl->loadPatterns(implRoot); + } + catch(int err) { + throw(err); + } availableImplementations.append(impl); ReferenceBlock* ref = NULL; @@ -694,9 +700,12 @@ void Parameters::loadImplementationsFromXml() throw(Exception) { } if (ref == NULL) { cout << "Cannot find a reference block for impl :" << qPrintable(fileName) << endl; - } - ref->addImplementation(impl); - impl->setReference(ref); + } + else { + ref->addImplementation(impl); + impl->setReference(ref); + if (! impl->checkPatterns()) throw(Exception(IMPLFILE_CORRUPTED)); + } cout << "OK" << endl; } } @@ -741,8 +750,11 @@ void Parameters::loadImplementationsFromLib() throw(Exception) { if (ref == NULL) { cout << "Cannot find a reference block for impl :" << qPrintable(impl->getXmlFile()) << endl; } - ref->addImplementation(impl); - impl->setReference(ref); + else { + ref->addImplementation(impl); + impl->setReference(ref); + if (! impl->checkPatterns()) throw(Exception(IMPLFILE_CORRUPTED)); + } } libFile.close(); } diff --git a/ReferenceBlock.cpp b/ReferenceBlock.cpp index ae7f0ce..12db4b4 100644 --- a/ReferenceBlock.cpp +++ b/ReferenceBlock.cpp @@ -157,7 +157,7 @@ void ReferenceBlock::loadParameters(QDomElement &elt) throw(Exception) { valueStr = ""; } if (contextStr == "user") { - param = new BlockParameterUser(this,nameStr,valueStr); + param = new BlockParameterUser(this,nameStr,typeStr,valueStr); } else if (contextStr == "generic") { param = new BlockParameterGeneric(this,nameStr,typeStr,valueStr); @@ -471,7 +471,7 @@ QDataStream& operator>>(QDataStream &in, ReferenceBlock &b) { in >> valueStr; if (contextStr == "user") { - p = new BlockParameterUser(&b,nameStr,valueStr); + p = new BlockParameterUser(&b,nameStr,typeStr,valueStr); } else if (contextStr == "generic") { p = new BlockParameterGeneric(&b,nameStr,typeStr,valueStr); @@ -567,6 +567,7 @@ QDataStream& operator>>(QDataStream &in, ReferenceBlock &b) { return in; } -void ReferenceBlock::computeOutputPattern(int nbExec) { +bool ReferenceBlock::computeOutputPattern(int nbExec) { // does strictly nothing + return false; } diff --git a/ReferenceBlock.h b/ReferenceBlock.h index 2e34984..b10c142 100644 --- a/ReferenceBlock.h +++ b/ReferenceBlock.h @@ -68,7 +68,7 @@ public: private: // patterns - void computeOutputPattern(int nbExec = -1); + bool computeOutputPattern(int nbExec = -1); }; #endif // __REFERENCEBLOCK_H__ diff --git a/blast.creator.user b/blast.creator.user index b9d826a..a4cb21c 100755 --- a/blast.creator.user +++ b/blast.creator.user @@ -1,10 +1,10 @@ - + EnvironmentId - {c8006d66-d34f-42be-ad10-d0207752286d} + {1d077e47-e3a1-47fd-8b12-4de650e39df5} ProjectExplorer.Project.ActiveTarget @@ -60,12 +60,12 @@ Desktop Desktop - {2c9bf876-3476-44eb-8065-1f0844704dda} + {451ee8a3-56ff-4aba-8a8e-3da882cc142e} 0 0 0 - /home/sdomas/Projet/Blast/code/blast + /localhome/sdomas/Projet/Blast/code/blast diff --git a/implementation.xsd b/implementation.xsd index 0dff1f6..c838514 100644 --- a/implementation.xsd +++ b/implementation.xsd @@ -135,6 +135,7 @@ + @@ -142,7 +143,6 @@ - diff --git a/lib/implementations/average-Nx3_impl.xml b/lib/implementations/average-Nx3_impl.xml index 1ea7a7f..de874d1 100644 --- a/lib/implementations/average-Nx3_impl.xml +++ b/lib/implementations/average-Nx3_impl.xml @@ -28,8 +28,8 @@ - - + + diff --git a/lib/implementations/impls.bmf b/lib/implementations/impls.bmf index 7fd7598fad1ca6067e30c3313a113855cddb779d..15dfac4ea57ccf0c25326ec2f4d067d82a1d427a 100644 GIT binary patch literal 1214 zcmc(eJx;?w5QU#5=u#jG3JQb}LZHZmm;#BC10ZgI?AU;jW56*#65>GPmPZzqkEo(^umJ9WHMz zyx+{a{F!^r&R0x+V80t*KO1&8{Cu~+J*G9H?hU$_Z>uD;W~aNvb5t=g7ip-0`-Q!< Ypof`NVYfBql|Btt?7U|jw{NG5G3QFlj{pDw delta 59 zcmdnTIf0Fbfq@x_8CZb$%0!;)tVe*1SrY|HC+9Nyv91Af`X&k#PhQAm!MX*=nFQh# Hve*IukQNT| diff --git a/lib/references/references.bmf b/lib/references/references.bmf index 7eefb86f5b9c126156af3b149b5029ce13bb34fd..60ea24991a6600f046e574563d7088b2a29e4a9e 100644 GIT binary patch delta 601 zcmb`EF-yZx6opS)m57TJn}P^-5S)~1tVSI4R|vXjO_LglX>Fpmi`^Vt^9RJiS#j}a z`4jwJpbnufBH`Y5-hJntdvf2K`+8_et1pt~->tsARv7@7)s?T97^tmOJ=P6*O2E=n z_Eio2-x-@4>RJ)Z$AXTJLPN)dhi1&q2i>9?>JDs9CnqVLIJ5&$pDL8=d9jh67t -- 2.39.5