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

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