1 #include "AbstractInterface.h"
2 #include "BlockParameterPort.h"
3 #include "AbstractBlock.h"
4 #include "Parameters.h"
6 AbstractInterface::AbstractInterface(AbstractBlock* _owner) {
14 endianess = LittleEndian;
15 associatedIface = NULL;
19 AbstractInterface::AbstractInterface(AbstractBlock* _owner, const QString& _name, int _direction, int _purpose, const QString& _type, const QString& _width, int _endianess) {
22 name = Parameters::normalizeName(_name);
24 direction = _direction;
26 type = typeFromString(_type);
27 endianess = _endianess;
28 associatedIface = NULL;
31 AbstractInterface::AbstractInterface(AbstractInterface* other) {
33 name = Parameters::normalizeName(other->name);
36 direction = other->direction;
37 purpose = other->purpose;
38 endianess = LittleEndian;
39 associatedIface = NULL;
42 void AbstractInterface::setName(const QString& _name) {
43 name = Parameters::normalizeName(_name);
46 AbstractInterface::~AbstractInterface() {
50 bool AbstractInterface::isReferenceInterface() {
54 bool AbstractInterface::isFunctionalInterface() {
58 bool AbstractInterface::isGroupInterface() {
62 int AbstractInterface::getWidth() {
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.
76 For this reason, if it is boolean, 0 is returned instead of 1.
78 if (type == Boolean) {
81 else if (type == Natural) {
85 else if (type == Expression) {
87 QList<BlockParameter*> listGenerics = owner->getGenericParameters();
88 QList<BlockParameter*> listUsers = owner->getUserParameters();
89 QList<BlockParameter*> listPorts = owner->getPortParameters();
91 foreach(BlockParameter* p, listUsers) {
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());
100 foreach(BlockParameter* p, listPorts) {
103 if (width.contains(var)) {
104 expr.replace(var,p->toVHDL(0,0));
107 foreach(BlockParameter* p, listGenerics) {
110 if (width.contains(var)) {
111 int tmp = p->getValue().toInt(&ok);
118 // now evaluate the whole expression
119 ArithmeticEvaluator evaluator;
122 evaluator.setVariableMarkers("$");
123 evaluator.setExpression(expr);
124 w = (int)(evaluator.evaluate());
125 cout << "iface size :" << w << endl;
128 cerr << "invalid expression in size of interface " << qPrintable(name) << " at character " << e << endl;
135 QString AbstractInterface::getEndianessString() {
136 QString str="unknown";
138 case AbstractInterface::LittleEndian:
139 str = QString("little");
141 case AbstractInterface::BigEndian:
142 str = QString("big");
148 QString AbstractInterface::getPurposeString() {
151 case AbstractInterface::AnyPurpose:
152 str = QString("any");
154 case AbstractInterface::Data:
155 str = QString("data");
157 case AbstractInterface::Control:
158 str = QString("control");
160 case AbstractInterface::Clock:
161 str = QString("clock");
163 case AbstractInterface::Reset:
164 str = QString("reset");
166 case AbstractInterface::Wishbone:
167 str = QString("wishbone");
173 QString AbstractInterface::getDirectionString() {
176 case AbstractInterface::Input:
177 str = QString("input");
179 case AbstractInterface::Output:
180 str = QString("output");
182 case AbstractInterface::InOut:
183 str = QString("inout");
189 double AbstractInterface::getDoubleWidth() throw(QException) {
191 static QString fctName = "AbstractInterface::getDoubleWidth()";
193 cout << "call to " << qPrintable(fctName) << endl;
197 cout << "start AbstractInterface::getDoubleWidth()" << endl;
199 double width = getWidth().toDouble(&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;
210 width = evaluator->evaluate();
211 cout << "expression evaluated succefully!" << endl;
213 cout << "real width : " << width << endl;
220 void AbstractInterface::setPurpose(int _purpose) {
221 if ((_purpose>=Data) && (_purpose <= Wishbone)) {
226 void AbstractInterface::setDirection(int _direction) {
227 if ((_direction > Input) && (_direction <= InOut)) {
228 direction = _direction;
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;
241 int AbstractInterface::getIntDirection(QString str) {
242 if(str == "input") return Input;
243 if(str == "output") return Output;
244 if(str == "inout") return InOut;
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;
256 QString AbstractInterface::getTypeString() {
258 if (type == Boolean) {
261 else if (type == Natural) {
264 else if (type == Expression) {
267 else if (type == Inherited) {
270 return "invalid_type";
273 int AbstractInterface::typeFromString(const QString &_type) {
275 int ret = Expression; // default type
276 if (_type == "expression") {
279 else if (_type == "boolean") {
282 else if (_type == "natural") {
285 else if (_type == "inherited") {
291 QString AbstractInterface::toVHDL(int context, int flags) throw(Exception) {
294 if (isReferenceInterface()) throw(Exception(IFACE_INVALID_TYPE));
301 //cout << "iface " << qPrintable(name) << " must be evaluated to vhdl :" << qPrintable(width) << " with type = " << qPrintable(getTypeString()) << endl;
303 if (context == Instance) {
304 if (direction == Output) {
305 ret = "from_"+owner->getName()+"_"+name;
307 else if (direction == InOut) {
308 ret = "fromto_"+owner->getName()+"_"+name;
313 // create the width part
314 QString widthStr = "";
315 if (type == Boolean) {
316 widthStr = "std_logic";
319 QString formatWidth = "";
320 if (endianess == LittleEndian) formatWidth = "std_logic_vector(%1 downto %2)";
321 else formatWidth = "std_logic_vector(%2 to %1)";
323 if (type == Natural) {
324 w = width.toInt(&ok);
326 throw(Exception(INVALID_VALUE));
331 widthStr = formatWidth.arg(wStr).arg(0);
334 else if (type == Expression) {
336 // NB: if for signal, must retrieve the real size, not the one with generics
337 if (context == Signal) {
339 if (w == -1) throw(Exception(INVALID_VALUE));
341 widthStr = "std_logic";
346 widthStr = formatWidth.arg(wStr).arg(0);
351 /* must check the following conditions :
352 - if it contains user/port parameters : must evaluate their numeric value
353 - if it contains generic parameters : just remove the $ -> the expression is not arithmetically evaluated.
356 QList<BlockParameter*> listGenerics = owner->getGenericParameters();
357 QList<BlockParameter*> listUsers = owner->getUserParameters();
358 QList<BlockParameter*> listPorts = owner->getPortParameters();
359 foreach(BlockParameter* p, listUsers) {
362 if (width.contains(var)) {
363 w = p->getValue().toInt(&ok);
364 if (!ok) throw(Exception(INVALID_VALUE));
365 wStr.replace(var,p->getValue().toString());
368 foreach(BlockParameter* p, listPorts) {
371 if (width.contains(var)) {
372 wStr.replace(var,p->toVHDL(0,0));
375 foreach(BlockParameter* p, listGenerics) {
378 if (width.contains(var)) {
379 wStr.replace(var,p->getName());
383 widthStr = formatWidth.arg(wStr).arg(0);
386 else if (type == Inherited) {
388 if (w == -1) throw(Exception(INVALID_VALUE));
390 widthStr = "std_logic";
395 widthStr = formatWidth.arg(wStr).arg(0);
400 if ((flags & NoComma) == 0) {
401 widthStr.append(";");
404 // generate for an Entity or Component port
405 if ((context == Entity) || (context == Component)) {
407 QString formatPort = "%1 : %2 ";
409 QString orientation="";
410 if (direction == Input) {
413 else if (direction == Output) {
417 orientation = "inout";
420 ret = formatPort.arg(name).arg(orientation);
423 else if (context == Signal) {
424 if (direction == Output) {
425 ret = "from_"+owner->getName()+"_"+name+" : "+widthStr;
427 else if (direction == InOut) {
428 ret = "fromto_"+owner->getName()+"_"+name+" : "+widthStr;
430 else if (direction == Input) {
431 ret = owner->getName()+"_"+name+" : "+widthStr;