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

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