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

Private GIT Repository
add graph modif, progress on vhdl generation
[blast.git] / BlockImplementation.cpp
1 #include "BlockImplementation.h"\r
2 \r
3 #include "FunctionalBlock.h"\r
4 #include "ReferenceBlock.h"\r
5 #include "ReferenceInterface.h"\r
6 #include "FunctionalInterface.h"\r
7 #include "BlockParameter.h"\r
8 #include <QHashIterator>\r
9 \r
10 \r
11 BlockImplementation::BlockImplementation(const QString& _xmlFile) {\r
12   xmlFile = _xmlFile;\r
13   productionCounter = "";\r
14   delta = "";\r
15 \r
16   evaluator = new ArithmeticEvaluator;\r
17   evaluator->setVariableMarkers("@$");\r
18 }\r
19 \r
20 BlockImplementation::BlockImplementation(const QString& _xmlFile, const QString &_referenceXml, const QString &_referenceMd5) {\r
21   xmlFile = _xmlFile;  \r
22   productionCounter = "";\r
23   delta = "";\r
24   referenceXml = _referenceXml;\r
25   referenceMd5 = _referenceMd5;\r
26 }\r
27 \r
28 void BlockImplementation::loadPatterns(QDomElement& root) throw(Exception) {\r
29     \r
30   QDomNodeList patternNode = root.elementsByTagName("patterns");\r
31   \r
32   if (patternNode.isEmpty()) {\r
33     cout << "impl has no patterns" << endl;\r
34     return;\r
35   }\r
36   \r
37   QDomElement patternElt = patternNode.at(0).toElement();\r
38   \r
39   QDomElement eltDelta  = patternElt.firstChildElement("delta");\r
40   delta = eltDelta.attribute("value","none");\r
41   \r
42   QDomElement eltCons  = eltDelta.nextSiblingElement("consumption");\r
43   \r
44   QDomNodeList listNodeInput = eltCons.elementsByTagName("input");\r
45   for(int i=0; i<listNodeInput.size(); i++) {\r
46     QDomNode node = listNodeInput.at(i);    \r
47     QDomElement elt = node.toElement();    \r
48     QString nameStr = elt.attribute("name","none");\r
49     if (nameStr == "none") throw(Exception(IMPLFILE_CORRUPTED));\r
50     QString patternStr = elt.attribute("pattern","none");    \r
51     consumptionPattern.insert(nameStr,patternStr);\r
52   }\r
53   \r
54   QDomElement eltProd  = eltCons.nextSiblingElement("production");\r
55   \r
56   productionCounter = eltProd.attribute("counter","none");\r
57   QDomNodeList listNodeOutput = eltProd.elementsByTagName("output");\r
58   for(int i=0; i<listNodeOutput.size(); i++) {\r
59     QDomNode node = listNodeOutput.at(i);    \r
60     QDomElement elt = node.toElement();        \r
61     QString nameStr = elt.attribute("name","none");\r
62     if (nameStr == "none") throw(Exception(IMPLFILE_CORRUPTED));\r
63     QString patternStr = elt.attribute("pattern","none");    \r
64     productionPattern.insert(nameStr,patternStr);    \r
65   }\r
66   cout << "patterns summary:" << endl;\r
67   QHashIterator<QString,QString> iterP(productionPattern);\r
68   while (iterP.hasNext()) {\r
69     iterP.next();\r
70     cout << qPrintable(iterP.key()) << " -> " << qPrintable(iterP.value()) << endl;\r
71   }\r
72   cout << "impls patterns read correctly" << endl;\r
73 }\r
74 \r
75 bool BlockImplementation::checkPatterns() {\r
76 \r
77 \r
78   if (reference == NULL) {\r
79     cout << "no ref. while checking patterns of implementation " << endl;\r
80     return false;\r
81   }\r
82   \r
83   AbstractInterface* iface;  \r
84   QHashIterator<QString,QString> iterI(consumptionPattern);\r
85   while (iterI.hasNext()) {\r
86     iterI.next();\r
87     iface = reference->getIfaceFromName(iterI.key());\r
88     if (iface == NULL) {\r
89       cout << "cannot found an input  ref. iface for impl. iface " << qPrintable(iterI.key()) << endl;\r
90       return false;\r
91     }\r
92   }\r
93   QHashIterator<QString,QString> iterO(productionPattern);\r
94   while (iterO.hasNext()) {\r
95     iterO.next();\r
96     iface = reference->getIfaceFromName(iterO.key());\r
97     if (iface == NULL) {\r
98       cout << "cannot found an output  ref. iface for impl. iface " << qPrintable(iterI.key()) << endl;\r
99       return false;\r
100     }\r
101   }  \r
102   return true;  \r
103 }\r
104 \r
105 void BlockImplementation::generateVHDL(FunctionalBlock* _block, const QString &path) throw(Exception) {\r
106 \r
107   block = _block;\r
108 \r
109   QFile implFile(xmlFile);\r
110 \r
111   // reading in into QDomDocument\r
112   QDomDocument document("implFile");\r
113 \r
114   if (!implFile.open(QIODevice::ReadOnly)) {\r
115     throw(Exception(IMPLFILE_NOACCESS));\r
116   }\r
117   if (!document.setContent(&implFile)) {\r
118     implFile.close();\r
119     throw(Exception(IMPLFILE_NOACCESS));\r
120   }\r
121   implFile.close();\r
122 \r
123   bool genController = false;\r
124   QString coreFile = "";\r
125   QString controllerFile = "";\r
126 \r
127   if (reference->isWBConfigurable()) {\r
128     genController = true;\r
129     controllerFile = path;\r
130     controllerFile.append(block->getName());\r
131     controllerFile.append("_ctrl.vhd");    \r
132   }\r
133   else {\r
134     controllerFile = "nofile.vhd";    \r
135   }\r
136   coreFile = path;\r
137   coreFile.append(block->getName());\r
138   coreFile.append(".vhd");\r
139 \r
140   QFile vhdlCore(coreFile);\r
141   QFile vhdlController(controllerFile);\r
142 \r
143   if (!vhdlCore.open(QIODevice::WriteOnly)) {\r
144     throw(Exception(VHDLFILE_NOACCESS));\r
145   }\r
146 \r
147   if (genController) {\r
148     if (!vhdlController.open(QIODevice::WriteOnly)) {\r
149       throw(Exception(VHDLFILE_NOACCESS));\r
150     }\r
151   }\r
152   QTextStream outCore(&vhdlCore);\r
153   QTextStream outController;\r
154   if (genController) {\r
155     outController.setDevice(&vhdlController);\r
156   }\r
157 \r
158   try {\r
159 \r
160 \r
161     //Get the root element\r
162     QDomElement impl = document.documentElement();\r
163     QDomElement eltComments = impl.firstChildElement("comments");\r
164     generateComments(eltComments, coreFile, outCore);\r
165     QDomElement eltLibs = eltComments.nextSiblingElement("libraries");\r
166     generateLibraries(eltLibs, outCore);\r
167     generateEntity(outCore, genController);\r
168     QDomElement eltArch = eltLibs.nextSiblingElement("architecture");\r
169     generateArchitecture(eltArch, outCore);\r
170     if (genController) {\r
171       generateController(outController);\r
172     }\r
173   }\r
174   catch(Exception err) {\r
175     throw(err);\r
176   }\r
177 \r
178   vhdlCore.close();\r
179   vhdlController.close();\r
180 }\r
181 \r
182 // This function generates the comments part of the VHDL document\r
183 void BlockImplementation::generateComments(QDomElement &elt, QString coreFile, QTextStream& out) throw(Exception) {\r
184 \r
185   for(int i = 0; i < 50; i++) {\r
186     out << "--";\r
187   }\r
188   out << "\n--\n";\r
189   QString fileName = coreFile;\r
190   out << "--  File        : " << fileName << "\n";\r
191   out << "--\n";\r
192   QDomElement eltAuthor = elt.firstChildElement("author");\r
193   QString firstName = eltAuthor.attribute("firstname","");\r
194   QString lastName = eltAuthor.attribute("lastname","");\r
195   QString mail = eltAuthor.attribute("mail","");\r
196   out << "--  Author(s)   : "<<firstName+" "<<lastName<<" ("<<mail<<")\n";\r
197   out << "--\n";\r
198   QDomElement eltDate = eltAuthor.nextSiblingElement("date");\r
199   QString crea = eltDate.attribute("creation","");\r
200   out << "--  Creation Date   : "<<crea<<"\n";\r
201   out << "--\n";\r
202   QDomElement eltRelated = eltDate.nextSiblingElement("related_files");\r
203   QString relateds = eltRelated.attribute("list","");\r
204   out << "--  Related files   :\n"<<relateds<<"\n";\r
205   out << "--\n";\r
206   QDomElement eltDesc = eltRelated.nextSiblingElement("description");\r
207   QDomElement desc = eltDesc.firstChildElement();\r
208   QString descTxt = desc.text();\r
209   out << "--  Decription      :\n"<<descTxt<<"\n";\r
210   out << "--\n";\r
211   QDomElement eltNote = eltDesc.nextSiblingElement("description");\r
212   QDomElement note = eltNote.firstChildElement();\r
213   QString noteTxt = note.text();\r
214   out << "--  Note          :\n"<<noteTxt<<"\n";\r
215   out << "--\n";\r
216   for(int i = 0; i < 50; i++) {\r
217     out << "--";\r
218   }\r
219   out << "\n\n";\r
220 }\r
221 \r
222 // This function generates the library part of the VHDL document\r
223 void BlockImplementation::generateLibraries(QDomElement &elt, QTextStream& out) throw(Exception) {\r
224 \r
225   QDomNodeList listLib = elt.elementsByTagName("library");\r
226   for(int i = 0; i < listLib.length(); i++) {\r
227     QDomNode nodeLib = listLib.item(i);\r
228     QDomElement eltLib = nodeLib.toElement();\r
229     QString nameLib = eltLib.attribute("name","none");\r
230     out << "library " << nameLib << ";\n";\r
231     QDomNodeList listPack = eltLib.elementsByTagName("package");\r
232     for(int j = 0; j < listPack.length(); j++) {\r
233       QDomNode nodePack = listPack.item(j);\r
234       QDomElement eltPack = nodePack.toElement();\r
235       QString namePack = eltPack.attribute("name","none");\r
236       QString usePack = eltPack.attribute("use","none");\r
237       out << "use " << nameLib << "." << namePack << "." << usePack << endl;\r
238     }\r
239     out << endl;\r
240   }\r
241 }\r
242 \r
243 // This function generates the entity part of the VHDL document\r
244 void BlockImplementation::generateEntity(QTextStream& out, bool hasController) throw(Exception) {\r
245 \r
246   int i=0;\r
247   nameEnt = block->getName();\r
248   //QList<BlockParameter*> listParams = reference->getParameters();\r
249   QList<AbstractInterface*> listInputs = block->getInputs();\r
250   QList<AbstractInterface*> listOutputs = block->getOutputs();\r
251   QList<AbstractInterface*> listBidirs = block->getBidirs();\r
252   QString typePort, namePort;\r
253 \r
254   out << "entity " << nameEnt << " is\n";\r
255 \r
256 \r
257   /* TODO : rewrite the generation to take into acocunt the new object hierarchy */\r
258 \r
259   // Generation of the generics\r
260   QList<BlockParameter*> listGenerics = block->getGenericParameters();\r
261   if ((!listGenerics.isEmpty()) || (hasController)) {\r
262     out << "  generic (" << endl;\r
263     if (hasController) {\r
264       out << "    wb_data_width : integer = 16;" << endl;\r
265       out << "    wb_addr_width : integer = 12";\r
266       if (!listGenerics.isEmpty()) out << ";";\r
267       out << endl;\r
268     }\r
269     for(i=0;i<listGenerics.size()-1;i++) {\r
270       out << "    " << listGenerics.at(i)->toVHDL(BlockParameter::Entity, 0) << endl;\r
271     }\r
272     out << "    " << listGenerics.at(i)->toVHDL(BlockParameter::Entity,BlockParameter::NoComma) << endl;\r
273 \r
274     out << "    );" << endl;\r
275   }\r
276 \r
277   out << "  port (" << endl;\r
278 \r
279   // Generation of the clk & rst signals\r
280   out << "    -- clk/rst" << endl;\r
281   foreach(AbstractInterface* iface, listInputs) {\r
282     if(iface->getPurpose() == AbstractInterface::Clock || iface->getPurpose() == AbstractInterface::Reset) {\r
283       out << "    " << iface->getName() << " : in std_logic;" << endl;\r
284     }\r
285   }\r
286 \r
287   if (hasController) {\r
288     // Generation of the wishbone signals\r
289     out << "    -- registers r/w via wishbone" << endl;\r
290     QList<BlockParameter*> listWB = reference->getWishboneParameters();\r
291     for(i=0;i<listWB.size()-1;i++) {\r
292       out << "    " << listWB.at(i)->toVHDL(BlockParameter::Entity, 0) << endl;\r
293     }\r
294     out << "    " << listWB.at(i)->toVHDL(BlockParameter::Entity,BlockParameter::NoComma) << endl;\r
295   }\r
296 \r
297 \r
298   int count = 0;\r
299   foreach(AbstractInterface* iface, block->getInterfaces()) {\r
300     if((iface->getPurpose() == AbstractInterface::Data)||(iface->getPurpose() == AbstractInterface::Control)) count++;\r
301   }\r
302   // Generation of the data/control signals\r
303 \r
304   int flag = 0;\r
305   bool first = true;\r
306 \r
307   foreach(AbstractInterface* iface, listInputs) {\r
308     if(iface->getPurpose() == AbstractInterface::Data) {\r
309       if (first) {\r
310         out << "    -- input data ports" << endl;\r
311         first = false;\r
312       }\r
313       count--;\r
314       if (count == 0) flag = AbstractInterface::NoComma;\r
315       out << "    " << iface->toVHDL(AbstractInterface::Entity, flag) << endl;\r
316     }\r
317   }\r
318   first = true;\r
319   foreach(AbstractInterface* iface, listInputs) {\r
320     if(iface->getPurpose() == AbstractInterface::Control) {\r
321       if (first) {\r
322         out << "    -- input control ports" << endl;\r
323         first = false;\r
324       }\r
325       count--;\r
326       if (count == 0) flag = AbstractInterface::NoComma;\r
327       out << "    " << iface->toVHDL(AbstractInterface::Entity, flag) << endl;\r
328     }\r
329   }\r
330   first = true;\r
331   foreach(AbstractInterface* iface, listOutputs) {\r
332     if(iface->getPurpose() == AbstractInterface::Data) {\r
333       if (first) {\r
334         out << "    -- output data ports" << endl;\r
335         first = false;\r
336       }\r
337       count--;\r
338       if (count == 0) flag = AbstractInterface::NoComma;\r
339       out << "    " << iface->toVHDL(AbstractInterface::Entity, flag) << endl;\r
340     }\r
341   }\r
342   first = true;\r
343   foreach(AbstractInterface* iface, listOutputs) {\r
344     if(iface->getPurpose() == AbstractInterface::Control) {\r
345       if (first) {\r
346         out << "    -- output control ports" << endl;\r
347         first = false;\r
348       }\r
349       count--;\r
350       if (count == 0) flag = AbstractInterface::NoComma;\r
351       out << "    " << iface->toVHDL(AbstractInterface::Entity, flag) << endl;\r
352     }\r
353   }\r
354   first = true;\r
355   foreach(AbstractInterface* iface, listBidirs) {\r
356     if(iface->getPurpose() == AbstractInterface::Data) {\r
357       if (first) {\r
358         out << "    -- bidirs data ports" << endl;\r
359         first = false;\r
360       }\r
361       count--;\r
362       if (count == 0) flag = AbstractInterface::NoComma;\r
363       out << "    " << iface->toVHDL(AbstractInterface::Entity, flag) << endl;\r
364     }\r
365   }\r
366   out << "    );" << endl << endl;\r
367   out << "end " << nameEnt << ";" << endl << endl;\r
368 }\r
369 \r
370 // This function generates the architecture part of the VHDL document\r
371 void BlockImplementation::generateArchitecture(QDomElement &elt, QTextStream& out) throw(Exception) {\r
372 \r
373   QString expr;\r
374   QString code = elt.text();\r
375   cout << qPrintable(code) << endl;\r
376   out << "architecture rtl of " << nameEnt << " is" << endl;\r
377 \r
378   QStringList listLine = code.split("\n");\r
379   for(int i =0; i < listLine.size(); i++) {\r
380     QString line = listLine.at(i).simplified();\r
381 \r
382     /*\r
383     if(listLine.at(i).contains(QRegularExpression("@foreach{"))) {\r
384       while(listLine.at(i).compare("@endforeach") != -1) {\r
385         expr = expr + listLine.at(i) + '\n';\r
386         i++;\r
387       }\r
388       expr = expr + listLine.at(i);\r
389       out << evalComplex(expr, 1) << '\n';\r
390     }\r
391     if(listLine.at(i).contains(QRegularExpression("@caseeach{"))) {\r
392       while(listLine.at(i).compare("@endcaseeach") != -1) {\r
393         expr = expr + listLine.at(i) + '\n';\r
394         i++;\r
395       }\r
396       expr = expr + listLine.at(i);\r
397       out << evalComplex(expr, 2) << '\n';\r
398     }\r
399 */\r
400     if(line.contains("@{")) {\r
401       out << line << endl;\r
402     }\r
403   }\r
404 }\r
405 \r
406 void BlockImplementation::generateController(QTextStream &out) throw(Exception) {\r
407 }\r
408 \r
409 QString BlockImplementation::eval(QString line, QTextStream& out) {\r
410   QString res, s, begLine, endLine, expr;\r
411   evaluator->setExpression(line);\r
412   QRegExp *rxString = new QRegExp("(.*)@{(.*)}(.*)");\r
413   QRegExp *rxValue = new QRegExp("(.*)@val{(.*)}(.*)");\r
414   QRegExp *rxExpr = new QRegExp(".*@eval{(.*)}.*");\r
415 \r
416   int nbAt = line.count('@');\r
417   while(nbAt != 0) {\r
418     for(int i = 0; i < line.size(); i++) {\r
419       if(rxString->indexIn(line)) {\r
420         begLine = rxString->cap(1);\r
421         s = rxString->cap(2);\r
422         endLine = rxString->cap(3);\r
423         res = begLine + evalString(s) + endLine + '\n';\r
424         nbAt --;\r
425       }\r
426     }\r
427     for(int i = 0; i < line.size(); i++) {\r
428       if(rxValue->indexIn(line)) {\r
429         begLine = rxValue->cap(1);\r
430         s = rxValue->cap(2);\r
431         endLine = rxValue->cap(3);\r
432         res = begLine + evalValue(s) + endLine + '\n';\r
433         nbAt --;\r
434       }\r
435     }\r
436     for(int i = 0; i < line.size(); i++) {\r
437       if(rxExpr->indexIn(line)) {\r
438         expr = rxExpr->cap(1);\r
439         if(expr.count('@') == 0) {\r
440           evaluator->setExpression(expr);\r
441           s = QString::number(evaluator->evaluate());\r
442         }\r
443         res = begLine + s + endLine + '\n';\r
444         nbAt --;\r
445       }\r
446     }\r
447   }\r
448   return res;\r
449 }\r
450 \r
451 QString BlockImplementation::evalComplex(QString line, int id) {\r
452   QString res, s, begLine, endLine, expr;\r
453   QRegExp *rxString = new QRegExp("(.*)@{(.*)}(.*)");\r
454   QRegExp *rxValue = new QRegExp("(.*)@val{(.*)}(.*)");\r
455   QRegExp *rxExpr = new QRegExp(".*@eval{(.*)}.*");\r
456   QRegExp *rxFor = new QRegExp("@foreach{.*}(@{.*})(.*)@endforeach");\r
457   QRegExp *rxCase = new QRegExp("@caseeach{.*,(.*),(.*)}(@{.*})(.*)@endcaseeach");\r
458   QRegExp *rxCaseDown = new QRegExp("@#-:(.*)");\r
459   QRegExp *rxCaseUp = new QRegExp("@#:(.*)");\r
460   evaluator->setExpression(line);\r
461 \r
462   int nbAt = line.count('@') - 2;\r
463   while(nbAt != 0) {\r
464     for(int i = 0; i < line.size(); i++) {\r
465       if(rxString->indexIn(line)) {\r
466         begLine = rxString->cap(1);\r
467         s = rxString->cap(2);\r
468         endLine = rxString->cap(3);\r
469         if(evalStringComplex(s)->size() == 0)\r
470           line = begLine + evalString(s) + endLine;\r
471         nbAt --;\r
472       }\r
473     }\r
474     for(int i = 0; i < line.size(); i++) {\r
475       if(rxValue->indexIn(line)) {\r
476         begLine = rxValue->cap(1);\r
477         s = rxValue->cap(2);\r
478         endLine = rxValue->cap(3);\r
479         line = begLine + evalValue(s) + endLine;\r
480         nbAt --;\r
481       }\r
482     }\r
483     for(int i = 0; i < line.size(); i++) {\r
484       if(rxExpr->indexIn(line)) {\r
485         expr = rxExpr->cap(1);\r
486         if(expr.count('@') == 0) {\r
487           evaluator->setExpression(expr);\r
488           s = QString::number(evaluator->evaluate());\r
489         }\r
490         res = begLine + s + endLine + '\n';\r
491         nbAt --;\r
492       }\r
493     }\r
494   }\r
495 \r
496   if(id == 1) {\r
497     if(rxFor->indexIn(line)) {\r
498       QString intName, instruc;\r
499       intName = rxFor->cap(1);\r
500       instruc = rxFor->cap(2);\r
501       QList<AbstractInterface*> *intList = evalStringComplex(intName);\r
502       if(intList->size() != 0) {\r
503         for(int i = 0; i < intList->size(); i++) {\r
504           res = intList->at(i)->getName() + instruc + '\n';\r
505         }\r
506       }\r
507     }\r
508   }\r
509 \r
510   else if(id == 2) {\r
511     if(rxCase->indexIn(line)) {\r
512       QString intName, sigName, cases, instruc;\r
513       int number;\r
514       sigName = rxCase->cap(1);\r
515       cases = rxCase->cap(2);\r
516       intName = rxCase->cap(3);\r
517       instruc = rxCase->cap(4);\r
518       QList<AbstractInterface*> *intList = evalStringComplex(intName);\r
519       int listSize = intList->count();\r
520       res = "case " + sigName + " is\n";\r
521       if(rxCaseUp->indexIn(cases)) {\r
522         number = rxCaseUp->cap(1).toInt();\r
523         for(int j = number; j < listSize; j++) {\r
524           if(listSize > 0) {\r
525             for(int i = 0; i < listSize; i++) {\r
526               res += "\twhen " + QString::number(number) + " " + intList->at(i)->getName() + instruc + "\n";\r
527             }\r
528           }\r
529           else\r
530             res += "\twhen " + number + ' ' + intName + instruc + "\n";\r
531           number++;\r
532         }\r
533       }\r
534       if(rxCaseDown->indexIn(cases)) {\r
535         number = rxCaseDown->cap(1).toInt();\r
536         for(int j = number; j < listSize; j++) {\r
537           if(listSize > 0) {\r
538             for(int i = 0; i < listSize; i++) {\r
539               res += "\twhen " + QString::number(number) + " " + intList->at(i)->getName() + instruc + "\n";\r
540             }\r
541           }\r
542           else\r
543             res += "\twhen " + number + ' ' + intName + instruc + "\n";\r
544           number--;\r
545         }\r
546         res += "end case ;\n";\r
547       }\r
548     }\r
549   }\r
550   return res;\r
551 }\r
552 \r
553 QString BlockImplementation::evalString(QString s) {\r
554 \r
555   QString name = getIfaceUserName(block->AbstractBlock::getIfaceFromName(s));\r
556   return name;\r
557 }\r
558 \r
559 QList<AbstractInterface*>* BlockImplementation::evalStringComplex(QString s) {\r
560 \r
561   int j = 0;\r
562   QList<AbstractInterface*> *listInterfaces = new QList<AbstractInterface*>();\r
563   AbstractInterface *inter = block->AbstractBlock::getIfaceFromName(s);\r
564   QList<AbstractInterface*> listIntBlock = block->getInterfaces();\r
565   for(int i = 0; i < listIntBlock.size(); i++) {\r
566     if(inter->getName().compare(listIntBlock.at(i)->getName()) < -1) {\r
567       listInterfaces->insert(j, inter);\r
568       j ++;\r
569     }\r
570   }\r
571   return listInterfaces;\r
572 }\r
573 \r
574 QString BlockImplementation::evalValue(QString s) {\r
575 \r
576   QString val = "";\r
577   if(paramMap.contains(s))\r
578     val = paramMap.value(s);\r
579   return val;\r
580 }\r
581 \r
582 QString BlockImplementation::getIfaceUserName(AbstractInterface* refIface) {\r
583 \r
584   if (! refIface->isReferenceInterface()) return "";\r
585 \r
586   AbstractInterface* funcIface = NULL;\r
587 \r
588   if (refIface->getDirection() == AbstractInterface::Input) {\r
589     foreach(AbstractInterface* iface, block->getInputs()) {\r
590       FunctionalInterface* fi = (FunctionalInterface*)iface;\r
591       if (fi->getReference() == refIface) {\r
592         funcIface = iface;\r
593         break;\r
594       }\r
595     }\r
596   }\r
597   else if (refIface->getDirection() == AbstractInterface::Output) {\r
598     foreach(AbstractInterface* iface, block->getOutputs()) {\r
599       FunctionalInterface* fi = (FunctionalInterface*)iface;\r
600       if (fi->getReference() == refIface) {\r
601         funcIface = iface;\r
602         break;\r
603       }\r
604     }\r
605   }\r
606   else if (refIface->getDirection() == AbstractInterface::InOut) {\r
607     foreach(AbstractInterface* iface, block->getBidirs()) {\r
608       FunctionalInterface* fi = (FunctionalInterface*)iface;\r
609       if (fi->getReference() == refIface) {\r
610         funcIface = iface;\r
611         break;\r
612       }\r
613     }\r
614   }\r
615   if (funcIface == NULL) return "";\r
616 \r
617   return funcIface->getName();\r
618 }\r
619 \r
620 QDataStream& operator<<(QDataStream &out, const BlockImplementation &impl) {\r
621 \r
622   out.setVersion(QDataStream::Qt_5_0);\r
623 \r
624   QByteArray blockData;\r
625   QDataStream toWrite(&blockData, QIODevice::WriteOnly);\r
626 \r
627   toWrite << impl.xmlFile;\r
628   toWrite << impl.referenceXml;\r
629   toWrite << impl.referenceMd5;\r
630   // saving patterns\r
631   toWrite << impl.delta;\r
632   toWrite << impl.consumptionPattern;\r
633   toWrite << impl.productionPattern;\r
634   toWrite << impl.productionCounter;\r
635   \r
636   out << blockData;\r
637 \r
638   return out;\r
639 }\r
640 \r
641 QDataStream& operator>>(QDataStream &in, BlockImplementation &impl) {\r
642 \r
643   quint32 blockSize;\r
644 \r
645   in.setVersion(QDataStream::Qt_5_0);\r
646 \r
647   in >> blockSize;\r
648 \r
649   in >> impl.xmlFile;\r
650   in >> impl.referenceXml;\r
651   in >> impl.referenceMd5;\r
652   // loading patterns\r
653   in >> impl.delta;\r
654   in >> impl.consumptionPattern;\r
655   in >> impl.productionPattern;\r
656   in >> impl.productionCounter;\r
657 \r
658   return in;\r
659 }\r
660 \r
661 QString BlockImplementation::calculateWidth(QString s){\r
662   QRegExp *rxWidth = new QRegExp("$*([a-zA-Z0-9_-]*)");\r
663   QStringList matchList = s.split(" ");\r
664   int pos = 0;\r
665   QString res, line;\r
666   QList<BlockParameter*> listParams = reference->getParameters();\r
667 \r
668   while ((pos = rxWidth->indexIn(s, pos)) != -1) {\r
669     matchList << rxWidth->cap(1);\r
670     pos += rxWidth->matchedLength();\r
671   }\r
672 \r
673   for (int i = 0; i < matchList.size(); i++) {\r
674     QString match = matchList.at(i);\r
675     if(rxWidth->indexIn(match)) {\r
676       for(int j = 0; j < listParams.size(); j++) {\r
677         if(match.compare(listParams.at(j)->getName())) {\r
678           BlockParameter *param = listParams.at(i);\r
679           if(param->getContext() == "generic") {\r
680             match = match.remove('$');\r
681           }\r
682           else {\r
683             match = param->getValue().toString();\r
684           }\r
685         }\r
686       }\r
687     }\r
688   }\r
689   line = matchList.join(' ');\r
690   evaluator->setExpression(line);\r
691   res = evaluator->evaluate();\r
692   return res;\r
693 }\r
694 \r