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

Private GIT Repository
begun integration of control ifaces
[blast.git] / ReferenceBlock.cpp
1 #include "ReferenceBlock.h"
2
3 #include "ReferenceInterface.h"
4 #include "BlockParameter.h"
5 #include "BlockParameterUser.h"
6 #include "BlockParameterGeneric.h"
7 #include "BlockParameterPort.h"
8 #include "BlockParameterWishbone.h"
9
10 ReferenceBlock::ReferenceBlock(const QString _xmlFile) : AbstractBlock() {
11   xmlFile = _xmlFile;
12 }
13
14 void ReferenceBlock::addCategory(int id) {
15  categories.append(id);
16 }
17
18 void ReferenceBlock::setBriefDescription(const QString& str) {
19   if(str != NULL)
20     descriptionBrief = str;
21 }
22
23 void ReferenceBlock::setDetailedDescription(const QString& str) {
24   if(str != NULL)
25     descriptionDetail = str;
26 }
27
28 void ReferenceBlock::addImplementation(BlockImplementation *impl) {
29   implementations.append(impl);
30 }
31
32 void ReferenceBlock::setHashMd5() {
33   QFile file(xmlFile);
34   if (file.open(QIODevice::ReadOnly)) {
35     QByteArray fileData = file.readAll();
36     QByteArray hashData = QCryptographicHash::hash(fileData, QCryptographicHash::Md5);
37     hashMd5 = QString(hashData.toHex());
38     cout << qPrintable(xmlFile) << " has md5 hash : " << qPrintable(hashMd5) << endl;
39   }
40   else {
41     hashMd5 = "";
42   }
43 }
44
45 void ReferenceBlock::load(QDomElement &elt) throw(Exception) {
46
47
48   cout << "Block : get informations" << endl;  
49   QDomElement eltInfo  = elt.firstChildElement("informations");
50   try {
51     loadInformations(eltInfo);
52   }
53   catch(int err) {
54     throw(err);
55   }
56
57   cout << "Block : get params" << endl;  
58   QDomElement eltParams  = eltInfo.nextSiblingElement("parameters");
59   try {
60     loadParameters(eltParams);
61   }
62   catch(int err) {
63     throw(err);
64   }
65
66   cout << "Block : get interfaces" << endl;  
67   QDomElement eltInter  = eltParams.nextSiblingElement("interfaces");
68   try {
69     loadInterfaces(eltInter);
70   }
71   catch(int err) {
72     throw(err);
73   }
74
75   // create interfaces that correspond to a wishbone parameter, if any.
76   try {
77     createInterfaceForParameters();    
78   }
79   catch(int err) {
80     throw(err);
81   }  
82 }
83
84 void ReferenceBlock::loadInformations(QDomElement &elt) throw(Exception) {
85
86   bool ok;
87   if ((elt.isNull()) || (elt.tagName() != "informations")) throw (Exception(BLOCKFILE_CORRUPTED));
88   // getting name
89   cout << "Block info : get name" << endl;
90   QDomNode nodeName = elt.firstChild();  
91   QDomNode nodeNameTxt = nodeName.firstChild();
92   if (nodeNameTxt.isNull()) {
93     name = "no_name";
94   }
95   else {
96     QDomText txtName = nodeNameTxt.toText();
97     name = txtName.data().trimmed();
98     cout<< "block name : " << qPrintable(name) << endl;
99   }
100
101   // getting categories
102   cout << "Block info : get categories" << endl;  
103   QDomElement eltCat = nodeName.nextSiblingElement("category");
104
105   QString idsStr = eltCat.attribute("ids","none");
106   if (idsStr == "none") throw (Exception(BLOCKFILE_CORRUPTED));
107   QStringList listCat = idsStr.split(",");
108   foreach(QString str, listCat)
109   {
110     int idCat = str.toInt(&ok);
111     categories.append(idCat);
112   }
113
114   // getting description
115   cout << "Block info : get description" << endl;  
116   QDomElement eltDesc = eltCat.nextSiblingElement("description");
117   // getting brief  
118   QDomElement eltBrief = eltDesc.firstChildElement("brief");
119   QDomNode nodeBriefTxt = eltBrief.firstChild();
120   if (nodeBriefTxt.isNull()) {
121     descriptionBrief = "no brief description";
122   }
123   else {
124     QDomText txtBrief = nodeBriefTxt.toText();
125     descriptionBrief = txtBrief.data().trimmed();
126     cout << "block brief desc : " << qPrintable(descriptionBrief) << endl;
127   }
128   // getting detailed  
129   QDomElement eltDetail = eltBrief.nextSiblingElement("detailed");
130   QDomNode nodeDetailTxt = eltDetail.firstChild();
131   if (nodeDetailTxt.isNull()) {
132     descriptionDetail = "no detailed description";
133   }
134   else {
135     QDomText txtDetail = nodeDetailTxt.toText();
136     descriptionDetail = txtDetail.data().trimmed();
137     cout << "block detail desc : " << qPrintable(descriptionDetail) << endl;
138   }
139 }
140
141 void ReferenceBlock::loadParameters(QDomElement &elt) throw(Exception) {
142
143   if ((elt.isNull()) || (elt.tagName() != "parameters")) throw (Exception(BLOCKFILE_CORRUPTED));
144
145   QDomNodeList listNodeParam = elt.elementsByTagName("parameter");
146   for(int i=0; i<listNodeParam.size(); i++) {
147     QDomNode node = listNodeParam.at(i);    
148     QDomElement elt = node.toElement();    
149     QString nameStr = elt.attribute("name","none");    
150     QString contextStr = elt.attribute("context","none");
151     QString typeStr = elt.attribute("type","none");
152     QString valueStr = elt.attribute("value","none");
153     BlockParameter *param = NULL;
154
155     if(valueStr == "none"){
156         if (contextStr == "generic") throw (Exception(BLOCKFILE_CORRUPTED)); // set is required for generics
157         valueStr = "";
158     }
159     if (contextStr == "user") {
160       param = new BlockParameterUser(this,nameStr,valueStr);
161     }
162     else if (contextStr == "generic") {
163       param = new BlockParameterGeneric(this,nameStr,typeStr,valueStr);
164     }
165     else if (contextStr == "wb") {
166       QString widthStr = elt.attribute("width","none");
167       QString wbStr = elt.attribute("wishbone","none");
168       int access = 0;
169       int duration = 0;
170       QString wbValue = "";
171       QStringList listWb = wbStr.split(",");
172
173       if (listWb.at(0) == "r") {
174         access = BlockParameter::Read;
175       }
176       else if (wbStr == "w") {
177         access = BlockParameter::Write;
178         bool ok;
179         wbValue = listWb.at(1).toInt(&ok);
180         if(!ok){
181             if(listWb.at(1) == "true" || listWb.at(1) == "false"){
182                 wbValue = listWb.at(1);
183             } else {
184                 wbValue = "data";
185             }
186         }
187         if(listWb.at(2) == "trigger") {
188             duration = BlockParameter::Trigger;
189         }
190         else if(listWb.at(2) == "perm") {
191             duration = BlockParameter::Permanent;
192         }
193       }
194       param = new BlockParameterWishbone(this,nameStr,typeStr,widthStr,valueStr,access,wbValue,duration);
195     }
196     else if (contextStr == "port") {
197       QString ifaceStr = elt.attribute("iface","none");
198       param = new BlockParameterPort(this,nameStr,valueStr,ifaceStr);
199
200     }
201     else {
202       throw (Exception(BLOCKFILE_CORRUPTED));
203     }
204     params.append(param);
205   }
206 }
207
208 void ReferenceBlock::loadInterfaces(QDomElement &elt) throw(Exception) {
209
210   QString nameStr;
211   QString typeStr;
212   QString widthStr;
213   QString purposeStr;
214   int purpose;
215   QString multStr;
216   int mult;
217   AbstractInterface* inter;
218
219   if ((elt.isNull()) || (elt.tagName() != "interfaces")) throw (Exception(BLOCKFILE_CORRUPTED));
220
221   QDomElement eltInputs = elt.firstChildElement("inputs");
222   QDomNodeList listNodeInputs = eltInputs.elementsByTagName("input");
223   for(int i=0;i<listNodeInputs.size();i++) {
224     QDomNode node = listNodeInputs.at(i);
225     QDomElement eltInput = node.toElement();
226     nameStr = eltInput.attribute("name","none");
227     typeStr = eltInput.attribute("type","none");
228     widthStr = eltInput.attribute("width","none");
229     purposeStr = eltInput.attribute("purpose","none");
230     cout << "block : " << this->getName().toStdString() << endl;
231     cout << "purpose for " << nameStr.toStdString() << " : " << purposeStr.toStdString() << endl;
232     purpose = ReferenceInterface::translatePurpose(purposeStr);
233     cout << "translated purpose : " << purpose << endl;
234     multStr = eltInput.attribute("multiplicity","none");
235     mult = ReferenceInterface::translateMultiplicity(multStr);
236
237     inter = new ReferenceInterface(this,nameStr,typeStr,widthStr,AbstractInterface::Input, purpose, mult);
238     inputs.append(inter);
239   }
240
241   QDomElement eltOutputs = eltInputs.nextSiblingElement("outputs");
242   QDomNodeList listNodeOutputs = eltOutputs.elementsByTagName("output");
243   for(int i=0;i<listNodeOutputs.size();i++) {
244     QDomNode node = listNodeOutputs.at(i);
245     QDomElement eltOutput = node.toElement();
246     nameStr = eltOutput.attribute("name","none");
247     typeStr = eltOutput.attribute("type","none");
248     widthStr = eltOutput.attribute("width","none");
249     purposeStr = eltOutput.attribute("type","none");
250     purpose = ReferenceInterface::translatePurpose(purposeStr);
251     multStr = eltOutput.attribute("multiplicity","none");
252     mult = ReferenceInterface::translateMultiplicity(multStr);
253
254     inter = new ReferenceInterface(this,nameStr,typeStr,widthStr,AbstractInterface::Output, purpose, mult);
255     outputs.append(inter);
256   }
257
258   QDomElement eltBidirs = eltInputs.nextSiblingElement("bidirs");
259   QDomNodeList listNodeBidirs = eltBidirs.elementsByTagName("bidir");
260   for(int i=0;i<listNodeBidirs.size();i++) {
261     QDomNode node = listNodeBidirs.at(i);
262     QDomElement eltBidir = node.toElement();
263     nameStr = eltBidir.attribute("name","none");
264     typeStr = eltBidir.attribute("type","none");
265     widthStr = eltBidir.attribute("width","none");
266     purposeStr = eltBidir.attribute("type","none");
267     purpose = ReferenceInterface::translatePurpose(purposeStr);
268     multStr = eltBidir.attribute("multiplicity","none");
269     mult = ReferenceInterface::translateMultiplicity(multStr);
270
271     inter = new ReferenceInterface(this,nameStr,typeStr,widthStr,AbstractInterface::InOut, purpose, mult);
272     bidirs.append(inter);
273   }
274 }
275
276 void ReferenceBlock::createInterfaceForParameters() throw(Exception){
277   ReferenceInterface* iface = NULL;
278   foreach(BlockParameter* param, params) {
279     
280     if (param->isWishboneParameter()) {
281       BlockParameterWishbone* p = (BlockParameterWishbone*)param;
282       int orientation = -1;
283       if (p->getWBAccess() == BlockParameter::Read) {
284         iface = new ReferenceInterface(this,p->getName(),p->getType(),p->getWidth(), AbstractInterface::Output, AbstractInterface::Wishbone,1);
285         outputs.append(iface);        
286       }
287       else if (p->getWBAccess() == BlockParameter::Write) {
288         iface = new ReferenceInterface(this,p->getName(),p->getType(),p->getWidth(), AbstractInterface::Input, AbstractInterface::Wishbone,1);
289         inputs.append(iface);                
290       }
291       ReferenceInterface* iface = new ReferenceInterface(this,p->getName(),p->getType(),p->getWidth(), orientation, AbstractInterface::Wishbone,1);
292     }
293   }
294 }
295
296 void ReferenceBlock::parametersValidation(QList<AbstractBlock *> *checkedBlocks, QList<AbstractBlock *> *blocksToConfigure) {
297     return;
298 }
299
300 /* operator<<() :
301    only used to save all ReferenceBlock in a library in binary format, so that reference blocks
302    are read very fast at application startup.
303
304  */
305 QDataStream& operator<<(QDataStream &out, const ReferenceBlock &b) {
306
307   out.setVersion(QDataStream::Qt_5_0);
308
309   QByteArray blockData;
310   QDataStream toWrite(&blockData, QIODevice::WriteOnly);
311
312   toWrite << b.name;
313   toWrite << b.xmlFile;
314   toWrite << b.descriptionBrief;
315   toWrite << b.descriptionDetail;
316   toWrite << b.categories;
317   toWrite << b.hashMd5;
318   toWrite << b.params.size();
319   BlockParameter* p;
320   for(int i=0;i<b.params.size();i++) {
321     p = b.params.at(i);
322     toWrite << p->getContext();
323     toWrite << p->getName();
324     toWrite << p->getTypeString();
325     toWrite << p->getValue().toString();
326     if (p->isPortParameter()) {
327       toWrite << ((BlockParameterPort*)p)->getIfaceName();
328     }
329     else if (p->isWishboneParameter()) {
330       BlockParameterWishbone* pwb = (BlockParameterWishbone*)p;
331       toWrite << pwb->getWidth();
332       toWrite << pwb->getWBAccess();
333       toWrite << pwb->getWBValue();
334       toWrite << pwb->getWBDuration();
335     }
336
337   }
338
339   toWrite << b.inputs.size();
340   for(int i=0; i<b.inputs.size(); i++){
341     ReferenceInterface *iface = (ReferenceInterface *)(b.inputs.at(i));
342     toWrite << iface->getName();
343     toWrite << iface->getWidth();
344     toWrite << iface->getPurpose();
345     toWrite << iface->getDirection();    
346     toWrite << iface->getMultiplicity();
347   }
348   toWrite << b.outputs.size();
349   for(int i=0; i<b.outputs.size(); i++){
350     ReferenceInterface *iface = (ReferenceInterface *)(b.outputs.at(i));
351     toWrite << iface->getName();
352     toWrite << iface->getWidth();
353     toWrite << iface->getPurpose();
354     toWrite << iface->getDirection();    
355     toWrite << iface->getMultiplicity();
356   }
357   toWrite << b.bidirs.size();
358   for(int i=0; i<b.bidirs.size(); i++){
359     ReferenceInterface *iface = (ReferenceInterface *)(b.bidirs.at(i));
360     toWrite << iface->getName();
361     toWrite << iface->getWidth();
362     toWrite << iface->getPurpose();
363     toWrite << iface->getDirection();    
364     toWrite << iface->getMultiplicity();
365   }
366
367   out << blockData;
368
369   return out;
370 }
371
372 QDataStream& operator>>(QDataStream &in, ReferenceBlock &b) {
373
374   quint32 blockSize;
375   ReferenceInterface* iface;
376   BlockParameter* p;
377   int val;
378   QString txt="";
379
380   in.setVersion(QDataStream::Qt_5_0);
381
382   in >> blockSize;
383
384   in >> b.name;
385   in >> b.xmlFile;
386   in >> b.descriptionBrief;
387   in >> b.descriptionDetail;
388   in >> b.categories;
389   in >> b.hashMd5;
390   b.params.clear();
391   int nb;
392   in >> nb;
393   cout << qPrintable(b.name) << " has " << nb << " parameters" << endl;
394   for(int i=0;i<nb;i++) {
395     QString contextStr = "";
396     QString nameStr= "";
397     QString typeStr = "";
398     QString valueStr = "";
399     in >> contextStr;
400     in >> nameStr;
401     in >> typeStr;
402     in >> valueStr;
403
404     if (contextStr == "user") {
405       p = new BlockParameterUser(&b,nameStr,valueStr);
406     }
407     else if (contextStr == "generic") {
408       p = new BlockParameterGeneric(&b,nameStr,typeStr,valueStr);
409     }
410     else if (contextStr == "port") {
411       QString ifaceStr = "";
412       in >> ifaceStr;
413       p = new BlockParameterPort(&b,nameStr,valueStr,ifaceStr);
414     }
415     else if (contextStr == "wb") {
416       QString widthStr = "";
417       int wbAccess;
418       QString wbValue;
419       int wbDuration;
420       in >> widthStr;
421       in >> wbAccess;
422       in >> wbValue;
423       in >> wbDuration;
424       p = new BlockParameterWishbone(&b,nameStr,typeStr,widthStr,valueStr,wbAccess,wbValue,wbDuration);
425     }
426     b.params.append(p);
427   }
428
429   b.inputs.clear();
430   in >> nb;
431   for(int i=0;i<nb;i++) {
432     iface = new ReferenceInterface(&b);
433     in >> txt;
434     iface->setName(txt);
435     in >> txt;
436     iface->setWidth(txt);
437     in >> val;
438     iface->setPurpose(val);
439     in >> val;
440     iface->setDirection(val);    
441     in >> val;
442     iface->setMultiplicity(val);
443     b.inputs.append(iface);
444   }
445
446   b.outputs.clear();
447   in >> nb;
448   for(int i=0;i<nb;i++) {
449     iface = new ReferenceInterface(&b);
450     in >> txt;
451     iface->setName(txt);
452     in >> txt;
453     iface->setWidth(txt);
454     in >> val;
455     iface->setPurpose(val);
456     in >> val;
457     iface->setDirection(val);
458     in >> val;   
459     iface->setMultiplicity(val);
460     b.outputs.append(iface);
461   }
462
463   b.bidirs.clear();
464   in >> nb;
465   for(int i=0;i<nb;i++) {
466     iface = new ReferenceInterface(&b);
467     in >> txt;
468     iface->setName(txt);
469     in >> txt;
470     iface->setWidth(txt);
471     in >> val;
472     iface->setPurpose(val);
473     in >> val;
474     iface->setDirection(val);
475     in >> val;    
476     iface->setMultiplicity(val);
477     b.bidirs.append(iface);
478   }
479
480   return in;
481 }