1 #include "Dispatcher.h"
2 #include "Parameters.h"
3 #include "MainWindow.h"
5 #include "ExternalResource.h"
8 #include "ReferenceBlock.h"
9 #include "GroupBlock.h"
10 #include "FunctionalBlock.h"
12 #include "ConnectedInterface.h"
13 #include "ReferenceInterface.h"
14 #include "GroupInterface.h"
15 #include "FunctionalInterface.h"
17 #include "GroupWidget.h"
18 #include "GroupScene.h"
19 #include "GroupItem.h"
21 #include "StimuliItem.h"
22 #include "InterfaceItem.h"
23 #include "ConnectionItem.h"
25 #include "BlockLibraryWidget.h"
26 #include "BlockLibraryTree.h"
28 #include "AbstractInputModifier.h"
29 #include "DelayInputModifier.h"
32 #include "InterfacePropertiesDialog.h"
34 #include <QHashIterator>
36 int Dispatcher::sceneCounter = 0;
38 Dispatcher::Dispatcher(Parameters* _params, MainWindow* _window) {
41 params->setDispatcher(this);
42 currentGroupWidget = NULL;
43 topGroupWidget = NULL;
46 GroupWidget *Dispatcher::loadProject(const QString& filename) {
50 root = params->openProjectFile(filename);
52 catch(Exception err) {
57 // creating the top widget/scene
58 topGroup = new GroupWidget(NULL,this,params);
59 currentGroup = topGroup;
60 // getting the newly created scene
61 GroupScene *scene = topGroup->getScene();
63 params->setTopScene(scene);
64 params->setCurrentScene(scene);
67 topGroupWidget = params->loadProject(root);
70 cerr << qPrintable(e.getDefaultMessage()) << endl;
71 cerr << "Aborting ..." << endl;
72 // TO DO : deleteting topGroup and all
76 QFileInfo info(filename);
77 params->projectPath = info.absolutePath();
78 params->projectName = info.baseName();
79 cout << "project path = " << qPrintable(params->projectPath) << endl;
80 groupList.append(topGroupWidget);
81 return topGroupWidget;
84 void Dispatcher::closeCurrentProject() {
86 foreach(GroupWidget* win, groupList) {
90 params->destroyGraph();
91 topGroupWidget = NULL;
92 currentGroupWidget = NULL;
96 void Dispatcher::setSceneCounter(Context context, int value) {
98 if (context != Load) return;
102 bool Dispatcher::createConnection(Context context, InterfaceItem *iface1, InterfaceItem *iface2, bool visible) {
103 static QString fctName = "Dispatcher::createConnection()";
105 cout << "call to " << qPrintable(fctName) << endl;
108 bool testClock = false;
109 if (context == Design) {
113 ConnectedInterface* ref1 = iface1->refInter;
114 ConnectedInterface* ref2 = iface2->refInter;
115 // connect both interface
120 cout << "trying to create a connection between " << qPrintable(ref1->getOwner()->getName()) << "/" << qPrintable(ref1->getName());
121 cout << " and " << qPrintable(ref2->getOwner()->getName()) << "/" << qPrintable(ref2->getName());
123 // test the ref1->ref2 connection
124 if ((ref1->canConnectTo(ref2,testClock)) && (ref2->canConnectFrom(ref1,testClock))) {
125 ref1->connectTo(ref2);
128 // if the first one did not work, test ref2->ref1
129 if ((ok1 == false) && (ref2->canConnectTo(ref1,testClock)) && (ref1->canConnectFrom(ref2,testClock))) {
130 ref2->connectTo(ref1);
133 if ((ok1 == true) || (ok2 == true)) {
136 cout << " ... done with " << qPrintable(ref1->getOwner()->getName()) << "/" << qPrintable(ref1->getName());
137 cout << " to " << qPrintable(ref2->getOwner()->getName()) << "/" << qPrintable(ref2->getName());
138 iface1->getOwner()->getScene()->createConnectionItem(iface1,iface2, visible);
141 cout << "... done with " << qPrintable(ref2->getOwner()->getName()) << "/" << qPrintable(ref2->getName());
142 cout << " to " << qPrintable(ref1->getOwner()->getName()) << "/" << qPrintable(ref1->getName());
143 iface2->getOwner()->getScene()->createConnectionItem(iface2,iface1, visible);
148 unselectAllItems(context);
149 params->unsaveModif = true;
156 void Dispatcher::unselectAllItems(Context context, int direction){
158 GroupScene *scene = params->getCurrentScene();
160 foreach(BoxItem* block, scene->getBoxItems()) {
161 block->setSelected(false);
162 block->setCurrentInterface(NULL);
164 scene->unselecteInterfaces();
168 void Dispatcher::setCurrentGroupWidget(Context context, GroupWidget *win){
170 win->changeConnectionMode(-1);
171 currentGroupWidget = win;
172 params->setCurrentScene(win->getScene());
175 void Dispatcher::changeConnectionMode(Context context, int mode){
178 foreach(GroupWidget* win, groupList){
180 QToolButton* buttonNewConnection = win->getButtonNewConnection();
182 QPalette pal = buttonNewConnection->palette();
185 if(params->sceneMode != Parameters::EditOnConnection){
186 params->sceneMode = Parameters::EditOnConnection;
187 pal.setColor(QPalette::Button, QColor(Qt::lightGray));
189 params->sceneMode = Parameters::EditNoOperation;
190 pal.setColor(QPalette::Button, QColor("#edeceb"));
193 else if(mode == Parameters::EditOnConnection){
194 params->sceneMode = Parameters::EditOnConnection;
195 pal.setColor(QPalette::Button, QColor(Qt::lightGray));
198 params->sceneMode = Parameters::EditNoOperation;
199 pal.setColor(QPalette::Button, QColor("#edeceb"));
201 unselectAllInterfaces();
203 buttonNewConnection->setAutoFillBackground(true);
204 buttonNewConnection->setPalette(pal);
205 buttonNewConnection->update();
210 void Dispatcher::generateVHDL(Context context) throw(Exception) {
211 static QString fctName = "Dispatcher::generateVHDL()";
213 cout << "call to " << qPrintable(fctName) << endl;
215 /* NB: only called in Design context */
216 if (context != Design) {
217 cout << "Abnormal case: call to " << qPrintable(fctName) << " not in Design context" << endl;
222 QDir baseDir(params->projectPath);
223 QDir srcDir(params->projectPath+"/src");
225 if (!baseDir.exists()) {
226 cerr << "Project path " << qPrintable(params->projectPath) << " no longer exists. First, recreate it and put the project file within. Then retry to generate." << endl;
230 if (srcDir.exists()) {
231 srcDir.removeRecursively();
233 baseDir.mkdir("src");
235 if (! baseDir.exists("testbench")) {
236 baseDir.mkdir("testbench");
238 if (! baseDir.exists("Makefile")) {
239 QFile make("/home/sdomas/Projet/Blast/code/blast/Makefile-isim");
240 QString dest = params->projectPath;
245 // generate VHDL + copying external resources
246 QString dest = params->projectPath;
249 params->getGraph()->generateVHDL(dest);
251 QList<QString> extResources = params->getGraph()->getExternalResources();
252 foreach(QString name, extResources) {
253 cout << qPrintable(name) << endl;
254 QList<ExternalResource*> lstRes = params->searchResourceByName(name);
255 foreach(ExternalResource* res, lstRes) {
256 QFile resFile(res->getFile());
257 QFileInfo info(res->getFile());
258 QString destFile = dest+info.fileName();
259 cout << "copying " << qPrintable(res->getFile()) << " into " << qPrintable(destFile) << endl;
260 resFile.copy(destFile);
267 // generate testbench
268 dest = params->projectPath;
269 dest += "/testbench/";
270 dest += params->projectName;
273 params->getGraph()->generateTestbench(params->projectName, dest);
279 // creating parameters file
280 QString paramName = params->projectPath+"/params-isim.txt";
281 QFile paramFile(paramName);
282 if (!paramFile.open(QIODevice::WriteOnly)) {
283 throw(Exception(PROJECTPATH_NOACCESS));
285 QTextStream out(¶mFile);
286 out << "PROJECT_NAME := " << params->projectName << endl << endl;
287 out << "SRC_DIR := src" << endl;
288 out << "TB_DIR := testbench" << endl << endl;
289 out << "VHDL_SRC := ";
292 srcDir.setNameFilters(filter);
293 QStringList listVHDL = srcDir.entryList();
294 for(int j=0;j<listVHDL.size();j++) {
298 out << "$(SRC_DIR)/" << qPrintable(listVHDL.at(j));
299 if (j != listVHDL.size()-1) {
305 out << "VL_SRC := ${XILINX}/verilog/src/glbl.v" << endl << endl;
306 out << "TB_SRC := $(TB_DIR)/$(PROJECT_NAME)_tb.vhd" << endl << endl;
307 out << "SIMU_EXE := $(PROJECT_NAME)_tb" << endl << endl;
311 QString msg = "VHDL generation completed successfully. Go to ";
312 msg += params->projectPath+" and type the following commands to launch a simulation:\n";
313 msg += "\tmake clean\n";
315 msg += "\tmake view\n";
316 QMessageBox::information(mainWindow,"VHDL generation", msg, QMessageBox::Ok);
320 void Dispatcher::generateBlockVHDL(Context context, BoxItem *item){
321 static QString fctName = "Dispatcher::generateBlockVHDL()";
323 cout << "call to " << qPrintable(fctName) << endl;
325 /* NB: only called in Design context */
326 if (context != Design) {
327 cout << "Abnormal case: call to " << qPrintable(fctName) << " not in Design context" << endl;
332 if (item->getRefBlock()->isFunctionalBlock()) {
333 FunctionalBlock* block = AB_TO_FUN(item->getRefBlock());
335 block->generateVHDL(params->projectPath);
338 cout << qPrintable(e.getMessage()) << endl;
343 void Dispatcher::renameFunctionalBlock(Context context, BoxItem *item){
344 static QString fctName = "Dispatcher::renameFunctionalBlock()";
346 cout << "call to " << qPrintable(fctName) << endl;
348 /* NB: only called in Design context */
349 if (context != Design) {
350 cout << "Abnormal case: call to " << qPrintable(fctName) << " not in Design context" << endl;
355 GroupWidget* win = item->getScene()->getGroupWidget();
360 text = QInputDialog::getText(win, "Rename a functional block",
361 "New name:", QLineEdit::Normal,
362 item->getRefBlock()->getName(), &ok);
365 if (text == item->getRefBlock()->getName()) return;
367 if( (text.isEmpty()) || (text.length() > 30)) {
368 QMessageBox::warning(win,"Error in given name",
369 "the block name must be shorter than 30 characters, cannot be empty",
374 FunctionalBlock* block = params->getGraph()->getFunctionalBlockByName(text, AB_TO_GRP(item->getRefBlock()->getParent()));
376 QMessageBox::warning(win,"Error in given name",
377 "the name provided is similar to that of another functional block within the group",
384 item->getRefBlock()->setName(text);
388 void Dispatcher::renameGroupBlock(Context context, GroupItem *item){
389 static QString fctName = "Dispatcher::renameGroupBlock()";
391 cout << "call to " << qPrintable(fctName) << endl;
393 /* NB: only called in Design context */
394 if (context != Design) {
395 cout << "Abnormal case: call to " << qPrintable(fctName) << " not in Design context" << endl;
400 GroupWidget* win = item->getScene()->getGroupWidget();
405 text = QInputDialog::getText(win, "Rename a group",
406 "New name:", QLineEdit::Normal,
407 item->getRefBlock()->getName(), &ok);
410 if (text == item->getRefBlock()->getName()) return;
412 if( (text.isEmpty()) || (text.length() > 30)) {
413 QMessageBox::warning(win,"Error in given name",
414 "the block name must be shorter than 30 characters, cannot be empty",
419 GroupBlock* block = params->getGraph()->getGroupBlockByName(text);
421 QMessageBox::warning(win,"Error in given name",
422 "the name provided is similar to that of another group",
429 item->getRefBlock()->setName(text);
430 if(item->getScene()->getGroupWidget()->isTopGroup()) {
431 mainWindow->setWindowTitle("blast - "+text);
434 item->getScene()->getGroupWidget()->setWindowTitle("blast - "+text);
437 mainWindow->getLibrary()->updateComboScene();
440 void Dispatcher::renameStimuliItem(Context context, StimuliItem *item){
441 static QString fctName = "Dispatcher::renameStimuliItem()";
443 cout << "call to " << qPrintable(fctName) << endl;
445 /* NB: only called in Design context */
446 if (context != Design) {
447 cout << "Abnormal case: call to " << qPrintable(fctName) << " not in Design context" << endl;
452 GroupWidget* win = item->getScene()->getGroupWidget();
457 text = QInputDialog::getText(win, "Rename a stimuli",
458 "New name:", QLineEdit::Normal,
459 item->getRefBlock()->getName(), &ok);
462 if (text == item->getRefBlock()->getName()) return;
464 if( (text.isEmpty()) || (text.length() > 30)) {
465 QMessageBox::warning(win,"Error in given name",
466 "the block name must be shorter than 30 characters, cannot be empty",
471 FunctionalBlock* block = params->getGraph()->getStimuliBlockByName(text);
473 QMessageBox::warning(win,"Error in given name",
474 "the name provided is similar to that of another stimuli block within the top group",
481 item->getRefBlock()->setName(text);
486 void Dispatcher::renameInterface(Context context, InterfaceItem *item) {
487 static QString fctName = "Dispatcher::renameInterface()";
489 cout << "call to " << qPrintable(fctName) << endl;
491 /* NB: only called in Design context */
492 if (context != Design) {
493 cout << "Abnormal case: call to " << qPrintable(fctName) << " not in Design context" << endl;
497 GroupWidget* win = item->getOwner()->getScene()->getGroupWidget();
502 text = QInputDialog::getText(win, "Rename an interface",
503 "New name:", QLineEdit::Normal,
504 item->refInter->getName(), &ok);
508 if (text == item->refInter->getName()) return;
510 if( (text.isEmpty()) || (text.length() > 30)) {
511 QMessageBox::warning(win,"Error in given name",
512 "the interface name must be shorter than 30 characters, cannot be empty",
517 AbstractInterface* iface = item->refInter->getOwner()->getIfaceFromName(text);
519 QMessageBox::warning(win,"Error in given name",
520 "the name provided is similar to that of another interface",
526 item->refInter->setName(text);
527 AbstractInterface* assoIface = item->refInter->getAssociatedIface();
528 if (assoIface != NULL) {
529 assoIface->setName(text+"_enb");
531 item->updateName(text);
532 item->getOwner()->nameChanged();
535 void Dispatcher::showPatterns(Context context, InterfaceItem *item) {
536 static QString fctName = "Dispatcher::showPatterns()";
538 cout << "call to " << qPrintable(fctName) << endl;
540 /* NB: only called in Design context */
541 if (context != Design) {
542 cout << "Abnormal case: call to " << qPrintable(fctName) << " not in Design context" << endl;
547 if (item->refInter->getDirection() == AbstractInterface::Input) {
548 msg = "Input pattern of iface ";
549 msg += item->refInter->getName();
551 msg += item->refInter->getOwner()->getName();
553 // get the precursor output pattern
554 ConnectedInterface* connIface = AI_TO_CON(item->refInter->getAssociatedIface());
555 QList<char>* out = connIface->getConnectedFrom()->getOutputPattern();
557 AbstractInputModifier* modifier = connIface->getInputModifier();
558 // check if the input is modified
559 if (modifier != NULL) {
561 out = modifier->getModifiedInput(out);
564 foreach(char c, *out) {
565 msg += QString::number((int)c);
569 else if (item->refInter->getDirection() == AbstractInterface::Output) {
570 msg = "Output pattern of iface ";
571 msg += item->refInter->getName();
573 msg += item->refInter->getOwner()->getName();
575 ConnectedInterface* iface = AI_TO_CON(item->refInter->getAssociatedIface());
576 if (iface->getOutputPattern() == NULL) return;
577 foreach(char c, *(iface->getOutputPattern())) {
578 msg += QString::number((int)c);
582 QMessageBox::information(NULL,"Interface pattern",msg,QMessageBox::Ok,QMessageBox::Ok);
585 void Dispatcher::showModifier(Context context, InterfaceItem *item) {
586 static QString fctName = "Dispatcher::showModifier()";
588 cout << "call to " << qPrintable(fctName) << endl;
590 /* NB: only called in Design context */
591 if (context != Design) {
592 cout << "Abnormal case: call to " << qPrintable(fctName) << " not in Design context" << endl;
597 ConnectedInterface* assoIface = AI_TO_CON(item->refInter->getAssociatedIface());
598 AbstractInputModifier* mod = assoIface->getInputModifier();
599 if (mod->isDelay()) {
600 DelayInputModifier* delay = (DelayInputModifier *)mod;
601 msg = "Pattern of iface ";
602 msg += item->refInter->getName();
604 msg += item->refInter->getOwner()->getName();
605 msg += " is modified by a simple delay of ";
606 msg += QString::number(delay->getDelayLength());
609 QMessageBox::information(NULL,"Interface pattern",msg,QMessageBox::Ok,QMessageBox::Ok);
612 void Dispatcher::removeModifier(Context context, InterfaceItem *item) {
613 static QString fctName = "Dispatcher::removeModifier()";
615 cout << "call to " << qPrintable(fctName) << endl;
617 /* NB: only called in Design context */
618 if (context != Design) {
619 cout << "Abnormal case: call to " << qPrintable(fctName) << " not in Design context" << endl;
624 ConnectedInterface* assoIface = AI_TO_CON(item->refInter->getAssociatedIface());
625 assoIface->clearInputModifier();
629 void Dispatcher::duplicateBoxItem(Context context, BoxItem *item){
630 static QString fctName = "Dispatcher::duplicateBoxItem()";
632 cout << "call to " << qPrintable(fctName) << endl;
634 /* NB: only called in Design context */
635 if (context != Design) {
636 cout << "Abnormal case: call to " << qPrintable(fctName) << " not in Design context" << endl;
641 GroupScene *scene = item->getScene();
642 AbstractBlock* block = item->getRefBlock();
643 AbstractBlock *newBlock;
645 // only duplicate functional blocks
646 if(block->isFunctionalBlock()) {
648 // adding to the model
649 FunctionalBlock* funBlock = (FunctionalBlock*)block;
650 newBlock = params->getGraph()->duplicateFunctionalBlock(funBlock);
651 // adding to the view
652 scene->createBoxItem(newBlock);
654 params->unsaveModif = true;
658 void Dispatcher::duplicateStimuliItem(Context context, StimuliItem *item) {
659 static QString fctName = "Dispatcher::duplicateStimuliItem()";
661 cout << "call to " << qPrintable(fctName) << endl;
663 /* NB: only called in Design context */
664 if (context != Design) {
665 cout << "Abnormal case: call to " << qPrintable(fctName) << " not in Design context" << endl;
670 GroupScene *scene = item->getScene();
671 AbstractBlock* block = item->getRefBlock();
672 AbstractBlock *newBlock;
674 // only duplicate functional blocks
675 if(block->isFunctionalBlock()) {
677 // adding to the model
678 FunctionalBlock* funBlock = (FunctionalBlock*)block;
679 newBlock = params->getGraph()->duplicateStimuliBlock(funBlock);
680 // adding to the view
681 scene->createStimuliItem(newBlock);
683 params->unsaveModif = true;
687 void Dispatcher::duplicateInterfaceItem(Context context, InterfaceItem *item) {
688 static QString fctName = "Dispatcher::duplicateInterfaceItem()";
690 cout << "call to " << qPrintable(fctName) << endl;
692 /* NB: only called in Design context */
693 if (context != Design) {
694 cout << "Abnormal case: call to " << qPrintable(fctName) << " not in Design context" << endl;
699 AbstractInterface *refI = item->refInter;
700 if (! refI->isFunctionalInterface()) return;
702 AbstractBlock *refB = refI->getOwner();
703 if(! refB->isFunctionalBlock()) return;
705 FunctionalInterface* iface = (FunctionalInterface*)refI;
706 AbstractInterface *cloneIface = iface->clone();
707 if (cloneIface == NULL) {
708 QMessageBox::warning(NULL,"Error while cloning an interface","the interface cannot be cloned because its maximum multiplicity is reached", QMessageBox::Ok);
712 refB->addInterface(cloneIface);
714 InterfaceItem *cloneIfaceItem = new InterfaceItem(item->getPosition(),item->getOrientation(),(ConnectedInterface*)cloneIface,item->getOwner(),params);
715 item->getOwner()->addInterfaceItem(cloneIfaceItem,true);
717 // creating control interface if needed
718 if (refI->getAssociatedIface() != NULL) {
719 QString ctlName = cloneIface->getName()+"_enb";
720 ReferenceInterface* ctlIface = new ReferenceInterface(refB,ctlName,cloneIface->getDirection(), AbstractInterface::Control,"boolean","1", AbstractInterface::LittleEndian, 1);
721 refB->addInterface(ctlIface);
722 if (! ctlIface->setAssociatedIface(cloneIface)) {
723 cerr << "Abnormal case while cloning an interface and creating its associated control interface" << endl;
729 void Dispatcher::addBlock(Context context, int idCategory, int idBlock, int idScene, QHash<QString, int> clkRstToGen) {
730 static QString fctName = "Dispatcher::addBlock()";
732 cout << "call to " << qPrintable(fctName) << endl;
734 bool newStimuli = false;
736 /* For now, this method is only used while designing and not loading */
737 if (context == Design) {
738 GroupScene *scene = getSceneById(idScene);
739 ReferenceBlock* ref = params->getReferenceBlock(idCategory,idBlock);
740 // if block has no inputs, propose to add it as a source to top scene
741 if ((scene->isTopScene()) && (ref->isSourceBlock())) {
742 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 ?");
743 if (ret == QMessageBox::Yes) {
748 FunctionalBlock* newOne = params->getGraph()->createStimuliBlock(ref, true);
749 StimuliItem* item = scene->createStimuliItem(newOne);
750 QHashIterator<QString,int> iter(clkRstToGen);
751 while (iter.hasNext()) {
753 AbstractInterface* iface = newOne->getIfaceFromName(iter.key());
754 if (iface->getPurpose() == AbstractInterface::Clock) {
755 connectStimuliItemClock(context,item,iface->getName(),iter.value());
757 else if (iface->getPurpose() == AbstractInterface::Reset) {
758 connectStimuliItemReset(context,item,iface->getName(),iter.value());
764 GroupBlock* group = AB_TO_GRP(scene->getGroupItem()->getRefBlock());
765 FunctionalBlock* newOne = params->getGraph()->createFunctionalBlock(group, ref, true);
767 // creating the box item
768 BoxItem* item = scene->createBoxItem(newOne);
770 QHashIterator<QString,int> iter(clkRstToGen);
771 while (iter.hasNext()) {
773 AbstractInterface* iface = newOne->getIfaceFromName(iter.key());
774 if (iface->getPurpose() == AbstractInterface::Clock) {
775 connectBoxItemClock(context,item,iface->getName(),iter.value());
777 else if (iface->getPurpose() == AbstractInterface::Reset) {
778 connectBoxItemReset(context,item,iface->getName(),iter.value());
782 params->blockToItem.insert(newOne,item);
784 params->unsaveModif = true;
788 void Dispatcher::addClkRstGenBlock(Context context, double frequency) {
789 static QString fctName = "Dispatcher::addClkRstGenBlock()";
791 cout << "call to " << qPrintable(fctName) << endl;
795 if (context == Design) {
797 params->getGraph()->addClock(frequency);
800 GroupBlock *group = params->getGraph()->getTopGroup();
801 GroupScene *scene = topGroupWidget->getScene();
803 // creating the clkrstgen block
804 ReferenceBlock* ref = params->getHiddenReferenceBlock("clkrstgen");
805 FunctionalBlock* newOne = params->getGraph()->createFunctionalBlock(group, ref, true);
807 QString name = "clkrstgen_";
808 name += QString::number(params->getGraph()->getClocks().size()-1);
809 newOne->setName(name);
811 // creating the box item
812 BoxItem* item = scene->createBoxItem(newOne, BoxItem::Left, AbstractBoxItem::Dimension);
813 item->setVisible(false);
815 ConnectedInterface* fromIfaceClk = NULL;
816 ConnectedInterface* fromIfaceReset = NULL;
817 QString clkName = "ext_clk_"+QString::number(params->getGraph()->getClocks().size()-1);
818 QString rstName = "ext_reset_"+QString::number(params->getGraph()->getClocks().size()-1);
819 fromIfaceClk = new GroupInterface(group,clkName, AbstractInterface::Input, AbstractInterface::Clock);
820 fromIfaceReset = new GroupInterface(group,rstName, AbstractInterface::Input, AbstractInterface::Reset);
821 group->addInterface(fromIfaceClk);
822 group->addInterface(fromIfaceReset);
823 // creating top group ext_clk iface item
824 GroupItem* groupItem = scene->getGroupItem();
825 InterfaceItem* fromIfaceItemClk = new InterfaceItem(0.5 , Parameters::West, fromIfaceClk, groupItem, params, true);
826 groupItem->addInterfaceItem(fromIfaceItemClk,true);
827 // creating top group ext_reset iface item
828 InterfaceItem* fromIfaceItemReset = new InterfaceItem(0.5 , Parameters::West, fromIfaceReset, groupItem, params, false);
829 groupItem->addInterfaceItem(fromIfaceItemReset,true);
830 // connecting ext_clk iface items
831 InterfaceItem* toIfaceItemClk = item->searchInterfaceItemByName("ext_clk");
832 if (toIfaceItemClk == NULL) {
833 cerr << "Abnormal case while connecting top group ext_clk to clkrstgen" << endl;
835 createConnection(context,fromIfaceItemClk, toIfaceItemClk, false);
836 // connecting ext_reset iface items
837 InterfaceItem* toIfaceItemReset = item->searchInterfaceItemByName("ext_reset");
838 if (toIfaceItemReset == NULL) {
839 cerr << "Abnormal case while connecting top group ext_reset to clkrstgen" << endl;
841 createConnection(context,fromIfaceItemReset, toIfaceItemReset, false);
843 params->blockToItem.insert(newOne,item);
844 params->unsaveModif = true;
850 GroupWidget *Dispatcher::createTopScene(Context context, double mainClock){
851 static QString fctName = "Dispatcher::createTopScene()";
853 cout << "call to " << qPrintable(fctName) << endl;
857 // creating the graph and thus, the topgroup
858 if (context == Design) {
859 graph = params->initGraph(true);
860 graph->addClock(mainClock);
862 else if (context == Load) {
863 graph = params->initGraph(false);
867 GroupBlock *topBlock = graph->getTopGroup();
868 // creating the top group widget
869 topGroupWidget = new GroupWidget(NULL,this,params);
870 currentGroupWidget = topGroupWidget;
871 // getting the newly created scene
872 GroupScene *scene = topGroupWidget->getScene();
873 scene->setId(sceneCounter++);
874 params->setTopScene(scene);
875 params->setCurrentScene(scene);
876 // creating the view part of the group
877 GroupItem *group = new GroupItem(NULL,topBlock,this,params);
878 // associate the top scene to the top group iten
879 scene->setGroupItem(group);
881 // adding the fake interface to the top group item
882 //InterfaceItem* item = new InterfaceItem(0.0 , Parameters::West, (ConnectedInterface*)iface, group, params);
883 //group->addInterface(item,true);
886 if (context == Design) {
888 double freq = params->getGraph()->getClock(0);
889 params->getGraph()->resetClocks();
890 addClkRstGenBlock(context,freq);
893 groupList.append(topGroupWidget);
894 return topGroupWidget;
897 GroupWidget* Dispatcher::addNewEmptyGroup(Context context, GroupScene* scene, bool show) {
898 static QString fctName = "Dispatcher::addNewEmptyGroup();";
900 cout << "call to " << qPrintable(fctName) << endl;
902 bool createIfaces = true;
903 if (context == Load) {
904 createIfaces = false;
907 // getting the parent block in the graph
908 GroupBlock* parent = AB_TO_GRP(scene->getGroupItem()->getRefBlock());
909 cout << "new group : parent = "<< qPrintable(parent->getName()) << endl;
910 GroupBlock* groupBlock = params->getGraph()->createChildGroupBlock(parent, createIfaces);
911 cout << "new group : child = "<< qPrintable(groupBlock->getName()) << ", child of " << qPrintable(groupBlock->getParent()->getName()) << endl;
912 // creating the BlockItem in the scene
913 BoxItem* newItem = scene->createBoxItem(groupBlock);
915 params->unsaveModif = true;
917 GroupWidget* child = createChildScene(context, scene->getGroupWidget(),newItem);
918 if (show) child->show();
923 GroupWidget *Dispatcher::createChildScene(Context context, GroupWidget* parentWidget, BoxItem *upperItemOfGroupItem) {
924 static QString fctName = "Dispatcher::createChildScene()";
926 cout << "call to " << qPrintable(fctName) << endl;
929 GroupWidget* group = NULL;
930 /* NB: this method may be called during design process or when loading
931 a project. In this case, upperItemOfGroupItem is NULL, thus a lot of things
932 cannot be initialized yet. This is why there are 2 cases below
935 if (upperItemOfGroupItem != NULL) {
936 // getting back the goup block already created
937 GroupBlock* groupBlock = AB_TO_GRP(upperItemOfGroupItem->getRefBlock());
938 // creating the view part of the group
939 GroupItem *groupItem = new GroupItem(upperItemOfGroupItem,groupBlock,this,params);
941 // creating the group widget
942 group = new GroupWidget(parentWidget, this, params);
943 // getting the newly created scene
944 GroupScene *scene = group->getScene();
945 scene->setId(sceneCounter++);
946 // affecting group item to the scene
947 scene->setGroupItem(groupItem);
948 groupList.append(group);
950 mainWindow->getLibrary()->updateComboScene();
953 GroupItem *groupItem = new GroupItem(this,params);
954 // creating the group widget
955 group = new GroupWidget(parentWidget, this, params);
956 // getting the newly created scene
957 GroupScene *scene = group->getScene();
958 // affecting group item to the scene
959 scene->setGroupItem(groupItem);
960 groupList.append(group);
965 void Dispatcher::destroyScene(Context context, GroupScene *scene) {
966 foreach(GroupScene* s, scene->getChildrenScene()) {
967 destroyScene(context, s);
970 if (scene->getNbChildScene() == 0) {
971 // remove scene from the parent list, if possible
972 if (scene->getParentScene() != NULL) {
973 scene->getParentScene()->removeChildScene(scene);
975 // destroy the GroupWidget
976 groupList.removeAll(scene->getGroupWidget());
977 scene->getGroupWidget()->deleteLater();
980 cerr << "Abnormal case when destroying a scene" << endl;
984 void Dispatcher::showRaiseWindow(Context context, BoxItem *item) {
985 static QString fctName = "Dispatcher::showRaiseWindow()";
987 cout << "call to " << qPrintable(fctName) << endl;
990 cout << "raising child scene of " << qPrintable(item->getRefBlock()->getName()) << endl;
991 GroupItem* child = item->getChildGroupItem();
993 cerr << "abnormal case: child group item is null " << endl;
997 GroupWidget* win = child->getScene()->getGroupWidget();
1001 win->activateWindow();
1003 currentGroupWidget = win;
1004 params->setCurrentScene(currentGroupWidget->getScene());
1007 void Dispatcher::showRstClkIface(Context context, AbstractBoxItem *item) {
1008 static QString fctName = "Dispatcher::showRstClkIface()";
1009 #ifdef DEBUG_FCTNAME
1010 cout << "call to " << qPrintable(fctName) << endl;
1013 item->setRstClkVisible(!item->isRstClkVisible());
1017 void Dispatcher::showWishboneIface(Context context, AbstractBoxItem *item) {
1018 static QString fctName = "Dispatcher::showWishboneIface()";
1019 #ifdef DEBUG_FCTNAME
1020 cout << "call to " << qPrintable(fctName) << endl;
1023 item->setWishboneVisible(!item->isWishboneVisible());
1026 void Dispatcher::addNewFullGroup(Context context) {
1027 static QString fctName = "Dispatcher::addNewFullGroup()";
1028 #ifdef DEBUG_FCTNAME
1029 cout << "call to " << qPrintable(fctName) << endl;
1033 #ifdef DEBUG_INCLFUN
1035 QList<BlockItem*> listBlocks = params->getCurrentScene()->getSelectedBlocks(); //selected blocks in the current scene
1036 QList<AbstractBlock*> listAbstractBlocks; //abstract blocks in the group
1037 QList<ConnectionItem *> connections = params->getCurrentScene()->getConnectionItems();
1039 /* What must be done:
1040 1 - creating a new GroupBlock
1041 2 - moving the selected blocks from the current GroupBlock to the new GroupBlock
1042 3 - creating a BlockItem that references the new GroupBlock
1043 4 - creating a new GroupWidget
1044 5 - creating a new GroupItem added to the scene of the GroupWidget
1048 /* step 1 : creating new GroupBlock that will have as a parent the GroupBlock
1049 associated to the GroupItem of the current scene
1051 GroupBlock* parentBlock = params->getCurrentScene()->getGroupItem()->getRefBlock();
1052 GroupBlock* newGroupBlock = new GroupBlock(parentBlock);
1053 /* step 2: moving selected blocks */
1054 foreach(BlockItem* blockItem, listBlocks) {
1055 parentBlock->removeBlock(blockItem->getRefBlock());
1056 newGroupBlock->addBlock(blockItem->getRefBlock());
1059 GroupItem *parent = currentGroup->getScene()->getGroupItem();
1060 GroupBlock *groupBlock = new GroupBlock(((GroupBlock*)parent->getRefBlock()),params->currentWindow);
1061 BlockItem *blockItem = new BlockItem(params->getCurrentScene()->getGroupItem(),groupBlock,this,params);
1062 GroupItem *groupItem = new GroupItem(blockItem,groupBlock,this,params);
1064 //create the new window
1065 GroupWidget* win = new GroupWidget(this,params);
1066 win->getScene()->setGroupItem(groupItem);
1067 win->getScene()->addItem(groupItem);
1068 ((GroupBlock*)groupItem->getRefBlock())->setWindow(win);
1069 params->addWindow(win);
1073 params->getCurrentScene()->addBlockItem(blockItem);
1074 params->getCurrentScene()->addItem(blockItem);
1075 ((GroupItem*)params->getCurrentScene()->getGroupItem())->addBlockItem(blockItem);
1077 //replace selected blocks in the group
1078 foreach(AbstractBoxItem *block, listBlocks){
1079 ((GroupItem*)block->getParentItem())->removeBlockItem(block);
1080 ((GroupBlock*)block->getParentItem()->getRefBlock())->removeBlock(block->getRefBlock());
1081 params->getCurrentScene()->removeItem(block);
1082 params->getCurrentScene()->removeBlockItem(block);
1084 groupBlock->addBlock(block->getRefBlock());
1085 listAbstractBlocks.append(block->getRefBlock());
1087 block->setUpperItem(groupItem);
1088 groupItem->addBlockItem(block);
1089 win->getScene()->addItem(block);
1090 win->getScene()->addBlockItem(block);
1093 //replace connection between selected blocks in the group
1094 foreach(ConnectionItem *conn, connections){
1095 if(listBlocks.contains(conn->getFromInterfaceItem()->getOwner())){
1096 if(listBlocks.contains(conn->getToInterfaceItem()->getOwner())){
1097 parent->removeConnection(conn);
1098 params->getCurrentScene()->removeItem(conn);
1100 groupItem->addConnection(conn);
1101 win->getScene()->addItem(conn);
1106 //create new interfaces and connections for the new group
1107 foreach(AbstractBoxItem *block, listBlocks){
1108 foreach(InterfaceItem *inter, block->getInterfaces()){
1109 cout << "inter : " << inter->getName().toStdString() << endl;
1110 if(inter->refInter->getConnectedFrom() != NULL && inter->refInter->getDirection() == AbstractInterface::Input){
1111 cout << "connected from non null" << endl;
1112 if(!listAbstractBlocks.contains(inter->refInter->getConnectedFrom()->getOwner())){
1114 AbstractInterface *iface = inter->refInter->clone(0);
1115 iface->setName(iface->getName()+"_group");
1116 groupBlock->addInterface(iface);
1118 InterfaceItem *ifaceItem = new InterfaceItem(0,Parameters::East,iface,blockItem,params);
1119 blockItem->addInterface(ifaceItem);
1120 blockItem->resetInterfacesPosition();
1122 InterfaceItem *ifaceGroupItem = new InterfaceItem(0,Parameters::West,iface,groupItem,params);
1123 groupItem->addInterface(ifaceGroupItem);
1124 groupItem->resetInterfacesPosition();
1125 foreach(ConnectionItem* conn, currentGroup->getScene()->getInterfaceConnections(inter)){
1126 if(conn->getToInterfaceItem() == inter){
1127 conn->setToInterfaceItem(ifaceItem);
1128 ifaceItem->refInter->setConnectedFrom(NULL);
1129 conn->getFromInterfaceItem()->refInter->clearConnectedTo();
1130 connect(ifaceItem,conn->getFromInterfaceItem());
1133 params->setCurrentWindow(win);
1135 inter->refInter->setConnectedFrom(NULL);
1136 ifaceGroupItem->refInter->clearConnectedTo();
1137 connect(inter,ifaceGroupItem);
1138 params->setCurrentWindow(mainWindow);
1142 if(!inter->refInter->getConnectedTo().isEmpty() && inter->refInter->getDirection() == AbstractInterface::Output){
1143 cout << "connected to non null" << endl;
1144 foreach(AbstractInterface *iface, inter->refInter->getConnectedTo()){
1145 if(!listAbstractBlocks.contains(iface->getOwner())){
1147 AbstractInterface *iface = inter->refInter->clone(0);
1148 iface->setName(iface->getName()+"_group");
1149 groupBlock->addInterface(iface);
1151 InterfaceItem *ifaceItem = new InterfaceItem(0,Parameters::East,iface,blockItem,params);
1152 blockItem->addInterface(ifaceItem);
1153 blockItem->resetInterfacesPosition();
1155 foreach(ConnectionItem* conn, currentGroup->getScene()->getInterfaceConnections(inter)){
1156 if(conn->getFromInterfaceItem() == inter){
1157 conn->setFromInterfaceItem(ifaceItem);
1158 iface->addConnectedTo(conn->getToInterfaceItem()->refInter);
1159 conn->getToInterfaceItem()->refInter->setConnectedFrom(iface);
1163 InterfaceItem *ifaceGroupItem = new InterfaceItem(0,Parameters::East,iface,groupItem,params);
1164 groupItem->addInterface(ifaceGroupItem);
1165 groupItem->resetInterfacesPosition();
1166 inter->refInter->clearConnectedTo();
1167 ifaceGroupItem->refInter->setConnectedFrom(NULL);
1168 connect(ifaceGroupItem,inter);
1177 parent->updateShape();
1178 currentGroup->getScene()->updateConnectionItemsShape();
1180 groupItem->updateShape();
1181 win->getScene()->updateConnectionItemsShape();
1182 groupItem->update(groupItem->boundingRect());
1187 void Dispatcher::removeBoxItem(Context context, BoxItem *item) {
1188 static QString fctName = "Dispatcher::removeBoxItem()";
1189 #ifdef DEBUG_FCTNAME
1190 cout << "call to " << qPrintable(fctName) << endl;
1192 /* NB: only called in Design context */
1193 if (context != Design) {
1194 cout << "Abnormal case: call to " << qPrintable(fctName) << " not in Design context" << endl;
1198 /* a BoxItem (group of func) can be removed only if none of its
1199 interfaces is connected to a group interface that is itself
1200 connected to another one.
1202 bool canRemove = true;
1204 foreach(InterfaceItem* ifaceItem, item->getInterfaces()) {
1205 foreach(ConnectionItem* conn, ifaceItem->connections) {
1206 InterfaceItem* other = NULL;
1207 if (conn->getFromInterfaceItem() == ifaceItem) {
1208 other = conn->getToInterfaceItem();
1211 other = conn->getFromInterfaceItem();
1214 if (other->getOwner()->isGroupItem()) {
1215 ConnectedInterface* ref = other->refInter;
1216 if ((ref->isConnectedFrom()) && (ref->isConnectedTo())) {
1223 QMessageBox::warning(NULL,"Forbidden operation",
1224 "The block has at least one connection to a group interface that is totally connected.",
1230 if (item->getRefBlock()->isFunctionalBlock()) {
1231 msg = "Removing block ";
1234 msg = "Removing group ";
1236 msg += item->getRefBlock()->getName();
1237 msg += " and all its connections.\n\nAre you sure ?";
1239 int ret = QMessageBox::question(NULL,"Removing functional block",msg, QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Ok);
1240 if (ret == QMessageBox::Cancel) {
1243 removeAllBlockConnections(context, item);
1245 if (item->getRefBlock()->isFunctionalBlock()) {
1246 FunctionalBlock* block = AB_TO_FUN(item->getRefBlock());
1247 item->getScene()->removeBoxItem(item);
1248 params->getGraph()->removeFunctionalBlock(block);
1249 params->blockToItem.remove(block);
1252 else if (item->getRefBlock()->isGroupBlock()) {
1254 GroupBlock* group = AB_TO_GRP(item->getRefBlock());
1256 // remove all child scenes recursively
1257 GroupItem* subgroup = item->getChildGroupItem();
1258 destroyScene(context, subgroup->getScene());
1259 // remove the BoxItem
1260 item->getScene()->removeBoxItem(item);
1261 // remove the group from the graph
1262 params->getGraph()->removeGroupBlock(group);
1266 void Dispatcher::removeAllBlockConnections(Context context, AbstractBoxItem *item) {
1267 static QString fctName = "Dispatcher::removeAllBlockConnection()";
1268 #ifdef DEBUG_FCTNAME
1269 cout << "call to " << qPrintable(fctName) << endl;
1271 /* NB: only called in Design context */
1272 if (context != Design) {
1273 cout << "Abnormal case: call to " <<qPrintable(fctName) << " not in Design context" << endl;
1277 foreach(InterfaceItem* ifaceItem, item->getInterfaces()) {
1278 foreach(ConnectionItem* conn, ifaceItem->connections) {
1279 removeConnection(context, conn);
1284 void Dispatcher::removeStimuliItem(Context context, StimuliItem *item) {
1285 static QString fctName = "Dispatcher::removeStimuliItem()";
1286 #ifdef DEBUG_FCTNAME
1287 cout << "call to " << qPrintable(fctName) << endl;
1289 /* NB: only called in Design context */
1290 if (context != Design) {
1291 cout << "Abnormal case: call to " <<qPrintable(fctName) << " not in Design context" << endl;
1295 QString msg = "Removing stimmuli ";
1297 msg += item->getRefBlock()->getName();
1298 msg += " and all its connections.\n\nAre you sure ?";
1300 int ret = QMessageBox::question(NULL,"Removing stimuli block",msg, QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Ok);
1301 if (ret == QMessageBox::Cancel) {
1304 removeAllBlockConnections(context, item);
1306 FunctionalBlock* block = AB_TO_FUN(item->getRefBlock());
1307 item->getScene()->removeStimuliItem(item);
1308 params->getGraph()->removeStimuliBlock(block);
1312 void Dispatcher::removeConnection(Context context, ConnectionItem *connItem) {
1313 static QString fctName = "Dispatcher::removeConnection()";
1314 #ifdef DEBUG_FCTNAME
1315 cout << "call to " << qPrintable(fctName) << endl;
1317 /* NB: only called in Design context */
1318 if (context != Design) {
1319 cout << "Abnormal case: call to " <<qPrintable(fctName) << " not in Design context" << endl;
1323 InterfaceItem* fromIfaceItem = connItem->getFromInterfaceItem();
1324 InterfaceItem* toIfaceItem = connItem->getToInterfaceItem();
1327 cout << "remove connection from " << qPrintable(fromIfaceItem->refInter->getName()) << " to " << qPrintable(toIfaceItem->refInter->getName()) << endl;
1330 InterfaceItem* groupIfaceItem = NULL; // in case of one of the two interface belongs to the GroupItem, and stays NULL if not
1331 GroupItem* groupItem = NULL; // the GroupItem of the scene that contains connItem
1333 ConnectedInterface *fromInter = fromIfaceItem->refInter;
1334 ConnectedInterface *toInter = toIfaceItem->refInter;
1336 // test if one of the interface bounded to item is owned by a GroupItem
1337 if (fromIfaceItem->getOwner()->isGroupItem()) {
1338 groupItem = ABI_TO_GI(fromIfaceItem->getOwner());
1339 groupIfaceItem = fromIfaceItem;
1341 else if (toIfaceItem->getOwner()->isGroupItem()) {
1342 groupItem = ABI_TO_GI(toIfaceItem->getOwner());
1343 groupIfaceItem = toIfaceItem;
1346 groupItem = fromIfaceItem->getOwner()->getScene()->getGroupItem();
1349 // removing the connection from graph
1351 cout << "removing connections from graph ..." ;
1353 fromInter->disconnectTo(toInter);
1356 cout << "done." << endl ;
1359 // removing the connection from scene
1361 cout << "removing connections from scene ..." ;
1363 groupItem->getScene()->removeConnectionItem(connItem);
1366 cout << "done." << endl ;
1369 // if one of the interface bounded to connItem is owned by the GroupItem of the scene
1370 if (groupIfaceItem != NULL) {
1372 // determine if the interface must be removed since it has no more connections.
1373 bool groupInterRemove = false;
1374 if ((groupIfaceItem->refInter->isConnectedTo() == false) && (groupIfaceItem->refInter->isConnectedFrom() == false)) groupInterRemove = true;
1376 if (groupInterRemove) {
1377 // get the GroupInterface from interface item
1378 ConnectedInterface* groupInter = groupIfaceItem->refInter;
1379 // remove interface from GroupItem, and delete it.
1380 groupItem->removeInterfaceItem(groupIfaceItem);
1381 // get the parent BoxItem of GroupItem if it exists.
1382 BoxItem* parent2Item = groupItem->getParentItem();
1383 if (parent2Item != NULL) {
1384 InterfaceItem* group2IfaceItem = parent2Item->searchInterfaceItemByRef(groupInter);
1385 // remove interface intem in parent BoxItem
1386 parent2Item->removeInterfaceItem(group2IfaceItem);
1388 // remove GroupInterface in the graph.
1389 groupInter->getOwner()->removeInterface(groupInter);
1394 void Dispatcher::connectBoxItemClock(Context context, BoxItem *item, QString clkName, int idGen) throw(Exception) {
1396 static QString fctName = "Dispatcher::connectBoxItemClock()";
1397 #ifdef DEBUG_FCTNAME
1398 cout << "call to " << qPrintable(fctName) << endl;
1400 /* NB: only called in Design context */
1401 if (context != Design) {
1402 cout << "Abnormal case: call to " <<qPrintable(fctName) << " not in Design context" << endl;
1406 InterfaceItem* fromIfaceItemClk = NULL;
1407 InterfaceItem* toIfaceItemClk = item->searchInterfaceItemByName(clkName);
1408 GroupItem* parentGroup = item->getScene()->getGroupItem();
1409 BoxItem* clkrstItem = NULL;
1411 if (parentGroup->getRefBlock()->isTopGroupBlock()) {
1412 QString genName = "clkrstgen_" + QString::number(idGen);
1413 clkrstItem = item->getScene()->searchBoxItemByName(genName);
1414 if (clkrstItem == NULL) {
1415 throw(Exception(IFACE_TOP_NOCLKRSTGEN));
1418 fromIfaceItemClk = clkrstItem->searchInterfaceItemByName("clk");
1420 cout << "connecting clock of " << qPrintable(item->getRefBlock()->getName()) << " to clk of " << qPrintable(genName) << endl;
1423 // searching for ext_clk_idGen
1424 QString name = "ext_clk_"+QString::number(idGen);
1425 fromIfaceItemClk = parentGroup->searchInterfaceItemByName(name);
1426 cout << "connecting clock of " << qPrintable(item->getRefBlock()->getName()) << " to " << qPrintable(name) << " of parent group " << qPrintable(parentGroup->getRefBlock()->getName()) << endl;
1429 if (fromIfaceItemClk == NULL) {
1430 throw(Exception(IFACE_GROUP_NOCLKRST));
1433 createConnection(context, fromIfaceItemClk, toIfaceItemClk, false);
1434 cout << "connection done." << endl;
1438 void Dispatcher::connectBoxItemReset(Context context, BoxItem *item, QString rstName, int idGen) throw(Exception) {
1440 static QString fctName = "Dispatcher::connectBoxItemReset()";
1441 #ifdef DEBUG_FCTNAME
1442 cout << "call to " << qPrintable(fctName) << endl;
1444 /* NB: only called in Design context */
1445 if (context != Design) {
1446 cout << "Abnormal case: call to " <<qPrintable(fctName) << " not in Design context" << endl;
1450 InterfaceItem* fromIfaceItemRst = NULL;
1451 InterfaceItem* toIfaceItemRst = item->searchInterfaceItemByName(rstName);
1452 GroupItem* parentGroup = item->getScene()->getGroupItem();
1453 BoxItem* clkrstItem = NULL;
1455 if (parentGroup->getRefBlock()->isTopGroupBlock()) {
1456 QString genName = "clkrstgen_" + QString::number(idGen);
1457 clkrstItem = item->getScene()->searchBoxItemByName(genName);
1458 if (clkrstItem == NULL) {
1459 throw(Exception(IFACE_TOP_NOCLKRSTGEN));
1462 fromIfaceItemRst = clkrstItem->searchInterfaceItemByName("reset");
1464 cout << "connecting reset of " << qPrintable(item->getRefBlock()->getName()) << " to reset of " << qPrintable(genName) << endl;
1467 // searching for ext_rst_idGen
1468 QString name = "ext_rst_"+QString::number(idGen);
1469 fromIfaceItemRst = parentGroup->searchInterfaceItemByName(name);
1470 cout << "connecting reset of " << qPrintable(item->getRefBlock()->getName()) << " to " << qPrintable(name) << " of parent group " << qPrintable(parentGroup->getRefBlock()->getName()) << endl;
1473 if (fromIfaceItemRst == NULL) {
1474 throw(Exception(IFACE_GROUP_NOCLKRST));
1477 createConnection(context, fromIfaceItemRst, toIfaceItemRst, false);
1478 cout << "connection done." << endl;
1482 void Dispatcher::connectStimuliItemClock(Context context, StimuliItem *item, QString clkName, int idGen) throw(Exception) {
1484 static QString fctName = "Dispatcher::connectStimuliItemClock()";
1485 #ifdef DEBUG_FCTNAME
1486 cout << "call to " << qPrintable(fctName) << endl;
1488 /* NB: only called in Design context */
1489 if (context != Design) {
1490 cout << "Abnormal case: call to " <<qPrintable(fctName) << " not in Design context" << endl;
1494 InterfaceItem* fromIfaceItemClk = NULL;
1495 InterfaceItem* toIfaceItemClk = item->searchInterfaceItemByName(clkName);
1496 BoxItem* clkrstItem = NULL;
1498 QString genName = "clkrstgen_" + QString::number(idGen);
1499 clkrstItem = item->getScene()->searchBoxItemByName(genName);
1500 if (clkrstItem == NULL) {
1501 throw(Exception(IFACE_TOP_NOCLKRSTGEN));
1504 fromIfaceItemClk = clkrstItem->searchInterfaceItemByName("clk");
1506 cout << "connecting clock of " << qPrintable(item->getRefBlock()->getName()) << " to clock of " << qPrintable(genName) << endl;
1508 if (fromIfaceItemClk == NULL) {
1509 throw(Exception(IFACE_GROUP_NOCLKRST));
1512 createConnection(context, fromIfaceItemClk, toIfaceItemClk, false);
1513 cout << "connection done." << endl;
1517 void Dispatcher::connectStimuliItemReset(Context context, StimuliItem *item, QString rstName, int idGen) throw(Exception) {
1518 static QString fctName = "Dispatcher::connectStimuliItemReset()";
1519 #ifdef DEBUG_FCTNAME
1520 cout << "call to " << qPrintable(fctName) << endl;
1522 /* NB: only called in Design context */
1523 if (context != Design) {
1524 cout << "Abnormal case: call to " <<qPrintable(fctName) << " not in Design context" << endl;
1528 InterfaceItem* fromIfaceItemRst = NULL;
1529 InterfaceItem* toIfaceItemRst = item->searchInterfaceItemByName(rstName);
1530 BoxItem* clkrstItem = NULL;
1532 QString genName = "clkrstgen_" + QString::number(idGen);
1533 clkrstItem = item->getScene()->searchBoxItemByName(genName);
1534 if (clkrstItem == NULL) {
1535 throw(Exception(IFACE_TOP_NOCLKRSTGEN));
1538 fromIfaceItemRst = clkrstItem->searchInterfaceItemByName("reset");
1540 cout << "connecting reset of " << qPrintable(item->getRefBlock()->getName()) << " to reset of " << qPrintable(genName) << endl;
1542 if (fromIfaceItemRst == NULL) {
1543 throw(Exception(IFACE_GROUP_NOCLKRST));
1546 createConnection(context, fromIfaceItemRst, toIfaceItemRst, false);
1547 cout << "connection done." << endl;
1552 void Dispatcher::showBlocksLibrary(){
1553 cout << "showing block library" << endl;
1554 mainWindow->getLibrary()->show();
1555 mainWindow->getLibrary()->raise();
1558 void Dispatcher::showProperties(Context context, InterfaceItem *inter) {
1560 static QString fctName = "Dispatcher::showProperties()";
1561 #ifdef DEBUG_FCTNAME
1562 cout << "call to " << qPrintable(fctName) << endl;
1564 /* NB: only called in Design context */
1565 if (context != Design) {
1566 cout << "Abnormal case: call to " <<qPrintable(fctName) << " not in Design context" << endl;
1570 QDialog* dial = new InterfacePropertiesDialog(inter);
1574 /* connectInterToGroup() :
1575 The only way for a block (functional of group) within a GroupItem to be connected
1576 to the latter is to right-click on one of its interfaces and to choose "connect to group".
1577 That action will create a new InterfaceItem on the GroupItem and a connectionItem between the
1580 void Dispatcher::connectInterToGroup(Context context, InterfaceItem *item){
1582 static QString fctName = "Dispatcher::connectInterToGroup()";
1583 #ifdef DEBUG_FCTNAME
1584 cout << "call to " << qPrintable(fctName) << endl;
1586 /* NB: only called in Design context */
1587 if (context != Design) {
1588 cout << "Abnormal case: call to " <<qPrintable(fctName) << " not in Design context" << endl;
1592 // getting the GroupBlock and GroupItem that are parent of the block that owns item
1593 ConnectedInterface *refInter = item->refInter;
1594 cout << "owner of iface = " << qPrintable(refInter->getOwner()->getName()) << endl;
1595 GroupBlock* parentBlock = AB_TO_GRP(refInter->getOwner()->getParent());
1596 cout << "create iface for parent group = " << qPrintable(parentBlock->getName()) << endl;
1597 GroupItem *parentItem = item->getOwner()->getScene()->getGroupItem();
1599 // creating/adding the group interface in the graph model
1600 GroupInterface *groupInter = new GroupInterface(parentBlock,refInter->getName()+"_group",refInter->getDirection(),refInter->getPurpose());
1601 parentItem->getRefBlock()->addInterface(groupInter);
1602 // creating/adding the group control interface in the graph model if the purpose is data
1603 if (refInter->getPurpose() == AbstractInterface::Data) {
1604 GroupInterface *groupCtlInter = new GroupInterface(parentBlock,refInter->getName()+"_group_enb",refInter->getDirection(),AbstractInterface::Control);
1605 groupCtlInter->setAssociatedIface(groupInter);
1606 parentItem->getRefBlock()->addInterface(groupCtlInter);
1608 // creating/adding the group interface in the current scene model, and connection item
1609 InterfaceItem *groupIfaceItem = new InterfaceItem(0,item->getOrientation(),groupInter,parentItem,params);
1610 parentItem->addInterfaceItem(groupIfaceItem,true);
1612 // creating the connection, in graph and with an item
1614 Since the group interface is for now unconnected, it is impossible to determine
1615 its clock domain. Thus, the connection must be created without testing the clock domain
1616 consistency. For that, we cheat by changing the context to Load because it implies no clock test.
1618 createConnection(Load, item, groupIfaceItem);
1620 // if groupItem is not topGroup, must also add a new interface to the parent BlockItem
1621 BoxItem* parent2Item = parentItem->getParentItem();
1622 if(parent2Item != NULL){
1623 InterfaceItem *blockIfaceItem = new InterfaceItem(0,item->getOrientation(),groupInter,parent2Item,params);
1624 parent2Item->addInterfaceItem(blockIfaceItem,true);
1628 parentItem->getScene()->updateConnectionItemsShape();
1629 unselectAllItems(context);
1630 params->unsaveModif = true;
1633 void Dispatcher::removeFunctionalInterface(Context context, InterfaceItem *item) {
1634 static QString fctName = "Dispatcher::removeBlockInterface()";
1635 #ifdef DEBUG_FCTNAME
1636 cout << "call to " << qPrintable(fctName) << endl;
1638 /* NB: only called in Design context */
1639 if (context != Design) {
1640 cout << "Abnormal case: call to " <<qPrintable(fctName) << " not in Design context" << endl;
1644 /* first, remove all connections from item
1645 NB: if there is a connection to a group interface, then this
1646 method should not be called if the group interface is also
1647 connected to another interface. Normally, this is not possible
1648 because such a check is done when creating the contextual menu
1649 that allows to remove an interface.
1651 foreach(ConnectionItem* conn, item->connections) {
1652 removeConnection(context, conn);
1655 ConnectedInterface* ref = item->refInter;
1656 item->getOwner()->removeInterfaceItem(item);
1657 FunctionalBlock* fun = AB_TO_FUN(ref->getOwner());
1658 fun->removeInterface(ref);
1661 void Dispatcher::removeGroupInterface(Context context, InterfaceItem *item) {
1662 static QString fctName = "Dispatcher::removeGroupInterface()";
1663 #ifdef DEBUG_FCTNAME
1664 cout << "call to " << qPrintable(fctName) << endl;
1666 /* NB: only called in Design context */
1667 if (context != Design) {
1668 cout << "Abnormal case: call to " <<qPrintable(fctName) << " not in Design context" << endl;
1672 /* NB: just remove all connections from/to this item, since when there are no more
1673 ones to a GroupItem, it is automatically deleted.
1675 foreach(ConnectionItem* conn, item->connections) {
1676 removeConnection(context, conn);
1680 QMap<int, QString> Dispatcher::getAllGroupNames() {
1682 QMap<int, QString> list;
1683 foreach(GroupWidget *group, groupList) {
1684 list.insert(group->getScene()->getId(), group->getScene()->getGroupItem()->getRefBlock()->getName());
1689 GroupScene* Dispatcher::getSceneById(int id) {
1690 foreach(GroupWidget *group, groupList){
1691 if(group->getScene()->getId() == id)
1692 return group->getScene();
1694 cout << "search scene by id :" << id << " :: not found..." << endl;
1698 GroupItem *Dispatcher::getGroupItemById(int id) {
1699 foreach(GroupWidget *group, groupList) {
1700 GroupScene* scene = group->getScene();
1701 if (scene->getGroupItem()->getId() == id) return scene->getGroupItem();
1703 cout << "search GroupItem by id :" << id << " :: not found..." << endl;
1707 BoxItem *Dispatcher::getBoxItemById(int id) {
1708 foreach(GroupWidget *group, groupList) {
1710 GroupScene* scene = group->getScene();
1711 foreach(BoxItem *item, scene->getBoxItems()){
1712 if(item->getId() == id){
1717 cout << "search BlockItem by id :" << id << " :: not found..." << endl;
1721 InterfaceItem* Dispatcher::getInterfaceItemById(int id) {
1723 foreach(GroupWidget *group, groupList) {
1725 GroupScene* scene = group->getScene();
1727 foreach(InterfaceItem *item, scene->getGroupItem()->getInterfaces()){
1728 if(item->getId() == id){
1732 foreach(BoxItem *block, scene->getBoxItems()){
1733 foreach(InterfaceItem *item, block->getInterfaces()){
1734 if(item->getId() == id){
1740 cout << "search interface by id :" << id << " :: not found..." << endl;
1744 void Dispatcher::findGraphModifications(Context context, FunctionalBlock *block) {
1745 static QString fctName = "Dispatcher::findGraphModifications()";
1746 #ifdef DEBUG_FCTNAME
1747 cout << "call to " << qPrintable(fctName) << endl;
1749 /* NB: only called in Design context */
1750 if (context != Design) {
1751 cout << "Abnormal case: call to " <<qPrintable(fctName) << " not in Design context" << endl;
1755 block->computeAdmittanceDelays();
1756 // get the block item that is associated to block
1757 BoxItem* toBlockItem = params->blockToItem.value(block);
1759 /* VERSION 1: just add delays if needed */
1760 QMap<AbstractInterface*,QList<int>* > delays = block->getAdmittanceDelays();
1761 QMapIterator<AbstractInterface*,QList<int>* > iterD(delays);
1762 while (iterD.hasNext()) {
1764 QList<int>* delay = iterD.value();
1765 if (delay->at(0) > 0) {
1766 // create delay and associate it to the connected input
1768 ConnectedInterface* toIface = AI_TO_CON(iterD.key());
1769 AbstractInputModifier* mod = new DelayInputModifier(toIface, delay->at(0));
1770 cout << "modify input of " << qPrintable(toIface->getName()) << endl;
1771 toIface->setInputModifier(mod);
1773 toBlockItem->update();