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

Private GIT Repository
finished testbench generation
[blast.git] / Dispatcher.cpp
index bbbb945399fec32d5221e8b6f608b3a2867dd871..574243ef2a2287fec1e5cf03a0e559bbc50c2cc3 100644 (file)
@@ -2,6 +2,8 @@
 #include "Parameters.h"
 #include "MainWindow.h"
 
+#include "ExternalResource.h"
+
 #include "Graph.h"
 #include "ReferenceBlock.h"
 #include "GroupBlock.h"
 #include "GroupScene.h"
 #include "GroupItem.h"
 #include "BoxItem.h"
-#include "SourceItem.h"
+#include "StimuliItem.h"
 #include "InterfaceItem.h"
 #include "ConnectionItem.h"
 
 #include "BlockLibraryWidget.h"
 #include "BlockLibraryTree.h"
 
-#include "InterfacePropertiesWindow.h"
+#include "AbstractInputModifier.h"
+#include "DelayInputModifier.h"
+
+
+#include "InterfacePropertiesDialog.h"
+
+#include <QHashIterator>
 
 int Dispatcher::sceneCounter = 0;
 
@@ -31,8 +39,8 @@ Dispatcher::Dispatcher(Parameters* _params, MainWindow* _window) {
   params = _params;
   mainWindow =_window;
   params->setDispatcher(this);
-  currentGroup = NULL;
-  topGroup = NULL;    
+  currentGroupWidget = NULL;
+  topGroupWidget = NULL;
 }
 
 GroupWidget *Dispatcher::loadProject(const QString& filename) {
@@ -56,7 +64,7 @@ GroupWidget *Dispatcher::loadProject(const QString& filename) {
   params->setCurrentScene(scene);
 */
   try {   
-    topGroup = params->loadProject(root);
+    topGroupWidget = params->loadProject(root);
   }
   catch(Exception e){
     cerr << qPrintable(e.getDefaultMessage()) << endl;
@@ -65,8 +73,12 @@ GroupWidget *Dispatcher::loadProject(const QString& filename) {
     return NULL;
   }
 
-  groupList.append(topGroup);
-  return topGroup;
+  QFileInfo info(filename);
+  params->projectPath = info.absolutePath();
+  params->projectName = info.baseName();
+  cout << "project path = " << qPrintable(params->projectPath) << endl;
+  groupList.append(topGroupWidget);
+  return topGroupWidget;
 }
 
 void Dispatcher::closeCurrentProject() {
@@ -76,41 +88,72 @@ void Dispatcher::closeCurrentProject() {
   }
   groupList.clear();
   params->destroyGraph();
-  topGroup = NULL;
-  currentGroup = NULL;
+  topGroupWidget = NULL;
+  currentGroupWidget = NULL;
   sceneCounter = 0;
 }
 
-bool Dispatcher::createConnectionItem(InterfaceItem *iface1, InterfaceItem *iface2) {
+void Dispatcher::setSceneCounter(Context context, int value) {
+
+  if (context != Load) return;
+  sceneCounter = value;
+}
+
+bool Dispatcher::createConnection(Context context, InterfaceItem *iface1, InterfaceItem *iface2, bool visible) {
+  static QString fctName = "Dispatcher::createConnection()";
+#ifdef DEBUG_FCTNAME
+  cout << "call to " << qPrintable(fctName) << endl;
+#endif
+
+  bool testClock = false;
+  if (context == Design) {
+    testClock = true;
+  }
 
   ConnectedInterface* ref1 = iface1->refInter;
-  ConnectedInterface* ref2 = iface2->refInter;
+  ConnectedInterface* ref2 = iface2->refInter;  
   // connect both interface
 
   bool ok1 = false;
   bool ok2 = false;
 
-  if (ref1->canConnectTo(ref2)) {
-    ok1 = ref1->connectTo(ref2);
-    ok1 = ok1 & ref2->connectFrom(ref1);
+  cout << "trying to create a connection between " << qPrintable(ref1->getOwner()->getName()) << "/" << qPrintable(ref1->getName());
+  cout << " and " << qPrintable(ref2->getOwner()->getName()) << "/" << qPrintable(ref2->getName());
+
+  // test the ref1->ref2 connection
+  if ((ref1->canConnectTo(ref2,testClock)) && (ref2->canConnectFrom(ref1,testClock))) {
+    ref1->connectTo(ref2);    
+    ok1 = true;
   }
-  if (ref2->canConnectTo(ref1)) {
-    ok2 = ref2->connectTo(ref1);
-    ok2 = ok2 & ref1->connectFrom(ref2);
+  // if the first one did not work, test ref2->ref1
+  if ((ok1 == false) && (ref2->canConnectTo(ref1,testClock)) && (ref1->canConnectFrom(ref2,testClock))) {
+    ref2->connectTo(ref1);    
+    ok2 = true;
   }
-  if ((ok1 == true) || (ok2 == true)) {
+  if ((ok1 == true) || (ok2 == true)) {    
 
-    iface1->getOwner()->getScene()->createConnectionItem(iface1,iface2);
+    if (ok1) {
+      cout << " ... done with " << qPrintable(ref1->getOwner()->getName()) << "/" << qPrintable(ref1->getName());
+      cout << " to " << qPrintable(ref2->getOwner()->getName()) << "/" << qPrintable(ref2->getName());
+      iface1->getOwner()->getScene()->createConnectionItem(iface1,iface2, visible);
+    }
+    else {
+      cout << "... done with " << qPrintable(ref2->getOwner()->getName()) << "/" << qPrintable(ref2->getName());
+      cout << " to " << qPrintable(ref1->getOwner()->getName()) << "/" << qPrintable(ref1->getName());
+      iface2->getOwner()->getScene()->createConnectionItem(iface2,iface1, visible);
+    }
 
-    unselectAllItems();
-    params->unsaveModif = true;
+    cout << endl;
+
+    unselectAllItems(context);
+    params->unsaveModif = true;    
     return true;
   }
   return false;
 }
 
 
-void Dispatcher::unselectAllItems(int direction){
+void Dispatcher::unselectAllItems(Context context, int direction){
 
   GroupScene *scene = params->getCurrentScene();
 
@@ -122,14 +165,14 @@ void Dispatcher::unselectAllItems(int direction){
   scene->update();
 }
 
-void Dispatcher::setCurrentGroupWidget(GroupWidget *win){
+void Dispatcher::setCurrentGroupWidget(Context context, GroupWidget *win){
   win->setFocus();
   win->changeConnectionMode(-1);
-  currentGroup = win;
+  currentGroupWidget = win;
   params->setCurrentScene(win->getScene());
 }
 
-void Dispatcher::changeConnectionMode(int mode){
+void Dispatcher::changeConnectionMode(Context context, int mode){
 
   /*
   foreach(GroupWidget* win, groupList){
@@ -164,11 +207,150 @@ void Dispatcher::changeConnectionMode(int mode){
   */
 }
 
-void Dispatcher::renameFunctionalBlock(BoxItem *item){
+void Dispatcher::generateVHDL(Context context) throw(Exception) {
+  static QString fctName = "Dispatcher::generateVHDL()";
+#ifdef DEBUG_FCTNAME
+  cout << "call to " << qPrintable(fctName) << endl;
+#endif
+  /* NB: only called in Design context */
+  if (context != Design) {
+    cout << "Abnormal case: call to " << qPrintable(fctName) << " not in Design context" << endl;
+    return;
+  }
+
+
+  QDir baseDir(params->projectPath);
+  QDir srcDir(params->projectPath+"/src");
+
+  if (!baseDir.exists()) {
+    cerr << "Project path " << qPrintable(params->projectPath) << " no longer exists. First, recreate it and put the project file within. Then retry to generate." << endl;
+    return;
+  }
+
+  if (srcDir.exists()) {
+    srcDir.removeRecursively();
+  }
+  baseDir.mkdir("src");
+
+  if (! baseDir.exists("testbench")) {
+    baseDir.mkdir("testbench");
+  }
+  if (! baseDir.exists("Makefile")) {
+    QFile make("/home/sdomas/Projet/Blast/code/blast/Makefile-isim");
+    QString dest = params->projectPath;
+    dest += "/Makefile";
+    make.copy(dest);
+  }
+
+  // generate VHDL + copying external resources
+  QString dest = params->projectPath;
+  dest += "/src/";  
+  try {    
+    params->getGraph()->generateVHDL(dest);
+
+    QList<QString> extResources = params->getGraph()->getExternalResources();
+    foreach(QString name, extResources) {
+      cout << qPrintable(name) << endl;
+      QList<ExternalResource*> lstRes = params->searchResourceByName(name);
+      foreach(ExternalResource* res, lstRes) {
+        QFile resFile(res->getFile());
+        QFileInfo info(res->getFile());
+        QString destFile = dest+info.fileName();
+        cout << "copying " << qPrintable(res->getFile()) << " into " << qPrintable(destFile) << endl;
+        resFile.copy(destFile);
+      }
+    }
+  }
+  catch(Exception e) {
+    throw(e);
+  }
+  // generate testbench
+  dest = params->projectPath;
+  dest += "/testbench/";
+  dest += params->projectName;
+  dest += "_tb.vhd";
+  try {
+    params->getGraph()->generateTestbench(params->projectName, dest);
+  }
+  catch(Exception e) {
+    throw(e);
+  }
+
+  // creating parameters file
+  QString paramName = params->projectPath+"/params-isim.txt";
+  QFile paramFile(paramName);
+  if (!paramFile.open(QIODevice::WriteOnly)) {
+    throw(Exception(PROJECTPATH_NOACCESS));
+  }
+  QTextStream out(&paramFile);
+  out << "PROJECT_NAME := " << params->projectName << endl << endl;
+  out << "SRC_DIR := src" << endl;
+  out << "TB_DIR := testbench" << endl << endl;
+  out << "VHDL_SRC := ";
+  QStringList filter;
+  filter << "*.vhd" ;
+  srcDir.setNameFilters(filter);
+  QStringList listVHDL = srcDir.entryList();
+  for(int j=0;j<listVHDL.size();j++) {
+    if (j > 0) {
+      out << "\t";
+    }
+    out << "$(SRC_DIR)/" << qPrintable(listVHDL.at(j));
+    if (j != listVHDL.size()-1) {
+      out << " \\";
+    }
+    out << endl;
+  }
+  out << endl;
+  out << "VL_SRC := ${XILINX}/verilog/src/glbl.v" << endl << endl;
+  out << "TB_SRC := $(TB_DIR)/$(PROJECT_NAME)_tb.vhd" << endl << endl;
+  out << "SIMU_EXE := $(PROJECT_NAME)_tb" << endl << endl;
+
+  paramFile.close();
+
+  QString msg = "VHDL generation completed successfully. Go to ";
+  msg += params->projectPath+" and type the following commands to launch a simulation:\n";
+  msg += "\tmake clean\n";
+  msg += "\tmake\n";
+  msg += "\tmake view\n";
+  QMessageBox::information(mainWindow,"VHDL generation", msg, QMessageBox::Ok);
+
+}
+
+void Dispatcher::generateBlockVHDL(Context context, BoxItem *item){
+  static QString fctName = "Dispatcher::generateBlockVHDL()";
+#ifdef DEBUG_FCTNAME
+  cout << "call to " << qPrintable(fctName) << endl;
+#endif
+  /* NB: only called in Design context */
+  if (context != Design) {
+    cout << "Abnormal case: call to " << qPrintable(fctName) << " not in Design context" << endl;
+    return;
+  }
+
+
+  if (item->getRefBlock()->isFunctionalBlock()) {
+    FunctionalBlock* block = AB_TO_FUN(item->getRefBlock());
+    try {
+      block->generateVHDL(params->projectPath);      
+    }
+    catch(Exception e) {
+      cout << qPrintable(e.getMessage()) << endl;
+    }
+  }
+}
+
+void Dispatcher::renameFunctionalBlock(Context context, BoxItem *item){
   static QString fctName = "Dispatcher::renameFunctionalBlock()";
 #ifdef DEBUG_FCTNAME
   cout << "call to " << qPrintable(fctName) << endl;
 #endif
+  /* NB: only called in Design context */
+  if (context != Design) {
+    cout << "Abnormal case: call to " << qPrintable(fctName) << " not in Design context" << endl;
+    return;
+  }
+
     
   GroupWidget* win = item->getScene()->getGroupWidget();
   
@@ -203,11 +385,17 @@ void Dispatcher::renameFunctionalBlock(BoxItem *item){
   item->nameChanged();
 }
 
-void Dispatcher::renameGroupBlock(GroupItem *item){
+void Dispatcher::renameGroupBlock(Context context, GroupItem *item){
   static QString fctName = "Dispatcher::renameGroupBlock()";
 #ifdef DEBUG_FCTNAME
   cout << "call to " << qPrintable(fctName) << endl;
 #endif
+  /* NB: only called in Design context */
+  if (context != Design) {
+    cout << "Abnormal case: call to " << qPrintable(fctName) << " not in Design context" << endl;
+    return;
+  }
+
   
   GroupWidget* win = item->getScene()->getGroupWidget();
   
@@ -249,18 +437,24 @@ void Dispatcher::renameGroupBlock(GroupItem *item){
   mainWindow->getLibrary()->updateComboScene();   
 }
 
-void Dispatcher::renameSourceBlock(SourceItem *item){
-  static QString fctName = "Dispatcher::renameSourceBlock()";
+void Dispatcher::renameStimuliItem(Context context, StimuliItem *item){
+  static QString fctName = "Dispatcher::renameStimuliItem()";
 #ifdef DEBUG_FCTNAME
   cout << "call to " << qPrintable(fctName) << endl;
 #endif
+  /* NB: only called in Design context */
+  if (context != Design) {
+    cout << "Abnormal case: call to " << qPrintable(fctName) << " not in Design context" << endl;
+    return;
+  }
+
     
   GroupWidget* win = item->getScene()->getGroupWidget();
   
   bool ok = false;
   QString text = "";  
   while (!ok) {  
-    text = QInputDialog::getText(win, "Rename a source",
+    text = QInputDialog::getText(win, "Rename a stimuli",
                                        "New name:", QLineEdit::Normal,
                                        item->getRefBlock()->getName(), &ok);
     if (!ok) return;
@@ -274,10 +468,10 @@ void Dispatcher::renameSourceBlock(SourceItem *item){
       ok = false;
     }
     else {
-      FunctionalBlock* block = params->getGraph()->getSourceBlockByName(text);
+      FunctionalBlock* block = params->getGraph()->getStimuliBlockByName(text);
       if (block != NULL) {
         QMessageBox::warning(win,"Error in given name",
-                             "the name provided is similar to that of another source block within the top group",
+                             "the name provided is similar to that of another stimuli block within the top group",
                              QMessageBox::Ok);
         ok = false;
       }
@@ -289,11 +483,16 @@ void Dispatcher::renameSourceBlock(SourceItem *item){
 }
 
 
-void Dispatcher::renameInterface(InterfaceItem *item) {
+void Dispatcher::renameInterface(Context context, InterfaceItem *item) {
   static QString fctName = "Dispatcher::renameInterface()";
 #ifdef DEBUG_FCTNAME
   cout << "call to " << qPrintable(fctName) << endl;
 #endif
+  /* NB: only called in Design context */
+  if (context != Design) {
+    cout << "Abnormal case: call to " << qPrintable(fctName) << " not in Design context" << endl;
+    return;
+  }
 
   GroupWidget* win = item->getOwner()->getScene()->getGroupWidget();
   
@@ -327,17 +526,117 @@ void Dispatcher::renameInterface(InterfaceItem *item) {
   item->refInter->setName(text);
   AbstractInterface* assoIface = item->refInter->getAssociatedIface();
   if (assoIface != NULL) {
-    assoIface->setName(text+"_ctl");
+    assoIface->setName(text+"_enb");
   }
   item->updateName(text);
   item->getOwner()->nameChanged();  
 }
 
-void Dispatcher::duplicateBoxItem(BoxItem *item){
+void Dispatcher::showPatterns(Context context, InterfaceItem *item) {
+  static QString fctName = "Dispatcher::showPatterns()";
+#ifdef DEBUG_FCTNAME
+  cout << "call to " << qPrintable(fctName) << endl;
+#endif
+  /* NB: only called in Design context */
+  if (context != Design) {
+    cout << "Abnormal case: call to " << qPrintable(fctName) << " not in Design context" << endl;
+    return;
+  }
+
+  QString msg = "";
+  if (item->refInter->getDirection() == AbstractInterface::Input) {
+    msg = "Input pattern of iface ";
+    msg += item->refInter->getName();
+    msg += " owned by ";
+    msg += item->refInter->getOwner()->getName();
+    msg += " is:\n";
+    // get the precursor output pattern
+    ConnectedInterface* connIface = AI_TO_CON(item->refInter->getAssociatedIface());
+    QList<char>* out = connIface->getConnectedFrom()->getOutputPattern();
+    // get the modifier
+    AbstractInputModifier* modifier = connIface->getInputModifier();
+    // check if the input is modified
+    if (modifier != NULL) {
+
+      out = modifier->getModifiedInput(out);
+    }
+
+    foreach(char c, *out) {
+      msg += QString::number((int)c);
+    }
+    msg += "\n";
+  }
+  else if (item->refInter->getDirection() == AbstractInterface::Output) {
+    msg = "Output pattern of iface ";
+    msg += item->refInter->getName();
+    msg += " owned by ";
+    msg += item->refInter->getOwner()->getName();
+    msg += " is:\n";
+    ConnectedInterface* iface = AI_TO_CON(item->refInter->getAssociatedIface());
+    if (iface->getOutputPattern() == NULL) return;
+    foreach(char c, *(iface->getOutputPattern())) {
+      msg += QString::number((int)c);
+    }
+    msg += "\n";
+  }
+  QMessageBox::information(NULL,"Interface pattern",msg,QMessageBox::Ok,QMessageBox::Ok);
+}
+
+void Dispatcher::showModifier(Context context, InterfaceItem *item) {
+  static QString fctName = "Dispatcher::showModifier()";
+#ifdef DEBUG_FCTNAME
+  cout << "call to " << qPrintable(fctName) << endl;
+#endif
+  /* NB: only called in Design context */
+  if (context != Design) {
+    cout << "Abnormal case: call to " << qPrintable(fctName) << " not in Design context" << endl;
+    return;
+  }
+
+  QString msg = "";
+  ConnectedInterface* assoIface = AI_TO_CON(item->refInter->getAssociatedIface());
+  AbstractInputModifier* mod = assoIface->getInputModifier();
+  if (mod->isDelay()) {
+    DelayInputModifier* delay = (DelayInputModifier *)mod;
+    msg = "Pattern of iface ";
+    msg += item->refInter->getName();
+    msg += " owned by ";
+    msg += item->refInter->getOwner()->getName();
+    msg += " is modified by a simple delay of ";
+    msg += QString::number(delay->getDelayLength());
+
+  }
+  QMessageBox::information(NULL,"Interface pattern",msg,QMessageBox::Ok,QMessageBox::Ok);
+}
+
+void Dispatcher::removeModifier(Context context, InterfaceItem *item) {
+  static QString fctName = "Dispatcher::removeModifier()";
+#ifdef DEBUG_FCTNAME
+  cout << "call to " << qPrintable(fctName) << endl;
+#endif
+  /* NB: only called in Design context */
+  if (context != Design) {
+    cout << "Abnormal case: call to " << qPrintable(fctName) << " not in Design context" << endl;
+    return;
+  }
+
+
+  ConnectedInterface* assoIface = AI_TO_CON(item->refInter->getAssociatedIface());
+  assoIface->clearInputModifier();
+}
+
+
+void Dispatcher::duplicateBoxItem(Context context, BoxItem *item){
   static QString fctName = "Dispatcher::duplicateBoxItem()";
 #ifdef DEBUG_FCTNAME
   cout << "call to " << qPrintable(fctName) << endl;
 #endif
+  /* NB: only called in Design context */
+  if (context != Design) {
+    cout << "Abnormal case: call to " << qPrintable(fctName) << " not in Design context" << endl;
+    return;
+  }
+
 
   GroupScene *scene = item->getScene();
   AbstractBlock* block = item->getRefBlock();  
@@ -356,11 +655,17 @@ void Dispatcher::duplicateBoxItem(BoxItem *item){
   }
 }
 
-void Dispatcher::duplicateSourceItem(SourceItem *item) {
-  static QString fctName = "Dispatcher::duplicateSourceItem()";
+void Dispatcher::duplicateStimuliItem(Context context, StimuliItem *item) {
+  static QString fctName = "Dispatcher::duplicateStimuliItem()";
 #ifdef DEBUG_FCTNAME
   cout << "call to " << qPrintable(fctName) << endl;
 #endif
+  /* NB: only called in Design context */
+  if (context != Design) {
+    cout << "Abnormal case: call to " << qPrintable(fctName) << " not in Design context" << endl;
+    return;
+  }
+
 
   GroupScene *scene = item->getScene();
   AbstractBlock* block = item->getRefBlock();  
@@ -371,19 +676,25 @@ void Dispatcher::duplicateSourceItem(SourceItem *item) {
 
     // adding to the model
     FunctionalBlock* funBlock = (FunctionalBlock*)block;
-    newBlock = params->getGraph()->duplicateSourceBlock(funBlock);
+    newBlock = params->getGraph()->duplicateStimuliBlock(funBlock);
     // adding to the view
-    scene->createSourceItem(newBlock);
+    scene->createStimuliItem(newBlock);
 
     params->unsaveModif = true;
   }
 }
 
-void Dispatcher::duplicateInterfaceItem(InterfaceItem *item) {
+void Dispatcher::duplicateInterfaceItem(Context context, InterfaceItem *item) {
   static QString fctName = "Dispatcher::duplicateInterfaceItem()";
 #ifdef DEBUG_FCTNAME
   cout << "call to " << qPrintable(fctName) << endl;
 #endif
+  /* NB: only called in Design context */
+  if (context != Design) {
+    cout << "Abnormal case: call to " << qPrintable(fctName) << " not in Design context" << endl;
+    return;
+  }
+
 
   AbstractInterface *refI = item->refInter;
   if (! refI->isFunctionalInterface()) return;
@@ -401,12 +712,12 @@ void Dispatcher::duplicateInterfaceItem(InterfaceItem *item) {
   refB->addInterface(cloneIface);
 
   InterfaceItem *cloneIfaceItem = new InterfaceItem(item->getPosition(),item->getOrientation(),(ConnectedInterface*)cloneIface,item->getOwner(),params);
-  item->getOwner()->addInterface(cloneIfaceItem,true);
+  item->getOwner()->addInterfaceItem(cloneIfaceItem,true);
   
   // creating control interface if needed
   if (refI->getAssociatedIface() != NULL) {
-    QString ctlName = cloneIface->getName()+"_ctl";
-    ReferenceInterface* ctlIface = new ReferenceInterface(refB,ctlName,"boolean","1",cloneIface->getDirection(), AbstractInterface::Control, 1);
+    QString ctlName = cloneIface->getName()+"_enb";
+    ReferenceInterface* ctlIface = new ReferenceInterface(refB,ctlName,cloneIface->getDirection(), AbstractInterface::Control,"boolean","1", AbstractInterface::LittleEndian, 1);
     refB->addInterface(ctlIface);
     if (! ctlIface->setAssociatedIface(cloneIface)) {
       cerr << "Abnormal case while cloning an interface and creating its associated control interface" << endl;
@@ -415,91 +726,201 @@ void Dispatcher::duplicateInterfaceItem(InterfaceItem *item) {
 }
 
 
-void Dispatcher::addBlock(int idCategory, int idBlock, int idScene) {
+void Dispatcher::addBlock(Context context, int idCategory, int idBlock, int idScene, QHash<QString, int> clkRstToGen) {
   static QString fctName = "Dispatcher::addBlock()";
 #ifdef DEBUG_FCTNAME
   cout << "call to " << qPrintable(fctName) << endl;
 #endif
-  bool newSource = false;
-  GroupScene *scene = getSceneById(idScene);
-  ReferenceBlock* ref = params->getReferenceBlock(idCategory,idBlock);
-  // if block has no inputs, propose to add it as a source to top scene
-  if ((scene->isTopScene()) && (ref->getDataInputs().isEmpty())) {
-    int ret = QMessageBox::question(NULL,"Adding a block to top scene","Selected block may be used as a source for the top scene. Do you want to add it as a source ?");
-    if (ret == QMessageBox::Yes) {
-      newSource = true;      
-    }   
-  }
-  if (newSource) {
-    FunctionalBlock* newOne = params->getGraph()->createSourceBlock(ref);
-    scene->createSourceItem(newOne);
+  bool newStimuli = false;  
+
+  /* For now, this method is only used while designing and not loading */
+  if (context == Design) {
+    GroupScene *scene = getSceneById(idScene);
+    ReferenceBlock* ref = params->getReferenceBlock(idCategory,idBlock);
+    // if block has no inputs, propose to add it as a source to top scene
+    if ((scene->isTopScene()) && (ref->isSourceBlock())) {
+      int ret = QMessageBox::question(NULL,"Adding a block to top scene","Selected block may be used as a stimuli for the top scene. Do you want to add it as a stimuli ?");
+      if (ret == QMessageBox::Yes) {
+        newStimuli = true;
+      }
+    }
+    if (newStimuli) {
+      FunctionalBlock* newOne = params->getGraph()->createStimuliBlock(ref, true);
+      StimuliItem* item = scene->createStimuliItem(newOne);
+      QHashIterator<QString,int> iter(clkRstToGen);
+      while (iter.hasNext()) {
+        iter.next();
+        AbstractInterface* iface = newOne->getIfaceFromName(iter.key());
+        if (iface->getPurpose() == AbstractInterface::Clock) {
+          connectStimuliItemClock(context,item,iface->getName(),iter.value());
+        }
+        else if (iface->getPurpose() == AbstractInterface::Reset) {
+          connectStimuliItemReset(context,item,iface->getName(),iter.value());
+        }
+      }
+    }
+    else {
+
+      GroupBlock* group = AB_TO_GRP(scene->getGroupItem()->getRefBlock());
+      FunctionalBlock* newOne = params->getGraph()->createFunctionalBlock(group, ref, true);
+
+      // creating the box item
+      BoxItem* item = scene->createBoxItem(newOne);
+
+      QHashIterator<QString,int> iter(clkRstToGen);
+      while (iter.hasNext()) {
+        iter.next();
+        AbstractInterface* iface = newOne->getIfaceFromName(iter.key());
+        if (iface->getPurpose() == AbstractInterface::Clock) {
+          connectBoxItemClock(context,item,iface->getName(),iter.value());
+        }
+        else if (iface->getPurpose() == AbstractInterface::Reset) {
+          connectBoxItemReset(context,item,iface->getName(),iter.value());
+        }
+      }
+
+      params->blockToItem.insert(newOne,item);
+    }
+    params->unsaveModif = true;
   }
-  else {
-    GroupBlock* group = AB_TO_GRP(scene->getGroupItem()->getRefBlock());
-    FunctionalBlock* newOne = params->getGraph()->createFunctionalBlock(group, ref);
-    scene->createBoxItem(newOne);
+}
+
+void Dispatcher::addClkRstGenBlock(Context context, double frequency) {
+  static QString fctName = "Dispatcher::addClkRstGenBlock()";
+#ifdef DEBUG_FCTNAME
+  cout << "call to " << qPrintable(fctName) << endl;
+#endif
+
+
+  if (context == Design) {
+
+    params->getGraph()->addClock(frequency);
+
+    // get the top group
+    GroupBlock *group = params->getGraph()->getTopGroup();
+    GroupScene *scene = topGroupWidget->getScene();
+
+    // creating the clkrstgen block
+    ReferenceBlock* ref = params->getHiddenReferenceBlock("clkrstgen");
+    FunctionalBlock* newOne = params->getGraph()->createFunctionalBlock(group, ref, true);
+
+    QString name = "clkrstgen_";
+    name += QString::number(params->getGraph()->getClocks().size()-1);
+    newOne->setName(name);
+
+    // creating the box item
+    BoxItem* item = scene->createBoxItem(newOne, BoxItem::Left, AbstractBoxItem::Dimension);
+    item->setVisible(false);
+
+    ConnectedInterface* fromIfaceClk = NULL;
+    ConnectedInterface* fromIfaceReset = NULL;
+    QString clkName = "ext_clk_"+QString::number(params->getGraph()->getClocks().size()-1);
+    QString rstName = "ext_reset_"+QString::number(params->getGraph()->getClocks().size()-1);
+    fromIfaceClk = new GroupInterface(group,clkName, AbstractInterface::Input, AbstractInterface::Clock);
+    fromIfaceReset = new GroupInterface(group,rstName, AbstractInterface::Input, AbstractInterface::Reset);
+    group->addInterface(fromIfaceClk);
+    group->addInterface(fromIfaceReset);
+  // creating top group ext_clk iface item
+    GroupItem* groupItem = scene->getGroupItem();
+    InterfaceItem* fromIfaceItemClk = new InterfaceItem(0.5 , Parameters::West, fromIfaceClk, groupItem, params, true);
+    groupItem->addInterfaceItem(fromIfaceItemClk,true);
+    // creating top group ext_reset iface item
+    InterfaceItem* fromIfaceItemReset = new InterfaceItem(0.5 , Parameters::West, fromIfaceReset, groupItem, params, false);
+    groupItem->addInterfaceItem(fromIfaceItemReset,true);
+    // connecting ext_clk iface items
+    InterfaceItem* toIfaceItemClk = item->searchInterfaceItemByName("ext_clk");
+    if (toIfaceItemClk == NULL) {
+      cerr << "Abnormal case while connecting top group ext_clk to clkrstgen" << endl;
+    }
+    createConnection(context,fromIfaceItemClk, toIfaceItemClk, false);
+    // connecting ext_reset iface items
+    InterfaceItem* toIfaceItemReset = item->searchInterfaceItemByName("ext_reset");
+    if (toIfaceItemReset == NULL) {
+      cerr << "Abnormal case while connecting top group ext_reset to clkrstgen" << endl;
+    }
+    createConnection(context,fromIfaceItemReset, toIfaceItemReset, false);
+
+    params->blockToItem.insert(newOne,item);
+    params->unsaveModif = true;
   }
-  params->unsaveModif = true;
 }
 
 
-GroupWidget *Dispatcher::createTopScene(){
+
+GroupWidget *Dispatcher::createTopScene(Context context, double mainClock){
   static QString fctName = "Dispatcher::createTopScene()";
 #ifdef DEBUG_FCTNAME
   cout << "call to " << qPrintable(fctName) << endl;
 #endif
 
-  // creating the model part of the group
-  Graph* graph = params->createGraph();
-  GroupBlock *refBlock = graph->getTopGroup();
-
-  // creating a fake and not connected interface
-  //AbstractInterface* iface = new GroupInterface(refBlock,"grp_iface",AbstractInterface::Input,AbstractInterface::Top);
+  Graph* graph = NULL;
+  // creating the graph and thus, the topgroup
+  if (context == Design) {
+    graph = params->initGraph(true);
+    graph->addClock(mainClock);
+  }
+  else if (context == Load) {
+    graph = params->initGraph(false);
+  }
 
-  // creating the group widget
-  topGroup = new GroupWidget(NULL,this,params);
-  currentGroup = topGroup;
+  // get the top group
+  GroupBlock *topBlock = graph->getTopGroup();
+  // creating the top group widget
+  topGroupWidget = new GroupWidget(NULL,this,params);
+  currentGroupWidget = topGroupWidget;
   // getting the newly created scene
-  GroupScene *scene = topGroup->getScene();
+  GroupScene *scene = topGroupWidget->getScene();
   scene->setId(sceneCounter++);
   params->setTopScene(scene);
   params->setCurrentScene(scene);
   // creating the view part of the group
-  GroupItem *group = new GroupItem(NULL,refBlock,this,params);
+  GroupItem *group = new GroupItem(NULL,topBlock,this,params);
+  // associate the top scene to the top group iten
+  scene->setGroupItem(group);
 
   // adding the fake interface to the top group item
   //InterfaceItem* item = new InterfaceItem(0.0 , Parameters::West, (ConnectedInterface*)iface, group, params);
   //group->addInterface(item,true);
 
-  scene->setGroupItem(group);
 
-  groupList.append(topGroup);
-  return topGroup;
+  if (context == Design) {
+    // create clkrstgen
+    double freq = params->getGraph()->getClock(0);
+    params->getGraph()->resetClocks();
+    addClkRstGenBlock(context,freq);
+  }
+
+  groupList.append(topGroupWidget);
+  return topGroupWidget;
 }
 
-GroupWidget* Dispatcher::addNewEmptyGroup(GroupScene* scene, bool show) {
+GroupWidget* Dispatcher::addNewEmptyGroup(Context context, GroupScene* scene, bool show) {
   static QString fctName = "Dispatcher::addNewEmptyGroup();";
 #ifdef DEBUG_FCTNAME
   cout << "call to " << qPrintable(fctName) << endl;
 #endif
+  bool createIfaces = true;
+  if (context == Load) {
+    createIfaces = false;
+  }
 
   // getting the parent block in the graph
   GroupBlock* parent = AB_TO_GRP(scene->getGroupItem()->getRefBlock());
   cout << "new group : parent = "<< qPrintable(parent->getName()) << endl;
-  GroupBlock* groupBlock = params->getGraph()->createChildGroupBlock(parent);
+  GroupBlock* groupBlock = params->getGraph()->createChildGroupBlock(parent, createIfaces);
   cout << "new group : child = "<< qPrintable(groupBlock->getName()) << ", child of " << qPrintable(groupBlock->getParent()->getName()) << endl;
   // creating the BlockItem in the scene
   BoxItem* newItem = scene->createBoxItem(groupBlock);
 
   params->unsaveModif = true;
 
-  GroupWidget* child = createChildScene(scene->getGroupWidget(),newItem);
+  GroupWidget* child = createChildScene(context, scene->getGroupWidget(),newItem);
   if (show) child->show();
   return child;
 
 }
 
-GroupWidget *Dispatcher::createChildScene(GroupWidget* parentWidget, BoxItem *upperItemOfGroupItem) {
+GroupWidget *Dispatcher::createChildScene(Context context, GroupWidget* parentWidget, BoxItem *upperItemOfGroupItem) {
   static QString fctName = "Dispatcher::createChildScene()";
 #ifdef DEBUG_FCTNAME
   cout << "call to " << qPrintable(fctName) << endl;
@@ -516,6 +937,7 @@ GroupWidget *Dispatcher::createChildScene(GroupWidget* parentWidget, BoxItem *up
     GroupBlock* groupBlock = AB_TO_GRP(upperItemOfGroupItem->getRefBlock());
     // creating the view part of the group
     GroupItem *groupItem = new GroupItem(upperItemOfGroupItem,groupBlock,this,params);
+
     // creating the group widget
     group = new GroupWidget(parentWidget, this, params);
     // getting the newly created scene
@@ -540,9 +962,9 @@ GroupWidget *Dispatcher::createChildScene(GroupWidget* parentWidget, BoxItem *up
   return group;
 }
 
-void Dispatcher::destroyScene(GroupScene *scene) {
+void Dispatcher::destroyScene(Context context, GroupScene *scene) {
   foreach(GroupScene* s, scene->getChildrenScene()) {
-    destroyScene(s);
+    destroyScene(context, s);
   }
 
   if (scene->getNbChildScene() == 0) {
@@ -559,7 +981,7 @@ void Dispatcher::destroyScene(GroupScene *scene) {
   }
 }
 
-void Dispatcher::showRaiseWindow(BoxItem *item) {
+void Dispatcher::showRaiseWindow(Context context, BoxItem *item) {
   static QString fctName = "Dispatcher::showRaiseWindow()";
 #ifdef DEBUG_FCTNAME
   cout << "call to " << qPrintable(fctName) << endl;
@@ -578,11 +1000,11 @@ void Dispatcher::showRaiseWindow(BoxItem *item) {
   win->raise();
   win->activateWindow();
 
-  currentGroup = win;
-  params->setCurrentScene(currentGroup->getScene());
+  currentGroupWidget = win;
+  params->setCurrentScene(currentGroupWidget->getScene());
 }
 
-void Dispatcher::showRstClkIface(AbstractBoxItem *item) {
+void Dispatcher::showRstClkIface(Context context, AbstractBoxItem *item) {
   static QString fctName = "Dispatcher::showRstClkIface()";
 #ifdef DEBUG_FCTNAME
   cout << "call to " << qPrintable(fctName) << endl;
@@ -592,7 +1014,7 @@ void Dispatcher::showRstClkIface(AbstractBoxItem *item) {
   
 }
 
-void Dispatcher::showWishboneIface(AbstractBoxItem *item) {
+void Dispatcher::showWishboneIface(Context context, AbstractBoxItem *item) {
   static QString fctName = "Dispatcher::showWishboneIface()";
 #ifdef DEBUG_FCTNAME
   cout << "call to " << qPrintable(fctName) << endl;
@@ -601,7 +1023,7 @@ void Dispatcher::showWishboneIface(AbstractBoxItem *item) {
   item->setWishboneVisible(!item->isWishboneVisible());  
 }
 
-void Dispatcher::addNewFullGroup() {
+void Dispatcher::addNewFullGroup(Context context) {
   static QString fctName = "Dispatcher::addNewFullGroup()";
 #ifdef DEBUG_FCTNAME
   cout << "call to " << qPrintable(fctName) << endl;
@@ -762,11 +1184,16 @@ void Dispatcher::addNewFullGroup() {
 #endif
 }
 
-void Dispatcher::removeBoxItem(BoxItem *item) {
+void Dispatcher::removeBoxItem(Context context, BoxItem *item) {
   static QString fctName = "Dispatcher::removeBoxItem()";
 #ifdef DEBUG_FCTNAME
   cout << "call to " << qPrintable(fctName) << endl;
 #endif
+  /* NB: only called in Design context */
+  if (context != Design) {
+    cout << "Abnormal case: call to " << qPrintable(fctName) << " not in Design context" << endl;
+    return;
+  }
 
   /* a BoxItem (group of func) can be removed only if none of its
      interfaces is connected to a group interface that is itself
@@ -813,13 +1240,14 @@ void Dispatcher::removeBoxItem(BoxItem *item) {
   if (ret == QMessageBox::Cancel) {
     return;
   }
-  removeAllBlockConnections(item);
+  removeAllBlockConnections(context, item);
 
   if (item->getRefBlock()->isFunctionalBlock()) {
-    FunctionalBlock* block = AB_TO_FUN(item->getRefBlock());
-    GroupBlock* group = AB_TO_GRP(block->getParent());
+    FunctionalBlock* block = AB_TO_FUN(item->getRefBlock());    
     item->getScene()->removeBoxItem(item);
     params->getGraph()->removeFunctionalBlock(block);
+    params->blockToItem.remove(block);
+
   }
   else if (item->getRefBlock()->isGroupBlock()) {
 
@@ -827,7 +1255,7 @@ void Dispatcher::removeBoxItem(BoxItem *item) {
 
     // remove all child scenes recursively
     GroupItem* subgroup = item->getChildGroupItem();
-    destroyScene(subgroup->getScene());
+    destroyScene(context, subgroup->getScene());
     // remove the BoxItem
     item->getScene()->removeBoxItem(item);
     // remove the group from the graph
@@ -835,79 +1263,84 @@ void Dispatcher::removeBoxItem(BoxItem *item) {
   }
 }
 
-void Dispatcher::removeAllBlockConnections(AbstractBoxItem *item) {
+void Dispatcher::removeAllBlockConnections(Context context, AbstractBoxItem *item) {
   static QString fctName = "Dispatcher::removeAllBlockConnection()";
 #ifdef DEBUG_FCTNAME
   cout << "call to " << qPrintable(fctName) << endl;
 #endif
+  /* NB: only called in Design context */
+  if (context != Design) {
+    cout << "Abnormal case: call to " <<qPrintable(fctName) << " not in Design context" << endl;
+    return;
+  }
 
   foreach(InterfaceItem* ifaceItem, item->getInterfaces()) {
     foreach(ConnectionItem* conn, ifaceItem->connections) {
-      removeConnection(conn);
+      removeConnection(context, conn);
     }
   }
 }
 
-void Dispatcher::removeSourceItem(SourceItem *item) {
-  static QString fctName = "Dispatcher::removeSourceItem()";
+void Dispatcher::removeStimuliItem(Context context, StimuliItem *item) {
+  static QString fctName = "Dispatcher::removeStimuliItem()";
 #ifdef DEBUG_FCTNAME
   cout << "call to " << qPrintable(fctName) << endl;
 #endif
+  /* NB: only called in Design context */
+  if (context != Design) {
+    cout << "Abnormal case: call to " <<qPrintable(fctName) << " not in Design context" << endl;
+    return;
+  }
   
-  QString msg = "Removing source ";
+  QString msg = "Removing stimmuli ";
   
   msg += item->getRefBlock()->getName();
   msg += " and all its connections.\n\nAre you sure ?";
 
-  int ret = QMessageBox::question(NULL,"Removing source block",msg, QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Ok);
+  int ret = QMessageBox::question(NULL,"Removing stimuli block",msg, QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Ok);
   if (ret == QMessageBox::Cancel) {
     return;
   }
-  removeAllBlockConnections(item);
+  removeAllBlockConnections(context, item);
   
   FunctionalBlock* block = AB_TO_FUN(item->getRefBlock());  
-  item->getScene()->removeSourceItem(item);
-  params->getGraph()->removeSourceBlock(block);  
+  item->getScene()->removeStimuliItem(item);
+  params->getGraph()->removeStimuliBlock(block);
 }
 
 
-void Dispatcher::removeConnection(ConnectionItem *conn) {
+void Dispatcher::removeConnection(Context context, ConnectionItem *connItem) {
   static QString fctName = "Dispatcher::removeConnection()";
 #ifdef DEBUG_FCTNAME
   cout << "call to " << qPrintable(fctName) << endl;
 #endif
-  InterfaceItem* fromIfaceItem = conn->getFromInterfaceItem();
-  InterfaceItem* toIfaceItem = conn->getToInterfaceItem();
+  /* NB: only called in Design context */
+  if (context != Design) {
+    cout << "Abnormal case: call to " <<qPrintable(fctName) << " not in Design context" << endl;
+    return;
+  }
+
+  InterfaceItem* fromIfaceItem = connItem->getFromInterfaceItem();
+  InterfaceItem* toIfaceItem = connItem->getToInterfaceItem();
 
 #ifdef DEBUG
   cout << "remove connection from " << qPrintable(fromIfaceItem->refInter->getName()) << " to " << qPrintable(toIfaceItem->refInter->getName()) << endl;
 #endif
 
-  InterfaceItem* groupIfaceItem = NULL; // in case of one of the two interface belongs to the GroupItem
-  GroupItem* groupItem = NULL;
+  InterfaceItem* groupIfaceItem = NULL; // in case of one of the two interface belongs to the GroupItem, and stays NULL if not
+  GroupItem* groupItem = NULL; // the GroupItem of the scene that contains connItem
 
   ConnectedInterface *fromInter = fromIfaceItem->refInter;
-  ConnectedInterface *toInter = toIfaceItem->refInter;
-  // process the speical case source->group apart
-  if (fromIfaceItem->getOwner()->isSourceItem()) {
-    // remove from graph
-    fromInter->removeConnectedTo(toInter);
-    toInter->clearConnectedFrom();
-    // remove from scene
-    fromIfaceItem->removeConnectionItem(conn);
-    toIfaceItem->removeConnectionItem(conn);
-    groupItem->getScene()->removeConnectionItem(conn);
-    return;
-  }
-  
+  ConnectedInterface *toInter = toIfaceItem->refInter;  
   
+  // test if one of the interface bounded to item is owned by a GroupItem
   if (fromIfaceItem->getOwner()->isGroupItem()) {
-    groupIfaceItem = fromIfaceItem;
-    groupItem = toIfaceItem->getOwner()->getScene()->getGroupItem();
+    groupItem = ABI_TO_GI(fromIfaceItem->getOwner());
+    groupIfaceItem = fromIfaceItem;    
   }
   else if (toIfaceItem->getOwner()->isGroupItem()) {
-    groupIfaceItem = toIfaceItem;
-    groupItem = fromIfaceItem->getOwner()->getScene()->getGroupItem();
+    groupItem = ABI_TO_GI(toIfaceItem->getOwner());
+    groupIfaceItem = toIfaceItem;    
   }
   else {
     groupItem = fromIfaceItem->getOwner()->getScene()->getGroupItem();
@@ -917,16 +1350,8 @@ void Dispatcher::removeConnection(ConnectionItem *conn) {
 #ifdef DEBUG
   cout << "removing connections from graph ..." ;
 #endif  
-  if (fromInter->getDirection() == AbstractInterface::InOut) {
-    fromInter->clearConnectedTo();
-    fromInter->clearConnectedFrom();
-    toInter->clearConnectedTo();
-    toInter->clearConnectedFrom();
-  }
-  else {
-    fromInter->removeConnectedTo(toInter);
-    toInter->clearConnectedFrom();
-  }
+  fromInter->disconnectTo(toInter);
+  
 #ifdef DEBUG
   cout << "done." << endl ;
 #endif
@@ -934,202 +1359,287 @@ void Dispatcher::removeConnection(ConnectionItem *conn) {
   // removing the connection from scene
 #ifdef DEBUG
   cout << "removing connections from scene ..." ;
-#endif
-  fromIfaceItem->removeConnectionItem(conn);
-  toIfaceItem->removeConnectionItem(conn);
-  groupItem->getScene()->removeConnectionItem(conn);
+#endif  
+  groupItem->getScene()->removeConnectionItem(connItem);
 
 #ifdef DEBUG
   cout << "done." << endl ;
 #endif
-
+  
+  // if one of the interface bounded to connItem is owned by the GroupItem of the scene
   if (groupIfaceItem != NULL) {
-    ConnectedInterface* groupInter = groupIfaceItem->refInter;
-    groupItem->removeInterface(groupIfaceItem);
-
-    BoxItem* parent2Item = groupItem->getParentItem();
-    if (parent2Item != NULL) {
-      InterfaceItem* group2IfaceItem = parent2Item->searchInterfaceByRef(groupInter);
-      parent2Item->removeInterface(group2IfaceItem);
+    
+    // determine if the interface must be removed since it has no more connections.
+    bool groupInterRemove = false;
+    if ((groupIfaceItem->refInter->isConnectedTo() == false) && (groupIfaceItem->refInter->isConnectedFrom() == false)) groupInterRemove = true;
+    
+    if (groupInterRemove) {
+      // get the GroupInterface from interface item
+      ConnectedInterface* groupInter = groupIfaceItem->refInter;            
+      // remove interface from GroupItem, and delete it.
+      groupItem->removeInterfaceItem(groupIfaceItem);      
+      // get the parent BoxItem of GroupItem if it exists.
+      BoxItem* parent2Item = groupItem->getParentItem();
+      if (parent2Item != NULL) {
+        InterfaceItem* group2IfaceItem = parent2Item->searchInterfaceItemByRef(groupInter);
+        // remove interface intem in parent BoxItem
+        parent2Item->removeInterfaceItem(group2IfaceItem);
+      }
+      // remove GroupInterface in the graph.
+      groupInter->getOwner()->removeInterface(groupInter);
     }
-    groupInter->getOwner()->removeInterface(groupInter);
   }
 }
 
-void Dispatcher::showBlocksLibrary(){
-  cout << "showing block library" << endl;
-  mainWindow->getLibrary()->show();
-  mainWindow->getLibrary()->raise();
-}
-
-void Dispatcher::showProperties(InterfaceItem *inter)
-{
-  new InterfacePropertiesWindow(inter);
-}
-
-/* connectInterToGroup() :
-   The only way for a block (functional of group) within a GroupItem to be connected
-   to the latter is to right-click on one of its interfaces and to choose "connect to group".
-   That action will create a new InterfaceItem on the GroupItem and a connectionItem between the
-   interfaces.
-*/
-void Dispatcher::connectInterToGroup(InterfaceItem *item){
+void Dispatcher::connectBoxItemClock(Context context, BoxItem *item, QString clkName, int idGen) throw(Exception) {
 
-  // getting the GroupBlock and GroupItem that are parent of the block that owns item
-  ConnectedInterface *refInter = item->refInter;
-  cout << "owner of iface = " << qPrintable(refInter->getOwner()->getName()) << endl;
-  GroupBlock* parentBlock = AB_TO_GRP(refInter->getOwner()->getParent());
-  cout << "create iface for parent group = " << qPrintable(parentBlock->getName()) << endl;
-  GroupItem *parentItem = item->getOwner()->getScene()->getGroupItem();
+  static QString fctName = "Dispatcher::connectBoxItemClock()";
+#ifdef DEBUG_FCTNAME
+  cout << "call to " << qPrintable(fctName) << endl;
+#endif
+  /* NB: only called in Design context */
+  if (context != Design) {
+    cout << "Abnormal case: call to " <<qPrintable(fctName) << " not in Design context" << endl;
+    return;
+  }
 
-  // creating/adding the group interface in the graph model
-  GroupInterface *groupInter = new GroupInterface(parentBlock,refInter->getName()+"_group",refInter->getDirection(),refInter->getPurpose());
-  groupInter->setType(refInter->getType());
-  groupInter->setWidth(refInter->getWidth());
-  groupInter->setPurpose(refInter->getPurpose());
-  parentItem->getRefBlock()->addInterface(groupInter);
+  InterfaceItem* fromIfaceItemClk = NULL;
+  InterfaceItem* toIfaceItemClk = item->searchInterfaceItemByName(clkName);
+  GroupItem* parentGroup = item->getScene()->getGroupItem();
+  BoxItem* clkrstItem = NULL;
 
-  // connect both interface
-  bool ok = true;
-  if (refInter->getDirection() == AbstractInterface::Output) {
-    ok = refInter->connectTo(groupInter);
-    ok = ok & groupInter->connectFrom(refInter);    
+  if (parentGroup->getRefBlock()->isTopGroupBlock()) {
+    QString genName = "clkrstgen_" + QString::number(idGen);
+    clkrstItem = item->getScene()->searchBoxItemByName(genName);
+    if (clkrstItem == NULL) {
+      throw(Exception(IFACE_TOP_NOCLKRSTGEN));
+    }
+    else {
+      fromIfaceItemClk = clkrstItem->searchInterfaceItemByName("clk");
+    }
+    cout << "connecting clock of " << qPrintable(item->getRefBlock()->getName()) << " to clk of " << qPrintable(genName) << endl;
   }
-  else if (refInter->getDirection() == AbstractInterface::Input) {
-    ok = groupInter->connectTo(refInter);
-    ok = ok & refInter->connectFrom(groupInter);
+  else {
+    // searching for ext_clk_idGen
+    QString name = "ext_clk_"+QString::number(idGen);
+    fromIfaceItemClk = parentGroup->searchInterfaceItemByName(name);
+    cout << "connecting clock of " << qPrintable(item->getRefBlock()->getName()) << " to " << qPrintable(name) << " of parent group " << qPrintable(parentGroup->getRefBlock()->getName()) << endl;
   }
-  else if (refInter->getDirection() == AbstractInterface::InOut) {
-    ok = refInter->connectTo(groupInter);
-    ok = ok & groupInter->connectFrom(refInter);
-    ok = ok & groupInter->connectTo(refInter);
-    ok = ok & refInter->connectFrom(groupInter);
+
+  if (fromIfaceItemClk == NULL) {
+    throw(Exception(IFACE_GROUP_NOCLKRST));
   }
-  if (!ok) {
-    cerr << "abnormal case while connecting a block iface to its parent group" << endl;
+  else {
+    createConnection(context, fromIfaceItemClk, toIfaceItemClk, false);
+    cout << "connection done."  << endl;
   }
-  // creating/adding the group interface in the current scene model, and connection item
-  InterfaceItem *groupIfaceItem = new InterfaceItem(0,item->getOrientation(),groupInter,parentItem,params);
-  parentItem->addInterface(groupIfaceItem,true);
+}
 
-  parentItem->getScene()->createConnectionItem(item, groupIfaceItem);
+void Dispatcher::connectBoxItemReset(Context context, BoxItem *item, QString rstName, int idGen) throw(Exception) {
 
-  // if groupItem is not topGroup, must also add a new interface to the parent BlockItem
-  BoxItem* parent2Item = parentItem->getParentItem();
-  if(parent2Item != NULL){
-    InterfaceItem *blockIfaceItem = new InterfaceItem(0,item->getOrientation(),groupInter,parent2Item,params);
-    parent2Item->addInterface(blockIfaceItem,true);
+  static QString fctName = "Dispatcher::connectBoxItemReset()";
+#ifdef DEBUG_FCTNAME
+  cout << "call to " << qPrintable(fctName) << endl;
+#endif
+  /* NB: only called in Design context */
+  if (context != Design) {
+    cout << "Abnormal case: call to " <<qPrintable(fctName) << " not in Design context" << endl;
+    return;
   }
 
+  InterfaceItem* fromIfaceItemRst = NULL;
+  InterfaceItem* toIfaceItemRst = item->searchInterfaceItemByName(rstName);
+  GroupItem* parentGroup = item->getScene()->getGroupItem();
+  BoxItem* clkrstItem = NULL;
 
-  parentItem->getScene()->updateConnectionItemsShape();
-  unselectAllItems();
-  params->unsaveModif = true;
-
+  if (parentGroup->getRefBlock()->isTopGroupBlock()) {
+    QString genName = "clkrstgen_" + QString::number(idGen);
+    clkrstItem = item->getScene()->searchBoxItemByName(genName);
+    if (clkrstItem == NULL) {
+      throw(Exception(IFACE_TOP_NOCLKRSTGEN));
+    }
+    else {
+      fromIfaceItemRst = clkrstItem->searchInterfaceItemByName("reset");
+    }
+    cout << "connecting reset of " << qPrintable(item->getRefBlock()->getName()) << " to reset of " << qPrintable(genName) << endl;
+  }
+  else {
+    // searching for ext_rst_idGen
+    QString name = "ext_rst_"+QString::number(idGen);
+    fromIfaceItemRst = parentGroup->searchInterfaceItemByName(name);
+    cout << "connecting reset of " << qPrintable(item->getRefBlock()->getName()) << " to " << qPrintable(name) << " of parent group " << qPrintable(parentGroup->getRefBlock()->getName()) << endl;
+  }
 
+  if (fromIfaceItemRst == NULL) {
+    throw(Exception(IFACE_GROUP_NOCLKRST));
+  }
+  else {
+    createConnection(context, fromIfaceItemRst, toIfaceItemRst, false);
+    cout << "connection done."  << endl;
+  }
 }
 
-void Dispatcher::disconnectInterFromGroup(InterfaceItem *item) {
-  static QString fctName = "Dispatcher::disconnectInterFromGroup()";
+void Dispatcher::connectStimuliItemClock(Context context, StimuliItem *item, QString clkName, int idGen) throw(Exception) {
+
+  static QString fctName = "Dispatcher::connectStimuliItemClock()";
 #ifdef DEBUG_FCTNAME
   cout << "call to " << qPrintable(fctName) << endl;
 #endif
+  /* NB: only called in Design context */
+  if (context != Design) {
+    cout << "Abnormal case: call to " <<qPrintable(fctName) << " not in Design context" << endl;
+    return;
+  }
 
-  // getting the GroupBlock and GroupItem that are parent of the block that owns item
-  ConnectedInterface *refInter = item->refInter;
-  ConnectedInterface *groupInter = NULL;
-  GroupBlock* parentGroup = AB_TO_GRP(refInter->getOwner()->getParent());
-  GroupItem *parentItem = item->getOwner()->getScene()->getGroupItem();
-
-  // removing the connection from graph
-#ifdef DEBUG
-  cout << "removing connections from graph ..." ;
-#endif
+  InterfaceItem* fromIfaceItemClk = NULL;
+  InterfaceItem* toIfaceItemClk = item->searchInterfaceItemByName(clkName);
+  BoxItem* clkrstItem = NULL;
 
-  if (refInter->getDirection() == AbstractInterface::Output) {
-    groupInter = refInter->getConnectionToParentGroup(); // must be a single connection to
-    refInter->removeConnectedTo(groupInter);
-    groupInter->clearConnectedFrom();
-  }
-  else if (refInter->getDirection() == AbstractInterface::Input) {
-    groupInter = refInter->getConnectedFrom();
-    refInter->clearConnectedFrom();
-    groupInter->clearConnectedTo();
+  QString genName = "clkrstgen_" + QString::number(idGen);
+  clkrstItem = item->getScene()->searchBoxItemByName(genName);
+  if (clkrstItem == NULL) {
+    throw(Exception(IFACE_TOP_NOCLKRSTGEN));
   }
-  else if (refInter->getDirection() == AbstractInterface::InOut) {
-    groupInter = refInter->getConnectionToParentGroup(); // must be a single connection to
-    refInter->clearConnectedTo();
-    refInter->clearConnectedFrom();
-    groupInter->clearConnectedTo();
-    groupInter->clearConnectedFrom();
+  else {
+    fromIfaceItemClk = clkrstItem->searchInterfaceItemByName("clk");
   }
-#ifdef DEBUG
-  cout << "done." << endl ;
-#endif
+  cout << "connecting clock of " << qPrintable(item->getRefBlock()->getName()) << " to clock of " << qPrintable(genName) << endl;
 
-  if (groupInter == NULL) {
-    cerr << "abnormal case 1 while removing an interface item of a block, linked to a parent group" << endl;
+  if (fromIfaceItemClk == NULL) {
+    throw(Exception(IFACE_GROUP_NOCLKRST));
   }
+  else {
+    createConnection(context, fromIfaceItemClk, toIfaceItemClk, false);
+    cout << "connection done."  << endl;
+  }
+}
 
-#ifdef DEBUG
-  cout << "getting group interface item, and connection item ..." ;
+void Dispatcher::connectStimuliItemReset(Context context, StimuliItem *item, QString rstName, int idGen) throw(Exception) {
+  static QString fctName = "Dispatcher::connectStimuliItemReset()";
+#ifdef DEBUG_FCTNAME
+  cout << "call to " << qPrintable(fctName) << endl;
 #endif
+  /* NB: only called in Design context */
+  if (context != Design) {
+    cout << "Abnormal case: call to " <<qPrintable(fctName) << " not in Design context" << endl;
+    return;
+  }
 
+  InterfaceItem* fromIfaceItemRst = NULL;
+  InterfaceItem* toIfaceItemRst = item->searchInterfaceItemByName(rstName);
+  BoxItem* clkrstItem = NULL;
 
-  InterfaceItem* groupIfaceItem = parentItem->searchInterfaceByRef(groupInter);
-  if (groupIfaceItem == NULL) {
-    cerr << "abnormal case 2 while removing an interface item of a block, linked to a parent group" << endl;
+  QString genName = "clkrstgen_" + QString::number(idGen);
+  clkrstItem = item->getScene()->searchBoxItemByName(genName);
+  if (clkrstItem == NULL) {
+    throw(Exception(IFACE_TOP_NOCLKRSTGEN));
   }
-  ConnectionItem* conn = parentItem->getScene()->searchConnectionItem(item,groupIfaceItem);
-  if (conn == NULL) {
-    cerr << "abnormal case 3 while removing an interface item of a block, linked to a parent group" << endl;
+  else {
+    fromIfaceItemRst = clkrstItem->searchInterfaceItemByName("reset");
   }
-#ifdef DEBUG
-  cout << "done." << endl ;
-#endif
+  cout << "connecting reset of " << qPrintable(item->getRefBlock()->getName()) << " to reset of " << qPrintable(genName) << endl;
 
-  // removing the interface group item from the group item, and the connection item
-#ifdef DEBUG
-  cout << "removing group interface item, and connection item ..." ;
-#endif
+  if (fromIfaceItemRst == NULL) {
+    throw(Exception(IFACE_GROUP_NOCLKRST));
+  }
+  else {
+    createConnection(context, fromIfaceItemRst, toIfaceItemRst, false);
+    cout << "connection done."  << endl;
+  }
+}
 
-  item->removeConnectionItem(conn);
-  groupIfaceItem->removeConnectionItem(conn);
-  parentItem->removeInterface(groupIfaceItem); // CAUTION : this deletes the interface item.
-  parentItem->getScene()->removeConnectionItem(conn);
-#ifdef DEBUG
-  cout << "done." << endl ;
+
+void Dispatcher::showBlocksLibrary(){
+  cout << "showing block library" << endl;
+  mainWindow->getLibrary()->show();
+  mainWindow->getLibrary()->raise();
+}
+
+void Dispatcher::showProperties(Context context, InterfaceItem *inter) {
+
+  static QString fctName = "Dispatcher::showProperties()";
+#ifdef DEBUG_FCTNAME
+  cout << "call to " << qPrintable(fctName) << endl;
 #endif
+  /* NB: only called in Design context */
+  if (context != Design) {
+    cout << "Abnormal case: call to " <<qPrintable(fctName) << " not in Design context" << endl;
+    return;
+  }
 
-  // removing the interface box item in the parent scene
-#ifdef DEBUG
-  cout << "removing the inteeface item of box item in parent scene if needed ..." ;
+  QDialog* dial = new InterfacePropertiesDialog(inter);
+  dial->exec();
+}
+
+/* connectInterToGroup() :
+   The only way for a block (functional of group) within a GroupItem to be connected
+   to the latter is to right-click on one of its interfaces and to choose "connect to group".
+   That action will create a new InterfaceItem on the GroupItem and a connectionItem between the
+   interfaces.
+*/
+void Dispatcher::connectInterToGroup(Context context, InterfaceItem *item){
+
+  static QString fctName = "Dispatcher::connectInterToGroup()";
+#ifdef DEBUG_FCTNAME
+  cout << "call to " << qPrintable(fctName) << endl;
 #endif
+  /* NB: only called in Design context */
+  if (context != Design) {
+    cout << "Abnormal case: call to " <<qPrintable(fctName) << " not in Design context" << endl;
+    return;
+  }
 
+  // getting the GroupBlock and GroupItem that are parent of the block that owns item
+  ConnectedInterface *refInter = item->refInter;
+  cout << "owner of iface = " << qPrintable(refInter->getOwner()->getName()) << endl;
+  GroupBlock* parentBlock = AB_TO_GRP(refInter->getOwner()->getParent());
+  cout << "create iface for parent group = " << qPrintable(parentBlock->getName()) << endl;
+  GroupItem *parentItem = item->getOwner()->getScene()->getGroupItem();
+
+  // creating/adding the group interface in the graph model
+  GroupInterface *groupInter = new GroupInterface(parentBlock,refInter->getName()+"_group",refInter->getDirection(),refInter->getPurpose());  
+  parentItem->getRefBlock()->addInterface(groupInter);
+  // creating/adding the group control interface in the graph model if the purpose is data
+  if (refInter->getPurpose() == AbstractInterface::Data) {
+    GroupInterface *groupCtlInter = new GroupInterface(parentBlock,refInter->getName()+"_group_enb",refInter->getDirection(),AbstractInterface::Control);
+    groupCtlInter->setAssociatedIface(groupInter);
+    parentItem->getRefBlock()->addInterface(groupCtlInter);
+  }
+  // creating/adding the group interface in the current scene model, and connection item
+  InterfaceItem *groupIfaceItem = new InterfaceItem(0,item->getOrientation(),groupInter,parentItem,params);
+  parentItem->addInterfaceItem(groupIfaceItem,true);
+
+  // creating the connection, in graph and with an item
+  /* NOTE:
+     Since the group interface is for now unconnected, it is impossible to determine
+     its clock domain. Thus, the connection must be created without testing the clock domain
+     consistency. For that, we cheat by changing the context to Load because it implies no clock test.
+   */
+  createConnection(Load, item, groupIfaceItem);
+
+  // if groupItem is not topGroup, must also add a new interface to the parent BlockItem
   BoxItem* parent2Item = parentItem->getParentItem();
-  if (parent2Item != NULL) {
-    InterfaceItem* group2IfaceItem = parent2Item->searchInterfaceByRef(groupInter);
-    parent2Item->removeInterface(group2IfaceItem);
+  if(parent2Item != NULL){
+    InterfaceItem *blockIfaceItem = new InterfaceItem(0,item->getOrientation(),groupInter,parent2Item,params);
+    parent2Item->addInterfaceItem(blockIfaceItem,true);
   }
-#ifdef DEBUG
-  cout << "done." << endl ;
-#endif
 
-  // removing the interface group from the group
-#ifdef DEBUG
-  cout << "removing group interface ..." ;
-#endif
-  parentGroup->removeInterface(groupInter);
-#ifdef DEBUG
-  cout << "done." << endl ;
-#endif
 
+  parentItem->getScene()->updateConnectionItemsShape();
+  unselectAllItems(context);
+  params->unsaveModif = true;
 }
-void Dispatcher::removeFunctionalInterface(InterfaceItem *item) {
+
+void Dispatcher::removeFunctionalInterface(Context context, InterfaceItem *item) {
   static QString fctName = "Dispatcher::removeBlockInterface()";
 #ifdef DEBUG_FCTNAME
   cout << "call to " << qPrintable(fctName) << endl;
 #endif
+  /* NB: only called in Design context */
+  if (context != Design) {
+    cout << "Abnormal case: call to " <<qPrintable(fctName) << " not in Design context" << endl;
+    return;
+  }
 
   /* first, remove all connections from item
      NB:  if there is a connection to a group interface, then this
@@ -1139,30 +1649,31 @@ void Dispatcher::removeFunctionalInterface(InterfaceItem *item) {
      that allows to remove an interface.
    */
   foreach(ConnectionItem* conn, item->connections) {
-    removeConnection(conn);
+    removeConnection(context, conn);
   }
 
   ConnectedInterface* ref = item->refInter;
-  item->getOwner()->removeInterface(item);
+  item->getOwner()->removeInterfaceItem(item);
   FunctionalBlock* fun = AB_TO_FUN(ref->getOwner());
   fun->removeInterface(ref);
 }
 
-void Dispatcher::removeGroupInterface(InterfaceItem *item) {
+void Dispatcher::removeGroupInterface(Context context, InterfaceItem *item) {
   static QString fctName = "Dispatcher::removeGroupInterface()";
 #ifdef DEBUG_FCTNAME
   cout << "call to " << qPrintable(fctName) << endl;
 #endif
+  /* NB: only called in Design context */
+  if (context != Design) {
+    cout << "Abnormal case: call to " <<qPrintable(fctName) << " not in Design context" << endl;
+    return;
+  }
 
-  /* NB: there is a single connection between item and another one that is owned
-     by a BoxItem. Thus, we just have to find it and to call disconnectInterFromGroup();
+  /* NB: just remove all connections from/to this item, since when there are no more
+     ones to a GroupItem, it is automatically deleted.
    */
-  ConnectionItem* conn = item->connections.at(0);
-  if (conn->getFromInterfaceItem() == item) {
-    disconnectInterFromGroup(conn->getToInterfaceItem());
-  }
-  else {
-    disconnectInterFromGroup(conn->getFromInterfaceItem());
+  foreach(ConnectionItem* conn, item->connections) {
+    removeConnection(context, conn);
   }
 }
 
@@ -1230,3 +1741,37 @@ InterfaceItem* Dispatcher::getInterfaceItemById(int id) {
   return NULL;
 }
 
+void Dispatcher::findGraphModifications(Context context, FunctionalBlock *block) {
+  static QString fctName = "Dispatcher::findGraphModifications()";
+#ifdef DEBUG_FCTNAME
+  cout << "call to " << qPrintable(fctName) << endl;
+#endif
+  /* NB: only called in Design context */
+  if (context != Design) {
+    cout << "Abnormal case: call to " <<qPrintable(fctName) << " not in Design context" << endl;
+    return;
+  }
+
+  block->computeAdmittanceDelays();
+  // get the block item that is associated to block
+  BoxItem* toBlockItem = params->blockToItem.value(block);
+
+  /* VERSION 1: just add delays if needed */
+  QMap<AbstractInterface*,QList<int>* > delays = block->getAdmittanceDelays();
+  QMapIterator<AbstractInterface*,QList<int>* > iterD(delays);
+  while (iterD.hasNext()) {
+    iterD.next();
+    QList<int>* delay = iterD.value();
+    if (delay->at(0) > 0) {
+      // create delay and associate it to the connected input
+
+      ConnectedInterface* toIface = AI_TO_CON(iterD.key());
+      AbstractInputModifier* mod = new DelayInputModifier(toIface, delay->at(0));
+      cout << "modify input of " << qPrintable(toIface->getName()) << endl;
+      toIface->setInputModifier(mod);
+      // repaint
+      toBlockItem->update();
+    }
+  }
+}
+