From: stephane Domas <stephane.domas@univ-fcomte.fr>
Date: Sun, 14 May 2017 19:45:38 +0000 (+0200)
Subject: pattern comput done
X-Git-Url: https://bilbo.iut-bm.univ-fcomte.fr/and/gitweb/blast.git/commitdiff_plain/48f48e6a26a54751ecd0ab90b10ab972cc5e89cd?ds=inline;hp=8e89ca269960b7bb43ccc054696dfc28e84d409a

pattern comput done
---

diff --git a/AbstractBlock.h b/AbstractBlock.h
index 88e4cb9..9216212 100644
--- a/AbstractBlock.h
+++ b/AbstractBlock.h
@@ -36,14 +36,11 @@ public:
   QList<BlockParameter *> getPortParameters();
   QList<BlockParameter *> getWishboneParameters();
   inline AbstractBlock* getParent() { return parent; }
-  inline QList<int> getProductionCounter() { return productionCounter; }
-  inline int getDelta() { return delta; }
+  inline bool getPatternComputed() { return patternComputed; }
   
   // setters
   void setName(const QString& str);
   virtual void setParent(AbstractBlock* _parent);
-  inline void setProductionCounter(QList<int> pattern) { productionCounter = pattern; }
-  inline void setDelta(int _delta) { delta = _delta; }
   inline void setPatternComputed(bool state) { patternComputed = state; }
 
   // testers
@@ -90,9 +87,7 @@ protected:
   
   // others
   
-  // patterns
-  QList<int> productionCounter; //! only usefull for output interfaces
-  int delta;
+  // patterns  
   bool patternComputed;
   
   // NB: only GroupBlock and FunctionalBlock have a real parent, except sources that have no parents
diff --git a/AbstractInterface.cpp b/AbstractInterface.cpp
index f57f780..49a937c 100644
--- a/AbstractInterface.cpp
+++ b/AbstractInterface.cpp
@@ -141,10 +141,17 @@ bool AbstractInterface::setAssociatedIface(AbstractInterface* iface) {
 int AbstractInterface::getIntDirection(QString str) {
     if(str == "input") return Input;
     if(str == "output") return Output;
-    if(str == "inOut") return InOut;
+    if(str == "inout") return InOut;
     return -1;
 }
 
+int AbstractInterface::getIntPurpose(QString str) {
+    if(str == "data") return Data;
+    else if(str == "clock") return Clock;
+    else if(str == "reset") return Reset;
+    else if(str == "wishbone") return Wishbone;
+    return -1;
+}
 
 QString AbstractInterface::getTypeString() {
 
diff --git a/AbstractInterface.h b/AbstractInterface.h
index ac47ca9..2c914d4 100644
--- a/AbstractInterface.h
+++ b/AbstractInterface.h
@@ -14,6 +14,7 @@ class Exception;
 #define AI_TO_REF(ptr) ((ReferenceInterface*)ptr)
 #define AI_TO_FUN(ptr) ((FunctionalInterface*)ptr)
 #define AI_TO_GRP(ptr) ((GroupInterface*)ptr)
+#define AI_TO_CON(ptr) ((ConnectedInterface*)ptr)
 
 using namespace std;
 using namespace Qt;
@@ -29,7 +30,8 @@ public :
   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);  
+  static int getIntDirection(QString str);
+  static int getIntPurpose(QString str);
 
   AbstractInterface(AbstractBlock* _owner);
   AbstractInterface(AbstractBlock* _owner, const QString& _name, const QString& _type, const QString& _width, int _direction, int _purpose);
@@ -50,16 +52,6 @@ public :
 
   double getDoubleWidth() throw(QException);
   
-  inline QList<char> getConsumptionPattern() { return consumptionPattern; }
-  inline QList<char> getProductionPattern() { return productionPattern; }  
-  inline QList<char> getOutputPattern() { return outputPattern; }
-
-  //virtual QList<AbstractInterface*> getConnectedTo() = 0;
-
-  /* NB: only GroupInterface and FunctionalInterface have a connectedFrom, so
-     defining getConnectedFrom as pure virtual is normal, usefull even though it is ugly :-)
-   */
-  virtual AbstractInterface* getConnectedFrom() = 0;
 
   // setters
   inline void setOwner(AbstractBlock* _owner) { owner = _owner; }
@@ -71,28 +63,14 @@ public :
   void setDirection(int _direction);
   bool setAssociatedIface(AbstractInterface* iface);
   
-  inline void setConsumptionPattern(QList<char> pattern) { consumptionPattern = pattern; }
-  inline void setProductionPattern(QList<char> pattern) { productionPattern = pattern; }  
-  inline void setOutputPattern(QList<char> pattern) { outputPattern = pattern; }
-
   // testers
   virtual bool isReferenceInterface();
   virtual bool isFunctionalInterface();
   virtual bool isGroupInterface();
-  //virtual bool isConnectedTo() = 0;
-  //virtual bool isConnectedFrom() = 0;
-  //virtual bool canConnectTo(AbstractInterface* iface) = 0; // returns yes if this can be connected to iface, no if not
-  //virtual bool canConnectFrom(AbstractInterface* iface) = 0; // returns yes if this can be connected from iface, no if not
 
   // others
   virtual AbstractInterface *clone() = 0;
-
-  //virtual bool addConnectedTo(AbstractInterface *inter) = 0;
-  //virtual void removeConnectedTo(AbstractInterface *inter) = 0;
-  //virtual bool setConnectedFrom(AbstractInterface* inter) = 0;
-  //virtual void clearConnectedTo() = 0;
-  //virtual void clearConnections() = 0;
-  //virtual void connectionsValidation(QStack<AbstractInterface*> *interfacetoValidate, QList<AbstractInterface*> *validatedInterfaces) throw(Exception) = 0;
+  
   int typeFromString(const QString &_type);
 
   QString toVHDL(int context, int flags) throw(Exception);
@@ -115,11 +93,7 @@ protected:
    */
   AbstractInterface* associatedIface;
   
-  // patterns
-  QList<char> consumptionPattern; //! only usefull for input interfaces
-  QList<char> productionPattern; //! only usefull for output interfaces
   
-  QList<char> outputPattern; //! only usefull for output interfaces
 };
 
 
diff --git a/ArithmeticEvaluator.cpp b/ArithmeticEvaluator.cpp
index dd8081e..54a9596 100644
--- a/ArithmeticEvaluator.cpp
+++ b/ArithmeticEvaluator.cpp
@@ -22,13 +22,19 @@ ArithmeticEvaluator::ArithmeticEvaluator() {
      since spaces are removed. Thus, an expression like sin 10 will lead to
      sin10 after spaces removal, and thus becomes invalid.
    */
-  fctMarkers << "sin" << "cos" << "log10" << "log2" << "log" << "ceil" << "floor" << "round";
+  fctMarkers << "sin" << "cos" << "log10" << "log2" << "log" << "ceil" << "floor" << "round";  
 }
 
 ArithmeticEvaluator::ArithmeticEvaluator(const QString& _expression) throw(int) {
   opMarkers = "+-*/";
   varMarkers = "$";
-  fctMarkers << "sin" << "cos" << "log10" << "log2" << "log" << "ceil" << "floor" << "round";
+  expression = QStringList();
+  /* CAUTION : function are mandatory using ( ) to encapsulate the operand
+     since spaces are removed. Thus, an expression like sin 10 will lead to
+     sin10 after spaces removal, and thus becomes invalid.
+   */
+  fctMarkers << "sin" << "cos" << "log10" << "log2" << "log" << "ceil" << "floor" << "round";   
+  
   try {
     setExpression(_expression);
   }
@@ -37,7 +43,10 @@ ArithmeticEvaluator::ArithmeticEvaluator(const QString& _expression) throw(int)
   }
 }
 
