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

Private GIT Repository
553955b414c24a5157c34a96934b391509bcc8e1
[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     createInterfaceForParameters();    
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   AbstractInterface* inter;
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       inter = new ReferenceInterface(this,nameStr,AbstractInterface::Input, AbstractInterface::Clock, "boolean", "1", AbstractInterface::LittleEndian, 1);
240       inputs.append(inter);
241       clocks.append(inter);
242     }
243   }
244   cout << "number of clocks: " << clocks.size() << endl;
245
246   // find inputs
247   for(int i=0;i<listNodeInputs.size();i++) {
248     QDomNode node = listNodeInputs.at(i);
249     QDomElement eltInput = node.toElement();
250     purposeStr = eltInput.attribute("purpose","none");
251     purpose = ReferenceInterface::translatePurpose(purposeStr);
252     if (purpose != AbstractInterface::Clock) {
253       cout << "translated purpose : " << purpose << endl;
254       nameStr = eltInput.attribute("name","none");
255       typeStr = eltInput.attribute("type","none");
256       widthStr = eltInput.attribute("width","none");
257       endianStr = eltInput.attribute("endian","none");
258       clockStr = eltInput.attribute("clock","none");
259       int endianess;
260       if ((endianStr == "none") || (endianStr == "little")) {
261         endianess = AbstractInterface::LittleEndian;
262       }
263       else if (endianStr == "big") {
264         endianess = AbstractInterface::BigEndian;
265       }
266       else {
267         throw (Exception(BLOCKFILE_CORRUPTED));
268       }
269
270       multStr = eltInput.attribute("multiplicity","none");
271       mult = ReferenceInterface::translateMultiplicity(multStr);
272
273       inter = new ReferenceInterface(this,nameStr, AbstractInterface::Input, purpose, typeStr, widthStr, endianess, mult);
274       if (clockStr == "none") {
275         // no clock given, take the first one (hope that there is a single one !)
276         clockStr = clocks.at(0)->getName();
277       }
278       if (! inter->setClockIface(clockStr)) {
279         throw (Exception(BLOCKFILE_CORRUPTED));
280       }
281       inputs.append(inter);
282     }
283   }
284   // getting each control
285   QDomNodeList listNodeInCtl = eltInputs.elementsByTagName("control");
286   for(int i=0;i<listNodeInCtl.size();i++) {
287     QDomNode node = listNodeInCtl.at(i);
288     QDomElement eltInput = node.toElement();
289     nameStr = eltInput.attribute("iface","none");
290     AbstractInterface* dataIface = getIfaceFromName(nameStr);
291     if (dataIface == NULL) throw (Exception(BLOCKFILE_CORRUPTED));
292     nameStr = dataIface->getName()+"_enb";
293     inter = new ReferenceInterface(this,nameStr,AbstractInterface::Input, AbstractInterface::Control,"boolean","1", AbstractInterface::LittleEndian, 1);
294     if (!inter->setAssociatedIface(dataIface)) {
295       throw (Exception(BLOCKFILE_CORRUPTED));      
296     }
297     cout << "created a control input named " << qPrintable(inter->getName()) << endl;
298     inputs.append(inter);
299   }
300   QDomElement eltOutputs = eltInputs.nextSiblingElement("outputs");
301   QDomNodeList listNodeOutputs = eltOutputs.elementsByTagName("output");
302   for(int i=0;i<listNodeOutputs.size();i++) {
303     QDomNode node = listNodeOutputs.at(i);
304     QDomElement eltOutput = node.toElement();
305
306     nameStr = eltOutput.attribute("name","none");
307     typeStr = eltOutput.attribute("type","none");
308     widthStr = eltOutput.attribute("width","none");
309     endianStr = eltOutput.attribute("endian","none");
310     clockStr = eltOutput.attribute("clock","none");
311     int endianess;
312     if ((endianStr == "none") || (endianStr == "little")) {
313       endianess = AbstractInterface::LittleEndian;
314     }
315     else if (endianStr == "big") {
316       endianess = AbstractInterface::BigEndian;
317     }
318     else {
319       throw (Exception(BLOCKFILE_CORRUPTED));
320     }
321     purposeStr = eltOutput.attribute("purpose","none");
322     purpose = ReferenceInterface::translatePurpose(purposeStr);
323     multStr = eltOutput.attribute("multiplicity","none");
324     mult = ReferenceInterface::translateMultiplicity(multStr);
325
326     inter = new ReferenceInterface(this,nameStr,AbstractInterface::Output, purpose,typeStr,widthStr, endianess, mult);
327     if (clockStr == "none") {
328       // no clock given, take the first one (hope that there is a single one !)
329       clockStr = clocks.at(0)->getName();
330     }
331     if (! inter->setClockIface(clockStr)) {
332       throw (Exception(BLOCKFILE_CORRUPTED));
333     }
334     outputs.append(inter);
335   }
336   // getting each control
337   QDomNodeList listNodeOutCtl = eltOutputs.elementsByTagName("control");
338   for(int i=0;i<listNodeOutCtl.size();i++) {
339     QDomNode node = listNodeOutCtl.at(i);
340     QDomElement eltOutput = node.toElement();
341     nameStr = eltOutput.attribute("iface","none");
342     AbstractInterface* dataIface = getIfaceFromName(nameStr);
343     if (dataIface == NULL) throw (Exception(BLOCKFILE_CORRUPTED));
344     nameStr = dataIface->getName()+"_enb";
345     inter = new ReferenceInterface(this,nameStr,AbstractInterface::Output, AbstractInterface::Control,"boolean","1",AbstractInterface::LittleEndian, 1);
346     if (!inter->setAssociatedIface(dataIface)) {
347       throw (Exception(BLOCKFILE_CORRUPTED));      
348     }
349     cout << "created a control output named " << qPrintable(inter->getName()) << endl;
350     outputs.append(inter);
351   }
352
353   QDomElement eltBidirs = eltInputs.nextSiblingElement("bidirs");
354   QDomNodeList listNodeBidirs = eltBidirs.elementsByTagName("bidir");
355   for(int i=0;i<listNodeBidirs.size();i++) {
356     QDomNode node = listNodeBidirs.at(i);
357     QDomElement eltBidir = node.toElement();
358     nameStr = eltBidir.attribute("name","none");
359     typeStr = eltBidir.attribute("type","none");
360     widthStr = eltBidir.attribute("width","none");
361     endianStr = eltBidir.attribute("endian","none");
362     clockStr = eltBidir.attribute("clock","none");
363     int endianess;
364     if ((endianStr == "none") || (endianStr == "little")) {
365       endianess = AbstractInterface::LittleEndian;
366     }
367     else if (endianStr == "big") {
368       endianess = AbstractInterface::BigEndian;
369     }
370     else {
371       throw (Exception(BLOCKFILE_CORRUPTED));
372     }
373     purposeStr = eltBidir.attribute("purpose","none");
374     purpose = ReferenceInterface::translatePurpose(purposeStr);
375     multStr = eltBidir.attribute("multiplicity","none");
376     mult = ReferenceInterface::translateMultiplicity(multStr);
377
378     inter = new ReferenceInterface(this,nameStr,AbstractInterface::InOut, purpose,typeStr,widthStr, endianess, mult);
379     if (clockStr == "none") {
380       // no clock given, take the first one (hope that there is a single one !)
381       clockStr = clocks.at(0)->getName();
382     }
383     if (! inter->setClockIface(clockStr)) {
384       throw (Exception(BLOCKFILE_CORRUPTED));
385     }
386     bidirs.append(inter);
387   }
388 }
389
390 void ReferenceBlock::createInterfaceForParameters() throw(Exception){
391   ReferenceInterface* iface = NULL;
392   foreach(BlockParameter* param, params) {
393     
394     if (param->isWishboneParameter()) {
395       
396       BlockParameterWishbone* p = (BlockParameterWishbone*)param;      
397       cout << "creating interface for parameter wb " << qPrintable(p->getName()) << endl;
398       
399       if (p->getWBAccess() == BlockParameter::Read) {
400         iface = new ReferenceInterface(this,p->getName(), AbstractInterface::Output, AbstractInterface::Wishbone, p->getTypeString(),p->getWidth(), AbstractInterface::LittleEndian, 1);
401         outputs.append(iface);        
402       }
403       else if (p->getWBAccess() == BlockParameter::Write) {
404         iface = new ReferenceInterface(this,p->getName(), AbstractInterface::Input, AbstractInterface::Wishbone,p->getTypeString(),p->getWidth(),AbstractInterface::LittleEndian,1);
405         inputs.append(iface);                
406       }
407       else {
408         throw (Exception(BLOCKFILE_CORRUPTED));
409       }
410     }
411   }
412 }
413
414 void ReferenceBlock::parametersValidation(QList<AbstractBlock *> *checkedBlocks, QList<AbstractBlock *> *blocksToConfigure) {
415     return;
416 }
417
418 /* operator<<() :
419    only used to save all ReferenceBlock in a library in binary format, so that reference blocks
420    are read very fast at application startup.
421
422  */
423 QDataStream& operator<<(QDataStream &out, const ReferenceBlock &b) {
424
425   out.setVersion(QDataStream::Qt_5_0);
426
427   QByteArray blockData;
428   QDataStream toWrite(&blockData, QIODevice::WriteOnly);
429
430   toWrite << b.name;
431   toWrite << b.xmlFile;
432   toWrite << b.specialType;
433   toWrite << b.version;
434   toWrite << b.description;
435   toWrite << b.categories;
436   toWrite << b.hashMd5;
437   toWrite << b.params.size();
438   BlockParameter* p;
439   for(int i=0;i<b.params.size();i++) {
440     p = b.params.at(i);
441     toWrite << p->getContext();
442     toWrite << p->getName();
443     toWrite << p->getTypeString();
444     toWrite << p->getValue().toString();
445     if (p->isPortParameter()) {
446       toWrite << ((BlockParameterPort*)p)->getIfaceName();
447     }
448     else if (p->isWishboneParameter()) {
449       BlockParameterWishbone* pwb = (BlockParameterWishbone*)p;
450       toWrite << pwb->getWidth();
451       toWrite << pwb->getWBAccess();
452       toWrite << pwb->getWBValue();
453       toWrite << pwb->getWBDuration();
454     }
455
456   }
457
458   toWrite << b.inputs.size();
459   // firstly write clock ifaces
460   for(int i=0; i<b.inputs.size(); i++){
461     ReferenceInterface *iface = (ReferenceInterface *)(b.inputs.at(i));
462     if (iface->getPurpose() == AbstractInterface::Clock) {
463       toWrite << iface->getName();
464       toWrite << iface->getType();
465       toWrite << iface->getWidthString();
466       toWrite << iface->getPurpose();
467       toWrite << iface->getDirection();
468       toWrite << iface->getMultiplicity();
469       toWrite << iface->getClockIfaceType();
470       toWrite << iface->getClockIfaceString();
471     }
472   }
473   // secondly write control ifaces
474   for(int i=0; i<b.inputs.size(); i++){
475     ReferenceInterface *iface = (ReferenceInterface *)(b.inputs.at(i));
476     if (iface->getPurpose() == AbstractInterface::Control) {
477       toWrite << iface->getName();
478       toWrite << iface->getType();
479       toWrite << iface->getWidthString();
480       toWrite << iface->getPurpose();
481       toWrite << iface->getDirection();    
482       toWrite << iface->getMultiplicity();
483       toWrite << iface->getClockIfaceType();
484       toWrite << iface->getClockIfaceString();
485     }
486   }
487   // secondly, write other ifaces
488   for(int i=0; i<b.inputs.size(); i++){
489     ReferenceInterface *iface = (ReferenceInterface *)(b.inputs.at(i));
490     if ((iface->getPurpose() != AbstractInterface::Control) && (iface->getPurpose() != AbstractInterface::Clock)) {
491       toWrite << iface->getName();
492       toWrite << iface->getType();
493       toWrite << iface->getWidthString();
494       toWrite << iface->getPurpose();
495       toWrite << iface->getDirection();    
496       toWrite << iface->getMultiplicity();
497       toWrite << iface->getClockIfaceType();
498       toWrite << iface->getClockIfaceString();
499     }
500   }
501   toWrite << b.outputs.size();
502   // firstly write control ifaces
503   for(int i=0; i<b.outputs.size(); i++){
504     ReferenceInterface *iface = (ReferenceInterface *)(b.outputs.at(i));
505     if (iface->getPurpose() == AbstractInterface::Control) {
506       toWrite << iface->getName();
507       toWrite << iface->getType();
508       toWrite << iface->getWidthString();
509       toWrite << iface->getPurpose();
510       toWrite << iface->getDirection();    
511       toWrite << iface->getMultiplicity();
512       toWrite << iface->getClockIfaceType();
513       toWrite << iface->getClockIfaceString();
514     }
515   }
516   // secondly, write other ifaces
517   for(int i=0; i<b.outputs.size(); i++){
518     ReferenceInterface *iface = (ReferenceInterface *)(b.outputs.at(i));
519     if (iface->getPurpose() != AbstractInterface::Control) {
520       toWrite << iface->getName();
521       toWrite << iface->getType();
522       toWrite << iface->getWidthString();
523       toWrite << iface->getPurpose();
524       toWrite << iface->getDirection();    
525       toWrite << iface->getMultiplicity();
526       toWrite << iface->getClockIfaceType();
527       toWrite << iface->getClockIfaceString();
528     }
529   }
530   toWrite << b.bidirs.size();
531   for(int i=0; i<b.bidirs.size(); i++){
532     ReferenceInterface *iface = (ReferenceInterface *)(b.bidirs.at(i));
533     toWrite << iface->getName();
534     toWrite << iface->getType();
535     toWrite << iface->getWidthString();
536     toWrite << iface->getPurpose();
537     toWrite << iface->getDirection();    
538     toWrite << iface->getMultiplicity();
539     toWrite << iface->getClockIfaceType();
540     toWrite << iface->getClockIfaceString();
541   }
542
543   out << blockData;
544
545   return out;
546 }
547
548 QDataStream& operator>>(QDataStream &in, ReferenceBlock &b) {
549
550   quint32 blockSize;
551   ReferenceInterface* iface;
552   BlockParameter* p;
553   int val;
554   QString txt="";
555
556   in.setVersion(QDataStream::Qt_5_0);
557
558   in >> blockSize;
559
560   in >> b.name;
561   in >> b.xmlFile;
562   in >> b.specialType;
563   in >> b.version;
564   in >> b.description;
565   in >> b.categories;
566   in >> b.hashMd5;
567   b.params.clear();
568   int nb;
569   in >> nb;
570   cout << qPrintable(b.name) << " has " << nb << " parameters" << endl;
571   for(int i=0;i<nb;i++) {
572     QString contextStr = "";
573     QString nameStr= "";
574     QString typeStr = "";
575     QString valueStr = "";
576     in >> contextStr;
577     in >> nameStr;
578     in >> typeStr;
579     in >> valueStr;
580
581     if (contextStr == "user") {
582       p = new BlockParameterUser(&b,nameStr,typeStr,valueStr);
583     }
584     else if (contextStr == "generic") {
585       p = new BlockParameterGeneric(&b,nameStr,typeStr,valueStr);
586     }
587     else if (contextStr == "port") {
588       QString ifaceStr = "";
589       in >> ifaceStr;
590       p = new BlockParameterPort(&b,nameStr,valueStr,ifaceStr);
591     }
592     else if (contextStr == "wb") {
593       QString widthStr = "";
594       int wbAccess;
595       QString wbValue;
596       int wbDuration;
597       in >> widthStr;
598       in >> wbAccess;
599       in >> wbValue;
600       in >> wbDuration;
601       p = new BlockParameterWishbone(&b,nameStr,typeStr,widthStr,valueStr,wbAccess,wbValue,wbDuration);
602     }
603     b.params.append(p);
604   }
605
606   b.inputs.clear();
607   in >> nb;
608   for(int i=0;i<nb;i++) {
609     iface = new ReferenceInterface(&b);
610     in >> txt;
611     iface->setName(txt);
612     int type;
613     in >> type;
614     iface->setType(type);
615     in >> txt;
616     iface->setWidth(txt);
617     in >> val;
618     iface->setPurpose(val);    
619     in >> val;
620     iface->setDirection(val);    
621     in >> val;
622     iface->setMultiplicity(val);
623     int clkType;
624     QString clk;
625     in >> clkType;
626     in >> clk;
627     if (clkType == AbstractInterface::ParameterName) {
628       clk = "$"+clk;
629     }
630     if (! iface->setClockIface(clk)) {
631       cerr << "Abnormal case while reading a reference block in library: cannot set ref clock for an interface" << endl;
632     }
633
634     b.inputs.append(iface);
635     if (iface->getPurpose() == AbstractInterface::Data) {
636       QString ctlRefName = iface->getName()+"_enb";
637       ReferenceInterface* ctlRefIface = AI_TO_REF(b.getIfaceFromName(ctlRefName));      
638       if (ctlRefIface != NULL) {        
639         if (! ctlRefIface->setAssociatedIface(iface)) {
640           cerr << "Abnormal case while reading a reference block in library: cannot set associated control interface for data interface" << endl;
641         }      
642       }        
643     }    
644   }
645
646   b.outputs.clear();
647   in >> nb;
648   for(int i=0;i<nb;i++) {
649     iface = new ReferenceInterface(&b);
650     in >> txt;
651     iface->setName(txt);
652     int type;
653     in >> type;
654     iface->setType(type);
655     in >> txt;
656     iface->setWidth(txt);
657     in >> val;
658     iface->setPurpose(val);    
659     in >> val;
660     iface->setDirection(val);
661     in >> val;   
662     iface->setMultiplicity(val);
663     int clkType;
664     QString clk;
665     in >> clkType;
666     in >> clk;
667     if (clkType == AbstractInterface::ParameterName) {
668       clk = "$"+clk;
669     }
670     if (! iface->setClockIface(clk)) {
671       cerr << "Abnormal case while reading a reference block in library: cannot set ref clock for an interface" << endl;
672     }
673     b.outputs.append(iface);
674     if (iface->getPurpose() == AbstractInterface::Data) {
675       QString ctlRefName = iface->getName()+"_enb";      
676       ReferenceInterface* ctlRefIface = AI_TO_REF(b.getIfaceFromName(ctlRefName));      
677       if (ctlRefIface != NULL) {        
678         if (! ctlRefIface->setAssociatedIface(iface)) {
679           cerr << "Abnormal case while reading a reference block in library" << endl;
680         }      
681       }        
682     }    
683   }
684
685   b.bidirs.clear();
686   in >> nb;
687   for(int i=0;i<nb;i++) {
688     iface = new ReferenceInterface(&b);
689     in >> txt;
690     iface->setName(txt);
691     int type;
692     in >> type;
693     iface->setType(type);
694     in >> txt;
695     iface->setWidth(txt);
696     in >> val;
697     iface->setPurpose(val);
698     in >> val;
699     iface->setDirection(val);
700     in >> val;    
701     iface->setMultiplicity(val);
702     int clkType;
703     QString clk;
704     in >> clkType;
705     in >> clk;
706     if (clkType == AbstractInterface::ParameterName) {
707       clk = "$"+clk;
708     }
709     if (! iface->setClockIface(clk)) {
710       cerr << "Abnormal case while reading a reference block in library: cannot set ref clock for an interface" << endl;
711     }
712     b.bidirs.append(iface);
713   }
714
715   return in;
716 }
717
718 void ReferenceBlock::checkInputPatternCompatibility()  throw(Exception){
719   throw(Exception(INVALID_REFBLOCK_USE));
720 }
721
722 void ReferenceBlock::computeOutputPattern(int nbExec)  throw(Exception) {
723   // does strictly nothing
724   throw(Exception(INVALID_REFBLOCK_USE));  
725 }
726
727 void ReferenceBlock::computeAdmittanceDelays() throw(Exception) {
728   // does strictly nothing
729   throw(Exception(INVALID_REFBLOCK_USE));
730 }
731
732
733 void ReferenceBlock::generateVHDL(const QString& path) throw(Exception){
734  throw(Exception(INVALID_REFBLOCK_USE));
735 }
736
737 void ReferenceBlock::generateComments(QTextStream& out, QDomElement &elt, QString coreFile) throw(Exception) {
738   throw(Exception(INVALID_REFBLOCK_USE));
739 }
740
741 void ReferenceBlock::generateLibraries(QTextStream& out, QDomElement &elt) throw(Exception) {
742   throw(Exception(INVALID_REFBLOCK_USE));
743 }
744
745 void ReferenceBlock::generateArchitecture(QTextStream& out, QDomElement &elt ) throw(Exception) {
746   throw(Exception(INVALID_REFBLOCK_USE));
747 }
748
749 void ReferenceBlock::generateController(QTextStream& out) throw(Exception) {
750   throw(Exception(INVALID_REFBLOCK_USE));
751 }
752
753 void ReferenceBlock::generateEntityOrComponentBody(QTextStream &out, int indentLevel, bool hasController) throw(Exception) {
754   throw(Exception(INVALID_REFBLOCK_USE));
755 }
756
757 QList<QString> ReferenceBlock::getExternalResources() {
758   QList<QString> list;
759   return list;
760 }
761
762