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

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