X-Git-Url: https://bilbo.iut-bm.univ-fcomte.fr/and/gitweb/blast.git/blobdiff_plain/624231601a0f5daea9b8809993ad3503beafce4f..5d4e709cb8d460b2efc083e6e7999f1c3a0eb602:/FunctionalBlock.cpp diff --git a/FunctionalBlock.cpp b/FunctionalBlock.cpp index 51bebe8..5731794 100644 --- a/FunctionalBlock.cpp +++ b/FunctionalBlock.cpp @@ -13,6 +13,19 @@ 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; + } + else { + implementation = reference->getImplementations().at(0); + } } @@ -96,7 +109,284 @@ QString FunctionalBlock::getReferenceXmlFile() { return ((ReferenceBlock *)reference)->getXmlFile(); } -QString FunctionalBlock::getReferenceHashMd5() -{ +QString FunctionalBlock::getReferenceHashMd5() { return ((ReferenceBlock *)reference)->getHashMd5(); } + +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 + */ + + if (nbExec > 0) { + foreach(AbstractInterface* iface, getControlOutputs()) { + QList pattern; + for(int i=0;igetProductionPattern(); + iface->setOutputPattern(pattern); + } + } + else { + // initialize consumption and production patterns + initConsumptionPattern(); + initProductionPattern(); + + // collect the input patterns for each input + char** inputPattern = NULL; + int idIface = 0; + inputPattern = new char*[nbConsumingPorts]; + int minLen = -1; + foreach(AbstractInterface* iface, getControlInputs()) { + QList in = iface->getConnectedFrom()->getOutputPattern(); + if (minLen == -1) { + minLen = in.size(); + } + else { + if (in.size() < minLen) minLen = in.size(); + } + 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;igetProductionPattern().size(); + outputPattern[idIface] = new char[lengthOP]; + memset(outputPattern[idIface],0,lengthOP); + idIface += 1; + } + + int clock = 0; + nbExec = 0; + // search for the beginning of the first execution. + while (! isValidDataGroup(inputPattern,nbConsumingPorts,clock)) clock++; + + while (clock < minLen) { + // initialize counters for current execution. + int p = 0; // index in production pattern + int o = 0; // clock+o will give the clock cycle of each output group + int cip = 0; // clock+cip give the clock cycle of an input group + int ccp = 0; // ccp give a column in the consumptio pattern + int nip = 0; // number of input data groups already consumed during the current execution, used while exploring IP + int ncp = 0; // number of input data groups already consumed during the current execution, used while exploring CP + bool cannotCompleteExec = false; + for(int m=0;m pattern; + for(int i=0;isetOutputPattern(pattern); + idIface += 1; + } + + // clear inputPattern and outputPattern + for(int i=0;i in = iface->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; + } +} + +void FunctionalBlock::initProductionPattern() { + if (productionPattern != NULL) clearProductionPattern(); + + nbProducingPorts = getControlOutputs().size(); + int idIface = 0; + productionPattern = new char*[nbProducingPorts]; + foreach(AbstractInterface* iface, getControlOutputs()) { + + QList in = iface->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; + } +}