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

Private GIT Repository
finished testbench generation
[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 #include "Parameters.h"
10
11 ReferenceBlock::ReferenceBlock(const QString _xmlFile) : AbstractBlock(NULL) {
12   xmlFile = _xmlFile;  
13 }
14
15 void ReferenceBlock::addCategory(int id) {
16  categories.append(id);
17 }
18
19 void ReferenceBlock::setDescription(const QString& str) {
20   if(str != NULL)
21     description = str;
22 }
23
24 void ReferenceBlock::addImplementation(BlockImplementation *impl) {
25   implementations.append(impl);
26 }
27
28 void ReferenceBlock::setHashMd5() {
29   QFile file(xmlFile);
30   if (file.open(QIODevice::ReadOnly)) {
31     QByteArray fileData = file.readAll();
32     QByteArray hashData = QCryptographicHash::hash(fileData, QCryptographicHash::Md5);
33     hashMd5 = QString(hashData.toHex());
34     cout << qPrintable(xmlFile) << " has md5 hash : " << qPrintable(hashMd5) << endl;
35   }
36   else {
37     hashMd5 = "";
38   }
39 }
40
41 void ReferenceBlock::load(QDomElement &elt) throw(Exception) {
42
43   cout << "Block : get version" << endl;
44   QString verStr = elt.attribute("version","none");
45   QString specialStr = elt.attribute("special","none");
46   if (verStr != "none") {
47     setVersion(verStr);
48   }
49   else {
50     setVersion("0.0");
51   }
52   setSpecialType(getSpecialTypeFromString(specialStr));
53
54   cout << "Block : get informations" << endl;  
55   QDomElement eltInfo  = elt.firstChildElement("informations");
56   try {
57     loadInformations(eltInfo);
58   }
59   catch(int err) {
60     throw(err);
61   }
62
63   cout << "Block : get params" << endl;  
64   QDomElement eltParams  = eltInfo.nextSiblingElement("parameters");
65   try {
66     loadParameters(eltParams);
67   }
68   catch(int err) {
69     throw(err);
70   }
71
72   cout << "Block : get interfaces" << endl;  
73   QDomElement eltInter  = eltParams.nextSiblingElement("interfaces");
74   try {
75     loadInterfaces(eltInter);
76   }
77   catch(int err) {
78     throw(err);
79   }
80
81   // create interfaces that correspond to a wishbone parameter, if any.
82   try {
83     createInterfaceForWishbone();
84   }
85   catch(int err) {
86     throw(err);
87   }  
88 }
89
90 void ReferenceBlock::loadInformations(QDomElement &elt) throw(Exception) {
91
92   bool ok;
93   if ((elt.isNull()) || (elt.tagName() != "informations")) throw (Exception(BLOCKFILE_CORRUPTED));
94   // getting name
95   cout << "Block info : get name" << endl;
96   QDomNode nodeName = elt.firstChild();  
97   QDomNode nodeNameTxt = nodeName.firstChild();
98   if (nodeNameTxt.isNull()) {
99     name = "no_name";
100   }
101   else {
102     QDomText txtName = nodeNameTxt.toText();
103     name = Parameters::normalizeName(txtName.data().trimmed());
104     cout<< "block name : " << qPrintable(name) << endl;
105   }
106
107   // getting categories
108   cout << "Block info : get categories" << endl;  
109   QDomElement eltCat = nodeName.nextSiblingElement("category");
110
111   QString idsStr = eltCat.attribute("ids","none");
112   if (idsStr == "none") throw (Exception(BLOCKFILE_CORRUPTED));
113   if (idsStr.isEmpty()) {
114     categories.append(99);
115   }
116   else {
117     QStringList listCat = idsStr.split(",");
118     foreach(QString str, listCat)
119     {
120       int idCat = str.toInt(&ok);
121       categories.append(idCat);
122     }
123   }
124
125   // getting description
126   cout << "Block info : get description" << endl;  
127   QDomElement eltDesc = eltCat.nextSiblingElement("description");
128   // getting text
129   QDomNode nodeTxt = eltDesc.firstChild();
130   if (nodeTxt.isNull()) {
131     description = "no description";
132   }
133   else {
134     QDomText txtBrief = nodeTxt.toText();
135     description = txtBrief.data().trimmed();
136     cout << "block desc : " << qPrintable(description) << endl;
137   }  
138 }
139
140 void ReferenceBlock::loadParameters(QDomElement &elt) throw(Exception) {
141
142   if ((elt.isNull()) || (elt.tagName() != "parameters")) throw (Exception(BLOCKFILE_CORRUPTED));
143
144   QDomNodeList listNodeParam = elt.elementsByTagName("parameter");
145   for(int i=0; i<listNodeParam.size(); i++) {
146     QDomNode node = listNodeParam.at(i);    
147     QDomElement elt = node.toElement();    
148     QString nameStr = elt.attribute("name","none");    
149     QString contextStr = elt.attribute("context","none");
150     QString typeStr = elt.attribute("type","none");
151     QString valueStr = elt.attribute("value","none");
152     BlockParameter *param = NULL;
153
154     if(valueStr == "none"){
155         if (contextStr == "generic") throw (Exception(BLOCKFILE_CORRUPTED)); // set is required for generics
156         valueStr = "";
157     }
158     if (contextStr == "user") {
159       param = new BlockParameterUser(this,nameStr,typeStr,valueStr);
160     }
161     else if (contextStr == "generic") {
162       param = new BlockParameterGeneric(this,nameStr,typeStr,valueStr);
163     }
164     else if (contextStr == "wb") {
165       QString widthStr = elt.attribute("width","none");
166       QString wbStr = elt.attribute("wishbone","none");
167       int access = 0;
168       int duration = 0;
169       QString wbValue = "";
170       QStringList listWb = wbStr.split(",");
171       cout << "wb param has:";
172       foreach(QString s, listWb) {
173         cout << qPrintable(s) << " | ";
174       }
175       cout << endl;
176
177       if (listWb.at(0) == "r") {
178         access = BlockParameter::Read;
179       }
180       else if (listWb.at(0) == "w") {
181         access = BlockParameter::Write;
182         bool ok;
183         wbValue = listWb.at(1).toInt(&ok);
184         if(!ok){
185             if(listWb.at(1) == "true" || listWb.at(1) == "false"){
186                 wbValue = listWb.at(1);
187             } else {
188                 wbValue = "data";
189             }
190         }
191         if(listWb.at(2) == "trigger") {
192             duration = BlockParameter::Trigger;
193         }
194         else if(listWb.at(2) == "perm") {
195             duration = BlockParameter::Permanent;
196         }
197       }
198       param = new BlockParameterWishbone(this,nameStr,typeStr,widthStr,valueStr,access,wbValue,duration);
199     }
200     else if (contextStr == "port") {
201       QString ifaceStr = elt.attribute("iface","none");
202       param = new BlockParameterPort(this,nameStr,valueStr,ifaceStr);
203
204     }
205     else {
206       throw (Exception(BLOCKFILE_CORRUPTED));
207     }
208     params.append(param);
209   }
210 }
211
212 void ReferenceBlock::loadInterfaces(QDomElement &elt) throw(Exception) {
213
214   QString nameStr;
215   QString typeStr;
216   QString widthStr;
217   QString endianStr;
218   QString purposeStr;
219   QString clockStr;
220   int purpose;
221   QString multStr;
222   int mult;
223   ReferenceInterface* iface;
224
225   if ((elt.isNull()) || (elt.tagName() != "interfaces")) throw (Exception(BLOCKFILE_CORRUPTED));
226
227   QDomElement eltInputs = elt.firstChildElement("inputs");
228   // getting each input
229   QDomNodeList listNodeInputs = eltInputs.elementsByTagName("input");
230
231   // find all input clocks
232   QList<AbstractInterface*> clocks;
233   for(int i=0;i<listNodeInputs.size();i++) {
234     QDomNode node = listNodeInputs.at(i);
235     QDomElement eltInput = node.toElement();
236     purposeStr = eltInput.attribute("purpose","none");
237     if (purposeStr == "clock") {
238       nameStr = eltInput.attribute("name","none");
239       iface = new ReferenceInterface(this,nameStr,AbstractInterface::Input, AbstractInterface::Clock, "boolean", "1", AbstractInterface::LittleEndian, 1);
240       if (! iface->checkSetClockIface(nameStr)) {
241         throw (Exception(BLOCKFILE_CORRUPTED));
242       }
243       inputs.append(iface);
244       clocks.append(iface);
245     }
246   }
247   cout << "number of clocks: " << clocks.size() << endl;
248
249   // find inputs
250   for(int i=0;i<listNodeInputs.size();i++) {
251     QDomNode node = listNodeInputs.at(i);
252     QDomElement eltInput = node.toElement();
253     purposeStr = eltInput.attribute("purpose","none");
254     purpose = ReferenceInterface::translatePurpose(purposeStr);
255     if (purpose != AbstractInterface::Clock) {
256       cout << "translated purpose : " << purpose << endl;
257       nameStr = eltInput.attribute("name","none");
258       typeStr = eltInput.attribute("type","none");
259       widthStr = eltInput.attribute("width","none");
260       endianStr = eltInput.attribute("endian","none");
261       clockStr = eltInput.attribute("clock","none");
262       int endianess;
263       if ((endianStr == "none") || (endianStr == "little")) {
264         endianess = AbstractInterface::LittleEndian;
265       }
266       else if (endianStr == "big") {
267         endianess = AbstractInterface::BigEndian;
268       }
269       else {
270         throw (Exception(BLOCKFILE_CORRUPTED));
271       }
272
273       multStr = eltInput.attribute("multiplicity","none");
274       mult = ReferenceInterface::translateMultiplicity(multStr);
275
276       iface = new ReferenceInterface(this,nameStr, AbstractInterface::Input, purpose, typeStr, widthStr, endianess, mult);
277       if (clockStr == "none") {
278         if (clocks.size() > 1) {
279           // if several clocks, the associated one MUST be given
280           throw (Exception(BLOCKFILE_CORRUPTED));
281         }
282         // no clock given, take the single one
283         clockStr = clocks.at(0)->getName();
284       }
285       if (! iface->checkSetClockIface(clockStr)) {
286         throw (Exception(BLOCKFILE_CORRUPTED));
287       }
288       inputs.append(iface);
289     }
290   }
291   // getting each control
292   QDomNodeList listNodeInCtl = eltInputs.elementsByTagName("control");
293   for(int i=0;i<listNodeInCtl.size();i++) {
294     QDomNode node = listNodeInCtl.at(i);
295     QDomElement eltInput = node.toElement();
296     nameStr = eltInput.attribute("iface","none");
297     AbstractInterface* dataIface = getIfaceFromName(nameStr);
298     if (dataIface == NULL) throw (Exception(BLOCKFILE_CORRUPTED));
299     QString nameEnbStr = dataIface->getName()+"_enb";
300     iface = new ReferenceInterface(this,nameEnbStr,AbstractInterface::Input, AbstractInterface::Control,"boolean","1", AbstractInterface::LittleEndian, 1);
301     if (!iface->setAssociatedIface(dataIface)) {
302       throw (Exception(BLOCKFILE_CORRUPTED));      
303     }
304     clockStr = dataIface->getClockIfaceString();
305     if (! iface->checkSetClockIface(clockStr)) {
306       throw (Exception(BLOCKFILE_CORRUPTED));
307     }
308     cout << "created a control input named " << qPrintable(iface->getName()) << endl;
309     inputs.append(iface);
310   }
311   QDomElement eltOutputs = eltInputs.nextSiblingElement("outputs");
312   QDomNodeList listNodeOutputs = eltOutputs.elementsByTagName("output");
313   for(int i=0;i<listNodeOutputs.size();i++) {
314     QDomNode node = listNodeOutputs.at(i);
315     QDomElement eltOutput = node.toElement();
316
317     nameStr = eltOutput.attribute("name","none");
318     typeStr = eltOutput.attribute("type","none");
319     widthStr = eltOutput.attribute("width","none");
320     endianStr = eltOutput.attribute("endian","none");
321     clockStr = eltOutput.attribute("clock","none");
322     int endianess;
323     if ((endianStr == "none") || (endianStr == "little")) {
324       endianess = AbstractInterface::LittleEndian;
325     }
326     else if (endianStr == "big") {
327       endianess = AbstractInterface::BigEndian;
328     }
329     else {
330       throw (Exception(BLOCKFILE_CORRUPTED));
331     }
332     purposeStr = eltOutput.attribute("purpose","none");
333     purpose = ReferenceInterface::translatePurpose(purposeStr);
334     multStr = eltOutput.attribute("multiplicity","none");
335     mult = ReferenceInterface::translateMultiplicity(multStr);
336
337     iface = new ReferenceInterface(this,nameStr,AbstractInterface::Output, purpose,typeStr,widthStr, endianess, mult);
338     if (clockStr == "none") {
339       if (clocks.size() > 1) {
340         // if several clocks, the associated one MUST be given
341         throw (Exception(BLOCKFILE_CORRUPTED));
342       }
343       // no clock given, take the single one
344       clockStr = clocks.at(0)->getName();
345     }
346     if (! iface->checkSetClockIface(clockStr)) {
347       throw (Exception(BLOCKFILE_CORRUPTED));
348     }
349
350     outputs.append(iface);
351   }
352   // getting each control
353   QDomNodeList listNodeOutCtl = eltOutputs.elementsByTagName("control");
354   for(int i=0;i<listNodeOutCtl.size();i++) {
355     QDomNode node = listNodeOutCtl.at(i);
356     QDomElement eltOutput = node.toElement();
357     nameStr = eltOutput.attribute("iface","none");
358     AbstractInterface* dataIface = getIfaceFromName(nameStr);
359     if (dataIface == NULL) throw (Exception(BLOCKFILE_CORRUPTED));
360     nameStr = dataIface->getName()+"_enb";
361     iface = new ReferenceInterface(this,nameStr,AbstractInterface::Output, AbstractInterface::Control,"boolean","1",AbstractInterface::LittleEndian, 1);
362     if (!iface->setAssociatedIface(dataIface)) {
363       throw (Exception(BLOCKFILE_CORRUPTED));      
364     }
365     clockStr = dataIface->getClockIfaceString();
366     if (! iface->checkSetClockIface(clockStr)) {
367       throw (Exception(BLOCKFILE_CORRUPTED));
368     }
369     cout << "created a control output named " << qPrintable(iface->getName()) << endl;
370     outputs.append(iface);
371   }
372
373   QDomElement eltBidirs = eltInputs.nextSiblingElement("bidirs");
374   QDomNodeList listNodeBidirs = eltBidirs.elementsByTagName("bidir");
375   for(int i=0;i<listNodeBidirs.size();i++) {
376     QDomNode node = listNodeBidirs.at(i);
377     QDomElement eltBidir = node.toElement();
378     nameStr = eltBidir.attribute("name","none");
379     typeStr = eltBidir.attribute("type","none");
380     widthStr = eltBidir.attribute("width","none");
381     endianStr = eltBidir.attribute("endian","none");
382     clockStr = eltBidir.attribute("clock","none");
383     int endianess;
384     if ((endianStr == "none") || (endianStr == "little")) {
385       endianess = AbstractInterface::LittleEndian;
386     }
387     else if (endianStr == "big") {
388       endianess = AbstractInterface::BigEndian;
389     }
390     else {
391       throw (Exception(BLOCKFILE_CORRUPTED));
392     }
393     purposeStr = eltBidir.attribute("purpose","none");
394     purpose = ReferenceInterface::translatePurpose(purposeStr);
395     multStr = eltBidir.attribute("multiplicity","none");
396     mult = ReferenceInterface::translateMultiplicity(multStr);
397
398     iface = new ReferenceInterface(this,nameStr,AbstractInterface::InOut, purpose,typeStr,widthStr, endianess, mult);
399     if (clockStr == "none") {
400       if (clocks.size() > 1) {
401         // if several clocks, the associated one MUST be given
402         throw (Exception(BLOCKFILE_CORRUPTED));
403       }
404       // no clock given, take the single one
405       clockStr = clocks.at(0)->getName();
406     }
407     if (! iface->checkSetClockIface(clockStr)) {
408       throw (Exception(BLOCKFILE_CORRUPTED));
409     }
410
411     bidirs.append(iface);
412   }
413 }
414
415 void ReferenceBlock::createInterfaceForWishbone() throw(Exception){
416   ReferenceInterface* iface = NULL;
417   foreach(BlockParameter* param, params) {
418     
419     if (param->isWishboneParameter()) {
420       
421       BlockParameterWishbone* p = (BlockParameterWishbone*)param;      
422       cout << "creating interface for parameter wb " << qPrintable(p->getName()) << endl;
423       
424       if (p->getWBAccess() == BlockParameter::Read) {
425         iface = new ReferenceInterface(this,p->getName(), AbstractInterface::Output, AbstractInterface::Wishbone, p->getTypeString(),p->getWidth(), AbstractInterface::LittleEndian, 1);
426         outputs.append(iface);        
427       }
428       else if (p->getWBAccess() == BlockParameter::Write) {
429         iface = new ReferenceInterface(this,p->getName(), AbstractInterface::Input, AbstractInterface::Wishbone,p->getTypeString(),p->getWidth(),AbstractInterface::LittleEndian,1);
430         inputs.append(iface);                
431       }
432       else {
433         throw (Exception(BLOCKFILE_CORRUPTED));
434       }
435     }
436   }
437 }
438
439 void ReferenceBlock::parametersValidation(QList<AbstractBlock *> *checkedBlocks, QList<AbstractBlock *> *blocksToConfigure) {
440     return;
441 }
442
443 /* operator<<() :
444    only used to save all ReferenceBlock in a library in binary format, so that reference blocks
445    are read very fast at application startup.
446
447  */
448 QDataStream& operator<<(QDataStream &out, const ReferenceBlock &b) {
449
450   out.setVersion(QDataStream::Qt_5_0);
451
452   QByteArray blockData;
453   QDataStream toWrite(&blockData, QIODevice::WriteOnly);
454
455   toWrite << b.name;
456   toWrite << b.xmlFile;
457   toWrite << b.specialType;
458   toWrite << b.version;
459   toWrite << b.description;
460   toWrite << b.categories;
461   toWrite << b.hashMd5;
462   toWrite << b.params.size();
463   BlockParameter* p;
464   for(int i=0;i<b.params.size();i++) {
465     p = b.params.at(i);
466     toWrite << p->getContext();
467     toWrite << p->getName();
468     toWrite << p->getTypeString();
469     toWrite << p->getValue().toString();
470     if (p->isPortParameter()) {
471       toWrite << ((BlockParameterPort*)p)->getIfaceName();
472     }
473     else if (p->isWishboneParameter()) {
474       BlockParameterWishbone* pwb = (BlockParameterWishbone*)p;
475       toWrite << pwb->getWidth();
476       toWrite << pwb->getWBAccess();
477       toWrite << pwb->getWBValue();
478       toWrite << pwb->getWBDuration();
479     }
480
481   }
482
483   toWrite << b.inputs.size();
484   // firstly write clock ifaces
485   for(int i=0; i<b.inputs.size(); i++){
486     ReferenceInterface *iface = (ReferenceInterface *)(b.inputs.at(i));
487     if (iface->getPurpose() == AbstractInterface::Clock) {
488       toWrite << iface->getName();
489       toWrite << iface->getType();
490       toWrite << iface->getWidthString();
491       toWrite << iface->getPurpose();
492       toWrite << iface->getDirection();
493       toWrite << iface->getMultiplicity();
494       toWrite << iface->getClockIfaceType();
495       toWrite << iface->getClockIfaceString();
496     }
497   }
498   // secondly write control ifaces
499   for(int i=0; i<b.inputs.size(); i++){
500     ReferenceInterface *iface = (ReferenceInterface *)(b.inputs.at(i));
501     if (iface->getPurpose() == AbstractInterface::Control) {
502       toWrite << iface->getName();
503       toWrite << iface->getType();
504       toWrite << iface->getWidthString();
505       toWrite << iface->getPurpose();
506       toWrite << iface->getDirection();    
507       toWrite << iface->getMultiplicity();
508       toWrite << iface->getClockIfaceType();
509       toWrite << iface->getClockIfaceString();
510     }
511   }
512   // thirdly, write other ifaces
513   for(int i=0; i<b.inputs.size(); i++){
514     ReferenceInterface *iface = (ReferenceInterface *)(b.inputs.at(i));
515     if ((iface->getPurpose() != AbstractInterface::Control) && (iface->getPurpose() != AbstractInterface::Clock)) {
516       toWrite << iface->getName();
517       toWrite << iface->getType();
518       toWrite << iface->getWidthString();
519       toWrite << iface->getPurpose();
520       toWrite << iface->getDirection();    
521       toWrite << iface->getMultiplicity();
522       toWrite << iface->getClockIfaceType();
523       toWrite << iface->getClockIfaceString();
524     }
525   }
526   toWrite << b.outputs.size();
527   // firstly write control ifaces
528   for(int i=0; i<b.outputs.size(); i++){
529     ReferenceInterface *iface = (ReferenceInterface *)(b.outputs.at(i));
530     if (iface->getPurpose() == AbstractInterface::Control) {
531       toWrite << iface->getName();
532       toWrite << iface->getType();
533       toWrite << iface->getWidthString();
534       toWrite << iface->getPurpose();
535       toWrite << iface->getDirection();    
536       toWrite << iface->getMultiplicity();
537       toWrite << iface->getClockIfaceType();
538       toWrite << iface->getClockIfaceString();
539     }
540   }
541   // secondly, write other ifaces
542   for(int i=0; i<b.outputs.size(); i++){
543     ReferenceInterface *iface = (ReferenceInterface *)(b.outputs.at(i));
544     if (iface->getPurpose() != AbstractInterface::Control) {
545       toWrite << iface->getName();
546       toWrite << iface->getType();
547       toWrite << iface->getWidthString();
548       toWrite << iface->getPurpose();
549       toWrite << iface->getDirection();    
550       toWrite << iface->getMultiplicity();
551       toWrite << iface->getClockIfaceType();
552       toWrite << iface->getClockIfaceString();
553     }
554   }
555   toWrite << b.bidirs.size();
556   for(int i=0; i<b.bidirs.size(); i++){
557     ReferenceInterface *iface = (ReferenceInterface *)(b.bidirs.at(i));
558     toWrite << iface->getName();
559     toWrite << iface->getType();
560     toWrite << iface->getWidthString();
561     toWrite << iface->getPurpose();
562     toWrite << iface->getDirection();    
563     toWrite << iface->getMultiplicity();
564     toWrite << iface->getClockIfaceType();
565     toWrite << iface->getClockIfaceString();
566   }
567
568   out << blockData;
569
570   return out;
571 }
572
573 QDataStream& operator>>(QDataStream &in, ReferenceBlock &b) {
574
575   quint32 blockSize;
576   ReferenceInterface* iface;
577   BlockParameter* p;
578   int val;
579   QString txt="";
580
581   in.setVersion(QDataStream::Qt_5_0);
582
583   in >> blockSize;
584
585   in >> b.name;
586   in >> b.xmlFile;
587   in >> b.specialType;
588   in >> b.version;
589   in >> b.description;
590   in >> b.categories;
591   in >> b.hashMd5;
592   b.params.clear();
593   int nb;
594   in >> nb;
595   cout << qPrintable(b.name) << " has " << nb << " parameters" << endl;
596   for(int i=0;i<nb;i++) {
597     QString contextStr = "";
598     QString nameStr= "";
599     QString typeStr = "";
600     QString valueStr = "";
601     in >> contextStr;
602     in >> nameStr;
603     in >> typeStr;
604     in >> valueStr;
605
606     if (contextStr == "user") {
607       p = new BlockParameterUser(&b,nameStr,typeStr,valueStr);
608     }
609     else if (contextStr == "generic") {
610       p = new BlockParameterGeneric(&b,nameStr,typeStr,valueStr);
611     }
612     else if (contextStr == "port") {
613       QString ifaceStr = "";
614       in >> ifaceStr;
615       p = new BlockParameterPort(&b,nameStr,valueStr,ifaceStr);
616     }
617     else if (contextStr == "wb") {
618       QString widthStr = "";
619       int wbAccess;
620       QString wbValue;
621       int wbDuration;
622       in >> widthStr;
623       in >> wbAccess;
624       in >> wbValue;
625       in >> wbDuration;
626       p = new BlockParameterWishbone(&b,nameStr,typeStr,widthStr,valueStr,wbAccess,wbValue,wbDuration);
627     }
628     b.params.append(p);
629   }
630
631   b.inputs.clear();
632   in >> nb;
633   for(int i=0;i<nb;i++) {
634     iface = new ReferenceInterface(&b);
635     in >> txt;
636     iface->setName(txt);
637     int type;
638     in >> type;
639     iface->setType(type);
640     in >> txt;
641     iface->setWidth(txt);
642     in >> val;
643     iface->setPurpose(val);    
644     in >> val;
645     iface->setDirection(val);    
646     in >> val;
647     iface->setMultiplicity(val);
648     int clkType;
649     QString clk;
650     in >> clkType;
651     in >> clk;
652     iface->setClockIfaceName(clk);
653     iface->setClockIfaceType(clkType);
654     b.inputs.append(iface);
655     if (iface->getPurpose() == AbstractInterface::Data) {
656       QString ctlRefName = iface->getName()+"_enb";
657       ReferenceInterface* ctlRefIface = AI_TO_REF(b.getIfaceFromName(ctlRefName));      
658       if (ctlRefIface != NULL) {        
659         if (! ctlRefIface->setAssociatedIface(iface)) {
660           cerr << "Abnormal case while reading a reference block in library: cannot set associated control interface for data interface" << endl;
661         }      
662       }        
663     }    
664   }
665
666   b.outputs.clear();
667   in >> nb;
668   for(int i=0;i<nb;i++) {
669     iface = new ReferenceInterface(&b);
670     in >> txt;
671     iface->setName(txt);
672     int type;
673     in >> type;
674     iface->setType(type);
675     in >> txt;
676     iface->setWidth(txt);
677     in >> val;
678     iface->setPurpose(val);    
679     in >> val;
680     iface->setDirection(val);
681     in >> val;   
682     iface->setMultiplicity(val);
683     int clkType;
684     QString clk;
685     in >> clkType;
686     in >> clk;
687     iface->setClockIfaceName(clk);
688     iface->setClockIfaceType(clkType);
689     b.outputs.append(iface);
690     if (iface->getPurpose() == AbstractInterface::Data) {
691       QString ctlRefName = iface->getName()+"_enb";      
692       ReferenceInterface* ctlRefIface = AI_TO_REF(b.getIfaceFromName(ctlRefName));      
693       if (ctlRefIface != NULL) {        
694         if (! ctlRefIface->setAssociatedIface(iface)) {
695           cerr << "Abnormal case while reading a reference block in library" << endl;
696         }      
697       }        
698     }    
699   }
700
701   b.bidirs.clear();
702   in >> nb;
703   for(int i=0;i<nb;i++) {
704     iface = new ReferenceInterface(&b);
705     in >> txt;
706     iface->setName(txt);
707     int type;
708     in >> type;
709     iface->setType(type);
710     in >> txt;
711     iface->setWidth(txt);
712     in >> val;
713     iface->setPurpose(val);
714     in >> val;
715     iface->setDirection(val);
716     in >> val;    
717     iface->setMultiplicity(val);
718     int clkType;
719     QString clk;
720     in >> clkType;
721     in >> clk;
722     iface->setClockIfaceName(clk);
723     iface->setClockIfaceType(clkType);
724     b.bidirs.append(iface);
725   }
726
727   return in;
728 }
729
730 void ReferenceBlock::checkInputPatternCompatibility()  throw(Exception){
731   throw(Exception(INVALID_REFBLOCK_USE));
732 }
733
734 void ReferenceBlock::computeOutputPattern(int nbExec)  throw(Exception) {
735   // does strictly nothing
736   throw(Exception(INVALID_REFBLOCK_USE));  
737 }
738
739 void ReferenceBlock::computeAdmittanceDelays() throw(Exception) {
740   // does strictly nothing
741   throw(Exception(INVALID_REFBLOCK_USE));
742 }
743
744
745 void ReferenceBlock::generateVHDL(const QString& path) throw(Exception){
746  throw(Exception(INVALID_REFBLOCK_USE));
747 }
748
749 void ReferenceBlock::generateComments(QTextStream& out, QDomElement &elt, QString coreFile) throw(Exception) {
750   throw(Exception(INVALID_REFBLOCK_USE));
751 }
752
753 void ReferenceBlock::generateLibraries(QTextStream& out, QDomElement &elt) throw(Exception) {
754   throw(Exception(INVALID_REFBLOCK_USE));
755 }
756
757 void ReferenceBlock::generateArchitecture(QTextStream& out, QDomElement &elt ) throw(Exception) {
758   throw(Exception(INVALID_REFBLOCK_USE));
759 }
760
761 void ReferenceBlock::generateController(QTextStream& out) throw(Exception) {
762   throw(Exception(INVALID_REFBLOCK_USE));
763 }
764
765 void ReferenceBlock::generateEntityOrComponentBody(QTextStream &out, int indentLevel, bool hasController) throw(Exception) {
766   throw(Exception(INVALID_REFBLOCK_USE));
767 }
768
769 QList<QString> ReferenceBlock::getExternalResources() {
770   QList<QString> list;
771   return list;
772 }
773
774