]> AND Private Git Repository - blast.git/commitdiff
Logo AND Algorithmique Numérique Distribuée

Private GIT Repository
added admittance computation
authorstephane Domas <stephane.domas@univ-fcomte.fr>
Fri, 19 May 2017 14:41:28 +0000 (16:41 +0200)
committerstephane Domas <stephane.domas@univ-fcomte.fr>
Fri, 19 May 2017 14:41:28 +0000 (16:41 +0200)
FunctionalBlock.cpp
FunctionalBlock.h
Graph.cpp
blast.creator.user
lib/implementations/generator-cst_impl.xml

index 23d43b9033c5c6157afdeb3ceb5c1a90fcddde58..ac27de40a0168d25129cb50334badc96c7d6e3df 100644 (file)
@@ -117,10 +117,10 @@ bool FunctionalBlock::createPatterns() {
   \r
   cout << "create patterns for block " << qPrintable(name) << endl;\r
   evaluator = new ArithmeticEvaluator();\r
-  bool ok = true;\r
-  ok = ok & createDelta();\r
+  bool ok = true;  \r
   if (! isGeneratorBlock()) {\r
-    if (ok) ok = ok & createConsumptionPattern();\r
+    ok = ok & createDelta();\r
+    if (ok) ok = ok & createConsumptionPattern();    \r
     if (ok) ok = ok & createProductionCounter();\r
   }\r
   if (ok) ok = ok & createProductionPattern();\r
@@ -134,8 +134,12 @@ bool FunctionalBlock::createDelta() {
   cout << "call to " << qPrintable(fctName) << endl;\r
 #endif \r
   \r
-  QString deltaStr = implementation->getDelta();\r
+  QString deltaStr = implementation->getDelta();  \r
   cout << "delta for " << qPrintable(name) << " = " << qPrintable(deltaStr) << endl;\r
+  if (deltaStr.isEmpty()) {\r
+    delta = -1;\r
+    return true;\r
+  }\r
   \r
   // look for parameter names\r
   bool ok = true;\r
@@ -154,6 +158,7 @@ bool FunctionalBlock::createConsumptionPattern() {
   cout << "call to " << qPrintable(fctName) << endl;\r
 #endif\r
   \r
+  lengthCP = -1;\r
   bool ok = true; \r
   QHash<QString,QString> consPattern = implementation->getConsumptionPattern();  \r
   \r
@@ -164,10 +169,15 @@ bool FunctionalBlock::createConsumptionPattern() {
       cerr << "no consumption pattern for reference interface " << qPrintable(refName) << endl;\r
       return false;\r
     }\r
-    QList<char>* pattern = expandPattern(consPattern.value(refName),&ok);    \r
-    \r
+    QList<char>* pattern = expandPattern(consPattern.value(refName),&ok);        \r
     if (!ok) return false;\r
-    consumptionPattern.insert(connIface,pattern);        \r
+    consumptionPattern.insert(connIface,pattern);\r
+    if (lengthCP == -1) {\r
+      lengthCP = pattern->size();\r
+    }\r
+    else {\r
+      if (pattern->size() != lengthCP) return false;\r
+    }\r
   }        \r
   return true;\r
 }\r
@@ -178,6 +188,7 @@ bool FunctionalBlock::createProductionPattern() {
   cout << "call to " << qPrintable(fctName) << endl;\r
 #endif\r
   \r
+  lengthPP = -1;\r
   bool ok = true; \r
   QHash<QString,QString> prodPattern = implementation->getProductionPattern();  \r
   \r
@@ -190,7 +201,13 @@ bool FunctionalBlock::createProductionPattern() {
     }\r
     QList<char>* pattern = expandPattern(prodPattern.value(refName),&ok);\r
     if (!ok) return false;\r
-    productionPattern.insert(connIface,pattern);    \r
+    productionPattern.insert(connIface,pattern);\r
+    if (lengthPP == -1) {\r
+      lengthPP = pattern->size();\r
+    }\r
+    else {\r
+      if (pattern->size() != lengthPP) return false;\r
+    }\r
   }    \r
   return true;\r
 }\r
@@ -379,6 +396,121 @@ double FunctionalBlock::evaluateExpression(const QString& expression, bool* ok)
   return result;\r
 }\r
 \r
