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

Private GIT Repository
finished testbench generation
[blast.git] / ReferenceBlock.cpp
index 8b50bfa4d0d6d466402614e53154304dab18893b..56a34dbe9b8d9939a866177f1f78c93a96ce7165 100644 (file)
@@ -6,23 +6,19 @@
 #include "BlockParameterGeneric.h"
 #include "BlockParameterPort.h"
 #include "BlockParameterWishbone.h"
 #include "BlockParameterGeneric.h"
 #include "BlockParameterPort.h"
 #include "BlockParameterWishbone.h"
+#include "Parameters.h"
 
 
-ReferenceBlock::ReferenceBlock(const QString _xmlFile) : AbstractBlock() {
-  xmlFile = _xmlFile;
+ReferenceBlock::ReferenceBlock(const QString _xmlFile) : AbstractBlock(NULL) {
+  xmlFile = _xmlFile;  
 }
 
 void ReferenceBlock::addCategory(int id) {
  categories.append(id);
 }
 
 }
 
 void ReferenceBlock::addCategory(int id) {
  categories.append(id);
 }
 
-void ReferenceBlock::setBriefDescription(const QString& str) {
+void ReferenceBlock::setDescription(const QString& str) {
   if(str != NULL)
   if(str != NULL)
-    descriptionBrief = str;
-}
-
-void ReferenceBlock::setDetailedDescription(const QString& str) {
-  if(str != NULL)
-    descriptionDetail = str;
+    description = str;
 }
 
 void ReferenceBlock::addImplementation(BlockImplementation *impl) {
 }
 
 void ReferenceBlock::addImplementation(BlockImplementation *impl) {
@@ -44,6 +40,16 @@ void ReferenceBlock::setHashMd5() {
 
 void ReferenceBlock::load(QDomElement &elt) throw(Exception) {
 
 
 void ReferenceBlock::load(QDomElement &elt) throw(Exception) {
 
+  cout << "Block : get version" << endl;
+  QString verStr = elt.attribute("version","none");
+  QString specialStr = elt.attribute("special","none");
+  if (verStr != "none") {
+    setVersion(verStr);
+  }
+  else {
+    setVersion("0.0");
+  }
+  setSpecialType(getSpecialTypeFromString(specialStr));
 
   cout << "Block : get informations" << endl;  
   QDomElement eltInfo  = elt.firstChildElement("informations");
 
   cout << "Block : get informations" << endl;  
   QDomElement eltInfo  = elt.firstChildElement("informations");
@@ -68,6 +74,14 @@ void ReferenceBlock::load(QDomElement &elt) throw(Exception) {
   try {
     loadInterfaces(eltInter);
   }
   try {
     loadInterfaces(eltInter);
   }
+  catch(int err) {
+    throw(err);
+  }
+
+  // create interfaces that correspond to a wishbone parameter, if any.
+  try {
+    createInterfaceForWishbone();
+  }
   catch(int err) {
     throw(err);
   }  
   catch(int err) {
     throw(err);
   }  
@@ -86,7 +100,7 @@ void ReferenceBlock::loadInformations(QDomElement &elt) throw(Exception) {
   }
   else {
     QDomText txtName = nodeNameTxt.toText();
   }
   else {
     QDomText txtName = nodeNameTxt.toText();
-    name = txtName.data().trimmed();
+    name = Parameters::normalizeName(txtName.data().trimmed());
     cout<< "block name : " << qPrintable(name) << endl;
   }
 
     cout<< "block name : " << qPrintable(name) << endl;
   }
 
@@ -96,38 +110,31 @@ void ReferenceBlock::loadInformations(QDomElement &elt) throw(Exception) {
 
   QString idsStr = eltCat.attribute("ids","none");
   if (idsStr == "none") throw (Exception(BLOCKFILE_CORRUPTED));
 
   QString idsStr = eltCat.attribute("ids","none");
   if (idsStr == "none") throw (Exception(BLOCKFILE_CORRUPTED));
-  QStringList listCat = idsStr.split(",");
-  foreach(QString str, listCat)
-  {
-    int idCat = str.toInt(&ok);
-    categories.append(idCat);
+  if (idsStr.isEmpty()) {
+    categories.append(99);
+  }
+  else {
+    QStringList listCat = idsStr.split(",");
+    foreach(QString str, listCat)
+    {
+      int idCat = str.toInt(&ok);
+      categories.append(idCat);
+    }
   }
 
   // getting description
   cout << "Block info : get description" << endl;  
   QDomElement eltDesc = eltCat.nextSiblingElement("description");
   }
 
   // getting description
   cout << "Block info : get description" << endl;  
   QDomElement eltDesc = eltCat.nextSiblingElement("description");
-  // getting brief  
-  QDomElement eltBrief = eltDesc.firstChildElement("brief");
-  QDomNode nodeBriefTxt = eltBrief.firstChild();
-  if (nodeBriefTxt.isNull()) {
-    descriptionBrief = "no brief description";
+  // getting text
+  QDomNode nodeTxt = eltDesc.firstChild();
+  if (nodeTxt.isNull()) {
+    description = "no description";
   }
   else {
   }
   else {
-    QDomText txtBrief = nodeBriefTxt.toText();
-    descriptionBrief = txtBrief.data().trimmed();
-    cout << "block brief desc : " << qPrintable(descriptionBrief) << endl;
-  }
-  // getting detailed  
-  QDomElement eltDetail = eltBrief.nextSiblingElement("detailed");
-  QDomNode nodeDetailTxt = eltDetail.firstChild();
-  if (nodeDetailTxt.isNull()) {
-    descriptionDetail = "no detailed description";
-  }
-  else {
-    QDomText txtDetail = nodeDetailTxt.toText();
-    descriptionDetail = txtDetail.data().trimmed();
-    cout << "block detail desc : " << qPrintable(descriptionDetail) << endl;
-  }
+    QDomText txtBrief = nodeTxt.toText();
+    description = txtBrief.data().trimmed();
+    cout << "block desc : " << qPrintable(description) << endl;
+  }  
 }
 
 void ReferenceBlock::loadParameters(QDomElement &elt) throw(Exception) {
 }
 
 void ReferenceBlock::loadParameters(QDomElement &elt) throw(Exception) {
@@ -149,7 +156,7 @@ void ReferenceBlock::loadParameters(QDomElement &elt) throw(Exception) {
         valueStr = "";
     }
     if (contextStr == "user") {
         valueStr = "";
     }
     if (contextStr == "user") {
-      param = new BlockParameterUser(this,nameStr,valueStr);
+      param = new BlockParameterUser(this,nameStr,typeStr,valueStr);
     }
     else if (contextStr == "generic") {
       param = new BlockParameterGeneric(this,nameStr,typeStr,valueStr);
     }
     else if (contextStr == "generic") {
       param = new BlockParameterGeneric(this,nameStr,typeStr,valueStr);
@@ -161,11 +168,16 @@ void ReferenceBlock::loadParameters(QDomElement &elt) throw(Exception) {
       int duration = 0;
       QString wbValue = "";
       QStringList listWb = wbStr.split(",");
       int duration = 0;
       QString wbValue = "";
       QStringList listWb = wbStr.split(",");
+      cout << "wb param has:";
+      foreach(QString s, listWb) {
+        cout << qPrintable(s) << " | ";
+      }
+      cout << endl;
 
       if (listWb.at(0) == "r") {
         access = BlockParameter::Read;
       }
 
       if (listWb.at(0) == "r") {
         access = BlockParameter::Read;
       }
-      else if (wbStr == "w") {
+      else if (listWb.at(0) == "w") {
         access = BlockParameter::Write;
         bool ok;
         wbValue = listWb.at(1).toInt(&ok);
         access = BlockParameter::Write;
         bool ok;
         wbValue = listWb.at(1).toInt(&ok);
@@ -202,55 +214,160 @@ void ReferenceBlock::loadInterfaces(QDomElement &elt) throw(Exception) {
   QString nameStr;
   QString typeStr;
   QString widthStr;
   QString nameStr;
   QString typeStr;
   QString widthStr;
+  QString endianStr;
   QString purposeStr;
   QString purposeStr;
+  QString clockStr;
   int purpose;
   int purpose;
-  QString levelStr;
-  int level;
   QString multStr;
   int mult;
   QString multStr;
   int mult;
-  AbstractInterface* inter;
+  ReferenceInterface* iface;
 
   if ((elt.isNull()) || (elt.tagName() != "interfaces")) throw (Exception(BLOCKFILE_CORRUPTED));
 
   QDomElement eltInputs = elt.firstChildElement("inputs");
 
   if ((elt.isNull()) || (elt.tagName() != "interfaces")) throw (Exception(BLOCKFILE_CORRUPTED));
 
   QDomElement eltInputs = elt.firstChildElement("inputs");
+  // getting each input
   QDomNodeList listNodeInputs = eltInputs.elementsByTagName("input");
   QDomNodeList listNodeInputs = eltInputs.elementsByTagName("input");
+
+  // find all input clocks
+  QList<AbstractInterface*> clocks;
+  for(int i=0;i<listNodeInputs.size();i++) {
+    QDomNode node = listNodeInputs.at(i);
+    QDomElement eltInput = node.toElement();
+    purposeStr = eltInput.attribute("purpose","none");
+    if (purposeStr == "clock") {
+      nameStr = eltInput.attribute("name","none");
+      iface = new ReferenceInterface(this,nameStr,AbstractInterface::Input, AbstractInterface::Clock, "boolean", "1", AbstractInterface::LittleEndian, 1);
+      if (! iface->checkSetClockIface(nameStr)) {
+        throw (Exception(BLOCKFILE_CORRUPTED));
+      }
+      inputs.append(iface);
+      clocks.append(iface);
+    }
+  }
+  cout << "number of clocks: " << clocks.size() << endl;
+
+  // find inputs
   for(int i=0;i<listNodeInputs.size();i++) {
     QDomNode node = listNodeInputs.at(i);
     QDomElement eltInput = node.toElement();
   for(int i=0;i<listNodeInputs.size();i++) {
     QDomNode node = listNodeInputs.at(i);
     QDomElement eltInput = node.toElement();
-    nameStr = eltInput.attribute("name","none");
-    typeStr = eltInput.attribute("type","none");
-    widthStr = eltInput.attribute("width","none");
     purposeStr = eltInput.attribute("purpose","none");
     purposeStr = eltInput.attribute("purpose","none");
-    cout << "block : " << this->getName().toStdString() << endl;
-    cout << "purpose for " << nameStr.toStdString() << " : " << purposeStr.toStdString() << endl;
     purpose = ReferenceInterface::translatePurpose(purposeStr);
     purpose = ReferenceInterface::translatePurpose(purposeStr);
-    cout << "translated purpose : " << purpose << endl;
-    levelStr = eltInput.attribute("level","none");
-    level = ReferenceInterface::translateLevel(levelStr);
-    multStr = eltInput.attribute("multiplicity","none");
-    mult = ReferenceInterface::translateMultiplicity(multStr);
+    if (purpose != AbstractInterface::Clock) {
+      cout << "translated purpose : " << purpose << endl;
+      nameStr = eltInput.attribute("name","none");
+      typeStr = eltInput.attribute("type","none");
+      widthStr = eltInput.attribute("width","none");
+      endianStr = eltInput.attribute("endian","none");
+      clockStr = eltInput.attribute("clock","none");
+      int endianess;
+      if ((endianStr == "none") || (endianStr == "little")) {
+        endianess = AbstractInterface::LittleEndian;
+      }
+      else if (endianStr == "big") {
+        endianess = AbstractInterface::BigEndian;
+      }
+      else {
+        throw (Exception(BLOCKFILE_CORRUPTED));
+      }
 
 
-    inter = new ReferenceInterface(this,nameStr,typeStr,widthStr,AbstractInterface::Input, purpose, level, mult);
-    inputs.append(inter);
-  }
+      multStr = eltInput.attribute("multiplicity","none");
+      mult = ReferenceInterface::translateMultiplicity(multStr);
 
 
+      iface = new ReferenceInterface(this,nameStr, AbstractInterface::Input, purpose, typeStr, widthStr, endianess, mult);
+      if (clockStr == "none") {
+        if (clocks.size() > 1) {
+          // if several clocks, the associated one MUST be given
+          throw (Exception(BLOCKFILE_CORRUPTED));
+        }
+        // no clock given, take the single one
+        clockStr = clocks.at(0)->getName();
+      }
+      if (! iface->checkSetClockIface(clockStr)) {
+        throw (Exception(BLOCKFILE_CORRUPTED));
+      }
+      inputs.append(iface);
+    }
+  }
+  // getting each control
+  QDomNodeList listNodeInCtl = eltInputs.elementsByTagName("control");
+  for(int i=0;i<listNodeInCtl.size();i++) {
+    QDomNode node = listNodeInCtl.at(i);
+    QDomElement eltInput = node.toElement();
+    nameStr = eltInput.attribute("iface","none");
+    AbstractInterface* dataIface = getIfaceFromName(nameStr);
+    if (dataIface == NULL) throw (Exception(BLOCKFILE_CORRUPTED));
+    QString nameEnbStr = dataIface->getName()+"_enb";
+    iface = new ReferenceInterface(this,nameEnbStr,AbstractInterface::Input, AbstractInterface::Control,"boolean","1", AbstractInterface::LittleEndian, 1);
+    if (!iface->setAssociatedIface(dataIface)) {
+      throw (Exception(BLOCKFILE_CORRUPTED));      
+    }
+    clockStr = dataIface->getClockIfaceString();
+    if (! iface->checkSetClockIface(clockStr)) {
+      throw (Exception(BLOCKFILE_CORRUPTED));
+    }
+    cout << "created a control input named " << qPrintable(iface->getName()) << endl;
+    inputs.append(iface);
+  }
   QDomElement eltOutputs = eltInputs.nextSiblingElement("outputs");
   QDomNodeList listNodeOutputs = eltOutputs.elementsByTagName("output");
   for(int i=0;i<listNodeOutputs.size();i++) {
     QDomNode node = listNodeOutputs.at(i);
     QDomElement eltOutput = node.toElement();
   QDomElement eltOutputs = eltInputs.nextSiblingElement("outputs");
   QDomNodeList listNodeOutputs = eltOutputs.elementsByTagName("output");
   for(int i=0;i<listNodeOutputs.size();i++) {
     QDomNode node = listNodeOutputs.at(i);
     QDomElement eltOutput = node.toElement();
+
     nameStr = eltOutput.attribute("name","none");
     typeStr = eltOutput.attribute("type","none");
     widthStr = eltOutput.attribute("width","none");
     nameStr = eltOutput.attribute("name","none");
     typeStr = eltOutput.attribute("type","none");
     widthStr = eltOutput.attribute("width","none");
-    purposeStr = eltOutput.attribute("type","none");
+    endianStr = eltOutput.attribute("endian","none");
+    clockStr = eltOutput.attribute("clock","none");
+    int endianess;
+    if ((endianStr == "none") || (endianStr == "little")) {
+      endianess = AbstractInterface::LittleEndian;
+    }
+    else if (endianStr == "big") {
+      endianess = AbstractInterface::BigEndian;
+    }
+    else {
+      throw (Exception(BLOCKFILE_CORRUPTED));
+    }
+    purposeStr = eltOutput.attribute("purpose","none");
     purpose = ReferenceInterface::translatePurpose(purposeStr);
     purpose = ReferenceInterface::translatePurpose(purposeStr);
-    levelStr = eltOutput.attribute("level","none");
-    level = ReferenceInterface::translateLevel(levelStr);
     multStr = eltOutput.attribute("multiplicity","none");
     mult = ReferenceInterface::translateMultiplicity(multStr);
 
     multStr = eltOutput.attribute("multiplicity","none");
     mult = ReferenceInterface::translateMultiplicity(multStr);
 
-    inter = new ReferenceInterface(this,nameStr,typeStr,widthStr,AbstractInterface::Output, purpose, level, mult);
-    outputs.append(inter);
+    iface = new ReferenceInterface(this,nameStr,AbstractInterface::Output, purpose,typeStr,widthStr, endianess, mult);
+    if (clockStr == "none") {
+      if (clocks.size() > 1) {
+        // if several clocks, the associated one MUST be given
+        throw (Exception(BLOCKFILE_CORRUPTED));
+      }
+      // no clock given, take the single one
+      clockStr = clocks.at(0)->getName();
+    }
+    if (! iface->checkSetClockIface(clockStr)) {
+      throw (Exception(BLOCKFILE_CORRUPTED));
+    }
+
+    outputs.append(iface);
+  }
+  // getting each control
+  QDomNodeList listNodeOutCtl = eltOutputs.elementsByTagName("control");
+  for(int i=0;i<listNodeOutCtl.size();i++) {
+    QDomNode node = listNodeOutCtl.at(i);
+    QDomElement eltOutput = node.toElement();
+    nameStr = eltOutput.attribute("iface","none");
+    AbstractInterface* dataIface = getIfaceFromName(nameStr);
+    if (dataIface == NULL) throw (Exception(BLOCKFILE_CORRUPTED));
+    nameStr = dataIface->getName()+"_enb";
+    iface = new ReferenceInterface(this,nameStr,AbstractInterface::Output, AbstractInterface::Control,"boolean","1",AbstractInterface::LittleEndian, 1);
+    if (!iface->setAssociatedIface(dataIface)) {
+      throw (Exception(BLOCKFILE_CORRUPTED));      
+    }
+    clockStr = dataIface->getClockIfaceString();
+    if (! iface->checkSetClockIface(clockStr)) {
+      throw (Exception(BLOCKFILE_CORRUPTED));
+    }
+    cout << "created a control output named " << qPrintable(iface->getName()) << endl;
+    outputs.append(iface);
   }
 
   QDomElement eltBidirs = eltInputs.nextSiblingElement("bidirs");
   }
 
   QDomElement eltBidirs = eltInputs.nextSiblingElement("bidirs");
@@ -261,20 +378,65 @@ void ReferenceBlock::loadInterfaces(QDomElement &elt) throw(Exception) {
     nameStr = eltBidir.attribute("name","none");
     typeStr = eltBidir.attribute("type","none");
     widthStr = eltBidir.attribute("width","none");
     nameStr = eltBidir.attribute("name","none");
     typeStr = eltBidir.attribute("type","none");
     widthStr = eltBidir.attribute("width","none");
-    purposeStr = eltBidir.attribute("type","none");
+    endianStr = eltBidir.attribute("endian","none");
+    clockStr = eltBidir.attribute("clock","none");
+    int endianess;
+    if ((endianStr == "none") || (endianStr == "little")) {
+      endianess = AbstractInterface::LittleEndian;
+    }
+    else if (endianStr == "big") {
+      endianess = AbstractInterface::BigEndian;
+    }
+    else {
+      throw (Exception(BLOCKFILE_CORRUPTED));
+    }
+    purposeStr = eltBidir.attribute("purpose","none");
     purpose = ReferenceInterface::translatePurpose(purposeStr);
     purpose = ReferenceInterface::translatePurpose(purposeStr);
-    levelStr = eltBidir.attribute("level","none");
-    level = ReferenceInterface::translateLevel(levelStr);
     multStr = eltBidir.attribute("multiplicity","none");
     mult = ReferenceInterface::translateMultiplicity(multStr);
 
     multStr = eltBidir.attribute("multiplicity","none");
     mult = ReferenceInterface::translateMultiplicity(multStr);
 
-    inter = new ReferenceInterface(this,nameStr,typeStr,widthStr,AbstractInterface::InOut, purpose, level, mult);
-    bidirs.append(inter);
+    iface = new ReferenceInterface(this,nameStr,AbstractInterface::InOut, purpose,typeStr,widthStr, endianess, mult);
+    if (clockStr == "none") {
+      if (clocks.size() > 1) {
+        // if several clocks, the associated one MUST be given
+        throw (Exception(BLOCKFILE_CORRUPTED));
+      }
+      // no clock given, take the single one
+      clockStr = clocks.at(0)->getName();
+    }
+    if (! iface->checkSetClockIface(clockStr)) {
+      throw (Exception(BLOCKFILE_CORRUPTED));
+    }
+
+    bidirs.append(iface);
   }
 }
 
   }
 }
 
-void ReferenceBlock::parametersValidation(QList<AbstractBlock *> *checkedBlocks, QList<AbstractBlock *> *blocksToConfigure)
-{
+void ReferenceBlock::createInterfaceForWishbone() throw(Exception){
+  ReferenceInterface* iface = NULL;
+  foreach(BlockParameter* param, params) {
+    
+    if (param->isWishboneParameter()) {
+      
+      BlockParameterWishbone* p = (BlockParameterWishbone*)param;      
+      cout << "creating interface for parameter wb " << qPrintable(p->getName()) << endl;
+      
+      if (p->getWBAccess() == BlockParameter::Read) {
+        iface = new ReferenceInterface(this,p->getName(), AbstractInterface::Output, AbstractInterface::Wishbone, p->getTypeString(),p->getWidth(), AbstractInterface::LittleEndian, 1);
+        outputs.append(iface);        
+      }
+      else if (p->getWBAccess() == BlockParameter::Write) {
+        iface = new ReferenceInterface(this,p->getName(), AbstractInterface::Input, AbstractInterface::Wishbone,p->getTypeString(),p->getWidth(),AbstractInterface::LittleEndian,1);
+        inputs.append(iface);                
+      }
+      else {
+        throw (Exception(BLOCKFILE_CORRUPTED));
+      }
+    }
+  }
+}
+
+void ReferenceBlock::parametersValidation(QList<AbstractBlock *> *checkedBlocks, QList<AbstractBlock *> *blocksToConfigure) {
     return;
 }
 
     return;
 }
 
@@ -292,8 +454,9 @@ QDataStream& operator<<(QDataStream &out, const ReferenceBlock &b) {
 
   toWrite << b.name;
   toWrite << b.xmlFile;
 
   toWrite << b.name;
   toWrite << b.xmlFile;
-  toWrite << b.descriptionBrief;
-  toWrite << b.descriptionDetail;
+  toWrite << b.specialType;
+  toWrite << b.version;
+  toWrite << b.description;
   toWrite << b.categories;
   toWrite << b.hashMd5;
   toWrite << b.params.size();
   toWrite << b.categories;
   toWrite << b.hashMd5;
   toWrite << b.params.size();
@@ -318,34 +481,88 @@ QDataStream& operator<<(QDataStream &out, const ReferenceBlock &b) {
   }
 
   toWrite << b.inputs.size();
   }
 
   toWrite << b.inputs.size();
+  // firstly write clock ifaces
   for(int i=0; i<b.inputs.size(); i++){
     ReferenceInterface *iface = (ReferenceInterface *)(b.inputs.at(i));
   for(int i=0; i<b.inputs.size(); i++){
     ReferenceInterface *iface = (ReferenceInterface *)(b.inputs.at(i));
-    toWrite << iface->getName();
-    toWrite << iface->getWidth();
-    toWrite << iface->getPurpose();
-    toWrite << iface->getDirection();
-    toWrite << iface->getLevel();
-    toWrite << iface->getMultiplicity();
+    if (iface->getPurpose() == AbstractInterface::Clock) {
+      toWrite << iface->getName();
+      toWrite << iface->getType();
+      toWrite << iface->getWidthString();
+      toWrite << iface->getPurpose();
+      toWrite << iface->getDirection();
+      toWrite << iface->getMultiplicity();
+      toWrite << iface->getClockIfaceType();
+      toWrite << iface->getClockIfaceString();
+    }
+  }
+  // secondly write control ifaces
+  for(int i=0; i<b.inputs.size(); i++){
+    ReferenceInterface *iface = (ReferenceInterface *)(b.inputs.at(i));
+    if (iface->getPurpose() == AbstractInterface::Control) {
+      toWrite << iface->getName();
+      toWrite << iface->getType();
+      toWrite << iface->getWidthString();
+      toWrite << iface->getPurpose();
+      toWrite << iface->getDirection();    
+      toWrite << iface->getMultiplicity();
+      toWrite << iface->getClockIfaceType();
+      toWrite << iface->getClockIfaceString();
+    }
+  }
+  // thirdly, write other ifaces
+  for(int i=0; i<b.inputs.size(); i++){
+    ReferenceInterface *iface = (ReferenceInterface *)(b.inputs.at(i));
+    if ((iface->getPurpose() != AbstractInterface::Control) && (iface->getPurpose() != AbstractInterface::Clock)) {
+      toWrite << iface->getName();
+      toWrite << iface->getType();
+      toWrite << iface->getWidthString();
+      toWrite << iface->getPurpose();
+      toWrite << iface->getDirection();    
+      toWrite << iface->getMultiplicity();
+      toWrite << iface->getClockIfaceType();
+      toWrite << iface->getClockIfaceString();
+    }
   }
   toWrite << b.outputs.size();
   }
   toWrite << b.outputs.size();
+  // firstly write control ifaces
   for(int i=0; i<b.outputs.size(); i++){
     ReferenceInterface *iface = (ReferenceInterface *)(b.outputs.at(i));
   for(int i=0; i<b.outputs.size(); i++){
     ReferenceInterface *iface = (ReferenceInterface *)(b.outputs.at(i));
-    toWrite << iface->getName();
-    toWrite << iface->getWidth();
-    toWrite << iface->getPurpose();
-    toWrite << iface->getDirection();
-    toWrite << iface->getLevel();
-    toWrite << iface->getMultiplicity();
+    if (iface->getPurpose() == AbstractInterface::Control) {
+      toWrite << iface->getName();
+      toWrite << iface->getType();
+      toWrite << iface->getWidthString();
+      toWrite << iface->getPurpose();
+      toWrite << iface->getDirection();    
+      toWrite << iface->getMultiplicity();
+      toWrite << iface->getClockIfaceType();
+      toWrite << iface->getClockIfaceString();
+    }
+  }
+  // secondly, write other ifaces
+  for(int i=0; i<b.outputs.size(); i++){
+    ReferenceInterface *iface = (ReferenceInterface *)(b.outputs.at(i));
+    if (iface->getPurpose() != AbstractInterface::Control) {
+      toWrite << iface->getName();
+      toWrite << iface->getType();
+      toWrite << iface->getWidthString();
+      toWrite << iface->getPurpose();
+      toWrite << iface->getDirection();    
+      toWrite << iface->getMultiplicity();
+      toWrite << iface->getClockIfaceType();
+      toWrite << iface->getClockIfaceString();
+    }
   }
   toWrite << b.bidirs.size();
   for(int i=0; i<b.bidirs.size(); i++){
     ReferenceInterface *iface = (ReferenceInterface *)(b.bidirs.at(i));
     toWrite << iface->getName();
   }
   toWrite << b.bidirs.size();
   for(int i=0; i<b.bidirs.size(); i++){
     ReferenceInterface *iface = (ReferenceInterface *)(b.bidirs.at(i));
     toWrite << iface->getName();
-    toWrite << iface->getWidth();
+    toWrite << iface->getType();
+    toWrite << iface->getWidthString();
     toWrite << iface->getPurpose();
     toWrite << iface->getPurpose();
-    toWrite << iface->getDirection();
-    toWrite << iface->getLevel();
+    toWrite << iface->getDirection();    
     toWrite << iface->getMultiplicity();
     toWrite << iface->getMultiplicity();
+    toWrite << iface->getClockIfaceType();
+    toWrite << iface->getClockIfaceString();
   }
 
   out << blockData;
   }
 
   out << blockData;
@@ -367,8 +584,9 @@ QDataStream& operator>>(QDataStream &in, ReferenceBlock &b) {
 
   in >> b.name;
   in >> b.xmlFile;
 
   in >> b.name;
   in >> b.xmlFile;
-  in >> b.descriptionBrief;
-  in >> b.descriptionDetail;
+  in >> b.specialType;
+  in >> b.version;
+  in >> b.description;
   in >> b.categories;
   in >> b.hashMd5;
   b.params.clear();
   in >> b.categories;
   in >> b.hashMd5;
   b.params.clear();
@@ -386,7 +604,7 @@ QDataStream& operator>>(QDataStream &in, ReferenceBlock &b) {
     in >> valueStr;
 
     if (contextStr == "user") {
     in >> valueStr;
 
     if (contextStr == "user") {
-      p = new BlockParameterUser(&b,nameStr,valueStr);
+      p = new BlockParameterUser(&b,nameStr,typeStr,valueStr);
     }
     else if (contextStr == "generic") {
       p = new BlockParameterGeneric(&b,nameStr,typeStr,valueStr);
     }
     else if (contextStr == "generic") {
       p = new BlockParameterGeneric(&b,nameStr,typeStr,valueStr);
@@ -416,17 +634,33 @@ QDataStream& operator>>(QDataStream &in, ReferenceBlock &b) {
     iface = new ReferenceInterface(&b);
     in >> txt;
     iface->setName(txt);
     iface = new ReferenceInterface(&b);
     in >> txt;
     iface->setName(txt);
+    int type;
+    in >> type;
+    iface->setType(type);
     in >> txt;
     iface->setWidth(txt);
     in >> val;
     in >> txt;
     iface->setWidth(txt);
     in >> val;
-    iface->setPurpose(val);
-    in >> val;
-    iface->setDirection(val);
+    iface->setPurpose(val);    
     in >> val;
     in >> val;
-    iface->setLevel(val);
+    iface->setDirection(val);    
     in >> val;
     iface->setMultiplicity(val);
     in >> val;
     iface->setMultiplicity(val);
+    int clkType;
+    QString clk;
+    in >> clkType;
+    in >> clk;
+    iface->setClockIfaceName(clk);
+    iface->setClockIfaceType(clkType);
     b.inputs.append(iface);
     b.inputs.append(iface);
+    if (iface->getPurpose() == AbstractInterface::Data) {
+      QString ctlRefName = iface->getName()+"_enb";
+      ReferenceInterface* ctlRefIface = AI_TO_REF(b.getIfaceFromName(ctlRefName));      
+      if (ctlRefIface != NULL) {        
+        if (! ctlRefIface->setAssociatedIface(iface)) {
+          cerr << "Abnormal case while reading a reference block in library: cannot set associated control interface for data interface" << endl;
+        }      
+      }        
+    }    
   }
 
   b.outputs.clear();
   }
 
   b.outputs.clear();
@@ -435,17 +669,33 @@ QDataStream& operator>>(QDataStream &in, ReferenceBlock &b) {
     iface = new ReferenceInterface(&b);
     in >> txt;
     iface->setName(txt);
     iface = new ReferenceInterface(&b);
     in >> txt;
     iface->setName(txt);
+    int type;
+    in >> type;
+    iface->setType(type);
     in >> txt;
     iface->setWidth(txt);
     in >> val;
     in >> txt;
     iface->setWidth(txt);
     in >> val;
-    iface->setPurpose(val);
+    iface->setPurpose(val);    
     in >> val;
     iface->setDirection(val);
     in >> val;
     iface->setDirection(val);
-    in >> val;
-    iface->setLevel(val);
-    in >> val;
+    in >> val;   
     iface->setMultiplicity(val);
     iface->setMultiplicity(val);
+    int clkType;
+    QString clk;
+    in >> clkType;
+    in >> clk;
+    iface->setClockIfaceName(clk);
+    iface->setClockIfaceType(clkType);
     b.outputs.append(iface);
     b.outputs.append(iface);
+    if (iface->getPurpose() == AbstractInterface::Data) {
+      QString ctlRefName = iface->getName()+"_enb";      
+      ReferenceInterface* ctlRefIface = AI_TO_REF(b.getIfaceFromName(ctlRefName));      
+      if (ctlRefIface != NULL) {        
+        if (! ctlRefIface->setAssociatedIface(iface)) {
+          cerr << "Abnormal case while reading a reference block in library" << endl;
+        }      
+      }        
+    }    
   }
 
   b.bidirs.clear();
   }
 
   b.bidirs.clear();
@@ -454,18 +704,71 @@ QDataStream& operator>>(QDataStream &in, ReferenceBlock &b) {
     iface = new ReferenceInterface(&b);
     in >> txt;
     iface->setName(txt);
     iface = new ReferenceInterface(&b);
     in >> txt;
     iface->setName(txt);
+    int type;
+    in >> type;
+    iface->setType(type);
     in >> txt;
     iface->setWidth(txt);
     in >> val;
     iface->setPurpose(val);
     in >> val;
     iface->setDirection(val);
     in >> txt;
     iface->setWidth(txt);
     in >> val;
     iface->setPurpose(val);
     in >> val;
     iface->setDirection(val);
-    in >> val;
-    iface->setLevel(val);
-    in >> val;
+    in >> val;    
     iface->setMultiplicity(val);
     iface->setMultiplicity(val);
+    int clkType;
+    QString clk;
+    in >> clkType;
+    in >> clk;
+    iface->setClockIfaceName(clk);
+    iface->setClockIfaceType(clkType);
     b.bidirs.append(iface);
   }
 
   return in;
 }
     b.bidirs.append(iface);
   }
 
   return in;
 }
+
+void ReferenceBlock::checkInputPatternCompatibility()  throw(Exception){
+  throw(Exception(INVALID_REFBLOCK_USE));
+}
+
+void ReferenceBlock::computeOutputPattern(int nbExec)  throw(Exception) {
+  // does strictly nothing
+  throw(Exception(INVALID_REFBLOCK_USE));  
+}
+
+void ReferenceBlock::computeAdmittanceDelays() throw(Exception) {
+  // does strictly nothing
+  throw(Exception(INVALID_REFBLOCK_USE));
+}
+
+
+void ReferenceBlock::generateVHDL(const QString& path) throw(Exception){
+ throw(Exception(INVALID_REFBLOCK_USE));
+}
+
+void ReferenceBlock::generateComments(QTextStream& out, QDomElement &elt, QString coreFile) throw(Exception) {
+  throw(Exception(INVALID_REFBLOCK_USE));
+}
+
+void ReferenceBlock::generateLibraries(QTextStream& out, QDomElement &elt) throw(Exception) {
+  throw(Exception(INVALID_REFBLOCK_USE));
+}
+
+void ReferenceBlock::generateArchitecture(QTextStream& out, QDomElement &elt ) throw(Exception) {
+  throw(Exception(INVALID_REFBLOCK_USE));
+}
+
+void ReferenceBlock::generateController(QTextStream& out) throw(Exception) {
+  throw(Exception(INVALID_REFBLOCK_USE));
+}
+
+void ReferenceBlock::generateEntityOrComponentBody(QTextStream &out, int indentLevel, bool hasController) throw(Exception) {
+  throw(Exception(INVALID_REFBLOCK_USE));
+}
+
+QList<QString> ReferenceBlock::getExternalResources() {
+  QList<QString> list;
+  return list;
+}
+
+