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

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