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

Private GIT Repository
started VHDL generation of GroupBlock
[blast.git] / AbstractInterface.cpp
1 #include "AbstractInterface.h"
2 #include "BlockParameterPort.h"
3 #include "AbstractBlock.h"
4 #include "Parameters.h"
5
6 AbstractInterface::AbstractInterface(AbstractBlock* _owner) {
7
8   owner = _owner;
9   name = "";
10   width = "1";
11   direction = Input;
12   purpose = Data;  
13   type = Boolean;
14   endianess = LittleEndian;
15   associatedIface = NULL;
16
17 }
18
19 AbstractInterface::AbstractInterface(AbstractBlock* _owner, const QString& _name, int _direction, int _purpose, const QString& _type, const QString& _width, int _endianess) {
20
21   owner = _owner;  
22   name = Parameters::normalizeName(_name);
23   width = _width;
24   direction = _direction;
25   purpose = _purpose;
26   type = typeFromString(_type);
27   endianess = _endianess;
28   associatedIface = NULL;
29 }
30
31 AbstractInterface::AbstractInterface(AbstractInterface* other) {
32   owner = NULL;
33   name = Parameters::normalizeName(other->name);
34   type = other->type;
35   width = other->width;
36   direction = other->direction;
37   purpose = other->purpose;
38   endianess = LittleEndian;
39   associatedIface = NULL;
40 }
41
42 void AbstractInterface::setName(const QString& _name) {
43   name = Parameters::normalizeName(_name);
44 }
45
46 AbstractInterface::~AbstractInterface() {
47
48 }
49
50 bool AbstractInterface::isReferenceInterface() {
51   return false;
52 }
53
54 bool AbstractInterface::isFunctionalInterface() {
55   return false;
56 }
57
58 bool AbstractInterface::isGroupInterface() {
59   return false;
60 }
61
62 int AbstractInterface::getWidth() {
63
64   bool ok;
65   int w = -1;
66
67   QString expr = width;
68
69   /* CAUTION :
70
71      Since VHDL allows to write std_logic_vector(O downto 0)
72      which is different from std_logic, we have to differentiate
73      a size of 1 that is really a boolean and thus a std_logic, from
74      a std_logic_vector of size 1.
75
76      For this reason, if it is boolean, 0 is returned instead of 1.
77    */
78   if (type == Boolean) {
79     return 0;
80   }
81   else if (type == Natural) {
82     w = width.toInt(&ok);
83     if (!ok) return -1;
84   }
85   else if (type == Expression) {
86
87     QList<BlockParameter*> listGenerics = owner->getGenericParameters();
88     QList<BlockParameter*> listUsers = owner->getUserParameters();
89     QList<BlockParameter*> listPorts = owner->getPortParameters();
90
91     foreach(BlockParameter* p, listUsers) {
92       QString var = "$";
93       var += p->getName();
94       if (width.contains(var)) {
95         int tmp = p->getValue().toInt(&ok);
96         if (!ok) return -1; // user parameter cannot be converted to an int
97         expr.replace(var,p->getValue().toString());
98       }
99     }
100     foreach(BlockParameter* p, listPorts) {
101       QString var = "$";
102       var += p->getName();
103       if (width.contains(var)) {
104         expr.replace(var,p->toVHDL(0,0));
105       }
106     }
107     foreach(BlockParameter* p, listGenerics) {
108       QString var = "$";
109       var += p->getName();
110       if (width.contains(var)) {
111         int tmp = p->getValue().toInt(&ok);
112         if (!ok) return -1;
113         QString s="";
114         s.setNum(tmp);
115         expr.replace(var,s);
116       }
117     }
118     // now evaluate the whole expression
119     ArithmeticEvaluator evaluator;
120
121     try {
122       evaluator.setVariableMarkers("$");
123       evaluator.setExpression(expr);
124       w = (int)(evaluator.evaluate());
125       cout << "iface size :" << w << endl;
126     }
127     catch(int e) {
128       cerr << "invalid expression in size of interface " << qPrintable(name) << " at character " << e << endl;
129       w = -1;
130     }
131   }
132   return w;
133 }
134
135 QString AbstractInterface::getEndianessString() {
136   QString str="unknown";
137   switch(endianess){
138   case AbstractInterface::LittleEndian:
139     str = QString("little");
140     break;
141   case AbstractInterface::BigEndian:
142     str = QString("big");
143     break;
144   }
145   return str;
146 }
147
148 QString AbstractInterface::getPurposeString() {
149   QString str;
150   switch(purpose){
151   case AbstractInterface::AnyPurpose:
152     str = QString("any");
153     break;
154   case AbstractInterface::Data:
155     str = QString("data");
156     break;
157   case AbstractInterface::Control:
158     str = QString("control");
159     break;
160   case AbstractInterface::Clock:
161     str = QString("clock");
162     break;
163   case AbstractInterface::Reset:
164     str = QString("reset");
165     break;
166   case AbstractInterface::Wishbone:
167     str = QString("wishbone");
168     break;
169   }
170   return str;
171 }
172
173 QString AbstractInterface::getDirectionString() {
174     QString str;
175     switch(direction){
176         case AbstractInterface::Input:
177             str = QString("input");
178             break;
179         case AbstractInterface::Output:
180             str = QString("output");
181             break;
182         case AbstractInterface::InOut:
183             str = QString("inout");
184             break;
185     }
186     return str;
187 }
188
189 double AbstractInterface::getDoubleWidth() throw(QException) {
190
191   static QString fctName = "AbstractInterface::getDoubleWidth()";
192  #ifdef DEBUG_FCTNAME
193    cout << "call to " << qPrintable(fctName) << endl;
194  #endif
195
196    /*
197     cout << "start AbstractInterface::getDoubleWidth()" << endl;
198     bool ok;
199     double width = getWidth().toDouble(&ok);
200
201     if(!ok){
202       ArithmeticEvaluator *evaluator = new ArithmeticEvaluator;
203       cout << "evaluator created!" << endl;
204       evaluator->setExpression(getWidth());
205       cout << "expression defined!" << endl;
206       foreach(BlockParameter *param, getOwner()->getParameters()){
207         evaluator->setVariableValue(param->getName(), param->getIntValue());
208         cout << "param : " << param->getName().toStdString() << " evaluated!" << endl;
209       }
210       width = evaluator->evaluate();
211       cout << "expression evaluated succefully!" << endl;
212     }
213     cout << "real width : " << width << endl;
214     return width;
215     */
216
217    return 1.0;
218 }
219
220 void AbstractInterface::setPurpose(int _purpose) {
221   if ((_purpose>=Data) && (_purpose <= Wishbone)) {
222     purpose = _purpose;
223   }
224 }
225
226 void AbstractInterface::setDirection(int _direction) {
227   if ((_direction > Input) && (_direction <= InOut)) {
228     direction = _direction;
229   }
230 }
231
232 bool AbstractInterface::setAssociatedIface(AbstractInterface* iface) {
233   if (purpose != Control) return false;
234   if (iface->purpose != Data) return false;
235   associatedIface = iface;
236   iface->associatedIface = this;  
237   return true;
238 }
239
240
241 int AbstractInterface::getIntDirection(QString str) {
242     if(str == "input") return Input;
243     if(str == "output") return Output;
244     if(str == "inout") return InOut;
245     return -1;
246 }
247
248 int AbstractInterface::getIntPurpose(QString str) {
249     if(str == "data") return Data;
250     else if(str == "clock") return Clock;
251     else if(str == "reset") return Reset;
252     else if(str == "wishbone") return Wishbone;
253     return -1;
254 }
255
256 QString AbstractInterface::getTypeString() {
257
258   if (type == Boolean) {
259     return "boolean";
260   }
261   else if (type == Natural) {
262     return "natural";
263   }
264   else if (type == Expression) {
265     return "expression";
266   }
267   else if (type == Inherited) {
268     return "inherited";
269   }
270   return "invalid_type";
271 }
272
273 int AbstractInterface::typeFromString(const QString &_type) {
274
275   int ret = Expression; // default type
276   if (_type == "expression") {
277     ret = Expression;
278   }
279   else if (_type == "boolean") {
280     ret = Boolean;
281   }
282   else if (_type == "natural") {
283     ret = Natural;
284   }
285   else if (_type == "inherited") {
286     ret = Inherited;
287   }
288   return ret;
289 }
290
291 QString AbstractInterface::toVHDL(int context, int flags) throw(Exception) {
292
293
294   if (isReferenceInterface()) throw(Exception(IFACE_INVALID_TYPE));
295
296   int w;
297   QString wStr = "";
298   QString ret="";
299
300   bool ok;
301   cout << "iface " << qPrintable(name) << " must be evaluated to vhdl :" << qPrintable(width) << " with type = " << qPrintable(getTypeString()) << endl;
302
303   // create the width part
304   QString widthStr = "";
305   if (type == Boolean) {
306     widthStr = "std_logic";
307   }
308   else {
309     QString formatWidth = "";
310     if (endianess == LittleEndian) formatWidth = "std_logic_vector(%1 downto %2)";
311     else formatWidth = "std_logic_vector(%2 to %1)";
312
313     if (type == Natural) {
314       w = width.toInt(&ok);
315       if (!ok) {
316         throw(Exception(INVALID_VALUE));
317       }
318       else {
319         w -= 1;
320         wStr.setNum(w);
321         widthStr = formatWidth.arg(wStr).arg(0);
322       }
323     }
324     else if (type == Expression) {
325
326       // NB: if for signal, must retrieve the real size, not the one with generics
327       if (context == Signal) {
328         w = getWidth();
329         if (w == -1) throw(Exception(INVALID_VALUE));
330         if (w == 0) {
331           widthStr = "std_logic";
332         }
333         else {
334           w--;
335           wStr.setNum(w);
336           widthStr = formatWidth.arg(wStr).arg(0);
337         }
338       }
339       else {
340
341         /* must check the following conditions :
342                - if it contains user/port parameters : must evaluate their numeric value
343                - if it contains generic parameters : just remove the $ -> the expression is not arithmetically evaluated.
344           */
345         wStr = width;
346         QList<BlockParameter*> listGenerics = owner->getGenericParameters();
347         QList<BlockParameter*> listUsers = owner->getUserParameters();
348         QList<BlockParameter*> listPorts = owner->getPortParameters();
349         foreach(BlockParameter* p, listUsers) {
350           QString var = "$";
351           var += p->getName();
352           if (width.contains(var)) {
353             w = p->getValue().toInt(&ok);
354             if (!ok) throw(Exception(INVALID_VALUE));
355             wStr.replace(var,p->getValue().toString());
356           }
357         }
358         foreach(BlockParameter* p, listPorts) {
359           QString var = "$";
360           var += p->getName();
361           if (width.contains(var)) {
362             wStr.replace(var,p->toVHDL(0,0));
363           }
364         }
365         foreach(BlockParameter* p, listGenerics) {
366           QString var = "$";
367           var += p->getName();
368           if (width.contains(var)) {
369             wStr.replace(var,p->getName());
370           }
371         }
372         wStr += "-1";
373         widthStr = formatWidth.arg(wStr).arg(0);
374       }
375     }
376     else if (type == Inherited) {
377       w = getWidth();
378       if (w == -1) throw(Exception(INVALID_VALUE));
379       if (w == 0) {
380         widthStr = "std_logic";
381       }
382       else {
383         w--;
384         wStr.setNum(w);
385         widthStr = formatWidth.arg(wStr).arg(0);
386       }
387     }
388   }
389
390   if ((flags & NoComma) == 0) {
391     widthStr.append(";");
392   }
393
394   // generate for an Entity or Component port
395   if ((context == Entity) || (context == Component)) {
396
397     QString formatPort = "%1 : %2 ";
398
399     QString orientation="";
400     if (direction == Input) {
401       orientation = "in";
402     }
403     else if (direction == Output) {
404       orientation = "out";
405     }
406     else {
407       orientation = "inout";
408     }
409
410     ret = formatPort.arg(name).arg(orientation);
411     ret += widthStr;
412   }
413   else if (context == Signal) {
414     ret = widthStr;
415   }
416   else if (context == Architecture) {
417
418   }
419
420   return ret;
421 }
422