+void FunctionalBlock::createInputPattern() {\r
+  lengthIP = -1;\r
+  foreach(AbstractInterface* iface, getControlInputs()) {      \r
+    ConnectedInterface* connIface = AI_TO_CON(iface);\r
+    QList<char>* out = connIface->getConnectedFrom()->getOutputPattern();\r
+    if (lengthIP == -1) {\r
+      lengthIP = out->size();\r
+    }\r
+    else {\r
+      if (out->size() < lengthIP) lengthIP = out->size();\r
+    }\r
+    if (out->size() > 0) {\r
+      QList<char>* in = new QList<char>(*out);\r
+      foreach(char c, *in) {\r
+        cout << (int)c;\r
+      }\r
+      cout << endl;\r
+\r
+      inputPattern.insert(connIface,in);\r
+    }\r
+    else {\r
+      inputPattern.insert(connIface,NULL);\r
+    }      \r
+  }  \r
+}\r
+\r
+bool FunctionalBlock::createAdmittance(int nbExec) {\r
+  static QString fctName = "FunctionalBlock::createAdmittance()";\r
+#ifdef DEBUG_FCTNAME\r
+  cout << "call to " << qPrintable(fctName) << endl;\r
+#endif\r
+  bool ok = true;\r
+  // firstly, copy CP in AP\r
+  QMapIterator<AbstractInterface*,QList<char>* > iterC(consumptionPattern);\r
+  while (iterC.hasNext()) {\r
+    iterC.next();\r
+    QList<char>* pattern = new QList<char>(*(iterC.value()));\r
+    admittance.insert(iterC.key(), pattern);    \r
+  }\r
+  lengthAP = lengthCP;\r
+  int clock = 0;  \r
+  cout << "trigger 1 at c.c. 0" << endl;\r
+  for(int i=1;i<nbExec;i++) {\r
+    // searching for the clock cycle for which a new exec starts\r
+    int nbGroup = 0;\r
+    while ((clock < lengthAP) && (nbGroup < delta)) {\r
+      if (isValidDataGroup(admittance,clock)) nbGroup+=1;\r
+      clock += 1;\r
+    }\r
+    while ((clock < lengthAP) && (! isValidDataGroup(admittance,clock))) clock+=1;\r
+    cout << "trigger " << (i+1) << " at c.c. " << clock << endl;\r
+    int sc = clock;\r
+    // combine CP with AP at sc\r
+    for(int j=0;j<lengthCP;j++) {\r
+      // first case : column of CP must be placed beyond AP's end.\r
+      if (sc == lengthAP) {\r
+        cout << i << "," << j << " append in AP at " << sc << endl;\r
+        appendToPattern(consumptionPattern,j,admittance,1);\r
+        lengthAP += 1;\r
+        sc += 1;              \r
+      }\r
+      // second case : CP and AP can be combined directly (i.e. no X | 1 to do)\r
+      else if (canCombinePatterns(consumptionPattern,j,admittance,sc)) {\r
+        cout << i << "," << j << " combine at " << sc << endl;\r
+        combinePatterns(consumptionPattern,j,admittance,sc);\r
+        sc += 1;\r
+      }\r
+      // third case : CP has an X column\r
+      else if (isOnlyXDataGroup(consumptionPattern,j)) {\r
+        cout << i << "," << j << " shift rigth AP to combine at " << sc << endl;\r
+        shiftRightPattern(admittance,sc);\r
+        lengthAP += 1;\r
+        if (! canCombinePatterns(consumptionPattern,j,admittance,sc)) {\r
+          cerr << "Abnormal case when combining AP and CP" << endl;\r
+        }\r
+        combinePatterns(consumptionPattern,j,admittance,sc);        \r
+        sc += 1;\r
+      }\r
+      // fourth case : AP has an X column\r
+      else if (isOnlyXDataGroup(admittance,sc)) {\r
+        cout << i << "," << j << " jump c.c. for CP at " << sc << endl;        \r
+        sc += 1;\r
+        j -= 1;\r
+      }\r
+      else {\r
+        cout << "AP and CP are not consistent" << endl;\r
+        return false;\r
+      }\r
+    }\r
+  }\r
+  \r
+  return true;\r
+}\r
+\r
+bool FunctionalBlock::checkInputPatternCompatibility() {\r
+  static QString fctName = "FunctionalBlock::checkInputPatternCompatibility()";\r
+#ifdef DEBUG_FCTNAME\r
+  cout << "call to " << qPrintable(fctName) << endl;\r
+#endif\r
+  \r
+  bool ok = true;\r
+  // firstly, create input pattern\r
+  createInputPattern();      \r
+  // if some patterns are not available, end now, returning false\r
+  if (lengthIP == 0) {\r
+    clearInputPattern();\r
+    return false;\r
+  }\r
+  int nbExec = getNumberOfExecution();\r
+  ok = createAdmittance(nbExec);\r
+  if (!ok) return false;\r
+  \r
+  return true;\r
+}\r
+\r
 bool FunctionalBlock::computeOutputPattern(int nbExec) {\r
   static QString fctName = "FunctionalBlock::computeOutputPattern()";\r
 #ifdef DEBUG_FCTNAME\r
@@ -407,48 +539,23 @@ bool FunctionalBlock::computeOutputPattern(int nbExec) {
   else {\r
     cout << "computing output pattern of " << qPrintable(name) << endl;\r
     \r
-    // collect the input patterns for each input \r
-    QMap<AbstractInterface*,QList<char>* > inputPattern;    \r
-    int minLen = -1;\r
-    foreach(AbstractInterface* iface, getControlInputs()) {      \r
-      ConnectedInterface* connIface = AI_TO_CON(iface);\r
-      QList<char>* out = connIface->getConnectedFrom()->getOutputPattern();\r
-      if (minLen == -1) {\r
-        minLen = out->size();\r
-      }\r
-      else {\r
-        if (out->size() < minLen) minLen = out->size();\r
+    // in case of inputPattern not created, do it\r
+    if (lengthIP <= 0) {\r
+      // collect the input patterns for each input    \r
+      createInputPattern();    \r
+      // if some patterns are not available, end now, returning false\r
+      if (lengthIP == 0) {\r
+        clearInputPattern();\r
+        return false;\r
       }\r
-      if (out->size() > 0) {\r
-        QList<char>* in = new QList<char>(*out);\r
-        foreach(char c, *in) {\r
-          cout << (int)c;\r
-        }\r
-        cout << endl;\r
-\r
-        inputPattern.insert(connIface,in);\r
-      }\r
-      else {\r
-        inputPattern.insert(connIface,NULL);\r
-      }      \r
-    }\r
-    // if some patterns are not available, end now, returning false\r
-    if (minLen == 0) {\r
-      QMapIterator<AbstractInterface*,QList<char>* > iterI(inputPattern);\r
-      while (iterI.hasNext()) {\r
-        iterI.next();\r
-        QList<char>* pattern = iterI.value();        \r
-        if (pattern != NULL) delete pattern;\r
-      }     \r
-      return false;\r
+      cout << "input pattern array initialized with min. len " << lengthIP << endl;\r
     }\r
-    cout << "input pattern array initialized with min. len " << minLen << endl;\r
     \r
     // initialize the output pattern    \r
-    int lengthOP = 0;\r
+    lengthOP = 0;\r
     foreach(AbstractInterface* iface, getControlOutputs()) {\r
       FunctionalInterface* connIface = AI_TO_FUN(iface);      \r
-      lengthOP = minLen+productionPattern.value(connIface)->size();\r
+      lengthOP = lengthIP+productionPattern.value(connIface)->size();\r
       QList<char>* pattern = new QList<char>();\r
       for(int i=0;i<lengthOP;i++) pattern->append(0);\r
       connIface->setOutputPattern(pattern);\r
@@ -459,10 +566,10 @@ bool FunctionalBlock::computeOutputPattern(int nbExec) {
     int clock = 0;\r
     nbExec = 0;\r
     // search for the beginning of the first execution.\r
-    while ((clock < minLen) && (! isValidDataGroup(inputPattern,clock))) clock++;\r
+    while ((clock < lengthIP) && (! isValidDataGroup(inputPattern,clock))) clock++;\r
     cout << "found 1st exec clock: " << clock << endl;\r
     \r
-    while (clock < minLen) {\r
+    while (clock < lengthIP) {\r
       // initialize counters for current execution.\r
       int p = 0; // index in production pattern\r
       int o = 0; // clock+o will give the clock cycle of each output group\r
@@ -480,7 +587,7 @@ bool FunctionalBlock::computeOutputPattern(int nbExec) {
         int gap = 0; // count the number of extra null columns\r
         // search for PC(m) valid input group in IP\r
         while (nip < productionCounter.at(m)) {\r
-          if (clock+cip < minLen) {\r
+          if (clock+cip < lengthIP) {\r
             if (isValidDataGroup(inputPattern,clock+cip)) nip += 1;\r
             cip += 1;\r
             gap += 1;\r
@@ -513,7 +620,7 @@ bool FunctionalBlock::computeOutputPattern(int nbExec) {
       // search for the next exec.\r
       clock += 1;      \r
       nip = 0;\r
-      while ((clock < minLen) && (nip < delta)) {\r
+      while ((clock < lengthIP) && (nip < delta)) {\r
         if (isValidDataGroup(inputPattern,clock)) nip += 1;\r
         if (nip < delta) clock += 1;\r
       }\r
@@ -525,13 +632,8 @@ bool FunctionalBlock::computeOutputPattern(int nbExec) {
       lengthOP -= 1;\r
     }\r
 \r
-    // clear input pattern    \r
-    QMapIterator<AbstractInterface*,QList<char>* > iterI(inputPattern);\r
-    while (iterI.hasNext()) {\r
-      iterI.next();\r
-      QList<char>* pattern = iterI.value();        \r
-      if (pattern != NULL) delete pattern;\r
-    }     \r
+    // clear input pattern\r
+    clearInputPattern();\r
   }\r
   return true;\r
 }\r
@@ -598,6 +700,17 @@ void FunctionalBlock::removeDataGroup(QMap<AbstractInterface *, QList<char> *> &
   }\r
 }\r
 \r
+void FunctionalBlock::shiftRightPattern(const QMap<AbstractInterface *, QList<char> *> &pattern, int offset) {\r
+  QMapIterator<AbstractInterface*, QList<char>* > iterSrc(pattern);  \r
+  while (iterSrc.hasNext()) {\r
+    iterSrc.next();    \r
+    QList<char>* srcPat = iterSrc.value();\r
+    if (offset < srcPat->size()) {\r
+      srcPat->insert(offset,0);\r
+    }\r
+  }\r
+}\r
+\r
 bool FunctionalBlock::isValidDataGroup(const QMap<AbstractInterface *, QList<char> *> &pattern, int offset) {\r
   QMapIterator<AbstractInterface*, QList<char>* > iterSrc(pattern);  \r
   while (iterSrc.hasNext()) {\r
@@ -627,6 +740,8 @@ void FunctionalBlock::clearConsumptionPattern() {
     QList<char>* pattern = iterP.value();\r
     if (pattern != NULL) delete pattern;\r
   }\r
+  consumptionPattern.clear();\r
+  lengthCP = -1;      \r
 }  \r
 \r
 void FunctionalBlock::clearProductionPattern() {\r
@@ -636,4 +751,40 @@ void FunctionalBlock::clearProductionPattern() {
     QList<char>* pattern = iterP.value();\r
     if (pattern != NULL) delete pattern;\r
   }\r
+  productionPattern.clear();\r
+  lengthPP = -1;\r
 }  \r
+\r
+void FunctionalBlock::clearInputPattern() {\r
+  \r
+  QMapIterator<AbstractInterface*,QList<char>* > iterI(inputPattern);\r
+  while (iterI.hasNext()) {\r
+    iterI.next();\r
+    QList<char>* pattern = iterI.value();\r
+    if (pattern != NULL) delete pattern;\r
+  }\r
+  inputPattern.clear();\r
+  lengthIP = -1;\r
+}\r
+\r
+int FunctionalBlock::getNumberOfExecution() {\r
+  /* NB: this method returns the number of executions that have been started\r
+     but not necessary completed.\r
+  */\r
+  if (delta <= 0) return 0;\r
+  int nbExec = 0;\r
+  int offset = 0;\r
+  // search for the first exec.\r
+  while ((offset < lengthIP) && (! isValidDataGroup(inputPattern,offset))) offset++;\r
+  if (offset == lengthIP) return 0;\r
+  nbExec = 1;\r
+  int nbGroup = 0;\r
+  for(int i = offset;i<lengthIP;i++) {\r
+    if (isValidDataGroup(inputPattern,offset)) nbGroup++;\r
+    if (nbGroup == delta+1) {\r
+      nbExec += 1;\r
+      nbGroup = 1;\r
+    }\r
+  }      \r
+  return nbExec;  \r
+}\r
index 2cf9a5afc01929f78b88f7abc352f5403fcce4b7..6f47a008033b7747ed9d7508c3dd6e4c158dd9cd 100644 (file)
@@ -31,6 +31,10 @@ public:
   // getters\r
   inline ReferenceBlock* getReference() { return reference; }\r
   inline QList<int> getProductionCounter() { return productionCounter; }\r
+  inline QMap<AbstractInterface*, QList<char>* > getConsumptionPattern() { return consumptionPattern; }\r
+  inline QMap<AbstractInterface*, QList<char>* > getProductionPattern() { return productionPattern; }\r
+  inline int getConsumptionPatternLength() { return lengthCP; }\r
+  inline int getProductionPatternLength() { return lengthPP; }\r
   inline int getDelta() { return delta; }\r
   \r
   // setters\r
@@ -57,8 +61,13 @@ public:
   bool createConsumptionPattern(); // initialize a QList<char> for each interface from patterns defined in implementation\r
   bool createProductionPattern(); // initialize a QList<char> for each interface from patterns defined in implementation\r
   bool createProductionCounter(); // initialize a QList<int> from counter defined in implementation\r
+  bool createAdmittance(int nbExec); // initialize a QList<char> from consumption pattern and delta\r
   void clearConsumptionPattern();\r
   void clearProductionPattern();\r
+  void createInputPattern();\r
+  void clearInputPattern();\r
+  int getNumberOfExecution(); // compute number of block execution from inputPattern and delta\r
+  bool checkInputPatternCompatibility();\r
   bool computeOutputPattern(int nbExec = -1);\r
   \r
 private:  \r
@@ -126,12 +135,17 @@ private:
   void shiftRightPattern(const QMap<AbstractInterface*, QList<char>* >& pattern, int offset);\r
 \r
   QMap<AbstractInterface*, QList<char>* > consumptionPattern;\r
-  QMap<AbstractInterface*, QString > admittance; // the admittance expressed as prologue-cyclic part-eppilogue\r
-  QMap<AbstractInterface*, QList<char>* > admittanceExpanded; // the admittance expanded by taking into account nb exec.\r
+  QMap<AbstractInterface*, QString > admittanceCyclic; // the admittance expressed as prologue-cyclic part-eppilogue, deduced from admittance\r
+  QMap<AbstractInterface*, QList<char>* > admittance; // the admittance taking into account nb exec.\r
   QMap<AbstractInterface*, QList<char>* > productionPattern;\r
+  QMap<AbstractInterface*,QList<char>* > inputPattern;\r
   QMap<AbstractInterface*, QList<char>* > outputPattern; // CAUTION: the QList<char>* must also be stored in the outputPattern attributes of AbstractInterface\r
   QList<int> productionCounter; //! only usefull for control output interfaces\r
-  \r
+  int lengthIP; // for convenience, set in createInputPattern()\r
+  int lengthCP; // for convenience, set in createConsumptionPattern()\r
+  int lengthAP; // for convenience, set in createAdmittance()\r
+  int lengthPP;  // for convenience, set in createProductionPattern()\r
+  int lengthOP;  // for convenience, set in computeOutputPattern()\r
   int delta;\r
     \r
   ArithmeticEvaluator* evaluator;\r
index 999e72aa375fc4d4d2a1c0a7a198057a3646deed..eb66dc4e8ad8b7cc35cb76108b78c06f9b0738c4 100644 (file)
--- a/Graph.cpp
+++ b/Graph.cpp
@@ -158,15 +158,15 @@ bool Graph::computeOutputPatterns(int nbExec) {
       }
     }    
   }
-  // search for maximum delta
-  int maxDelta = 0;
+  // search for maximum PP length
+  int maxPP = 0;
   foreach(FunctionalBlock* block, generators) {    
-    if (block->getDelta() > maxDelta) maxDelta = block->getDelta();
+    if (block->getProductionPatternLength() > maxPP) maxPP = block->getProductionPatternLength();
   }
   // compute output for generators
-  int maxExecLen = maxDelta*nbExec;
+  int maxExecLen = maxPP*nbExec;
   foreach(FunctionalBlock* block, generators) {    
-    int d = block->getDelta();
+    int d = block->getProductionPatternLength();
     block->computeOutputPattern((maxExecLen+d-1)/d);
   }
   // compute output for top group
index dc3af4ea70d8cd7361d7ed5d9670f8ae0b7cab10..acd48e98162630221628ad117c5f66f374d59b8f 100755 (executable)
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!DOCTYPE QtCreatorProject>
-<!-- Written by QtCreator 3.2.1, 2017-05-18T16:26:09. -->
+<!-- Written by QtCreator 3.2.1, 2017-05-19T16:37:01. -->
 <qtcreator>
  <data>
   <variable>EnvironmentId</variable>
index 0c94e162f924a0039696a10c4ab73a00dd981388..9768641b1d8d62e402e6737da576148b7718b83a 100644 (file)
   </architecture>
 
   <patterns>
-    <delta value="$seq_length+$idle_length" />
+    <delta value="$seq_length" />
     <consumption>
     </consumption>
     <production counter="">
-      <output name="data_o_enb" pattern="1{$seq_length}X{$idle_length}" />
+      <output name="data_o_enb" pattern="1{$seq_length}0{$idle_length}" />
     </production>
   </patterns>
 </block_impl>