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

Private GIT Repository
0f3f8015920df89b13bc3b19c4c2157913203519
[blast.git] / AbstractBlock.cpp
1 #include <AbstractBlock.h>\r
2 #include <QInputDialog>\r
3 #include <QMessageBox>\r
4 #include "AbstractInterface.h"\r
5 #include "BlockParameter.h"\r
6 #include "Parameters.h"\r
7 #include "GroupBlock.h"\r
8 #include "ConnectedInterface.h"\r
9 \r
10 \r
11 AbstractBlock::AbstractBlock(Graph *_graph) {\r
12   name = "";\r
13   parent = NULL;\r
14   specialType = NotSpecial;\r
15   graph = _graph;\r
16 }\r
17 \r
18 /*\r
19 AbstractBlock::AbstractBlock(const QString& _name) {\r
20   name = Parameters::normalizeName(_name);\r
21   parent = NULL;\r
22 }\r
23 */\r
24 \r
25 AbstractBlock::~AbstractBlock() {\r
26 \r
27   removeAllInterfaces();\r
28 \r
29   foreach(BlockParameter* p, params) {\r
30     delete p;\r
31   }\r
32   params.clear();\r
33 }\r
34 \r
35 void AbstractBlock::setName(const QString& str) {\r
36   name = Parameters::normalizeName(str);\r
37 }\r
38 \r
39 void AbstractBlock::setSpecialType(int type) {\r
40   if ((type >= NotSpecial) && (type <= ClkConvert)) {\r
41     specialType = type;\r
42   }\r
43   else {\r
44     specialType = NotSpecial;\r
45   }\r
46 }\r
47 \r
48 void AbstractBlock::setParent(AbstractBlock* _parent) {\r
49   parent = _parent;\r
50 }\r
51 \r
52 bool AbstractBlock::isReferenceBlock() {\r
53   return false;\r
54 }\r
55 \r
56 bool AbstractBlock::isFunctionalBlock() {\r
57   return false;\r
58 }\r
59 \r
60 bool AbstractBlock::isSpecialBlock() {\r
61   return false;\r
62 }\r
63 \r
64 bool AbstractBlock::isGroupBlock() {\r
65   return false;\r
66 }\r
67 \r
68 bool AbstractBlock::isTopGroupBlock() {  \r
69   return false;\r
70 }\r
71 \r
72 bool AbstractBlock::isStimuliBlock() {\r
73   return false;\r
74 }\r
75 /* NB: a source is a block that has no data inputs\r
76  * and has at least one data output.\r
77  * By the way, blocks that have no data input/output\r
78  * (like clkrstgen) are not sources !\r
79  */\r
80 bool AbstractBlock::isSourceBlock() {\r
81   if (getDataInputs().size() > 0) return false;\r
82   if (getDataOutputs().size() == 0) return false;\r
83   return true;\r
84 }\r
85 \r
86 /* NB: a sink is a block without outputs of any type */\r
87 bool AbstractBlock::isSinkBlock() {\r
88   if (getOutputs().size() == 0) return true;\r
89   return false;\r
90 }\r
91 \r
92 int AbstractBlock::getSpecialTypeFromString(QString str) {\r
93   if (str == "source") {\r
94     return Source;\r
95   }\r
96   else if (str == "sink") {\r
97     return Sink;\r
98   }\r
99   else if (str == "clkconvert") {\r
100     return ClkConvert;\r
101   }\r
102   return NotSpecial;\r
103 }\r
104 \r
105 \r
106 void AbstractBlock::addParameter(BlockParameter *param) {\r
107   params.append(param);\r
108 }\r
109 \r
110 \r
111 BlockParameter* AbstractBlock::getParameterFromName(QString name) {\r
112   foreach(BlockParameter* p, params) {\r
113     if (p->getName() == name) return p;\r
114   }\r
115   return NULL;\r
116 }\r
117 \r
118 void AbstractBlock::addInterface(AbstractInterface *inter) {\r
119   if(inter->getDirection() == AbstractInterface::Input){\r
120     inputs.append(inter);\r
121   } else if(inter->getDirection() == AbstractInterface::Output){\r
122     outputs.append(inter);\r
123   } else if(inter->getDirection() == AbstractInterface::InOut){\r
124     bidirs.append(inter);\r
125   }\r
126 }\r
127 \r
128 void AbstractBlock::removeInterface(AbstractInterface *inter) {\r
129   /* CAUTION: no check is done about the connection state of this interface\r
130      Thus, if it is still connected to/from, there will be a crash\r
131    */\r
132   if(inter->getDirection() == AbstractInterface::Input){\r
133     inputs.removeAll(inter);\r
134   } else if(inter->getDirection() == AbstractInterface::Output){\r
135     outputs.removeAll(inter);\r
136   } else if(inter->getDirection() == AbstractInterface::InOut){\r
137     bidirs.removeAll(inter);\r
138   }\r
139   delete inter;\r
140 }\r
141 \r
142 void AbstractBlock::removeAllInterfaces() {\r
143 \r
144   foreach(AbstractInterface* iface, inputs) {\r
145     delete iface;\r
146   }\r
147   foreach(AbstractInterface* iface, outputs) {\r
148     delete iface;\r
149   }\r
150   foreach(AbstractInterface* iface, bidirs) {\r
151     delete iface;\r
152   }\r
153   inputs.clear();\r
154   outputs.clear();\r
155   bidirs.clear();\r
156 \r
157 }\r
158 \r
159 void AbstractBlock::defineBlockParam(BlockParameter *param)\r
160 {\r
161   cout << "definition of param : " << param->getName().toStdString() << endl;\r
162   bool ok = false;\r
163   QString value = QInputDialog::getText(NULL, "Block parameter", "value for the "+ param->getName() +" parameter of " + param->getOwner()->getName() + "?", QLineEdit::Normal, param->getValue().toString(), &ok);\r
164 \r
165   while (!ok && value.isEmpty())\r
166   {\r
167     QMessageBox::critical(NULL, "Error", "You have to insert a value for the parameter or accept the default value !");\r
168     value = QInputDialog::getText(NULL, "Block parameter", "value for the "+ param->getName() +" parameter of " + param->getOwner()->getName() + " ?", QLineEdit::Normal, param->getValue().toString(), &ok);\r
169   }\r
170   param->setValue(value);  \r
171 }\r
172 \r
173 QList<AbstractInterface *> AbstractBlock::getInterfaces(int direction, int purpose) {\r
174   QList<AbstractInterface *> list;\r
175   bool selIn = false;\r
176   bool selOut = false;\r
177   bool selInOut = false;\r
178   \r
179   if (direction == AbstractInterface::AnyDirection) {\r
180     selIn = true;\r
181     selOut = true;\r
182     selInOut = true;\r
183   }\r
184   else if (direction == AbstractInterface::Input) {\r
185     selIn = true;    \r
186   }\r
187   else if (direction == AbstractInterface::Output) {\r
188     selOut = true;    \r
189   }\r
190   else if (direction == AbstractInterface::InOut) {\r
191     selInOut = true;    \r
192   }\r
193   if (selIn) {\r
194     foreach(AbstractInterface* iface, inputs) {\r
195       if ((iface->getPurpose() == purpose) || (purpose == AbstractInterface::AnyPurpose)) list.append(iface);      \r
196     }\r
197   }\r
198   if (selOut) {\r
199     foreach(AbstractInterface* iface, outputs) {\r
200       if ((iface->getPurpose() == purpose) || (purpose == AbstractInterface::AnyPurpose)) list.append(iface);      \r
201     }\r
202   }\r
203   if (selInOut) {\r
204     foreach(AbstractInterface* iface, bidirs) {\r
205       if ((iface->getPurpose() == purpose) || (purpose == AbstractInterface::AnyPurpose)) list.append(iface);      \r
206     }\r
207   }\r
208   return list;\r
209 }\r
210 \r
211 QList<AbstractInterface *> AbstractBlock::getDataInputs() {\r
212   return getInterfaces(AbstractInterface::Input, AbstractInterface::Data);  \r
213 }\r
214 \r
215 QList<AbstractInterface *> AbstractBlock::getDataOutputs() {\r
216   return getInterfaces(AbstractInterface::Output, AbstractInterface::Data);  \r
217 }\r
218 \r
219 QList<AbstractInterface *> AbstractBlock::getControlInputs() {\r
220   return getInterfaces(AbstractInterface::Input, AbstractInterface::Control);  \r
221 }\r
222 \r
223 QList<AbstractInterface *> AbstractBlock::getControlOutputs() {\r
224   return getInterfaces(AbstractInterface::Output, AbstractInterface::Control);    \r
225 }\r
226 \r
227 AbstractInterface* AbstractBlock::getIfaceFromName(QString name) {\r
228 \r
229   foreach(AbstractInterface* iface, inputs) {\r
230     if (iface->getName() == name) return iface;\r
231   }\r
232   foreach(AbstractInterface* iface, outputs) {\r
233     if (iface->getName() == name) return iface;\r
234   }\r
235   foreach(AbstractInterface* iface, bidirs) {\r
236     if (iface->getName() == name) return iface;\r
237   }\r
238   return NULL;\r
239 }\r
240 \r
241 bool AbstractBlock::isWBConfigurable() {\r
242 \r
243   foreach(BlockParameter* p, params) {\r
244     if (p->isWishboneParameter()) return true;\r
245   }\r
246   return false;\r
247 }\r
248 \r
249 QList<BlockParameter *> AbstractBlock::getUserParameters() {\r
250   QList<BlockParameter *> lst;\r
251   foreach(BlockParameter* p, params) {\r
252     if (p->isUserParameter()) lst.append(p);\r
253   }\r
254   return lst;\r
255 }\r
256 \r
257 QList<BlockParameter *> AbstractBlock::getGenericParameters() {\r
258   QList<BlockParameter *> lst;\r
259   foreach(BlockParameter* p, params) {\r
260     if (p->isGenericParameter()) lst.append(p);\r
261   }\r
262   return lst;\r
263 }\r
264 \r
265 QList<BlockParameter *> AbstractBlock::getPortParameters() {\r
266   QList<BlockParameter *> lst;\r
267   foreach(BlockParameter* p, params) {\r
268     if (p->isPortParameter()) lst.append(p);\r
269   }\r
270   return lst;\r
271 }\r
272 \r
273 QList<BlockParameter *> AbstractBlock::getWishboneParameters() {\r
274   QList<BlockParameter *> lst;\r
275   foreach(BlockParameter* p, params) {\r
276     if (p->isWishboneParameter()) lst.append(p);\r
277   }\r
278   return lst;\r
279 }\r
280 \r
281 void AbstractBlock::connectClock(QString clkName, int idGen) throw(Exception) {\r
282 \r
283   GroupBlock* parentBlock = AB_TO_GRP(parent);  \r
284   ConnectedInterface* fromClk = NULL;\r
285   ConnectedInterface* toClk = AI_TO_CON(getIfaceFromName(clkName));\r
286 \r
287   if (parentBlock->isTop()) {\r
288     QString genName = "clkrstgen_" + QString::number(idGen);\r
289     AbstractBlock* clkrstgen = parentBlock->getFunctionalBlockByName(genName);\r
290     if (clkrstgen == NULL) {\r
291       throw(Exception(IFACE_TOP_NOCLKRSTGEN,this));\r
292     }\r
293     else {\r
294       fromClk = AI_TO_CON(clkrstgen->getIfaceFromName("clk"));      \r
295     }\r
296     cout << "connecting clock for " << qPrintable(name) << " to " << qPrintable(genName) << endl;\r
297   }\r
298   else {\r
299     // searching for ext_clk_idGen\r
300     QString name = "ext_clk_"+QString::number(idGen);\r
301     fromClk = AI_TO_CON(parentBlock->getIfaceFromName(name));\r
302     cout << "connecting clk for child " << qPrintable(name) << " of " << qPrintable(parentBlock->getName()) << endl;\r
303   }\r
304 \r
305   if (fromClk == NULL) {\r
306     throw(Exception(IFACE_GROUP_NOCLKRST,parentBlock));\r
307   }\r
308   else {\r
309     fromClk->connectTo(toClk);\r
310     cout << "connection done between " << qPrintable(toClk->getConnectedFrom()->getOwner()->getName()) << "/" << qPrintable(toClk->getConnectedFrom()->getName());\r
311     cout << " and " << qPrintable(toClk->getOwner()->getName()) << "/" << qPrintable(toClk->getName()) << endl;\r
312   }\r
313 }\r
314 \r
315 void AbstractBlock::connectReset(QString rstName, int idGen) throw(Exception) {\r
316 \r
317   GroupBlock* parentBlock = AB_TO_GRP(parent);\r
318   ConnectedInterface* fromRst = NULL;\r
319   ConnectedInterface* toRst = AI_TO_CON(getIfaceFromName(rstName));\r
320 \r
321   if (parentBlock->isTop()) {\r
322     QString genName = "clkrstgen_" + QString::number(idGen);\r
323     AbstractBlock* clkrstgen = parentBlock->getFunctionalBlockByName(genName);\r
324     if (clkrstgen == NULL) {\r
325       throw(Exception(IFACE_TOP_NOCLKRSTGEN,this));\r
326     }\r
327     else {\r
328       fromRst = AI_TO_CON(clkrstgen->getIfaceFromName("reset"));\r
329     }\r
330     cout << "connecting reset for " << qPrintable(name) << " to " << qPrintable(genName) << endl;\r
331   }\r
332   else {\r
333     QString name = "ext_reset_"+QString::number(idGen);\r
334     fromRst = AI_TO_CON(parentBlock->getIfaceFromName(name));\r
335     cout << "connecting reset for child " << qPrintable(name) << " of " << qPrintable(parentBlock->getName()) << endl;\r
336   }\r
337 \r
338   if (fromRst == NULL) {\r
339     throw(Exception(IFACE_GROUP_NOCLKRST,parentBlock));\r
340   }\r
341   else {\r
342     fromRst->connectTo(toRst);\r
343     cout << "connection done between " << qPrintable(toRst->getConnectedFrom()->getOwner()->getName()) << "/" << qPrintable(toRst->getConnectedFrom()->getName());\r
344     cout << " and " << qPrintable(toRst->getOwner()->getName()) << "/" << qPrintable(toRst->getName()) << endl;\r
345   }\r
346 }\r
347 \r
348 void AbstractBlock::generateEntity(QTextStream& out, bool hasController) throw(Exception) {\r
349 \r
350   out << "entity " << name << " is" << endl;\r
351   try {\r
352     generateEntityOrComponentBody(out, 0, hasController);\r
353   }\r
354   catch(Exception e) {\r
355     throw(e);\r
356   }\r
357   out << "end entity " << name << ";" << endl << endl;\r
358 }\r
359 \r
360 void AbstractBlock::generateComponent(QTextStream& out, bool hasController) throw(Exception) {\r
361 \r
362   out << "  component " << name << " is" << endl;\r
363   try {\r
364     generateEntityOrComponentBody(out, 2, hasController);\r
365   }\r
366   catch(Exception e) {\r
367     throw(e);\r
368   }\r
369   out << "  end component; " << endl << endl;\r
370 }\r
371 \r
372 \r