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

Private GIT Repository
debugged clk/rst auto conn
[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 "GroupBlock.h"\r
7 #include "ConnectedInterface.h"\r
8 \r
9 AbstractBlock::AbstractBlock() {\r
10   name = "";\r
11   parent = NULL;\r
12 }\r
13 \r
14 /*\r
15 AbstractBlock::AbstractBlock(const QString& _name) {\r
16   name = normalizeName(_name);\r
17   parent = NULL;\r
18 }\r
19 */\r
20 \r
21 AbstractBlock::~AbstractBlock() {\r
22 \r
23   removeAllInterfaces();\r
24 \r
25   foreach(BlockParameter* p, params) {\r
26     delete p;\r
27   }\r
28   params.clear();\r
29 }\r
30 \r
31 void AbstractBlock::setName(const QString& str) {\r
32   name = normalizeName(str);\r
33 }\r
34 \r
35 void AbstractBlock::setParent(AbstractBlock* _parent) {\r
36   parent = _parent;\r
37 }\r
38 \r
39 bool AbstractBlock::isReferenceBlock() {\r
40   return false;\r
41 }\r
42 \r
43 bool AbstractBlock::isFunctionalBlock() {\r
44   return false;\r
45 }\r
46 \r
47 bool AbstractBlock::isGroupBlock() {\r
48   return false;\r
49 }\r
50 \r
51 bool AbstractBlock::isTopGroupBlock() {  \r
52   return false;\r
53 }\r
54 \r
55 bool AbstractBlock::isSourceBlock() {\r
56   return false;\r
57 }\r
58 /* NB: a generator is a block that has no data inputs\r
59  * and has at least one data output.\r
60  */\r
61 bool AbstractBlock::isGeneratorBlock() {\r
62   if (getDataInputs().size() > 0) return false;\r
63   \r
64   return true;\r
65 }\r
66 \r
67 void AbstractBlock::addParameter(BlockParameter *param) {\r
68   params.append(param);\r
69 }\r
70 \r
71 \r
72 BlockParameter* AbstractBlock::getParameterFromName(QString name) {\r
73   foreach(BlockParameter* p, params) {\r
74     if (p->getName() == name) return p;\r
75   }\r
76   return NULL;\r
77 }\r
78 \r
79 void AbstractBlock::addInterface(AbstractInterface *inter) {\r
80   if(inter->getDirection() == AbstractInterface::Input){\r
81     inputs.append(inter);\r
82   } else if(inter->getDirection() == AbstractInterface::Output){\r
83     outputs.append(inter);\r
84   } else if(inter->getDirection() == AbstractInterface::InOut){\r
85     bidirs.append(inter);\r
86   }\r
87 }\r
88 \r
89 void AbstractBlock::removeInterface(AbstractInterface *inter) {\r
90   /* CAUTION: no check is done about the connection state of this interface\r
91      Thus, if it is still connected to/from, there will be a crash\r
92    */\r
93   if(inter->getDirection() == AbstractInterface::Input){\r
94     inputs.removeAll(inter);\r
95   } else if(inter->getDirection() == AbstractInterface::Output){\r
96     outputs.removeAll(inter);\r
97   } else if(inter->getDirection() == AbstractInterface::InOut){\r
98     bidirs.removeAll(inter);\r
99   }\r
100   delete inter;\r
101 }\r
102 \r
103 void AbstractBlock::removeAllInterfaces() {\r
104 \r
105   foreach(AbstractInterface* iface, inputs) {\r
106     delete iface;\r
107   }\r
108   foreach(AbstractInterface* iface, outputs) {\r
109     delete iface;\r
110   }\r
111   foreach(AbstractInterface* iface, bidirs) {\r
112     delete iface;\r
113   }\r
114   inputs.clear();\r
115   outputs.clear();\r
116   bidirs.clear();\r
117 \r
118 }\r
119 \r
120 void AbstractBlock::defineBlockParam(BlockParameter *param)\r
121 {\r
122   cout << "definition of param : " << param->getName().toStdString() << endl;\r
123   bool ok = false;\r
124   QString value = QInputDialog::getText(NULL, "Block parameter", "value for the "+ param->getName() +" parameter of " + param->getOwner()->getName() + "?", QLineEdit::Normal, param->getValue().toString(), &ok);\r
125 \r
126   while (!ok && value.isEmpty())\r
127   {\r
128     QMessageBox::critical(NULL, "Error", "You have to insert a value for the parameter or accept the default value !");\r
129     value = QInputDialog::getText(NULL, "Block parameter", "value for the "+ param->getName() +" parameter of " + param->getOwner()->getName() + " ?", QLineEdit::Normal, param->getValue().toString(), &ok);\r
130   }\r
131   param->setValue(value);  \r
132 }\r
133 \r
134 QList<AbstractInterface *> AbstractBlock::getInterfaces(int direction, int purpose) {\r
135   QList<AbstractInterface *> list;\r
136   bool selIn = false;\r
137   bool selOut = false;\r
138   bool selInOut = false;\r
139   \r
140   if (direction == AbstractInterface::AnyDirection) {\r
141     selIn = true;\r
142     selOut = true;\r
143     selInOut = true;\r
144   }\r
145   else if (direction == AbstractInterface::Input) {\r
146     selIn = true;    \r
147   }\r
148   else if (direction == AbstractInterface::Output) {\r
149     selOut = true;    \r
150   }\r
151   else if (direction == AbstractInterface::InOut) {\r
152     selInOut = true;    \r
153   }\r
154   if (selIn) {\r
155     foreach(AbstractInterface* iface, inputs) {\r
156       if ((iface->getPurpose() == purpose) || (purpose == AbstractInterface::AnyPurpose)) list.append(iface);      \r
157     }\r
158   }\r
159   if (selOut) {\r
160     foreach(AbstractInterface* iface, outputs) {\r
161       if ((iface->getPurpose() == purpose) || (purpose == AbstractInterface::AnyPurpose)) list.append(iface);      \r
162     }\r
163   }\r
164   if (selInOut) {\r
165     foreach(AbstractInterface* iface, bidirs) {\r
166       if ((iface->getPurpose() == purpose) || (purpose == AbstractInterface::AnyPurpose)) list.append(iface);      \r
167     }\r
168   }\r
169   return list;\r
170 }\r
171 \r
172 QList<AbstractInterface *> AbstractBlock::getDataInputs() {\r
173   return getInterfaces(AbstractInterface::Input, AbstractInterface::Data);  \r
174 }\r
175 \r
176 QList<AbstractInterface *> AbstractBlock::getDataOutputs() {\r
177   return getInterfaces(AbstractInterface::Output, AbstractInterface::Data);  \r
178 }\r
179 \r
180 QList<AbstractInterface *> AbstractBlock::getControlInputs() {\r
181   return getInterfaces(AbstractInterface::Input, AbstractInterface::Control);  \r
182 }\r
183 \r
184 QList<AbstractInterface *> AbstractBlock::getControlOutputs() {\r
185   return getInterfaces(AbstractInterface::Output, AbstractInterface::Control);    \r
186 }\r
187 \r
188 AbstractInterface* AbstractBlock::getIfaceFromName(QString name) {\r
189 \r
190   foreach(AbstractInterface* iface, inputs) {\r
191     if (iface->getName() == name) return iface;\r
192   }\r
193   foreach(AbstractInterface* iface, outputs) {\r
194     if (iface->getName() == name) return iface;\r
195   }\r
196   foreach(AbstractInterface* iface, bidirs) {\r
197     if (iface->getName() == name) return iface;\r
198   }\r
199   return NULL;\r
200 }\r
201 \r
202 bool AbstractBlock::isWBConfigurable() {\r
203 \r
204   foreach(BlockParameter* p, params) {\r
205     if (p->isWishboneParameter()) return true;\r
206   }\r
207   return false;\r
208 }\r
209 \r
210 QList<BlockParameter *> AbstractBlock::getUserParameters() {\r
211   QList<BlockParameter *> lst;\r
212   foreach(BlockParameter* p, params) {\r
213     if (p->isUserParameter()) lst.append(p);\r
214   }\r
215   return lst;\r
216 }\r
217 \r
218 QList<BlockParameter *> AbstractBlock::getGenericParameters() {\r
219   QList<BlockParameter *> lst;\r
220   foreach(BlockParameter* p, params) {\r
221     if (p->isGenericParameter()) lst.append(p);\r
222   }\r
223   return lst;\r
224 }\r
225 \r
226 QList<BlockParameter *> AbstractBlock::getPortParameters() {\r
227   QList<BlockParameter *> lst;\r
228   foreach(BlockParameter* p, params) {\r
229     if (p->isPortParameter()) lst.append(p);\r
230   }\r
231   return lst;\r
232 }\r
233 \r
234 QList<BlockParameter *> AbstractBlock::getWishboneParameters() {\r
235   QList<BlockParameter *> lst;\r
236   foreach(BlockParameter* p, params) {\r
237     if (p->isWishboneParameter()) lst.append(p);\r
238   }\r
239   return lst;\r
240 }\r
241 \r
242 QString AbstractBlock::normalizeName(const QString &name) {\r
243   QString s = name;\r
244   s.replace(QRegularExpression("[^a-zA-Z0-9_]"),"_");\r
245   s.replace(QRegularExpression("[_]+"),"_");\r
246   return s;\r
247 }\r
248 \r
249 void AbstractBlock::connectClkReset() throw(Exception) {\r
250 \r
251   GroupBlock* parentBlock = AB_TO_GRP(parent);\r
252 \r
253   cout << "connecting clk/rst for child " << qPrintable(name) << " of " << qPrintable(parentBlock->getName()) << endl;\r
254 \r
255   QList<AbstractInterface* > lstClk = getInterfaces(AbstractInterface::Input,AbstractInterface::Clock);\r
256   QList<AbstractInterface* > lstRst = getInterfaces(AbstractInterface::Input,AbstractInterface::Reset);\r
257 \r
258   if ((lstClk.isEmpty()) || (lstRst.isEmpty())) {\r
259     throw(Exception(IFACE_GROUP_NOCLKRST,this));\r
260   }\r
261 \r
262   ConnectedInterface* toClk = AI_TO_CON(lstClk.at(0));\r
263   ConnectedInterface* toRst = AI_TO_CON(lstRst.at(0));\r
264 \r
265   ConnectedInterface* fromClk = NULL;\r
266   ConnectedInterface* fromRst = NULL;\r
267 \r
268   if (parentBlock->isTop()) {\r
269     AbstractBlock* clkrstgen = parentBlock->getFunctionalBlockByName("clkrstgen");\r
270     if (clkrstgen == NULL) {\r
271       throw(Exception(IFACE_TOP_NOCLKRSTGEN,this));\r
272     }\r
273     else {\r
274       fromClk = AI_TO_CON(clkrstgen->getIfaceFromName("clk"));\r
275       fromRst = AI_TO_CON(clkrstgen->getIfaceFromName("reset"));\r
276     }\r
277   }\r
278   else {\r
279     fromClk = AI_TO_CON(parentBlock->getIfaceFromName("clk"));\r
280     fromRst = AI_TO_CON(parentBlock->getIfaceFromName("reset"));\r
281   }\r
282   if ((fromClk == NULL) || (fromRst == NULL)) {\r
283     throw(Exception(IFACE_GROUP_NOCLKRST,parentBlock));\r
284   }\r
285   else {\r
286     fromClk->connectTo(toClk);\r
287     fromRst->connectTo(toRst);\r
288   }\r
289 \r
290 \r
291 }\r
292 \r
293 \r
294 \r