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

Private GIT Repository
adding link between ifaces and clk
[blast.git] / Dispatcher.cpp
index a552f208fa0a1c96064c7ae9aeeac91e893aad93..8d1164964036eb4af1ede213cb1e7325ed9c9b0a 100644 (file)
@@ -2,6 +2,8 @@
 #include "Parameters.h"
 #include "MainWindow.h"
 
+#include "ExternalResource.h"
+
 #include "Graph.h"
 #include "ReferenceBlock.h"
 #include "GroupBlock.h"
@@ -35,8 +37,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) {
@@ -60,7 +62,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;
@@ -69,8 +71,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() {
@@ -80,12 +86,18 @@ void Dispatcher::closeCurrentProject() {
   }
   groupList.clear();
   params->destroyGraph();
-  topGroup = NULL;
-  currentGroup = NULL;
+  topGroupWidget = NULL;
+  currentGroupWidget = NULL;
   sceneCounter = 0;
 }
 
-bool Dispatcher::createConnection(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) {
     
   ConnectedInterface* ref1 = iface1->refInter;
   ConnectedInterface* ref2 = iface2->refInter;  
@@ -99,16 +111,16 @@ bool Dispatcher::createConnection(InterfaceItem *iface1, InterfaceItem *iface2)
     ref1->connectTo(ref2);    
     ok1 = true;
   }
-  // if the frist one did not work, test ref2->ref1
+  // if the first one did not work, test ref2->ref1
   if ((ok1 == false) && (ref2->canConnectTo(ref1)) && (ref1->canConnectFrom(ref2))) {  
     ref2->connectTo(ref1);    
     ok2 = true;
   }
   if ((ok1 == true) || (ok2 == true)) {
 
-    iface1->getOwner()->getScene()->createConnectionItem(iface1,iface2);
+    iface1->getOwner()->getScene()->createConnectionItem(iface1,iface2, visible);
 
-    unselectAllItems();
+    unselectAllItems(context);
     params->unsaveModif = true;
     cout << "created a connection from " << qPrintable(ref1->getName()) << " to " << qPrintable(ref2->getName()) << endl;
     return true;
@@ -117,7 +129,7 @@ bool Dispatcher::createConnection(InterfaceItem *iface1, InterfaceItem *iface2)
 }
 
 
-void Dispatcher::unselectAllItems(int direction){
+void Dispatcher::unselectAllItems(Context context, int direction){
 
   GroupScene *scene = params->getCurrentScene();
 
@@ -129,14 +141,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){
@@ -171,7 +183,101 @@ void Dispatcher::changeConnectionMode(int mode){
   */
 }
 
-void Dispatcher::generateBlockVHDL(BoxItem *item){
+void Dispatcher::generateVHDL(Context context) throw(Exception) {
+  static QString fctName = "Dispatcher::generateVHDL()";
+#ifdef DEBUG_FCTNAME
+  cout << "call to " << qPrintable(fctName) << endl;
+#endif
+
+  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);
+  }
+
+  // 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);
+  }
+
+  // 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)/read_csv.vhd \\" << endl;
+  out << "\t$(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;
@@ -179,10 +285,8 @@ void Dispatcher::generateBlockVHDL(BoxItem *item){
 
   if (item->getRefBlock()->isFunctionalBlock()) {
     FunctionalBlock* block = AB_TO_FUN(item->getRefBlock());
-    ReferenceBlock* ref = block->getReference();
-    BlockImplementation* impl = ref->getImplementations().at(0);
     try {
-      impl->generateVHDL(block,"/home/sdomas/");
+      block->generateVHDL(params->projectPath);      
     }
     catch(Exception e) {
       cout << qPrintable(e.getMessage()) << endl;
@@ -190,7 +294,7 @@ void Dispatcher::generateBlockVHDL(BoxItem *item){
   }
 }
 
-void Dispatcher::renameFunctionalBlock(BoxItem *item){
+void Dispatcher::renameFunctionalBlock(Context context, BoxItem *item){
   static QString fctName = "Dispatcher::renameFunctionalBlock()";
 #ifdef DEBUG_FCTNAME
   cout << "call to " << qPrintable(fctName) << endl;
@@ -229,7 +333,7 @@ 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;
@@ -275,7 +379,7 @@ void Dispatcher::renameGroupBlock(GroupItem *item){
   mainWindow->getLibrary()->updateComboScene();   
 }
 
-void Dispatcher::renameSourceBlock(SourceItem *item){
+void Dispatcher::renameSourceBlock(Context context, SourceItem *item){
   static QString fctName = "Dispatcher::renameSourceBlock()";
 #ifdef DEBUG_FCTNAME
   cout << "call to " << qPrintable(fctName) << endl;
@@ -315,7 +419,7 @@ 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;
@@ -359,7 +463,7 @@ void Dispatcher::renameInterface(InterfaceItem *item) {
   item->getOwner()->nameChanged();  
 }
 
-void Dispatcher::showPatterns(InterfaceItem *item) {
+void Dispatcher::showPatterns(Context context, InterfaceItem *item) {
   static QString fctName = "Dispatcher::showPatterns()";
 #ifdef DEBUG_FCTNAME
   cout << "call to " << qPrintable(fctName) << endl;
@@ -371,10 +475,18 @@ void Dispatcher::showPatterns(InterfaceItem *item) {
     msg += " owned by ";
     msg += item->refInter->getOwner()->getName();
     msg += " is:\n";
-    ConnectedInterface* iface = AI_TO_CON(item->refInter->getAssociatedIface());
-    ConnectedInterface* fromIface = iface->getConnectedFrom();
-    if (fromIface->getOutputPattern() == NULL) return;
-    foreach(char c, *(fromIface->getOutputPattern())) {
+    // 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";
@@ -395,13 +507,14 @@ void Dispatcher::showPatterns(InterfaceItem *item) {
   QMessageBox::information(NULL,"Interface pattern",msg,QMessageBox::Ok,QMessageBox::Ok);
 }
 
-void Dispatcher::showModifier(InterfaceItem *item) {
+void Dispatcher::showModifier(Context context, InterfaceItem *item) {
   static QString fctName = "Dispatcher::showModifier()";
 #ifdef DEBUG_FCTNAME
   cout << "call to " << qPrintable(fctName) << endl;
 #endif
   QString msg = "";
-  AbstractInputModifier* mod = item->refInter->getInputModifier();
+  ConnectedInterface* assoIface = AI_TO_CON(item->refInter->getAssociatedIface());
+  AbstractInputModifier* mod = assoIface->getInputModifier();
   if (mod->isDelay()) {
     DelayInputModifier* delay = (DelayInputModifier *)mod;
     msg = "Pattern of iface ";
@@ -415,17 +528,18 @@ void Dispatcher::showModifier(InterfaceItem *item) {
   QMessageBox::information(NULL,"Interface pattern",msg,QMessageBox::Ok,QMessageBox::Ok);
 }
 
-void Dispatcher::removeModifier(InterfaceItem *item) {
+void Dispatcher::removeModifier(Context context, InterfaceItem *item) {
   static QString fctName = "Dispatcher::showModifier()";
 #ifdef DEBUG_FCTNAME
   cout << "call to " << qPrintable(fctName) << endl;
 #endif
 
-  item->refInter->clearInputModifier();
+  ConnectedInterface* assoIface = AI_TO_CON(item->refInter->getAssociatedIface());
+  assoIface->clearInputModifier();
 }
 
 
-void Dispatcher::duplicateBoxItem(BoxItem *item){
+void Dispatcher::duplicateBoxItem(Context context, BoxItem *item){
   static QString fctName = "Dispatcher::duplicateBoxItem()";
 #ifdef DEBUG_FCTNAME
   cout << "call to " << qPrintable(fctName) << endl;
@@ -448,7 +562,7 @@ void Dispatcher::duplicateBoxItem(BoxItem *item){
   }
 }
 
-void Dispatcher::duplicateSourceItem(SourceItem *item) {
+void Dispatcher::duplicateSourceItem(Context context, SourceItem *item) {
   static QString fctName = "Dispatcher::duplicateSourceItem()";
 #ifdef DEBUG_FCTNAME
   cout << "call to " << qPrintable(fctName) << endl;
@@ -471,7 +585,7 @@ void Dispatcher::duplicateSourceItem(SourceItem *item) {
   }
 }
 
-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;
@@ -507,73 +621,109 @@ void Dispatcher::duplicateInterfaceItem(InterfaceItem *item) {
 }
 
 
-BoxItem* Dispatcher::addBlock(int idCategory, int idBlock, int idScene) {
+BoxItem* Dispatcher::addBlock(Context context, int idCategory, int idBlock, int idScene) {
   static QString fctName = "Dispatcher::addBlock()";
 #ifdef DEBUG_FCTNAME
   cout << "call to " << qPrintable(fctName) << endl;
 #endif
   bool newSource = false;
   BoxItem* item = NULL;
-  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->isGeneratorBlock())) {
-    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);
-  }
-  else {
-    GroupBlock* group = AB_TO_GRP(scene->getGroupItem()->getRefBlock());
-    FunctionalBlock* newOne = params->getGraph()->createFunctionalBlock(group, ref);
-    item = scene->createBoxItem(newOne);
-    params->blockToItem.insert(newOne,item);
+
+  /* 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->isGeneratorBlock())) {
+      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, true);
+      scene->createSourceItem(newOne);
+    }
+    else {
+      GroupBlock* group = AB_TO_GRP(scene->getGroupItem()->getRefBlock());
+      FunctionalBlock* newOne = params->getGraph()->createFunctionalBlock(group, ref, true);
+      item = scene->createBoxItem(newOne);
+      params->blockToItem.insert(newOne,item);
+    }
+    params->unsaveModif = true;
   }
-  params->unsaveModif = true;
+
   return item;
 }
 
 
-GroupWidget *Dispatcher::createTopScene(){
+GroupWidget *Dispatcher::createTopScene(Context context){
   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);
-
-  // creating the group widget
-  topGroup = new GroupWidget(NULL,this,params);
-  currentGroup = topGroup;
+  bool createIfaces = true;
+  if (context == Load) {
+    createIfaces = false;
+  }
+  // creating the graph and thus, the topgroup
+  Graph* graph = params->createGraph(createIfaces);
+  // 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) {
+    // creating the clkrstgen block
+    ReferenceBlock* ref = params->getHiddenReferenceBlock("clkrstgen");
+    FunctionalBlock* newOne = params->getGraph()->createFunctionalBlock(topBlock, ref, true);
+    // creating the clkrstgen item
+    BoxItem* clkResetItem = scene->createBoxItem(newOne, BoxItem::TopLeft, AbstractBoxItem::Position | AbstractBoxItem::Dimension, BoxItem::NoSpan);
+    params->blockToItem.insert(newOne,clkResetItem);
+    // creating top group ext_clk iface item
+    ConnectedInterface* fromIfaceClk = AI_TO_CON(topBlock->getIfaceFromName("ext_clk"));
+    InterfaceItem* fromIfaceItemClk = new InterfaceItem(0.5 , Parameters::West, fromIfaceClk, group, params, true);
+    group->addInterfaceItem(fromIfaceItemClk,true);
+    // creating top group ext_reset iface item
+    ConnectedInterface* fromIfaceReset = AI_TO_CON(topBlock->getIfaceFromName("ext_reset"));
+    InterfaceItem* fromIfaceItemReset = new InterfaceItem(0.5 , Parameters::West, fromIfaceReset, group, params, false);
+    group->addInterfaceItem(fromIfaceItemReset,true);
+    // connecting ext_clk iface items
+    InterfaceItem* toIfaceItemClk = clkResetItem->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 = clkResetItem->searchInterfaceItemByName("ext_reset");
+    if (toIfaceItemReset == NULL) {
+      cerr << "Abnormal case while connecting top group ext_reset to clkrstgen" << endl;
+    }
+    createConnection(context,fromIfaceItemReset, toIfaceItemReset, false);
+  }
+
+
+  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;
@@ -589,13 +739,13 @@ GroupWidget* Dispatcher::addNewEmptyGroup(GroupScene* scene, bool show) {
 
   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;
@@ -637,9 +787,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) {
@@ -656,7 +806,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;
@@ -675,11 +825,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;
@@ -689,7 +839,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;
@@ -698,7 +848,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;
@@ -859,12 +1009,14 @@ 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
 
+  if (context != Design) return;
+
   /* a BoxItem (group of func) can be removed only if none of its
      interfaces is connected to a group interface that is itself
      connected to another one.
@@ -910,7 +1062,7 @@ 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());    
@@ -925,7 +1077,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
@@ -933,7 +1085,7 @@ 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;
@@ -941,12 +1093,12 @@ void Dispatcher::removeAllBlockConnections(AbstractBoxItem *item) {
 
   foreach(InterfaceItem* ifaceItem, item->getInterfaces()) {
     foreach(ConnectionItem* conn, ifaceItem->connections) {
-      removeConnection(conn);
+      removeConnection(context, conn);
     }
   }
 }
 
-void Dispatcher::removeSourceItem(SourceItem *item) {
+void Dispatcher::removeSourceItem(Context context, SourceItem *item) {
   static QString fctName = "Dispatcher::removeSourceItem()";
 #ifdef DEBUG_FCTNAME
   cout << "call to " << qPrintable(fctName) << endl;
@@ -961,7 +1113,7 @@ void Dispatcher::removeSourceItem(SourceItem *item) {
   if (ret == QMessageBox::Cancel) {
     return;
   }
-  removeAllBlockConnections(item);
+  removeAllBlockConnections(context, item);
   
   FunctionalBlock* block = AB_TO_FUN(item->getRefBlock());  
   item->getScene()->removeSourceItem(item);
@@ -969,7 +1121,7 @@ void Dispatcher::removeSourceItem(SourceItem *item) {
 }
 
 
-void Dispatcher::removeConnection(ConnectionItem *connItem) {
+void Dispatcher::removeConnection(Context context, ConnectionItem *connItem) {
   static QString fctName = "Dispatcher::removeConnection()";
 #ifdef DEBUG_FCTNAME
   cout << "call to " << qPrintable(fctName) << endl;
@@ -1051,7 +1203,7 @@ void Dispatcher::showBlocksLibrary(){
   mainWindow->getLibrary()->raise();
 }
 
-void Dispatcher::showProperties(InterfaceItem *inter) {
+void Dispatcher::showProperties(Context context, InterfaceItem *inter) {
   new InterfacePropertiesWindow(inter);
 }
 
@@ -1061,7 +1213,7 @@ void Dispatcher::showProperties(InterfaceItem *inter) {
    That action will create a new InterfaceItem on the GroupItem and a connectionItem between the
    interfaces.
 */
-void Dispatcher::connectInterToGroup(InterfaceItem *item){
+void Dispatcher::connectInterToGroup(Context context, InterfaceItem *item){
 
   // getting the GroupBlock and GroupItem that are parent of the block that owns item
   ConnectedInterface *refInter = item->refInter;
@@ -1073,16 +1225,18 @@ void Dispatcher::connectInterToGroup(InterfaceItem *item){
   // 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
-  GroupInterface *groupCtlInter = new GroupInterface(parentBlock,refInter->getName()+"_group_enb",refInter->getDirection(),AbstractInterface::Control);
-  groupCtlInter->setAssociatedIface(groupInter);
-  parentItem->getRefBlock()->addInterface(groupCtlInter);  
+  // 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
-  createConnection(item, groupIfaceItem);
+  createConnection(context, item, groupIfaceItem);
 
   // if groupItem is not topGroup, must also add a new interface to the parent BlockItem
   BoxItem* parent2Item = parentItem->getParentItem();
@@ -1093,11 +1247,11 @@ void Dispatcher::connectInterToGroup(InterfaceItem *item){
 
 
   parentItem->getScene()->updateConnectionItemsShape();
-  unselectAllItems();
+  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;
@@ -1111,7 +1265,7 @@ 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;
@@ -1120,7 +1274,7 @@ void Dispatcher::removeFunctionalInterface(InterfaceItem *item) {
   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;
@@ -1130,7 +1284,7 @@ void Dispatcher::removeGroupInterface(InterfaceItem *item) {
      ones to a GroupItem, it is automatically deleted.
    */
   foreach(ConnectionItem* conn, item->connections) {
-    removeConnection(conn);
+    removeConnection(context, conn);
   }
 }
 
@@ -1198,7 +1352,7 @@ InterfaceItem* Dispatcher::getInterfaceItemById(int id) {
   return NULL;
 }
 
-void Dispatcher::findGraphModifications(FunctionalBlock *block) {
+void Dispatcher::findGraphModifications(Context context, FunctionalBlock *block) {
   static QString fctName = "Dispatcher::findGraphModifications()";
 #ifdef DEBUG_FCTNAME
   cout << "call to " << qPrintable(fctName) << endl;
@@ -1216,8 +1370,9 @@ void Dispatcher::findGraphModifications(FunctionalBlock *block) {
     QList<int>* delay = iterD.value();
     if (delay->at(0) > 0) {
       // create delay and associate it to the connected input
-      AbstractInputModifier* mod = new DelayInputModifier(delay->at(0));
-      ConnectedInterface* toIface = AI_TO_CON(iterD.key()->getAssociatedIface());
+
+      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