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

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