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

Private GIT Repository
add graph modif, progress on vhdl generation
[blast.git] / GroupBlock.cpp
1 #include "GroupBlock.h"
2 #include "BlockParameterGeneric.h"
3 #include "AbstractInterface.h"
4 #include "ConnectedInterface.h"
5 #include "string.h"
6 #include <sstream>
7
8 int GroupBlock::counter = 1;
9
10 GroupBlock::GroupBlock(GroupBlock *_parent) throw(Exception) :  AbstractBlock() {
11
12   // force topGroup to false if this group has a parent
13   if (_parent != NULL) {
14     topGroup = false;
15     name = QString("sub_group")+"_"+QString::number(counter++);
16   }
17   else {
18     topGroup = true;
19     name = QString("top_group");
20   }
21   parent = _parent;
22   if (parent != NULL) {
23     // adding this to the child blocks of parent
24     AB_TO_GRP(parent)->addBlock(this);
25   }
26 }
27
28 GroupBlock::~GroupBlock() {
29   foreach(AbstractBlock* block, blocks) {
30     delete block;
31   }
32 }
33
34 bool GroupBlock::isGroupBlock() {
35   return true;
36 }
37
38 bool GroupBlock::isTopGroupBlock() {
39   return topGroup;
40 }
41
42 void GroupBlock::setParent(AbstractBlock *_parent) {
43   parent = _parent;
44   if (parent != NULL) {
45     topGroup = false;
46   }
47 }
48
49 void GroupBlock::removeAllBlocks() {
50   foreach(AbstractBlock* block, blocks) {
51     if (block->isGroupBlock()) {
52       GroupBlock* group = AB_TO_GRP(block);
53       group->removeAllBlocks();
54     }
55     removeBlock(block);
56   }
57 }
58
59 void GroupBlock::removeBlock(AbstractBlock* block) {
60   /* CAUTION: no check is done if the block has connected interface
61      or not. Thus, they must be deleted elsewhere.
62   */
63   blocks.removeAll(block);
64   delete block;
65 }
66
67 AbstractBlock *GroupBlock::getFunctionalBlockByName(QString name) {
68   foreach(AbstractBlock* block, blocks) {
69     if (block->isFunctionalBlock()) {
70       if (block->getName() == name) return block;
71     }
72   }
73   return NULL;
74 }
75
76 void GroupBlock::parametersValidation(QList<AbstractBlock *> *checkedBlocks, QList<AbstractBlock *> *blocksToConfigure) {
77
78   /*
79   checkedBlocks->append(this);
80
81   foreach(BlockParameter* param, params){
82     if(param->isUserParameter() && !param->isValueSet()){
83       if(!blocksToConfigure->contains(param->getOwner())){
84         blocksToConfigure->append(param->getOwner());
85       }
86     }
87   }
88   foreach(AbstractInterface *inter, outputs){
89     foreach(AbstractInterface *connectedInter, inter->getConnectedTo()){
90       if(!checkedBlocks->contains(connectedInter->getOwner())){
91         connectedInter->getOwner()->parametersValidation(checkedBlocks, blocksToConfigure);
92       }
93     }
94   }
95   */
96 }
97
98 void GroupBlock::addGenericParameter(QString name, QString type, QString value) {
99   BlockParameter* param = new BlockParameterGeneric(this, name, type, value);
100   params.append(param);
101 }
102
103 void GroupBlock::removeGenericParameter(QString name) {
104   BlockParameter* p = getParameterFromName(name);
105   if (p != NULL) params.removeAll(p);
106 }
107
108 void GroupBlock::createInputPattern() {
109   foreach(AbstractInterface* iface, getControlInputs()) {
110     ConnectedInterface* connIface = AI_TO_CON(iface);
111     QList<char>* pattern = new QList<char>(*(connIface->getConnectedFrom()->getOutputPattern()));
112     connIface->setOutputPattern(pattern);
113   }
114 }
115
116 void GroupBlock::computeAdmittanceDelays() throw(Exception) {
117   throw(Exception(INVALID_GROUPBLOCK_USE));
118 }
119
120 void GroupBlock::checkInputPatternCompatibility()  throw(Exception){
121   throw(Exception(INVALID_GROUPBLOCK_USE));
122 }
123
124
125 void GroupBlock::computeOutputPattern(int nbExec) throw(Exception) {
126
127   static QString fctName = "GroupBlock::computeOutputPattern()";
128 #ifdef DEBUG_FCTNAME
129   cout << "call to " << qPrintable(fctName) << endl;
130 #endif
131
132   cout << "computing output pattern of group " << qPrintable(name) << endl;
133   
134   bool canCompute = false;
135   // get the input pattern on each inputs
136   createInputPattern();
137   
138   cout << "Input pattern OK" << endl;
139   // find blocks that are connected to that inputs and generators
140   QList<AbstractBlock*> fifo;
141   foreach(AbstractBlock* block, blocks) {
142
143     bool addIt = false;
144     // if a block is a generator and has control outputs, add it
145     if (block->isGeneratorBlock()) {
146       if (block->getControlOutputs().size() > 0) addIt = true;
147     }
148     else {
149       // if the block has all its connected inputs that are connected to an intput of the group, add it too
150       addIt = true;
151       foreach(AbstractInterface* iface, block->getControlInputs()) {
152         //cout << qPrintable(iface->getName()) << " of " << qPrintable(iface->getOwner()->getName()) << " connected to " << endl;
153         ConnectedInterface* connFrom = ((ConnectedInterface*)iface)->getConnectedFrom();
154         //cout << qPrintable(connFrom->getName()) << " of " << qPrintable(connFrom->getOwner()->getName()) << endl;
155         
156         if (connFrom == NULL) {
157           addIt = false;
158           break;
159         }
160         else if (connFrom->getOwner() != this) {
161           addIt = false;
162           break;
163         }
164       }
165     }
166     if (addIt) {
167       cout << "adding " << qPrintable(block->getName()) << " to initialize the FIFO" << endl;
168       block->setTraversalLevel(0); // level 0 = first blocks to be evaluated
169       fifo.append(block);
170     }
171   }
172   
173   while (!fifo.isEmpty()) {
174     AbstractBlock* block = fifo.takeFirst();
175     
176     if (block->getPatternComputed()) continue; // block has already been processed
177
178     cout << "computing compat and output for " << qPrintable(block->getName()) << endl;
179     
180
181     try {
182       block->checkInputPatternCompatibility();
183     }
184     catch(Exception e) {      
185       cout << qPrintable(block->getName()) << " is not compatible with its input pattern" << endl;
186       throw(e);
187     }   
188     
189     try {
190       block->computeOutputPattern();
191     }
192     catch(Exception e) {
193       cout << "cannot finalize output pattern computation of " << qPrintable(block->getName()) << endl;
194       throw(e);
195     }
196     canCompute = true;
197     block->setPatternComputed(true);
198     /* add other blocks connected from block to the fifo but only if
199        all their connected inputs are connected to blocks that have
200        a traversalLevel >=0
201      */
202     foreach(AbstractInterface* iface, block->getControlOutputs()) {
203       ConnectedInterface* conn = (ConnectedInterface*)iface;
204       foreach(ConnectedInterface* connTo, conn->getConnectedTo()) {
205
206         AbstractBlock* block1 = connTo->getOwner();
207         cout << "testing if " << qPrintable(block1->getName()) << " has all connected inputs connected to already processed blocks" << endl;
208         bool addIt = true;
209         int maxLevel = 0;
210
211         foreach(AbstractInterface* iface, block1->getControlInputs()) {
212           //cout << qPrintable(iface->getName()) << " of " << qPrintable(iface->getOwner()->getName()) << " connected to " << endl;
213           ConnectedInterface* connFrom = ((ConnectedInterface*)iface)->getConnectedFrom();
214           //cout << qPrintable(connFrom->getName()) << " of " << qPrintable(connFrom->getOwner()->getName()) << endl;
215
216           if ((connFrom != NULL) && (connFrom->getOwner()->getPatternComputed() == false)) {
217             addIt = false;
218             break;
219           }
220           else {
221             if (connFrom->getOwner()->getTraversalLevel() > maxLevel) maxLevel = connFrom->getOwner()->getTraversalLevel();
222           }
223         }
224
225         if (addIt) {
226           cout << "adding " << qPrintable(block1->getName()) << " to the FIFO" << endl;
227           block1->setTraversalLevel(maxLevel+1); // level 0 = first blocks to be evaluated
228           fifo.append(block1);
229         }
230       }
231     }
232   }
233
234   if (canCompute) {
235     foreach(AbstractInterface* iface, getControlOutputs()) {
236       ConnectedInterface* connIface = AI_TO_CON(iface);
237       QList<char>* pattern = new QList<char>(*(connIface->getConnectedFrom()->getOutputPattern()));
238       connIface->setOutputPattern(pattern);
239     }
240     setPatternComputed(true);
241   }
242
243 }