X-Git-Url: https://bilbo.iut-bm.univ-fcomte.fr/and/gitweb/blast.git/blobdiff_plain/14cd6d834ab531525a51c6a6992583b3e9143e02..a13795fc34cd1e74f94695d35253c3d00abec9bc:/FunctionalBlock.cpp

diff --git a/FunctionalBlock.cpp b/FunctionalBlock.cpp
index 449e2ec..925a0f9 100644
--- a/FunctionalBlock.cpp
+++ b/FunctionalBlock.cpp
@@ -8,7 +8,7 @@
 #include "ArithmeticEvaluator.h"
 
 
-FunctionalBlock::FunctionalBlock(GroupBlock *_parent, ReferenceBlock *_reference) throw(Exception) :  AbstractBlock() {
+FunctionalBlock::FunctionalBlock(Graph *_graph, GroupBlock *_parent, ReferenceBlock *_reference, bool createIfaces) throw(Exception) :  AbstractBlock(_graph) {
   //if (! _reference->isReferenceBlock()) throw(Exception(BLOCK_INVALID_TYPE));
   //if (! _group->isGroupBlock()) throw(Exception(BLOCK_INVALID_TYPE));
   reference = _reference;
@@ -30,6 +30,10 @@ FunctionalBlock::FunctionalBlock(GroupBlock *_parent, ReferenceBlock *_reference
   delta = -1;
   evaluator = NULL;
 
+  if (createIfaces) {
+    populate();
+  }
+
 }
 
 FunctionalBlock::~FunctionalBlock() {
@@ -61,7 +65,7 @@ bool FunctionalBlock::isFunctionalBlock() {
   return true;
 }
 
-bool FunctionalBlock::isSourceBlock() {
+bool FunctionalBlock::isStimuliBlock() {
   if (parent == NULL) return true;
   return false;
 }
@@ -96,7 +100,7 @@ void FunctionalBlock::populate() {
     addInterface(inter);
     /* WARNING FOR THE FUTURE :
        in case of there are several clock interfaces ofr that block
-       it would be a godd idea to make the user choose which one
+       it would be a good idea to make the user choose which one
        must be connected to defautl clk.
        Presently, the first encountered is chosen
      */
@@ -122,18 +126,6 @@ void FunctionalBlock::populate() {
       }       
     }
   }
-
-  // connect clk and rst to group clk/rst or to clkrstgen
-  if ((name != "clkrstgen") && (parent != NULL)) {
-    try {
-      connectClkReset();
-    }
-    catch(Exception e) {
-      AbstractBlock* source = (AbstractBlock *)(e.getSource());
-      cerr << qPrintable(source->getName()) << ":" << qPrintable(e.getMessage()) << endl;
-      throw(e);
-    }
-  }
 }
 
 QString FunctionalBlock::getReferenceXmlFile() {
@@ -154,7 +146,7 @@ void FunctionalBlock::createPatterns() throw(Exception) {
   
   cout << "create patterns for block " << qPrintable(name) << endl;
   if (evaluator == NULL) evaluator = new ArithmeticEvaluator();
-  if (! isGeneratorBlock()) {
+  if (! isSourceBlock()) {
     try {
       createDelta();
       createConsumptionPattern();    
@@ -441,12 +433,17 @@ QList<char> FunctionalBlock::expandPatternRecur(const QString& patternIn, int *o
       catch(Exception e) {
         throw(e);
       }
+      if (repeat == 0) {
+        // remove the last
+        patternOut.removeLast();
+      }
+      else {
       // repeat just the last value in currentGroup
-      char last = patternOut.last();
-      //cout << "repeat last char " << repeat << " times : " << (int)last << endl;
-      
-      for(int i=1;i<(int)repeat;i++) {
-        patternOut.append(last);
+        char last = patternOut.last();
+        //cout << "repeat last char " << repeat << " times : " << (int)last << endl;
+        for(int i=1;i<(int)repeat;i++) {
+          patternOut.append(last);
+        }
       }
     }    
     *offset += 1;
@@ -470,15 +467,21 @@ QList<char> FunctionalBlock::expandPatternRecur(const QString& patternIn, int *o
     catch(Exception e) {
       throw(e);
     }
-    /*
+    if (repeat == 0) {
+      QList<char> voidList;
+      return voidList;
+    }
+    else {
+      /*
     cout << "repeat last group " << repeat << " times : ";
     foreach (char c, currentGroup) cout <<(int)c;
-    cout << endl;  
+    cout << endl;
     */
-    QList<char> single = patternOut;
-    for(int i=1;i<(int)repeat;i++) {
-      patternOut.append(single);
-    }    
+      QList<char> single = patternOut;
+      for(int i=1;i<(int)repeat;i++) {
+        patternOut.append(single);
+      }
+    }
   }  
   return patternOut;
 }
@@ -843,125 +846,113 @@ void FunctionalBlock::computeOutputPattern(int nbExec) throw(Exception) {
 
   clearOutputPattern();
 
-  /* case 1: the block is a generator for which output pattern
-     must be computed for a nbExec following executions
-  */
+  if (specialType != NotSpecial) {
+    cerr << "Abnormal case: the block is special and output pattern is computed normally" << endl;
+    throw(Exception(INVALID_FUNBLOCK_USE,this));
+  }
 
-  if (nbExec > 0) {
-    cout << "computing output pattern of " << qPrintable(name) << " for " << nbExec << " executions" << endl;
-    foreach(AbstractInterface* iface, getControlOutputs()) {
-      FunctionalInterface* connIface = AI_TO_FUN(iface);
-      // 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);      
+  cout << "computing output pattern of " << qPrintable(name) << endl;
+
+  // in case of inputPattern not created, do it
+  if (lengthIP <= 0) {
+
+    cout << "Strange case: input pattern is not created while it is time to compute output pattern !" << endl;
+    // collect the input patterns for each input
+    try {
+      createInputPattern();
     }
+    catch(Exception e) {
+      throw(e);
+    }
+    cout << "input pattern array initialized with min. len " << lengthIP << endl;
   }
-  else {
-    cout << "computing output pattern of " << qPrintable(name) << endl;
-    
-    // in case of inputPattern not created, do it
-    if (lengthIP <= 0) {
 
-      cout << "Strange case: input pattern is not created while it is time to compute output pattern !" << endl;
-      // collect the input patterns for each input    
-      try {
-        createInputPattern();
-      }
-      catch(Exception e) {
-        throw(e);
+  // initialize the output pattern
+  lengthOP = 0;
+  foreach(AbstractInterface* iface, getControlOutputs()) {
+    FunctionalInterface* connIface = AI_TO_FUN(iface);
+    lengthOP = lengthIP+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 < lengthIP) && (! isValidDataGroup(inputPattern,clock))) clock++;
+  cout << "found 1st exec clock: " << clock << endl;
+
+  while (clock < lengthIP) {
+    // 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<productionCounter.size();m++) {
+      // search for the first production in PP
+      while (!isValidDataGroup(productionPattern,p)) {
+        p += 1;
+        o += 1;
       }
-      cout << "input pattern array initialized with min. len " << lengthIP << endl;
-    }
-    
-    // initialize the output pattern    
-    lengthOP = 0;
-    foreach(AbstractInterface* iface, getControlOutputs()) {
-      FunctionalInterface* connIface = AI_TO_FUN(iface);      
-      lengthOP = lengthIP+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 < lengthIP) && (! isValidDataGroup(inputPattern,clock))) clock++;
-    cout << "found 1st exec clock: " << clock << endl;
-    
-    while (clock < lengthIP) {
-      // 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<productionCounter.size();m++) {
-        // search for the first production in PP
-        while (!isValidDataGroup(productionPattern,p)) {
-          p += 1;
-          o += 1;
+      int gap = 0; // count the number of extra null columns
+      // search for PC(m) valid input group in IP
+      while (nip < productionCounter.at(m)) {
+        if (clock+cip < lengthIP) {
+          if (isValidDataGroup(inputPattern,clock+cip)) nip += 1;
+          cip += 1;
+          gap += 1;
         }
-        int gap = 0; // count the number of extra null columns
-        // search for PC(m) valid input group in IP
-        while (nip < productionCounter.at(m)) {
-          if (clock+cip < lengthIP) {
-            if (isValidDataGroup(inputPattern,clock+cip)) nip += 1;
-            cip += 1;
-            gap += 1;
-          }
-          else {
-            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,ccp)) ncp += 1;
-          ccp += 1;
-          gap -= 1;
+        else {
+          cannotCompleteExec = true;
+          break;
         }
-        o += gap; // to take into acocunt of extra null columns
-        combinePatterns(productionPattern,p,outputPattern,clock+o);
-        p += 1;
-        o += 1;
       }
-      
+
       if (cannotCompleteExec) break; // no need to go further since the next search of input data group will lead to go outside inputPattern
-      
-      // current exec. taken into accunt
-      nbExec += 1;
-      
-      // search for the next exec.
-      clock += 1;      
-      nip = 0;
-      while ((clock < lengthIP) && (nip < delta)) {
-        if (isValidDataGroup(inputPattern,clock)) nip += 1;
-        if (nip < delta) clock += 1;
+
+      // search for PC(m) valid input group in IP
+      while (ncp < productionCounter.at(m)) {
+        if (isValidDataGroup(consumptionPattern,ccp)) ncp += 1;
+        ccp += 1;
+        gap -= 1;
       }
-      cout << "found exec " << nbExec << " at clock: " << clock << endl;
+      o += gap; // to take into acocunt of extra null columns
+      combinePatterns(productionPattern,p,outputPattern,clock+o);
+      p += 1;
+      o += 1;
     }
-    // find the last valid output data group
-    while(! isValidDataGroup(outputPattern,lengthOP-1)) {
-      removeDataGroup(outputPattern,lengthOP-1);
-      lengthOP -= 1;
+
+    if (cannotCompleteExec) break; // no need to go further since the next search of input data group will lead to go outside inputPattern
+
+    // current exec. taken into accunt
+    nbExec += 1;
+
+    // search for the next exec.
+    clock += 1;
+    nip = 0;
+    while ((clock < lengthIP) && (nip < delta)) {
+      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,lengthOP-1)) {
+    removeDataGroup(outputPattern,lengthOP-1);
+    lengthOP -= 1;
+  }
+
+  // clear input pattern
+  clearInputPattern();
+
+  setOutputPatternComputed(true);
 
-    // clear input pattern
-    clearInputPattern();
-  }  
 }
 
 /*
@@ -1421,23 +1412,22 @@ void FunctionalBlock::generateComments(QTextStream& out, QDomElement &elt, QStri
   QString mail = eltAuthor.attribute("mail","");
   out << "--  Author(s)   : "<<firstName+" "<<lastName<<" ("<<mail<<")" << endl;
   out << "--" << endl;
-  QDomElement eltDate = eltAuthor.nextSiblingElement("date");
-  QString crea = eltDate.attribute("creation","");
+  QDomElement eltLog = eltAuthor.nextSiblingElement("log");
+  QString crea = eltLog.attribute("creation","");
   out << "--  Creation Date   : "<<crea<< endl;
   out << "--" << endl;
-  QDomElement eltRelated = eltDate.nextSiblingElement("related_files");
-  QString relateds = eltRelated.attribute("list","");
-  out << "--  Related files   :\n"<<relateds<<endl;
-  out << "--" << endl;
-  QDomElement eltDesc = eltRelated.nextSiblingElement("description");
-  QDomElement desc = eltDesc.firstChildElement();
-  QString descTxt = desc.text();
-  out << "--  Decription      :\n"<<descTxt<<endl;
+  QDomNodeList listModifs = eltLog.elementsByTagName("modification");
+  for(int j=0;j<listModifs.length();j++) {
+    QDomNode nodeModif = listModifs.at(j);
+    QDomElement eltModif = nodeModif.toElement();
+  }
+  out << "-- Description   : " << endl;
+  out << reference->getDescription() << endl;
   out << "--" << endl;
-  QDomElement eltNote = eltDesc.nextSiblingElement("description");
+  QDomElement eltNote = eltLog.nextSiblingElement("notes");
   QDomElement note = eltNote.firstChildElement();
   QString noteTxt = note.text();
-  out << "--  Note          :\n"<<noteTxt<<endl;
+  out << "--  Notes          :\n"<<noteTxt<<endl;
   out << "--" << endl;
   for(int i = 0; i < 50; i++) {
     out << "--";