-void ArithmeticEvaluator::setExpression(const QString& _expression) throw(int) {
+void ArithmeticEvaluator::setExpression(const QString& _expression) throw(int) {  
+  
+  setVariableNames(_expression);
+  
   try {
     convert(_expression);
   }
@@ -46,6 +55,28 @@ void ArithmeticEvaluator::setExpression(const QString& _expression) throw(int) {
   }
 }
 
+void ArithmeticEvaluator::setVariablesValue(const QHash<QString,double>& _varValues) { 
+  varValues =  _varValues;
+  /*
+  QHashIterator<QString,double> iterV(varValues);
+  while (iterV.hasNext()) {
+    iterV.next();
+    cout << "var " << qPrintable(iterV.key()) << " = " << iterV.value() << endl;
+  }
+  */
+}
+
+void ArithmeticEvaluator::setVariableNames(const QString& _expression) {
+  varNames.clear();
+  QRegularExpression re("[$][a-zA-Z0-9_]+");
+  QRegularExpressionMatchIterator matcher = re.globalMatch(_expression);
+  while(matcher.hasNext()) {
+    QRegularExpressionMatch m = matcher.next();
+    QString var = m.captured(0);    
+    varNames.append(var);
+  }
+}
+
 void ArithmeticEvaluator::print() {
   foreach(QString elt, expression) {
     cout << qPrintable(elt) << " ";
@@ -84,6 +115,7 @@ double ArithmeticEvaluator::evalFunction(int indexFunc, double value) {
 }
 
 double ArithmeticEvaluator::evaluate() throw(int) {
+  errorMessage = "";
   QStack<double> stack;
   bool ok;
   double value1,value2;
@@ -102,7 +134,11 @@ double ArithmeticEvaluator::evaluate() throw(int) {
       stack.push(evalFunction(idFunc,value1));
     }
     else if (varMarkers.contains(c)) {
-      if (!varValues.contains(elt)) throw(-index);
+      if (!varValues.contains(elt)) {
+        errorMessage = "cannot find value of ";
+        errorMessage += qPrintable(elt);
+        throw(-index);
+      }
       stack.push(varValues.value(elt));
     }
     else if (opMarkers.contains(c)) {
@@ -166,18 +202,14 @@ double ArithmeticEvaluator::evaluate() throw(int) {
 
 void ArithmeticEvaluator::convert(const QString& _expression) throw(int) {
   
-  QString expr = _expression;  
-  cout << "converting " << qPrintable(expr) << endl;
+  QString expr = _expression;    
   QString result="";
-  expr.remove(QChar(' '), Qt::CaseInsensitive);
-  cout << "converting " << qPrintable(expr) << endl;
-  foreach(QString func, fctMarkers) {
-    cout << "for " << qPrintable(func) << endl;
+  expr.remove(QChar(' '), Qt::CaseInsensitive);  
+  foreach(QString func, fctMarkers) {    
     QString rep = QString("\x1b%1").arg(fctMarkers.indexOf(QRegExp(func)));
 
     expr.replace(QRegExp(func),rep);
-  }
-  cout << "packed expr: " << qPrintable(expr) << endl;
+  }  
 
   int offset = 0;
   try {
@@ -379,7 +411,7 @@ QString ArithmeticEvaluator::getVariable(const QString& _expression, int offset,
     *size = 1;
   }
 
-  while ((_expression[i].isLetterOrNumber()) || (_expression[i] == '-') || (_expression[i] == '_')) {
+  while ((_expression[i].isLetterOrNumber()) || (_expression[i] == '_')) {
     number.append(_expression[i]);
     i += 1;
     *size += 1;
diff --git a/ArithmeticEvaluator.h b/ArithmeticEvaluator.h
index f6d478b..67f50a5 100644
--- a/ArithmeticEvaluator.h
+++ b/ArithmeticEvaluator.h
@@ -30,16 +30,22 @@ public:
   ArithmeticEvaluator();
   ArithmeticEvaluator(const QString& _expression) throw(int);
 
+  //getters
+  inline QList<QString> getVariableNames() { return varNames; }
+  
+  // setters
   void setExpression(const QString& _expression) throw(int);
-  inline void setVariablesValue(const QHash<QString,double>& _varValues) { varValues =  _varValues; }
+  void setVariablesValue(const QHash<QString,double>& _varValues);
   inline void setVariableValue(const QString& var, double value) { varValues.insert(var,value); }
   inline void setVariableMarkers(const QString& _markers) { varMarkers = _markers; }
 
   void print();
   double evaluate() throw(int);
+  inline QString getError() { return errorMessage; }
 
 protected:
   QStringList expression;
+  QList<QString> varNames; // the names of variables that ARE in the expression
   QHash<QString,double> varValues;
   QString varMarkers; // a sequence of symbols that are allowed to start a variable. $ is by default
   QString opMarkers; // a sequence if symbols used as operators. +-*/ is the hard-coded default
@@ -54,6 +60,10 @@ protected:
   bool checkAfterPar(const QString& _expression, int offset);
 
   double evalFunction(int indexFunc, double value);
+  
+  void setVariableNames(const QString &_expression);
+  
+  QString errorMessage;
 
 };
 
diff --git a/BlockImplementation.cpp b/BlockImplementation.cpp
index e6b61ca..b751021 100644
--- a/BlockImplementation.cpp
+++ b/BlockImplementation.cpp
@@ -52,8 +52,9 @@ void BlockImplementation::loadPatterns(QDomElement& root) throw(Exception) {
   }
   
   QDomElement eltProd  = eltCons.nextSiblingElement("production");
+  
   productionCounter = eltProd.attribute("counter","none");
-  QDomNodeList listNodeOutput = eltCons.elementsByTagName("output");
+  QDomNodeList listNodeOutput = eltProd.elementsByTagName("output");
   for(int i=0; i<listNodeOutput.size(); i++) {
     QDomNode node = listNodeOutput.at(i);    
     QDomElement elt = node.toElement();        
@@ -62,6 +63,12 @@ void BlockImplementation::loadPatterns(QDomElement& root) throw(Exception) {
     QString patternStr = elt.attribute("pattern","none");    
     productionPattern.insert(nameStr,patternStr);    
   }
+  cout << "patterns summary:" << endl;
+  QHashIterator<QString,QString> iterP(productionPattern);
+  while (iterP.hasNext()) {
+    iterP.next();
+    cout << qPrintable(iterP.key()) << " -> " << qPrintable(iterP.value()) << endl;
+  }
   cout << "impls patterns read correctly" << endl;
 }
 
diff --git a/BoxItem.cpp b/BoxItem.cpp
index 568e946..c473e6f 100644
--- a/BoxItem.cpp
+++ b/BoxItem.cpp
@@ -504,6 +504,7 @@ void BoxItem::contextMenuEvent(QGraphicsSceneContextMenuEvent * event) {
   QAction* showRstClkIface = NULL;
   QAction* showWishboneIface = NULL;
   QAction* showParameters = NULL;
+  QAction* showPatterns = NULL;
 
   InterfaceItem* ifaceItem = getInterfaceItemFromCursor(event->pos().x(), event->pos().y());
   // menu for interface
@@ -550,6 +551,9 @@ void BoxItem::contextMenuEvent(QGraphicsSceneContextMenuEvent * event) {
         }
       }      
     }
+    if ((iface->getAssociatedIface() != NULL) && (iface->getDirection() == AbstractInterface::Output)) {
+      showPatterns = menu.addAction("Show patterns");
+    }
   }
   // menu for blocks (group or func)
   else {
@@ -624,13 +628,12 @@ void BoxItem::contextMenuEvent(QGraphicsSceneContextMenuEvent * event) {
   else if(selectedAction == showWishboneIface) {
     dispatcher->showWishboneIface(this);
   }
-  else if(selectedAction == showParameters) {
-    if (refBlock->isFunctionalBlock()) {
-      FunctionalBlock* fun = AB_TO_FUN(refBlock);
-      fun->createDelta();
-    }
+  else if(selectedAction == showParameters) {    
     new ParametersWindow(refBlock, params, NULL);
-  }    
+  }
+  else if(selectedAction == showPatterns) {    
+    dispatcher->showPatterns(ifaceItem);
+  }
 }
 
 void BoxItem::loadFunctional(QDomElement funcElement) throw(Exception) {
@@ -826,7 +829,7 @@ void BoxItem::save(QXmlStreamWriter &writer) {
 
     writer.writeAttribute("id",QString::number(id));
     writer.writeAttribute("inside_group",QString::number(childGroupItem->getId()));
-    QString attrPos = QString::number(pos().x()).append(",").append(QString::number(pos().y()));
+    QString attrPos = QString::number((int)(pos().x())).append(",").append(QString::number((int)(pos().y())));
     writer.writeAttribute("position",attrPos);
     QString attrDim = QString::number(getWidth()).append(",").append(QString::number(getHeight()));
     writer.writeAttribute("dimension",attrDim);
diff --git a/ConnectedInterface.h b/ConnectedInterface.h
index cfea68c..84066a6 100644
--- a/ConnectedInterface.h
+++ b/ConnectedInterface.h
@@ -24,11 +24,14 @@ public :
 
   ConnectedInterface(AbstractBlock* _owner);
   ConnectedInterface(AbstractBlock* _owner, const QString& _name, const QString& _type, const QString& _width, int _direction, int _purpose);
+  
   // getters
   inline QList<ConnectedInterface*> getConnectedTo() { return connectedTo;}
   inline ConnectedInterface* getConnectedFrom() { return connectedFrom;}
+  inline QList<char> getOutputPattern() { return outputPattern; }  
 
   // setters
+  inline void setOutputPattern(QList<char> pattern) { outputPattern = pattern; }
 
   // testers
   inline bool isConnectedTo(){return connectedTo.length() != 0;}
@@ -66,6 +69,9 @@ protected:
    * this interface. connecteFrom references such an interface if it exists.
    */
   ConnectedInterface* connectedFrom;  
+  
+  // patterns  
+  QList<char> outputPattern; //! only usefull for output interfaces
 };
 
 
diff --git a/Dispatcher.cpp b/Dispatcher.cpp
index 9035183..4cd112d 100644
--- a/Dispatcher.cpp
+++ b/Dispatcher.cpp
@@ -94,26 +94,12 @@ bool Dispatcher::createConnection(InterfaceItem *iface1, InterfaceItem *iface2)
 
   // test the ref1->ref2 connection
   if ((ref1->canConnectTo(ref2)) && (ref2->canConnectFrom(ref1))) {
-    ref1->connectTo(ref2);
-    /*
-    ref2->connectFrom(ref1);
-    if ((asso1 != NULL) && (asso2 != NULL)) {
-      asso1->connectTo(asso2);
-      asso2->connectFrom(asso1);
-    }
-    */
+    ref1->connectTo(ref2);    
     ok1 = true;
   }
   // if the frist one did not work, test ref2->ref1
   if ((ok1 == false) && (ref2->canConnectTo(ref1)) && (ref1->canConnectFrom(ref2))) {  
-    ref2->connectTo(ref1);
-    /*
-    ref1->connectFrom(ref2);
-    if ((asso1 != NULL) && (asso2 != NULL)) {
-      asso1->connectFrom(asso2);
-      asso2->connectTo(asso1);
-    }
-    */
+    ref2->connectTo(ref1);    
     ok2 = true;
   }
   if ((ok1 == true) || (ok2 == true)) {
@@ -122,6 +108,7 @@ bool Dispatcher::createConnection(InterfaceItem *iface1, InterfaceItem *iface2)
 
     unselectAllItems();
     params->unsaveModif = true;
+    cout << "created a connection from " << qPrintable(ref1->getName()) << " to " << qPrintable(ref2->getName()) << endl;
     return true;
   }
   return false;
@@ -351,6 +338,18 @@ void Dispatcher::renameInterface(InterfaceItem *item) {
   item->getOwner()->nameChanged();  
 }
 
+void Dispatcher::showPatterns(InterfaceItem *item) {
+  static QString fctName = "Dispatcher::showPatterns()";
+#ifdef DEBUG_FCTNAME
+  cout << "call to " << qPrintable(fctName) << endl;
+#endif
+  ConnectedInterface* iface = AI_TO_CON(item->refInter->getAssociatedIface());
+  foreach(char c, iface->getOutputPattern()) {
+    cout << (int)c;
+  }
+  cout << endl;
+}
+
 void Dispatcher::duplicateBoxItem(BoxItem *item){
   static QString fctName = "Dispatcher::duplicateBoxItem()";
 #ifdef DEBUG_FCTNAME
diff --git a/Dispatcher.h b/Dispatcher.h
index 3181137..75583d4 100644
--- a/Dispatcher.h
+++ b/Dispatcher.h
@@ -112,6 +112,7 @@ public slots:
   void duplicateInterfaceItem(InterfaceItem* item);
   void showProperties(InterfaceItem *inter);
   void renameInterface(InterfaceItem* item);
+  void showPatterns(InterfaceItem* item);
 
   // connection ops
   bool createConnection(InterfaceItem *iface1, InterfaceItem *iface2);    
diff --git a/FunctionalBlock.cpp b/FunctionalBlock.cpp
index 5731794..0db21c4 100644
--- a/FunctionalBlock.cpp
+++ b/FunctionalBlock.cpp
@@ -5,6 +5,7 @@
 #include "FunctionalInterface.h"
 #include "ReferenceInterface.h"
 #include "BlockParameter.h"
+#include "ArithmeticEvaluator.h"
 
 
 FunctionalBlock::FunctionalBlock(GroupBlock *_parent, ReferenceBlock *_reference) throw(Exception) :  AbstractBlock() {
@@ -114,82 +115,311 @@ QString FunctionalBlock::getReferenceHashMd5() {
 }
 
 bool FunctionalBlock::createPatterns() {
+  static QString fctName = "FunctionalBlock::createPatterns()";
+#ifdef DEBUG_FCTNAME
+  cout << "call to " << qPrintable(fctName) << endl;
+#endif
+  
+  cout << "create patterns for block " << qPrintable(name) << endl;
   evaluator = new ArithmeticEvaluator();
   bool ok = true;
   ok = ok & createDelta();
-  if (ok) ok = ok & createConsumptionPattern();
-  if (ok) ok = ok & createProductionCounter();
+  if (! isGeneratorBlock()) {
+    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;
+  static QString fctName = "FunctionalBlock::createDelta()";
+#ifdef DEBUG_FCTNAME
+  cout << "call to " << qPrintable(fctName) << endl;
+#endif 
+  
+  QString deltaStr = implementation->getDelta();
+  cout << "delta for " << qPrintable(name) << " = " << qPrintable(deltaStr) << endl;
   
   // look for parameter names
-  QHash<QString,double> 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<QString,double> 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;
+  bool ok = true;
+  double result = evaluateExpression(deltaStr, &ok);
+  if (!ok) return false;
+  
+  delta = result;
+  cout << "delta = " << delta << endl;
    
   return true;
 }
 
 bool FunctionalBlock::createConsumptionPattern() {
+  static QString fctName = "FunctionalBlock::createConsumptionPattern()";
+#ifdef DEBUG_FCTNAME
+  cout << "call to " << qPrintable(fctName) << endl;
+#endif
+  
+  bool ok = true; 
+  QHash<QString,QString> consPattern = implementation->getConsumptionPattern();  
+  
+  foreach(AbstractInterface* iface, getControlInputs()) {       
+    FunctionalInterface* connIface = AI_TO_FUN(iface);
+    QString refName = connIface->getReference()->getName();    
+    if (! consPattern.contains(refName)) {
+      cerr << "no consumption pattern for reference interface " << qPrintable(refName) << endl;
+      return false;
+    }
+    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;
+    
+  }        
   return true;
 }
 
-bool FunctionalBlock::createProductionPattern() {
+bool FunctionalBlock::createProductionPattern() {  
+  static QString fctName = "FunctionalBlock::createProductionPattern()";
+#ifdef DEBUG_FCTNAME
+  cout << "call to " << qPrintable(fctName) << endl;
+#endif
+  
+  bool ok = true; 
+  QHash<QString,QString> prodPattern = implementation->getProductionPattern();  
+  
+  foreach(AbstractInterface* iface, getControlOutputs()) {    
+    FunctionalInterface* connIface = AI_TO_FUN(iface);
+    QString refName = connIface->getReference()->getName();    
+    if (! prodPattern.contains(refName)) {
+      cerr << "no production pattern for reference interface " << qPrintable(refName) << endl;
+      return false;
+    }
+    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;
+    
+  }    
   return true;
 }
 
 bool FunctionalBlock::createProductionCounter() {
+  static QString fctName = "FunctionalBlock::createProductionCounter()";
+#ifdef DEBUG_FCTNAME
+  cout << "call to " << qPrintable(fctName) << endl;
+#endif
+  
+  QStringList counterParts = implementation->getProductionCounter().split(",");
+  foreach(QString s, counterParts) {
+    cout << "cont part = " << qPrintable(s) << endl;
+    bool ok;
+    double val = s.toDouble(&ok);
+    if (ok) {
+      productionCounter.append(val);
+    }
+    else if (s.at(0) == '{') {
+      s.remove(0,1);
+      s.chop(1);
+      QStringList gen = s.split(":");
+      if (gen.size() != 3) return false;
+      int start = 0;
+      int nb = 0;
+      int step = 0;
+      for(int i=0;i<3;i++) {
+        bool okVal;
+        double result = evaluateExpression(gen.at(i),&okVal);
+        if (!okVal) return false;
+        if (i==0) start = result;
+        else if (i==1) nb = result;
+        else if (i==2) step = result;
+      }
+      for(int j=0;j<nb;j++) {
+        productionCounter.append(start+j*step);
+      }
+    }
+    else {
+      bool okVal;
+      double result = evaluateExpression(s,&okVal);
+      
+      if (!okVal) return false;
+      productionCounter.append(result);      
+    }
+  }
+  foreach(int val, productionCounter) {
+    cout << val << ",";
+  }
+  cout << endl;
+  
   return true;
 }
 
+QList<char> FunctionalBlock::expandPattern(const QString& pattern, bool* ok) {
+  static QString fctName = "FunctionalBlock::expandPattern()";
+#ifdef DEBUG_FCTNAME
+  cout << "call to " << qPrintable(fctName) << endl;
+#endif
+  
+  QList<char> lst;
+  QString  p = pattern;
+  p.append(')');
+  int offset = 0;
+  lst = expandPatternRecur(p,&offset,ok);   
+  return lst;
+}
+
+QList<char> FunctionalBlock::expandPatternRecur(const QString& pattern, int *offset, bool *ok) {
+  
+  QList<char> currentGroup; 
+  
+  while ((*offset < pattern.size()) && (pattern.at(*offset) != ')')) {
+    
+    QChar c = pattern.at(*offset);
+    if (c == '(') {
+      *offset += 1;
+      currentGroup += expandPatternRecur(pattern,offset, ok);
+      if (!ok) {
+        return currentGroup;
+      }
+    }
+    else if (c == '0') {
+      currentGroup.append(0);
+    }
+    else if (c == '1') {
+      currentGroup.append(1);
+    }
+    else if (c == 'X') {
+      currentGroup.append(-1);
+    }
+    else if (c == '{') {
+      *offset += 1;
+      QString expr = "";      
+      while ((*offset < pattern.size()) && (pattern.at(*offset) != '}')) {
+        expr += pattern.at(*offset);        
+        *offset += 1;
+      }
+      if (*offset == pattern.size()) {
+        *ok = false;
+        return currentGroup;
+      }
+      double repeat = evaluateExpression(expr,ok);
+      if (!ok) {
+        return currentGroup;      
+      }            
+      // repeat just the last value in currentGroup
+      char last = currentGroup.last();      
+      //cout << "repeat last char " << repeat << " times : " << (int)last << endl;
+      
+      for(int i=1;i<(int)repeat;i++) {
+        currentGroup += last;
+      }
+    }    
+    *offset += 1;
+  }
+  
+  // must check if after ), there is a {
+  if ((*offset < pattern.size()-1) && (pattern.at(*offset+1) == '{')) {
+    *offset += 2;
+    QString expr = "";      
+    while ((*offset < pattern.size()) && (pattern.at(*offset) != '}')) {
+      expr += pattern.at(*offset);        
+      *offset += 1;
+    }
+    if (*offset == pattern.size()) {
+      *ok = false;
+      return currentGroup;
+    }
+    double repeat = evaluateExpression(expr,ok);
+    if (!ok) {
+      return currentGroup;      
+    }
+    /*
+    cout << "repeat last group " << repeat << " times : ";
+    foreach (char c, currentGroup) cout <<(int)c;
+    cout << endl;  
+    */
+    QList<char> single = currentGroup;
+    for(int i=1;i<(int)repeat;i++) {
+      currentGroup += single;
+    }    
+  }
+  //*offset += 1;
+  return currentGroup;
+}
+
+double FunctionalBlock::evaluateExpression(const QString& expression, bool* ok) {
+  static QString fctName = "FunctionalBlock::evaluateExpression()";
+#ifdef DEBUG_FCTNAME
+  cout << "call to " << qPrintable(fctName) << endl;
+#endif
+  
+  *ok = true;
+  QHash<QString,double> vars;
+  evaluator->setExpression(expression);
+  QList<QString> varNames = evaluator->getVariableNames();
+  foreach (QString name, varNames) {
+    QString paramName = name;
+    paramName.remove(0,1);
+    BlockParameter* param = reference->getParameterFromName(paramName);    
+    if (param == NULL) {
+      cerr << "found an unknown parameter in delta"<< endl;
+      *ok = false;
+      return 0.0;
+    }
+    bool okVal;
+    int val = param->getDoubleValue(&okVal);
+    if (!okVal) {
+      cerr << "cannot obtain double value of paramter " << qPrintable(paramName) << endl;
+      *ok = false;
+      return 0.0;
+    }
+    vars.insert(name,(double)val);    
+  }  
+  evaluator->setVariablesValue(vars);
+  double result;
+  try {
+    result = evaluator->evaluate();
+  }
+  catch(int index) {
+    cerr << "Error at index " << index << ": " << qPrintable(evaluator->getError()) << endl;
+    *ok = false;
+    return 0.0;
+  }
+  return result;
+}
+
 bool FunctionalBlock::computeOutputPattern(int nbExec) {
+  static QString fctName = "FunctionalBlock::computeOutputPattern()";
+#ifdef DEBUG_FCTNAME
+  cout << "call to " << qPrintable(fctName) << endl;
+#endif
   
   /* case 1: the block is a generator for which output pattern
      must be computed for a nbExec following executions
   */
   
+  
   if (nbExec > 0) {
+    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 += iface->getProductionPattern();
-      iface->setOutputPattern(pattern);
+      for(int i=0;i<nbExec;i++) pattern += connIface->getProductionPattern();
+      connIface->setOutputPattern(pattern);
     }    
   }
   else {
-    // initialize consumption and production patterns
+    cout << "computing output pattern of " << qPrintable(name) << endl;
+    
+    // initialize consumption and production patterns    
     initConsumptionPattern();
     initProductionPattern();
     
@@ -199,7 +429,8 @@ bool FunctionalBlock::computeOutputPattern(int nbExec) {
     inputPattern = new char*[nbConsumingPorts];
     int minLen = -1;
     foreach(AbstractInterface* iface, getControlInputs()) {      
-      QList<char> in = iface->getConnectedFrom()->getOutputPattern();
+      ConnectedInterface* connIface = AI_TO_CON(iface);
+      QList<char> in = connIface->getConnectedFrom()->getOutputPattern();
       if (minLen == -1) {
         minLen = in.size();
       }
@@ -224,22 +455,26 @@ bool FunctionalBlock::computeOutputPattern(int nbExec) {
       delete [] inputPattern;
       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()) {
-      lengthOP = minLen+iface->getProductionPattern().size();
+      FunctionalInterface* connIface = AI_TO_FUN(iface);
+      lengthOP = minLen+connIface->getProductionPattern().size();
       outputPattern[idIface] = new char[lengthOP];
       memset(outputPattern[idIface],0,lengthOP);
       idIface += 1;
     }
+    cout << "output pattern array initialized" << endl;
     
     int clock = 0;
     nbExec = 0;
     // search for the beginning of the first execution.
-    while (! isValidDataGroup(inputPattern,nbConsumingPorts,clock)) clock++;
+    while ((clock < minLen) && (! isValidDataGroup(inputPattern,nbConsumingPorts,clock))) clock++;
+    cout << "found 1st exec clock: " << clock << endl;
     
     while (clock < minLen) {
       // initialize counters for current execution.
@@ -274,7 +509,7 @@ bool FunctionalBlock::computeOutputPattern(int nbExec) {
         
         // search for PC(m) valid input group in IP
         while (ncp < productionCounter.at(m)) {
-          if (isValidDataGroup(consumptionPattern,nbConsumingPorts,ccp)) cip += 1;
+          if (isValidDataGroup(consumptionPattern,nbConsumingPorts,ccp)) ncp += 1;
           ccp += 1;
           gap -= 1;
         }
@@ -300,12 +535,15 @@ bool FunctionalBlock::computeOutputPattern(int nbExec) {
     // 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]);
-      iface->setOutputPattern(pattern);      
+      connIface->setOutputPattern(pattern);      
       idIface += 1;
     }
     
@@ -358,14 +596,19 @@ void FunctionalBlock::clearProductionPattern() {
 }
 
 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()) {
-    
-    QList<char> in = iface->getConsumptionPattern();
+    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;
@@ -375,14 +618,19 @@ void FunctionalBlock::initConsumptionPattern() {
 }
 
 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()) {
-    
-    QList<char> in = iface->getProductionPattern();
+    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;
diff --git a/FunctionalBlock.h b/FunctionalBlock.h
index f898990..b6ac65f 100644
--- a/FunctionalBlock.h
+++ b/FunctionalBlock.h
@@ -30,9 +30,14 @@ public:
 
   // getters
   inline ReferenceBlock* getReference() { return reference; }
-
+  inline QList<int> getProductionCounter() { return productionCounter; }
+  inline int getDelta() { return delta; }
+  
   // setters
   inline void setImplementation(BlockImplementation* impl) { implementation = impl; }
+  inline void setProductionCounter(QList<int> pattern) { productionCounter = pattern; }
+  inline void setDelta(int _delta) { delta = _delta; }
+  
 
   // testers
   bool isFunctionalBlock();
@@ -56,11 +61,14 @@ public:
   void initProductionPattern(); // initialize a char** from patterns defined for each interface
   void clearConsumptionPattern();
   void clearProductionPattern();
+  bool computeOutputPattern(int nbExec = -1);
   
 private:  
-  // patterns
-  bool computeOutputPattern(int nbExec = -1);
+  // patterns  
   bool isValidDataGroup(char** pattern, int nbPorts, int clock);
+  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);
   /*!
    * \brief combinePatterns
    * \param patternSrc the pattern that must be combined with patternDest (patternDest = patternDest OR patternSrc)  
@@ -74,6 +82,9 @@ private:
    */
   void combinePatterns(char** patternSrc, int srcCol, char** patternDest, int destCol, int nbCols, int nbPorts );
 
+  QList<int> productionCounter; //! only usefull for output interfaces
+  int delta;
+  
   char** consumptionPattern;
   int nbConsumingPorts;
   int lengthCP;
diff --git a/FunctionalInterface.cpp b/FunctionalInterface.cpp
index 495d60e..145b86a 100644
--- a/FunctionalInterface.cpp
+++ b/FunctionalInterface.cpp
@@ -101,7 +101,8 @@ bool FunctionalInterface::canConnectTo(AbstractInterface *iface) {
   */
   if (direction == Input) return false;
   if (iface->isReferenceInterface()) return false;
-  if (iface->getConnectedFrom() != NULL) return false;
+  ConnectedInterface* connIface = AI_TO_CON(iface);
+  if (connIface->getConnectedFrom() != NULL) return false;
   // first case: interface of blocks within the same group
   if (getOwner()->getParent() == iface->getOwner()->getParent()) {
 
diff --git a/FunctionalInterface.h b/FunctionalInterface.h
index 1dfa726..b87e2c7 100644
--- a/FunctionalInterface.h
+++ b/FunctionalInterface.h
@@ -35,8 +35,12 @@ public :
 
   // getters
   inline ReferenceInterface* getReference() { return reference; }
+  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; }  
 
   // testers
   bool isFunctionalInterface();
@@ -53,7 +57,10 @@ public :
 private:
 
   ReferenceInterface* reference;  
-
+  
+  //patterns
+  QList<char> consumptionPattern; //! only usefull for input interfaces
+  QList<char> productionPattern; //! only usefull for output interfaces  
 };
 
 #endif // __FUNCTIONALINTERFACE_H__
diff --git a/Graph.cpp b/Graph.cpp
index d3fd276..999e72a 100644
--- a/Graph.cpp
+++ b/Graph.cpp
@@ -141,3 +141,34 @@ void Graph::resetPatternComputed() {
     }
   }
 }
+
+bool Graph::computeOutputPatterns(int nbExec) {
+  
+  createPatterns();
+  resetPatternComputed();  
+  // search for all block that are generators.
+  QList<FunctionalBlock*> generators;
+  generators.append(sources);
+  foreach(AbstractBlock* block, groups) {    
+    GroupBlock* group = AB_TO_GRP(block);    
+    foreach(AbstractBlock* inBlock, group->getBlocks()) {
+      FunctionalBlock* funBlock = AB_TO_FUN(inBlock);
+      if ((inBlock->isFunctionalBlock()) && (inBlock->isGeneratorBlock())) {
+        generators.append(funBlock);
+      }
+    }    
+  }
+  // search for maximum delta
+  int maxDelta = 0;
+  foreach(FunctionalBlock* block, generators) {    
+    if (block->getDelta() > maxDelta) maxDelta = block->getDelta();
+  }
+  // compute output for generators
+  int maxExecLen = maxDelta*nbExec;
+  foreach(FunctionalBlock* block, generators) {    
+    int d = block->getDelta();
+    block->computeOutputPattern((maxExecLen+d-1)/d);
+  }
+  // compute output for top group
+  topGroup->computeOutputPattern();
+}
diff --git a/Graph.h b/Graph.h
index b2b8078..f3e9923 100644
--- a/Graph.h
+++ b/Graph.h
@@ -52,6 +52,7 @@ public:
    */
   bool createPatterns();
   void resetPatternComputed();
+  bool computeOutputPatterns(int nbExec);
   
   
 private:  
diff --git a/GroupBlock.cpp b/GroupBlock.cpp
index a8a06e6..474d5dc 100644
--- a/GroupBlock.cpp
+++ b/GroupBlock.cpp
@@ -107,20 +107,29 @@ void GroupBlock::removeGenericParameter(QString name) {
 
 void GroupBlock::initInputPattern() {
   foreach(AbstractInterface* iface, getControlInputs()) {
-    iface->setOutputPattern(iface->getConnectedFrom()->getOutputPattern());    
+    ConnectedInterface* connIface = AI_TO_CON(iface);
+    connIface->setOutputPattern(connIface->getConnectedFrom()->getOutputPattern());    
   }  
 }
 
 bool GroupBlock::computeOutputPattern(int nbExec) {
+
+  static QString fctName = "GroupBlock::computeOutputPattern()";
+#ifdef DEBUG_FCTNAME
+  cout << "call to " << qPrintable(fctName) << endl;
+#endif
+
+  cout << "computing output pattern of group " << qPrintable(name) << endl;
   
   bool canCompute = true;
   // get the input pattern on each inputs
   initInputPattern();
   
+  cout << "Input pattern OK" << endl;
   // find blocks that are connected to that inputs and generators
   QList<AbstractBlock*> fifo;
   foreach(AbstractBlock* block, blocks) {
-    
+        
     bool addIt = false;
     // if a block is a generator and has control outputs, add it
     if (block->isGeneratorBlock()) {
@@ -129,19 +138,27 @@ bool GroupBlock::computeOutputPattern(int nbExec) {
     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) {
+        //cout << qPrintable(iface->getName()) << " of " << qPrintable(iface->getOwner()->getName()) << " connected to " << endl;       
+        ConnectedInterface* connFrom = ((ConnectedInterface*)iface)->getConnectedFrom();
+        //cout << qPrintable(connFrom->getName()) << " of " << qPrintable(connFrom->getOwner()->getName()) << endl;
+        
+        if (connFrom->getOwner() == this) {
           addIt = true;
           break;
         }
       }
     }
-    if (addIt) fifo.append(block);    
+    if (addIt) {
+      cout << "adding " << qPrintable(block->getName()) << " to initialize the FIFO" << endl;
+      fifo.append(block);    
+    }
   }
+  
   while (!fifo.isEmpty()) {
     AbstractBlock* block = fifo.takeFirst();
-    cout << "computing pattern for " << qPrintable(block->getName()) << endl;
+    
+    if (block->getPatternComputed()) continue; // block has laready been processed
+        
     canCompute = block->computeOutputPattern();
     if (!canCompute) {
       cout << "cannot finalize output pattern computation of " << qPrintable(block->getName()) << endl;
@@ -167,7 +184,8 @@ bool GroupBlock::computeOutputPattern(int nbExec) {
   
   if (canCompute) {
     foreach(AbstractInterface* iface, getControlOutputs()) {
-      iface->setOutputPattern(iface->getConnectedFrom()->getOutputPattern());    
+      ConnectedInterface* connIface = AI_TO_CON(iface);
+      connIface->setOutputPattern(connIface->getConnectedFrom()->getOutputPattern());    
     }
     setPatternComputed(true);
   }
diff --git a/GroupBlock.h b/GroupBlock.h
index 547159e..593b854 100644
--- a/GroupBlock.h
+++ b/GroupBlock.h
@@ -42,6 +42,7 @@ public:
   // public attributes
   static int counter;
 
+  bool computeOutputPattern(int nbExec = -1);
   
 private:    
   // patterns  
@@ -52,7 +53,7 @@ private:
    * found by taking the output pattern of the connectedFrom interface.
    */   
   void initInputPattern();
-  bool computeOutputPattern(int nbExec = -1);
+  
   
   bool topGroup;  
   QList<AbstractBlock*> blocks; // contains instances of FunctionalBlock or GroupBlock that are children of this group
diff --git a/GroupInterface.cpp b/GroupInterface.cpp
index 934ad08..ecc6ba7 100644
--- a/GroupInterface.cpp
+++ b/GroupInterface.cpp
@@ -41,7 +41,8 @@ bool GroupInterface::canConnectTo(AbstractInterface *iface) {
 
   */
   if (iface->isReferenceInterface()) return false;
-  if (iface->getConnectedFrom() != NULL) return false;
+  ConnectedInterface* connIface = AI_TO_CON(iface);
+  if (connIface->getConnectedFrom() != NULL) return false;
 
   if (this->getOwner() == iface->getOwner()->getParent()) {
     if ((direction == Input) && (iface->getDirection() == Input)) return true;
diff --git a/GroupItem.cpp b/GroupItem.cpp
index 38d70eb..3286c14 100644
--- a/GroupItem.cpp
+++ b/GroupItem.cpp
@@ -22,7 +22,7 @@ GroupItem::GroupItem(BoxItem *_parentItem,
 
   parentItem = _parentItem;
   if (parentItem != NULL) {
-    parentItem->setChildGroupItem(this);
+    parentItem->setChildGroupItem(this);    
   }
 
   /*
@@ -618,7 +618,7 @@ void GroupItem::load(QDomElement groupElement) throw(Exception) {
   if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));
 
   QString nameStr = groupElement.attribute("name","none");
-  if(nameStr == "none") throw(Exception(PROJECTFILE_CORRUPTED));
+  if(nameStr == "none") throw(Exception(PROJECTFILE_CORRUPTED));    
 
   QStringList positionStr = groupElement.attribute("position","none").split(",");
   if(positionStr.length() != 2) throw(Exception(PROJECTFILE_CORRUPTED));
@@ -651,6 +651,10 @@ void GroupItem::load(QDomElement groupElement) throw(Exception) {
     QString name = currentInterfaceNode.attribute("name","none");
     if(name == "none") throw(Exception(PROJECTFILE_CORRUPTED));
 
+    QString purposeStr = currentInterfaceNode.attribute("purpose","none");
+    int purpose = AbstractInterface::getIntPurpose(purposeStr);
+    if(purpose == -1) throw(Exception(PROJECTFILE_CORRUPTED));
+    
     QString directionStr = currentInterfaceNode.attribute("direction","none");
     int direction = AbstractInterface::getIntDirection(directionStr);
     if(direction == -1) throw(Exception(PROJECTFILE_CORRUPTED));
@@ -661,13 +665,16 @@ void GroupItem::load(QDomElement groupElement) throw(Exception) {
 
     double position = currentInterfaceNode.attribute("position","none").toDouble(&ok);
     if(!ok) throw(Exception(PROJECTFILE_CORRUPTED));
-
-    GroupInterface *groupInterface = new GroupInterface(groupBlock,name,direction,AbstractInterface::Data);
-
-    InterfaceItem *interfaceItem = new InterfaceItem(position,orientation,groupInterface,this,params);
+    
+    GroupInterface *groupIface = new GroupInterface(groupBlock,name,direction,purpose);
+    GroupInterface *groupCtlIface = new GroupInterface(groupBlock,name+"_enb",direction,AbstractInterface::Control);
+    groupCtlIface->setAssociatedIface(groupIface);
+    
+    InterfaceItem *interfaceItem = new InterfaceItem(position,orientation,groupIface,this,params);
     interfaceItem->setId(id);
 
-    groupBlock->addInterface(groupInterface);
+    groupBlock->addInterface(groupIface);
+    groupBlock->addInterface(groupCtlIface);
     addInterfaceItem(interfaceItem, false);
     cout << "interface add to " << groupBlock->getName().toStdString() << endl;
   }
@@ -703,6 +710,7 @@ void GroupItem::save(QXmlStreamWriter &writer) {
 
     writer.writeAttribute("id",QString::number(item->getId()));
     writer.writeAttribute("name",item->getName());    
+    writer.writeAttribute("purpose",QString(item->refInter->getPurposeString()));    
     writer.writeAttribute("direction",QString(item->refInter->getDirectionString()));
     writer.writeAttribute("orientation",item->getStrOrientation());
     writer.writeAttribute("position",QString::number(item->getPositionRatio()));
diff --git a/GroupScene.cpp b/GroupScene.cpp
index 7fddacd..48de27e 100644
--- a/GroupScene.cpp
+++ b/GroupScene.cpp
@@ -61,6 +61,11 @@ QList<BoxItem *> GroupScene::getSelectedBlocks() {
 int GroupScene::setItemsId(int countInit) {
   int counter = countInit;
   groupItem->setId(counter++);
+  if (isTopScene()) {
+    foreach(SourceItem *item, sourceItems){
+      item->setId(counter++);
+    } 
+  }
   foreach(BoxItem *item, boxItems){
     item->setId(counter++);
   }
@@ -72,6 +77,13 @@ int GroupScene::setInterfacesId(int countInit) {
   foreach(InterfaceItem* inter, groupItem->getInterfaces()){
     inter->setId(counter++);
   }
+  if (isTopScene()) {
+    foreach(SourceItem *item, sourceItems){
+      foreach(InterfaceItem* inter, item->getInterfaces()){
+        inter->setId(counter++);
+      }
+    } 
+  }
   foreach(BoxItem *item, boxItems){
     foreach(InterfaceItem* inter, item->getInterfaces()){
       inter->setId(counter++);
@@ -129,6 +141,9 @@ SourceItem *GroupScene::createSourceItem(AbstractBlock *block) {
 }
 
 void GroupScene::addSourceItem(SourceItem* item) {  
+  // adding item to the scene
+  addItem(item);
+  item->setZValue(1);  
   // add item from the QList
   sourceItems.append(item);  
 }
diff --git a/GroupWidget.cpp b/GroupWidget.cpp
index 0705632..318e596 100644
--- a/GroupWidget.cpp
+++ b/GroupWidget.cpp
@@ -165,7 +165,7 @@ void GroupWidget::createToolbar() {
   toolbarEditMode->addWidget(butAddConnection);
   toolbarEditMode->addWidget(butEdit);
 
-  toolbarAdd->addAction(copyBlockAct);
+  //toolbarAdd->addAction(copyBlockAct);
   toolbarAdd->addAction(newEmptyGroupAct);
   toolbarAdd->addAction(newGroupAct);
 
diff --git a/MainWindow.cpp b/MainWindow.cpp
index 4be284b..877e9ac 100644
--- a/MainWindow.cpp
+++ b/MainWindow.cpp
@@ -373,7 +373,8 @@ void MainWindow::slotOpenBlockLibrary() {
 
 
 void MainWindow::slotGraphValidation() {
-  params->parametersValidation();
+  params->getGraph()->computeOutputPatterns(5);
+  //params->parametersValidation();
 }
 
 void MainWindow::addTopGroup(GroupWidget *_topGroup) {
diff --git a/Parameters.cpp b/Parameters.cpp
index 3cc8c14..322046d 100644
--- a/Parameters.cpp
+++ b/Parameters.cpp
@@ -9,6 +9,7 @@
 #include "GroupScene.h"
 #include "GroupItem.h"
 #include "BoxItem.h"
+#include "SourceItem.h"
 #include "InterfaceItem.h"
 #include "ConnectionItem.h"
 
@@ -232,6 +233,7 @@ GroupWidget *Parameters::loadProject(QDomElement root) throw(Exception) {
     if (idUpperScene != -1) {
       groupWidget->setWindowTitle(groupBlock->getName());
       groupWidget->show();
+      cout << qPrintable(groupItem->getRefBlock()->getName()) << " has upper box item in " << qPrintable(groupItem->getParentItem()->getScene()->getGroupItem()->getRefBlock()->getName()) << endl;
     }    
   }
   dispatcher->setSceneCounter(maxIdScene+1);
@@ -249,7 +251,29 @@ GroupWidget *Parameters::loadProject(QDomElement root) throw(Exception) {
     GroupScene *currentScene = searchSceneById(idScene,topScene);
 
     if(currentScene == NULL) throw(Exception(PROJECTFILE_CORRUPTED));
-
+    /**********************************************************
+     2.1 : getting sources if it is top scene
+    ***********************************************************/
+    if (currentScene->isTopScene()) {
+      QDomNodeList sourceNodes = currentSceneNode.elementsByTagName("source_item");
+      cout << "top scene has " << sourceNodes.length() << " sources" << endl;
+      for(int j=0; j<sourceNodes.length(); j++) {
+        QDomElement currentSBNode = sourceNodes.at(j).toElement();      
+        SourceItem* sourceItem = new SourceItem(dispatcher,this);
+        try {
+          sourceItem->load(currentSBNode);
+        }
+        catch(Exception err) {
+          throw(err);
+        }
+        cout << "source item has been read, add it to the scene" << endl;
+        // add the block to the GroupScene
+        currentScene->addSourceItem(sourceItem);
+      } 
+    }
+    /**********************************************************
+     2.2 : getting functional blocks
+    ***********************************************************/
     QDomNodeList functionalBlockNodes = currentSceneNode.elementsByTagName("bi_functional");
 
     for(int j=0; j<functionalBlockNodes.length(); j++) {
@@ -306,7 +330,7 @@ GroupWidget *Parameters::loadProject(QDomElement root) throw(Exception) {
       // get the GroupItem already created and set at phase 1
       GroupItem *insideGroup = searchGroupItemById(idGroup, topScene);
       BoxItem* upperItem = NULL;
-      if(insideGroup == NULL) cout << "group null" << endl;
+      if(insideGroup == NULL) cout << "group null" << endl;      
       // now search within the scene which BoxItem has a childItem that is = to insideGroup
       QList<BoxItem *> lst = currentScene->getBoxItems();
       foreach(BoxItem* item, lst) {
@@ -1022,6 +1046,15 @@ InterfaceItem* Parameters::searchInterfaceItemById(int id, GroupScene* scene) {
       return item;
     }
   }
+  if (scene->isTopScene()) {
+    foreach(SourceItem *block, scene->getSourceItems()){
+      foreach(InterfaceItem *item, block->getInterfaces()){
+        if(item->getId() == id){
+          return item;
+        }
+      }
+    } 
+  }
   foreach(BoxItem *block, scene->getBoxItems()){
     foreach(InterfaceItem *item, block->getInterfaces()){
       if(item->getId() == id){
diff --git a/ParametersWindow.cpp b/ParametersWindow.cpp
index 182460d..ee98880 100644
--- a/ParametersWindow.cpp
+++ b/ParametersWindow.cpp
@@ -60,8 +60,7 @@ void ParametersWindow::updateData()
   type->setText(param->getTypeString());
 }
 
-void ParametersWindow::save()
-{
+void ParametersWindow::save() {
   BlockParameter *param = block->getParameters().at(comboBox->currentIndex());
   param->setValue(value->text());  
 
diff --git a/ReferenceInterface.h b/ReferenceInterface.h
index 9ea4b23..d5219b6 100644
--- a/ReferenceInterface.h
+++ b/ReferenceInterface.h
@@ -22,8 +22,7 @@ public :
   ReferenceInterface(AbstractBlock* _owner, const QString& _name, const QString& _type, const QString& _width, int _direction, int _purpose, int _multiplicity=1) throw (Exception);
 
   // getters
-  inline int getMultiplicity() { return multiplicity; }
-  inline AbstractInterface* getConnectedFrom() { return NULL; }
+  inline int getMultiplicity() { return multiplicity; }  
   // setters
   void setMultiplicity(int _multiplicity);
 
diff --git a/SourceItem.cpp b/SourceItem.cpp
index 27db2a3..ca252c1 100644
--- a/SourceItem.cpp
+++ b/SourceItem.cpp
@@ -603,10 +603,9 @@ void SourceItem::load(QDomElement funcElement) throw(Exception) {
   else {
     reference = referenceMd5;
   }
-  
-  GroupBlock* parentGroupBlock = AB_TO_GRP(((GroupItem *)parentItem())->getRefBlock());
-  FunctionalBlock* functionalBlock = params->getGraph()->createFunctionalBlock(parentGroupBlock, reference);
-  /* NB: addFunctionalBlock creates all interfaces from the reference, which is annoying when
+    
+  FunctionalBlock* functionalBlock = params->getGraph()->createSourceBlock(reference);
+  /* NB: createSourceBlock creates all interfaces from the reference, which is annoying when
     reading bif_iface tags. Thus interface are all removed.
   */
   functionalBlock->setName(name);
@@ -617,7 +616,7 @@ void SourceItem::load(QDomElement funcElement) throw(Exception) {
   setId(id);
 
 
-  QDomNodeList blockParamNodes = funcElement.elementsByTagName("bif_parameter");
+  QDomNodeList blockParamNodes = funcElement.elementsByTagName("source_parameter");
   // setting parameters value
   for(int i=0; i<blockParamNodes.length(); i++){
     QDomElement currentBlockParamNode = blockParamNodes.at(i).toElement();
@@ -636,7 +635,7 @@ void SourceItem::load(QDomElement funcElement) throw(Exception) {
 
   // recreate all (non-control) interfaces because of some may have a multiplicity>1 with several examplars
   functionalBlock->removeAllInterfaces();
-  QDomNodeList interfaceNodes = funcElement.elementsByTagName("bif_iface");
+  QDomNodeList interfaceNodes = funcElement.elementsByTagName("source_iface");
   // setting interfaces (user name, and for multiplicity>1 may be create some new ones)
   for(int i=0; i<interfaceNodes.length(); i++) {
 
diff --git a/blast.creator.user b/blast.creator.user
index a4cb21c..d213478 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-12T16:46:10. -->
+<!-- Written by QtCreator 3.2.1, 2017-05-14T21:44:23. -->
 <qtcreator>
  <data>
   <variable>EnvironmentId</variable>
-  <value type="QByteArray">{1d077e47-e3a1-47fd-8b12-4de650e39df5}</value>
+  <value type="QByteArray">{c8006d66-d34f-42be-ad10-d0207752286d}</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">{451ee8a3-56ff-4aba-8a8e-3da882cc142e}</value>
+   <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">{2c9bf876-3476-44eb-8065-1f0844704dda}</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">/localhome/sdomas/Projet/Blast/code/blast</value>
+    <value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/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 de874d1..4c1457d 100644
--- a/lib/implementations/average-Nx3_impl.xml
+++ b/lib/implementations/average-Nx3_impl.xml
@@ -26,10 +26,10 @@
   <patterns>
     <delta value="$nb_data" />
     <consumption>
-      <input name="data_i" pattern="(1){$nb_data}" />
+      <input name="data_i_enb" pattern="1{$nb_data}" />
     </consumption>
-    <production counter="{2:$nb_data+2:1}">
-      <output name="data_o" pattern="00{$nb_data}" />
+    <production counter="{2:$nb_data:1}">
+      <output name="data_o_enb" pattern="0001{$nb_data}" />
     </production>
   </patterns>
 </block_impl>
diff --git a/lib/implementations/decimator-N_impl.xml b/lib/implementations/decimator-N_impl.xml
new file mode 100644
index 0000000..f68c396
--- /dev/null
+++ b/lib/implementations/decimator-N_impl.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<block_impl ref_name="decimator-N.xml" ref_md5="">
+  <comments>
+    <author firstname="stephane" lastname="Domas" mail="sdomas@univ-fcomte.fr" />
+    <date creation="2015-04-27" />
+    <related_files list=""/>
+    <description>
+      This component is a decimator of N-1 values out of N
+    </description>
+    <notes>
+      No notes
+    </notes>
+  </comments>
+
+  <libraries>
+    <library name="IEEE">
+      <package name="std_logic_1164" use="all"/>
+      <package name="numeric_std" use="all"/>
+    </library>
+  </libraries>
+
+  <architecture>
+    
+  </architecture>
+
+  <patterns>
+    <delta value="$nb_deci+1" />
+    <consumption>
+      <input name="data_i_enb" pattern="1{$nb_deci+1}" />
+    </consumption>
+    <production counter="1">
+      <output name="data_o_enb" pattern="010{$nb_deci}" />
+    </production>
+  </patterns>
+</block_impl>
diff --git a/lib/implementations/generator-cst_impl.xml b/lib/implementations/generator-cst_impl.xml
index 10b4299..0c94e16 100644
--- a/lib/implementations/generator-cst_impl.xml
+++ b/lib/implementations/generator-cst_impl.xml
@@ -28,7 +28,7 @@
     <consumption>
     </consumption>
     <production counter="">
-      <output name="data_o" pattern="1{$seq_length}X{$idle_length}" />
+      <output name="data_o_enb" pattern="1{$seq_length}X{$idle_length}" />
     </production>
   </patterns>
 </block_impl>
diff --git a/lib/implementations/generator-img_impl.xml b/lib/implementations/generator-img_impl.xml
new file mode 100644
index 0000000..d5f66f3
--- /dev/null
+++ b/lib/implementations/generator-img_impl.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<block_impl ref_name="generator-img.xml" ref_md5="">
+  <comments>
+    <author firstname="stephane" lastname="Domas" mail="sdomas@univ-fcomte.fr" />
+    <date creation="2015-05-10" />
+    <related_files list=""/>
+    <description>
+      This component is a generator of a RGB image, read in a CSV file
+    </description>
+    <notes>
+      No notes
+    </notes>
+  </comments>
+
+  <libraries>
+    <library name="IEEE">
+      <package name="std_logic_1164" use="all"/>
+      <package name="numeric_std" use="all"/>
+    </library>
+  </libraries>
+
+  <architecture>
+    
+  </architecture>
+
+  <patterns>
+    <delta value="($img_width+$row_idle)*$img_height" />
+    <consumption>
+    </consumption>
+    <production counter="1">
+      <output name="r_o_enb" pattern="(1{$img_width}0{$row_idle}){$img_height}" />
+      <output name="g_o_enb" pattern="(1{$img_width}0{$row_idle}){$img_height}" />
+      <output name="b_o_enb" pattern="(1{$img_width}0{$row_idle}){$img_height}" />
+    </production>
+  </patterns>
+</block_impl>
diff --git a/lib/implementations/impls.bmf b/lib/implementations/impls.bmf
index 15dfac4..d43a935 100644
Binary files a/lib/implementations/impls.bmf and b/lib/implementations/impls.bmf differ
diff --git a/lib/implementations/rgb216bits_impl.xml b/lib/implementations/rgb216bits_impl.xml
new file mode 100644
index 0000000..d5203d5
--- /dev/null
+++ b/lib/implementations/rgb216bits_impl.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<block_impl ref_name="rgb216bits.xml" ref_md5="">
+  <comments>
+    <author firstname="stephane" lastname="Domas" mail="sdomas@univ-fcomte.fr" />
+    <date creation="2015-04-27" />
+    <related_files list=""/>
+    <description>
+      This component converts a RGB pixel into a 16 bits pixel
+    </description>
+    <notes>
+      No notes
+    </notes>
+  </comments>
+
+  <libraries>
+    <library name="IEEE">
+      <package name="std_logic_1164" use="all"/>
+      <package name="numeric_std" use="all"/>
+    </library>
+  </libraries>
+
+  <architecture>
+    
+  </architecture>
+
+  <patterns>
+    <delta value="1" />
+    <consumption>
+      <input name="r_i_enb" pattern="1" />
+      <input name="g_i_enb" pattern="1" />
+      <input name="b_i_enb" pattern="1" />      
+    </consumption>
+    <production counter="1">
+      <output name="pix_o_enb" pattern="01" />
+    </production>
+  </patterns>
+</block_impl>
diff --git a/lib/implementations/scatter_impl.xml b/lib/implementations/scatter_impl.xml
new file mode 100644
index 0000000..e214f6a
--- /dev/null
+++ b/lib/implementations/scatter_impl.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<block_impl ref_name="scatter.xml" ref_md5="">
+  <comments>
+    <author firstname="stephane" lastname="Domas" mail="sdomas@univ-fcomte.fr" />
+    <date creation="2015-04-27" />
+    <related_files list=""/>
+    <description>
+      This component scatters an input over X outputs
+    </description>
+    <notes>
+      No notes
+    </notes>
+  </comments>
+
+  <libraries>
+    <library name="IEEE">
+      <package name="std_logic_1164" use="all"/>
+      <package name="numeric_std" use="all"/>
+    </library>
+  </libraries>
+
+  <architecture>   
+  </architecture>
+
+  <patterns>
+    <delta value="1" />
+    <consumption>
+      <input name="data_i_enb" pattern="1" />
+    </consumption>
+    <production counter="1">
+      <output name="data_o_enb" pattern="01" />
+    </production>
+  </patterns>
+
+</block_impl>
diff --git a/lib/references/average-Nx3.xml b/lib/references/average-Nx3.xml
index 063ec2a..24e96a3 100644
--- a/lib/references/average-Nx3.xml
+++ b/lib/references/average-Nx3.xml
@@ -16,8 +16,8 @@
   </informations>
 
   <parameters>
-    <parameter name="data_width" type="string" value="0" context="user"/>
-    <parameter name="nb_data" type="string" value="20" context="user"/>
+    <parameter name="data_width" type="positive" value="8" context="user"/>
+    <parameter name="nb_data" type="positive" value="10" context="user"/>
   </parameters>
 
   <interfaces>
diff --git a/lib/references/decimator-N.xml b/lib/references/decimator-N.xml
new file mode 100644
index 0000000..b008aa2
--- /dev/null
+++ b/lib/references/decimator-N.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<block>
+  <informations>
+    <name>
+      parametrized deicmator
+    </name>
+    <category ids="4" />  
+    <description>
+      <brief>
+	This block does a decimation of N-1 inputs overs N
+      </brief>
+      <detailed>
+	This block does a decimation of N-1 inputs overs N
+      </detailed>     
+    </description>    
+  </informations>
+
+  <parameters>
+    <parameter name="data_width" type="positive" value="8" context="user"/>
+    <parameter name="nb_deci" type="positive" value="1" context="user"/>
+  </parameters>
+
+  <interfaces>
+    <inputs>
+      <input name="clk" type="boolean" width="1" purpose="clock" />
+      <input name="rst" type="boolean" width="1" purpose="reset" />
+      <input name="data_i" type="expression" width="$data_width" />
+      <control iface="data_i" />
+    </inputs>
+    <outputs>
+      <output name="data_o" type="expression" width="$data_width" multiplicity="1"/>
+      <control iface="data_o" />
+    </outputs>    
+  </interfaces>
+
+</block>
diff --git a/lib/references/generator-cst.xml b/lib/references/generator-cst.xml
index d67b7ca..8522dd1 100644
--- a/lib/references/generator-cst.xml
+++ b/lib/references/generator-cst.xml
@@ -19,6 +19,7 @@
     <parameter name="data_width" type="positive" value="8" context="user"/>
     <parameter name="seq_length" type="positive" value="10" context="user"/>
     <parameter name="idle_length" type="positive" value="5" context="user"/>
+    <parameter name="fixed_value" type="integer" value="666" context="user"/>
   </parameters>
 
   <interfaces>
diff --git a/lib/references/generator-img.xml b/lib/references/generator-img.xml
new file mode 100644
index 0000000..55a5cee
--- /dev/null
+++ b/lib/references/generator-img.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<block>
+  <informations>
+    <name>
+      generator-img
+    </name>
+    <category ids="6" />  
+    <description>
+      <brief>
+	generates a RGB image, reading if from a csv file
+      </brief>
+      <detailed>
+	generates a RGB image, reading if from a csv file
+      </detailed>     
+    </description>    
+  </informations>
+
+  <parameters>
+    <parameter name="img_file" type="string" value="nofile.csv" context="user"/>
+    <parameter name="img_width" type="positive" value="8" context="user"/>
+    <parameter name="img_height" type="positive" value="8" context="user"/>
+    <parameter name="row_idle" type="natural" value="2" context="user"/>
+  </parameters>
+
+  <interfaces>
+    <inputs>
+      <input name="clk" width="1" purpose="clock" />
+      <input name="rst" width="1" purpose="reset" />
+    </inputs>
+    <outputs>
+      <output name="r_o" width="8"/>
+      <output name="g_o" width="8"/>
+      <output name="b_o" width="8"/>      
+      <control iface="r_o"/>
+      <control iface="g_o"/>
+      <control iface="b_o"/>
+    </outputs>
+  </interfaces>
+
+</block>
diff --git a/lib/references/references.bmf b/lib/references/references.bmf
index 60ea249..8ec5506 100644
Binary files a/lib/references/references.bmf and b/lib/references/references.bmf differ
diff --git a/lib/references/rgb216bits.xml b/lib/references/rgb216bits.xml
new file mode 100644
index 0000000..6898880
--- /dev/null
+++ b/lib/references/rgb216bits.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<block>
+  <informations>
+    <name>
+      RGB to 16 bits
+    </name>
+    <category ids="4" />  
+    <description>
+      <brief>
+	This block does a conversion of an RGB pixel into a 16 bits value
+      </brief>
+      <detailed>
+	This block does a conversion of an RGB pixel into a 16 bits value	
+      </detailed>     
+    </description>    
+  </informations>
+
+  <parameters>
+  </parameters>
+
+  <interfaces>
+    <inputs>
+      <input name="clk" type="boolean" width="1" purpose="clock" />
+      <input name="rst" type="boolean" width="1" purpose="reset" />
+      <input name="r_i" type="natural" width="8" />
+      <input name="g_i" type="natural" width="8" />
+      <input name="b_i" type="natural" width="8" />      
+      <control iface="r_i" />
+      <control iface="g_i" />
+      <control iface="b_i" />      
+    </inputs>
+    <outputs>
+      <output name="pix_o" type="natural" width="16" multiplicity="1"/>
+      <control iface="pix_o" />
+    </outputs>    
+  </interfaces>
+
+</block>
diff --git a/lib/references/scatter.xml b/lib/references/scatter.xml
new file mode 100644
index 0000000..ce9e2ef
--- /dev/null
+++ b/lib/references/scatter.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<block>
+  <informations>
+    <name>
+      scatter
+    </name>
+    <category ids="1,5" />  
+    <description>
+      <brief>
+	This block replicates the input over X outputs, the outputs being created at will.
+      </brief>
+      <detailed>
+	This block replicates the input over X outputs, the outputs being created at will.
+      </detailed>     
+    </description>    
+  </informations>
+
+  <parameters>
+    <parameter name="data_width" type="positive" value="16" context="user"/>
+  </parameters>
+
+  <interfaces>
+    <inputs>
+      <input name="clk" type="boolean" width="1" purpose="clock" />
+      <input name="rst" type="boolean" width="1" purpose="reset" />      
+      <input name="data_i" type="expression" width="$data_width" />
+      <control iface="data_i" />
+    </inputs>
+    <outputs>
+      <output name="data_o" type="expression" width="$data_width" multiplicity="*"/>
+      <control iface="data_o" />
+    </outputs>    
+  </interfaces>
+
+</block>
diff --git a/projectfile.xsd b/projectfile.xsd
index 8fdab46..811beb2 100644
--- a/projectfile.xsd
+++ b/projectfile.xsd
@@ -2,333 +2,448 @@
 <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
 
 
-    <!-- déclaration des groupes d'attributs -->
-
-    <xs:attributeGroup name="group_itemAttrGroup">
-	<xs:attribute ref="id"/>
-	<xs:attribute ref="name"/>
-	<xs:attribute ref="upper_group"/>
-	<xs:attribute ref="upper_item"/>
-	<xs:attribute ref="position"/>
-	<xs:attribute ref="dimension"/>
-    </xs:attributeGroup>
-
-    <xs:attributeGroup name="group_ifaceAttrGroup">
-	<xs:attribute ref="id"/>
-	<xs:attribute ref="name"/>
-	<xs:attribute ref="direction"/>
-	<xs:attribute ref="orientation"/>
-	<xs:attribute ref="position"/>
-    </xs:attributeGroup>
-
-    <xs:attributeGroup name="block_itemsAttrGroup">
-	<xs:attribute ref="functional_count" />
-	<xs:attribute ref="group_count" />
-    </xs:attributeGroup>
-
-    <xs:attributeGroup name="bi_functionalAttrGroup">
-	<xs:attribute ref="id" />
-	<xs:attribute ref="ref_xml" />
-	<xs:attribute ref="ref_md5" />
-	<xs:attribute ref="name" />
-	<xs:attribute ref="position" />
-	<xs:attribute ref="dimension" />
-    </xs:attributeGroup>
-
-    <xs:attributeGroup name="bif_parameterAttrGroup">
-	<xs:attribute ref="name" />
-	<xs:attribute ref="value" />
-	<xs:attribute ref="context" />
-	<xs:attribute ref="type" />
-
-    </xs:attributeGroup>
-
-    <xs:attributeGroup name="bif_ifaceAttrGroup">
-	<xs:attribute ref="id" />
-	<xs:attribute ref="name" />
-	<xs:attribute ref="ref_name" />
-	<xs:attribute ref="orientation" />
-	<xs:attribute ref="position" />
-    </xs:attributeGroup>
-
-    <xs:attributeGroup name="bi_groupAttrGroup">
-	<xs:attribute ref="id" />
-	<xs:attribute ref="inside_group" />
-	<xs:attribute ref="position" />
-	<xs:attribute ref="dimension" />
-    </xs:attributeGroup>
-
-    <xs:attributeGroup name="big_ifaceAttrGroup">
-	<xs:attribute ref="id" />
-	<xs:attribute ref="ref_name" />
-	<xs:attribute ref="orientation" />
-	<xs:attribute ref="position" />
-    </xs:attributeGroup>
-
-    <xs:attributeGroup name="connectionAttrGroup">
-	<xs:attribute ref="from" />
-	<xs:attribute ref="to" />
-    </xs:attributeGroup>
-
-
-    <!-- déclaration des attributs -->
-
-    <xs:attribute name="count">
-	<xs:simpleType>
-	    <xs:restriction base="xs:nonNegativeInteger">
-		<xs:minInclusive value="0"/>
-	    </xs:restriction>
-	</xs:simpleType>
-    </xs:attribute>
-
-    <xs:attribute name="id">
-	<xs:simpleType>
-	    <xs:restriction base="xs:nonNegativeInteger">
-		<xs:minInclusive value="0"/>
-	    </xs:restriction>
-	</xs:simpleType>
-    </xs:attribute>
-
-    <xs:attribute name="upper_scene">
-	<xs:simpleType>
-	    <xs:restriction base="xs:integer">
-		<xs:minInclusive value="-1"/>
-	    </xs:restriction>
-	</xs:simpleType>
-    </xs:attribute>
-
-    <xs:attribute name="upper_group">
-	<xs:simpleType>
-	    <xs:restriction base="xs:integer">
-		<xs:minInclusive value="-1"/>
-	    </xs:restriction>
-	</xs:simpleType>
-    </xs:attribute>
-
-    <xs:attribute name="upper_item">
-	<xs:simpleType>
-	    <xs:restriction base="xs:integer">
-		<xs:minInclusive value="-1"/>
-	    </xs:restriction>
-	</xs:simpleType>
-    </xs:attribute>
-
-    <xs:attribute name="inside_group">
-	<xs:simpleType>
-	    <xs:restriction base="xs:nonNegativeInteger">
-		<xs:minInclusive value="0"/>
-	    </xs:restriction>
-	</xs:simpleType>
-    </xs:attribute>
-
-    <xs:attribute name="functional_count">
-	<xs:simpleType>
-	    <xs:restriction base="xs:nonNegativeInteger">
-		<xs:minInclusive value="0"/>
-	    </xs:restriction>
-	</xs:simpleType>
-    </xs:attribute>
-
-    <xs:attribute name="group_count">
-	<xs:simpleType>
-	    <xs:restriction base="xs:nonNegativeInteger">
-		<xs:minInclusive value="0"/>
-	    </xs:restriction>
-	</xs:simpleType>
-    </xs:attribute>
-
-    <xs:attribute name="value" type="xs:string"/>
-
-    <xs:attribute name="from">
-	<xs:simpleType>
-	    <xs:restriction base="xs:nonNegativeInteger">
-		<xs:minInclusive value="0"/>
-	    </xs:restriction>
-	</xs:simpleType>
-    </xs:attribute>
-
-    <xs:attribute name="to">
-	<xs:simpleType>
-	    <xs:restriction base="xs:nonNegativeInteger">
-		<xs:minInclusive value="0"/>
-	    </xs:restriction>
-	</xs:simpleType>
-    </xs:attribute>
-
-    <xs:attribute name="position" type="xs:string"/>
-    <xs:attribute name="dimension" type="xs:string"/>
-    <xs:attribute name="direction" type="xs:string"/>
-    <xs:attribute name="orientation" type="xs:string"/>
-    <xs:attribute name="name" type="xs:string"/>
-    <xs:attribute name="ref_name" type="xs:string"/>
-    <xs:attribute name="ref_xml" type="xs:string"/>
-    <xs:attribute name="ref_md5" type="xs:string"/>
-    <xs:attribute name="context" type="xs:string"/>
-    <xs:attribute name="type" type="xs:string"/>
-
-
-    <!-- déclaration des groupes d'éléments -->
-
-    <xs:group name="rootElmtGroup">
-	<xs:sequence>
-	    <xs:element ref="scenes"/>
-	    <xs:element ref="connections"/>	
-	</xs:sequence>
-    </xs:group>
-
-    <xs:group name="sceneElmtGroup">
-	<xs:sequence>
-	    <xs:element ref="group_item"/>
-	    <xs:element ref="block_items"/>
-	</xs:sequence>
-    </xs:group>
-
-    <xs:group name="block_itemsElmtGroup">
+  <!-- déclaration des groupes d'attributs -->
+
+  <xs:attributeGroup name="group_itemAttrGroup">
+    <xs:attribute ref="id"/>
+    <xs:attribute ref="name"/>
+    <xs:attribute ref="upper_group"/>
+    <xs:attribute ref="upper_item"/>
+    <xs:attribute ref="position"/>
+    <xs:attribute ref="dimension"/>
+  </xs:attributeGroup>
+
+  <xs:attributeGroup name="group_ifaceAttrGroup">
+    <xs:attribute ref="id"/>
+    <xs:attribute ref="name"/>
+    <xs:attribute ref="purpose"/>
+    <xs:attribute ref="direction"/>
+    <xs:attribute ref="orientation"/>
+    <xs:attribute ref="position"/>
+  </xs:attributeGroup>
+
+  <xs:attributeGroup name="source_itemsAttrGroup">
+    <xs:attribute ref="count" />
+  </xs:attributeGroup>
+
+  <xs:attributeGroup name="block_itemsAttrGroup">
+    <xs:attribute ref="functional_count" />
+    <xs:attribute ref="group_count" />
+  </xs:attributeGroup>
+
+  <xs:attributeGroup name="source_itemAttrGroup">
+    <xs:attribute ref="id" />
+    <xs:attribute ref="ref_xml" />
+    <xs:attribute ref="ref_md5" />
+    <xs:attribute ref="name" />
+    <xs:attribute ref="position" />
+    <xs:attribute ref="dimension" />
+  </xs:attributeGroup>
+  
+  <xs:attributeGroup name="bi_functionalAttrGroup">
+    <xs:attribute ref="id" />
+    <xs:attribute ref="ref_xml" />
+    <xs:attribute ref="ref_md5" />
+    <xs:attribute ref="name" />
+    <xs:attribute ref="position" />
+    <xs:attribute ref="dimension" />
+  </xs:attributeGroup>
+
+  <xs:attributeGroup name="source_parameterAttrGroup">
+    <xs:attribute ref="name" />
+    <xs:attribute ref="value" />
+    <xs:attribute ref="context" />
+    <xs:attribute ref="type" />
+  </xs:attributeGroup>
+  
+  <xs:attributeGroup name="bif_parameterAttrGroup">
+    <xs:attribute ref="name" />
+    <xs:attribute ref="value" />
+    <xs:attribute ref="context" />
+    <xs:attribute ref="type" />
+  </xs:attributeGroup>
+
+  <xs:attributeGroup name="source_ifaceAttrGroup">
+    <xs:attribute ref="id" />
+    <xs:attribute ref="name" />
+    <xs:attribute ref="ref_name" />
+    <xs:attribute ref="orientation" />
+    <xs:attribute ref="position" />
+  </xs:attributeGroup>
+  
+  <xs:attributeGroup name="bif_ifaceAttrGroup">
+    <xs:attribute ref="id" />
+    <xs:attribute ref="name" />
+    <xs:attribute ref="ref_name" />
+    <xs:attribute ref="orientation" />
+    <xs:attribute ref="position" />
+  </xs:attributeGroup>
+
+  <xs:attributeGroup name="bi_groupAttrGroup">
+    <xs:attribute ref="id" />
+    <xs:attribute ref="inside_group" />
+    <xs:attribute ref="position" />
+    <xs:attribute ref="dimension" />
+  </xs:attributeGroup>
+
+  <xs:attributeGroup name="big_ifaceAttrGroup">
+    <xs:attribute ref="id" />
+    <xs:attribute ref="ref_name" />
+    <xs:attribute ref="orientation" />
+    <xs:attribute ref="position" />
+  </xs:attributeGroup>
+
+  <xs:attributeGroup name="connectionAttrGroup">
+    <xs:attribute ref="from" />
+    <xs:attribute ref="to" />
+  </xs:attributeGroup>
+
+
+  <!-- déclaration des attributs -->
+
+  <xs:attribute name="count">
+    <xs:simpleType>
+      <xs:restriction base="xs:nonNegativeInteger">
+	<xs:minInclusive value="0"/>
+      </xs:restriction>
+    </xs:simpleType>
+  </xs:attribute>
+
+  <xs:attribute name="id">
+    <xs:simpleType>
+      <xs:restriction base="xs:nonNegativeInteger">
+	<xs:minInclusive value="0"/>
+      </xs:restriction>
+    </xs:simpleType>
+  </xs:attribute>
+
+  <xs:attribute name="upper_scene">
+    <xs:simpleType>
+      <xs:restriction base="xs:integer">
+	<xs:minInclusive value="-1"/>
+      </xs:restriction>
+    </xs:simpleType>
+  </xs:attribute>
+
+  <xs:attribute name="upper_group">
+    <xs:simpleType>
+      <xs:restriction base="xs:integer">
+	<xs:minInclusive value="-1"/>
+      </xs:restriction>
+    </xs:simpleType>
+  </xs:attribute>
+
+  <xs:attribute name="upper_item">
+    <xs:simpleType>
+      <xs:restriction base="xs:integer">
+	<xs:minInclusive value="-1"/>
+      </xs:restriction>
+    </xs:simpleType>
+  </xs:attribute>
+
+  <xs:attribute name="inside_group">
+    <xs:simpleType>
+      <xs:restriction base="xs:nonNegativeInteger">
+	<xs:minInclusive value="0"/>
+      </xs:restriction>
+    </xs:simpleType>
+  </xs:attribute>
+
+  <xs:attribute name="functional_count">
+    <xs:simpleType>
+      <xs:restriction base="xs:nonNegativeInteger">
+	<xs:minInclusive value="0"/>
+      </xs:restriction>
+    </xs:simpleType>
+  </xs:attribute>
+
+  <xs:attribute name="group_count">
+    <xs:simpleType>
+      <xs:restriction base="xs:nonNegativeInteger">
+	<xs:minInclusive value="0"/>
+      </xs:restriction>
+    </xs:simpleType>
+  </xs:attribute>
+
+  <xs:attribute name="value" type="xs:string"/>
+
+  <xs:attribute name="from">
+    <xs:simpleType>
+      <xs:restriction base="xs:nonNegativeInteger">
+	<xs:minInclusive value="0"/>
+      </xs:restriction>
+    </xs:simpleType>
+  </xs:attribute>
+
+  <xs:attribute name="to">
+    <xs:simpleType>
+      <xs:restriction base="xs:nonNegativeInteger">
+	<xs:minInclusive value="0"/>
+      </xs:restriction>
+    </xs:simpleType>
+  </xs:attribute>
+
+  <xs:attribute name="purpose">
+    <xs:simpleType>
+      <xs:restriction base="xs:string">
+	<xs:enumeration value="data"/>
+	<xs:enumeration value="clock"/>
+	<xs:enumeration value="reset"/>
+	<xs:enumeration value="wishbone"/>
+      </xs:restriction>
+    </xs:simpleType>
+  </xs:attribute>
+  
+  <xs:attribute name="direction">
+    <xs:simpleType>
+      <xs:restriction base="xs:string">
+	<xs:enumeration value="input"/>
+	<xs:enumeration value="output"/>
+	<xs:enumeration value="inout"/>
+      </xs:restriction>
+    </xs:simpleType>
+  </xs:attribute>
+
+  <xs:attribute name="orientation">
+    <xs:simpleType>
+      <xs:restriction base="xs:string">
+      <xs:enumeration value="west"/>
+      <xs:enumeration value="east"/>
+      <xs:enumeration value="north"/>
+      <xs:enumeration value="south"/>
+      </xs:restriction>
+    </xs:simpleType>
+  </xs:attribute>
+  
+  <xs:attribute name="position" type="xs:string"/>
+  <xs:attribute name="dimension" type="xs:string"/>
+  <xs:attribute name="name" type="xs:string"/>
+  <xs:attribute name="ref_name" type="xs:string"/>
+  <xs:attribute name="ref_xml" type="xs:string"/>
+  <xs:attribute name="ref_md5" type="xs:string"/>
+  <xs:attribute name="context" type="xs:string"/>
+  <xs:attribute name="type" type="xs:string"/>
+
+
+  <!-- déclaration des groupes d'éléments -->
+
+  <xs:group name="rootElmtGroup">
+    <xs:sequence>
+      <xs:element ref="scenes"/>
+      <xs:element ref="connections"/>	
+    </xs:sequence>
+  </xs:group>
+
+  <xs:group name="sceneElmtGroup">
+    <xs:sequence>
+      <xs:element ref="group_item"/>
+      <xs:element ref="source_items" minOccurs="0" maxOccurs="unbounded"/>	  
+      <xs:element ref="block_items"/>
+    </xs:sequence>
+  </xs:group>
+
+  <xs:group name="source_itemsElmtGroup">
+    <xs:sequence>
+      <xs:element ref="source_item" minOccurs="0" maxOccurs="unbounded"/>
+    </xs:sequence>
+  </xs:group>
+  
+  <xs:group name="block_itemsElmtGroup">
+    <xs:sequence>
+      <xs:element ref="bi_functional" minOccurs="0" maxOccurs="unbounded"/>
+      <xs:element ref="bi_group" minOccurs="0" maxOccurs="unbounded"/>      
+    </xs:sequence>
+  </xs:group>
+
+  <xs:group name="source_itemElmtGroup">
+    <xs:sequence>
+      <xs:element ref="source_parameters"/>
+      <xs:element ref="source_ifaces"/>
+    </xs:sequence>
+  </xs:group>
+  
+  <xs:group name="bi_functionalElmtGroup">
+    <xs:sequence>
+      <xs:element ref="bif_parameters"/>
+      <xs:element ref="bif_ifaces"/>
+    </xs:sequence>
+  </xs:group>
+
+
+  <!-- déclaration des éléments -->
+
+  <xs:element name="scenes">
+    <xs:complexType>
       <xs:sequence>
-	<xs:element ref="bi_group" minOccurs="0" maxOccurs="unbounded"/>
-	<xs:element ref="bi_functional" minOccurs="0" maxOccurs="unbounded"/>
-	</xs:sequence>
-    </xs:group>
-
-    <xs:group name="bi_functionalElmtGroup">
-	<xs:sequence>
-	    <xs:element ref="bif_parameters"/>
-	    <xs:element ref="bif_ifaces"/>
-	</xs:sequence>
-    </xs:group>
-
-
-    <!-- déclaration des éléments -->
-
-    <xs:element name="scenes">
-	<xs:complexType>
-	    <xs:sequence>
-		<xs:element ref="scene" maxOccurs="unbounded" />
-	    </xs:sequence>
-	    <xs:attribute ref="count"/>
-	</xs:complexType>
-    </xs:element>
-
-    <xs:element name="scene">
-	<xs:complexType>
-	    <xs:group ref="sceneElmtGroup"/>
-	    <xs:attribute ref="id"/>
-	    <xs:attribute ref="upper_scene"/>
-	</xs:complexType>
-    </xs:element>
-
-    <xs:element name="group_item">
-	<xs:complexType>
-	    <xs:sequence>
-		<xs:element ref="group_ifaces" maxOccurs="unbounded" />
-	    </xs:sequence>	
-	    <xs:attributeGroup ref="group_itemAttrGroup"/>
-	</xs:complexType>
-    </xs:element>
-
-    <xs:element name="group_ifaces">
-	<xs:complexType>
-	    <xs:sequence>
-		<xs:element ref="group_iface" minOccurs="0" maxOccurs="unbounded"/>
-	    </xs:sequence>
-	    <xs:attribute ref="count"/>
-	</xs:complexType>
-    </xs:element>
-
-    <xs:element name="group_iface">
-	<xs:complexType>
-	    <xs:attributeGroup ref="group_ifaceAttrGroup"/>
-	</xs:complexType>
-    </xs:element>
-
-    <xs:element name="block_items">
-	<xs:complexType>
-	    <xs:group ref="block_itemsElmtGroup"/>
-	    <xs:attributeGroup ref="block_itemsAttrGroup"/>
-	</xs:complexType>
-    </xs:element>
-
-    <xs:element name="bi_functional">
-	<xs:complexType>
-	    <xs:group ref="bi_functionalElmtGroup"/>
-	    <xs:attributeGroup ref="bi_functionalAttrGroup"/>
-	</xs:complexType>
-    </xs:element>
-
-    <xs:element name="bif_parameters">
-	<xs:complexType>
-	    <xs:sequence>
-		<xs:element ref="bif_parameter" minOccurs="0" maxOccurs="unbounded" />
-	    </xs:sequence>
-	</xs:complexType>
-    </xs:element>
-	
-    <xs:element name="bif_parameter">
-	<xs:complexType>
-	    <xs:attributeGroup ref="bif_parameterAttrGroup"/>
-	</xs:complexType>
-    </xs:element>
-
-    <xs:element name="bif_ifaces">
-	<xs:complexType>
-	    <xs:sequence>
-	        <xs:element ref="bif_iface" minOccurs="0" maxOccurs="unbounded" />
-	    </xs:sequence>
-	    <xs:attribute ref="count"/>
-	</xs:complexType>
-    </xs:element>
-
-    <xs:element name="bif_iface">
-	<xs:complexType>
-	    <xs:attributeGroup ref="bif_ifaceAttrGroup"/>
-	</xs:complexType>
-    </xs:element>
-
-    <xs:element name="bi_group">
-	<xs:complexType>
-	    <xs:sequence>
-		<xs:element ref="big_ifaces"/>
-	    </xs:sequence>
-	    <xs:attributeGroup ref="bi_groupAttrGroup"/>
-	</xs:complexType>
-    </xs:element>
-
-    <xs:element name="big_ifaces">
-	<xs:complexType>
-	    <xs:sequence>
-		<xs:element ref="big_iface" minOccurs="0" maxOccurs="unbounded" />
-	    </xs:sequence>
-	    <xs:attribute ref="count" />
-	</xs:complexType>
-    </xs:element>
-
-    <xs:element name="big_iface">
-	<xs:complexType>
-	    <xs:attributeGroup ref="big_ifaceAttrGroup" />
-	</xs:complexType>
-    </xs:element>
-
-    <xs:element name="connections">
-	<xs:complexType>
-	    <xs:sequence>
-		<xs:element ref="connection" minOccurs="0" maxOccurs="unbounded"/>
-	    </xs:sequence>
-	    <xs:attribute ref="count" />
-	</xs:complexType>
-    </xs:element>
-
-    <xs:element name="connection">
-	<xs:complexType>
-	    <xs:attributeGroup ref="connectionAttrGroup"/>
-	</xs:complexType>
-    </xs:element>
-
-    <!-- racine du document -->
-
-    <xs:element name="blast_project">
-	<xs:complexType>
-	    <xs:group ref="rootElmtGroup"/>
-	</xs:complexType>
-    </xs:element>
+	<xs:element ref="scene" maxOccurs="unbounded" />
+      </xs:sequence>
+      <xs:attribute ref="count"/>
+    </xs:complexType>
+  </xs:element>
+
+  <xs:element name="scene">
+    <xs:complexType>
+      <xs:group ref="sceneElmtGroup"/>
+      <xs:attribute ref="id"/>
+      <xs:attribute ref="upper_scene"/>
+    </xs:complexType>
+  </xs:element>
+
+  <xs:element name="group_item">
+    <xs:complexType>
+      <xs:sequence>
+	<xs:element ref="group_ifaces" maxOccurs="unbounded" />
+      </xs:sequence>	
+      <xs:attributeGroup ref="group_itemAttrGroup"/>
+    </xs:complexType>
+  </xs:element>
+
+  <xs:element name="group_ifaces">
+    <xs:complexType>
+      <xs:sequence>
+	<xs:element ref="group_iface" minOccurs="0" maxOccurs="unbounded"/>
+      </xs:sequence>
+      <xs:attribute ref="count"/>
+    </xs:complexType>
+  </xs:element>
+
+  <xs:element name="group_iface">
+    <xs:complexType>
+      <xs:attributeGroup ref="group_ifaceAttrGroup"/>
+    </xs:complexType>
+  </xs:element>
+
+  <xs:element name="source_items">
+    <xs:complexType>
+      <xs:group ref="source_itemsElmtGroup"/>
+      <xs:attributeGroup ref="source_itemsAttrGroup"/>
+    </xs:complexType>
+  </xs:element>
+  
+  <xs:element name="block_items">
+    <xs:complexType>
+      <xs:group ref="block_itemsElmtGroup"/>
+      <xs:attributeGroup ref="block_itemsAttrGroup"/>
+    </xs:complexType>
+  </xs:element>
+
+  <xs:element name="source_item">
+    <xs:complexType>
+      <xs:group ref="source_itemElmtGroup"/>
+      <xs:attributeGroup ref="source_itemAttrGroup"/>
+    </xs:complexType>
+  </xs:element>
+  
+  <xs:element name="bi_functional">
+    <xs:complexType>
+      <xs:group ref="bi_functionalElmtGroup"/>
+      <xs:attributeGroup ref="bi_functionalAttrGroup"/>
+    </xs:complexType>
+  </xs:element>
+
+  <xs:element name="source_parameters">
+    <xs:complexType>
+      <xs:sequence>
+	<xs:element ref="source_parameter" minOccurs="0" maxOccurs="unbounded" />
+      </xs:sequence>
+    </xs:complexType>
+  </xs:element>
+  
+  <xs:element name="source_parameter">
+    <xs:complexType>
+      <xs:attributeGroup ref="source_parameterAttrGroup"/>
+    </xs:complexType>
+  </xs:element>
+  
+  <xs:element name="bif_parameters">
+    <xs:complexType>
+      <xs:sequence>
+	<xs:element ref="bif_parameter" minOccurs="0" maxOccurs="unbounded" />
+      </xs:sequence>
+    </xs:complexType>
+  </xs:element>
+  
+  <xs:element name="bif_parameter">
+    <xs:complexType>
+      <xs:attributeGroup ref="bif_parameterAttrGroup"/>
+    </xs:complexType>
+  </xs:element>
+
+  <xs:element name="source_ifaces">
+    <xs:complexType>
+      <xs:sequence>
+	<xs:element ref="source_iface" minOccurs="0" maxOccurs="unbounded" />
+      </xs:sequence>
+      <xs:attribute ref="count"/>
+    </xs:complexType>
+  </xs:element>
+  
+  <xs:element name="source_iface">
+    <xs:complexType>
+      <xs:attributeGroup ref="source_ifaceAttrGroup"/>
+    </xs:complexType>
+  </xs:element>
+
+  <xs:element name="bif_ifaces">
+    <xs:complexType>
+      <xs:sequence>
+	<xs:element ref="bif_iface" minOccurs="0" maxOccurs="unbounded" />
+      </xs:sequence>
+      <xs:attribute ref="count"/>
+    </xs:complexType>
+  </xs:element>
+
+  <xs:element name="bif_iface">
+    <xs:complexType>
+      <xs:attributeGroup ref="bif_ifaceAttrGroup"/>
+    </xs:complexType>
+  </xs:element>
+
+  <xs:element name="bi_group">
+    <xs:complexType>
+      <xs:sequence>
+	<xs:element ref="big_ifaces"/>
+      </xs:sequence>
+      <xs:attributeGroup ref="bi_groupAttrGroup"/>
+    </xs:complexType>
+  </xs:element>
+
+  <xs:element name="big_ifaces">
+    <xs:complexType>
+      <xs:sequence>
+	<xs:element ref="big_iface" minOccurs="0" maxOccurs="unbounded" />
+      </xs:sequence>
+      <xs:attribute ref="count" />
+    </xs:complexType>
+  </xs:element>
+
+  <xs:element name="big_iface">
+    <xs:complexType>
+      <xs:attributeGroup ref="big_ifaceAttrGroup" />
+    </xs:complexType>
+  </xs:element>
+
+  <xs:element name="connections">
+    <xs:complexType>
+      <xs:sequence>
+	<xs:element ref="connection" minOccurs="0" maxOccurs="unbounded"/>
+      </xs:sequence>
+      <xs:attribute ref="count" />
+    </xs:complexType>
+  </xs:element>
+
+  <xs:element name="connection">
+    <xs:complexType>
+      <xs:attributeGroup ref="connectionAttrGroup"/>
+    </xs:complexType>
+  </xs:element>
+
+  <!-- racine du document -->
+
+  <xs:element name="blast_project">
+    <xs:complexType>
+      <xs:group ref="rootElmtGroup"/>
+    </xs:complexType>
+  </xs:element>
 
 </xs:schema>
diff --git a/reference.xsd b/reference.xsd
index 3fa3faa..b219bfa 100644
--- a/reference.xsd
+++ b/reference.xsd
@@ -4,8 +4,8 @@
     <!-- déclaration des groupes d'attributs -->
 
     <xs:attributeGroup name="parameterAttrGroup">
-	<xs:attribute ref="name" use="required"/>
-	<xs:attribute ref="type" use="required"/>
+      <xs:attribute ref="name" use="required"/>
+	<xs:attribute name="type" type="typeparam" use="required"/>
 	<xs:attribute ref="wishbone" use="optional"/>
 	<xs:attribute ref="value" use="optional"/>
 	<xs:attribute ref="iface" use="optional"/>
@@ -16,7 +16,7 @@
     <xs:attributeGroup name="inOutAttrGroup">
 	<xs:attribute ref="name" use="required"/>
 	<xs:attribute ref="width" use="required"/>
-	<xs:attribute ref="type"/>
+	<xs:attribute name="type" type="typeiface"/>
 	<xs:attribute ref="purpose"/>
 	<xs:attribute ref="multiplicity"/>
     </xs:attributeGroup>
@@ -26,7 +26,28 @@
 
     <xs:attribute name="ids" type="xs:string"/>
     <xs:attribute name="name" type="xs:string"/>
-    <xs:attribute name="type" type="xs:string"/>
+
+    <xs:simpleType name="typeparam">
+      <xs:restriction base="xs:string">
+	<xs:enumeration value="string"/>
+	<xs:enumeration value="expression"/>
+	<xs:enumeration value="boolean"/>
+	<xs:enumeration value="integer"/>
+	<xs:enumeration value="natural"/>
+	<xs:enumeration value="positive"/>
+	<xs:enumeration value="real"/>
+	<xs:enumeration value="time"/>
+      </xs:restriction>
+    </xs:simpleType>
+
+    <xs:simpleType name="typeiface">
+      <xs:restriction base="xs:string">
+	<xs:enumeration value="expression"/>
+	<xs:enumeration value="boolean"/>
+	<xs:enumeration value="natural"/>
+      </xs:restriction>
+    </xs:simpleType>
+      
     <xs:attribute name="wishbone" type="xs:string"/>
     <xs:attribute name="context" type="xs:string" />
     <xs:attribute name="multiplicity" type="xs:string" />