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;
21 AbstractInterface::AbstractInterface(AbstractBlock* _owner, const QString& _name, int _direction, int _purpose, const QString& _type, const QString& _width, int _endianess) {
24 name = Parameters::normalizeName(_name);
26 direction = _direction;
28 type = typeFromString(_type);
29 endianess = _endianess;
30 associatedIface = NULL;
35 AbstractInterface::AbstractInterface(AbstractInterface* other) {
37 name = Parameters::normalizeName(other->name);
40 direction = other->direction;
41 purpose = other->purpose;
42 endianess = LittleEndian;
43 associatedIface = NULL;
44 clkIface = other->clkIface;
45 clkIfaceType = other->clkIfaceType;
48 void AbstractInterface::setName(const QString& _name) {
49 name = Parameters::normalizeName(_name);
52 AbstractInterface::~AbstractInterface() {
56 bool AbstractInterface::isReferenceInterface() {
60 bool AbstractInterface::isFunctionalInterface() {
64 bool AbstractInterface::isGroupInterface() {
68 int AbstractInterface::getWidth() {
77 Since VHDL allows to write std_logic_vector(O downto 0)
78 which is different from std_logic, we have to differentiate
79 a size of 1 that is really a boolean and thus a std_logic, from
80 a std_logic_vector of size 1.
82 For this reason, if it is boolean, 0 is returned instead of 1.
84 if (type == Boolean) {
87 else if (type == Natural) {
91 else if (type == Expression) {
93 QList<BlockParameter*> listGenerics = owner->getGenericParameters();
94 QList<BlockParameter*> listUsers = owner->getUserParameters();
95 QList<BlockParameter*> listPorts = owner->getPortParameters();
97 foreach(BlockParameter* p, listUsers) {
100 if (width.contains(var)) {
101 int tmp = p->getValue().toInt(&ok);
102 if (!ok) return -1; // user parameter cannot be converted to an int
103 expr.replace(var,p->getValue().toString());
106 foreach(BlockParameter* p, listPorts) {
109 if (width.contains(var)) {
110 expr.replace(var,p->toVHDL(0,0));
113 foreach(BlockParameter* p, listGenerics) {
116 if (width.contains(var)) {
117 int tmp = p->getValue().toInt(&ok);
124 // now evaluate the whole expression
125 ArithmeticEvaluator evaluator;
128 evaluator.setVariableMarkers("$");
129 evaluator.setExpression(expr);
130 w = (int)(evaluator.evaluate());
131 cout << "iface size :" << w << endl;
134 cerr << "invalid expression in size of interface " << qPrintable(name) << " at character " << e << endl;
141 QString AbstractInterface::getEndianessString() {
142 QString str="unknown";
144 case AbstractInterface::LittleEndian:
145 str = QString("little");
147 case AbstractInterface::BigEndian:
148 str = QString("big");
154 QString AbstractInterface::getPurposeString() {
157 case AbstractInterface::AnyPurpose:
158 str = QString("any");
160 case AbstractInterface::Data:
161 str = QString("data");
163 case AbstractInterface::Control:
164 str = QString("control");
166 case AbstractInterface::Clock:
167 str = QString("clock");
169 case AbstractInterface::Reset:
170 str = QString("reset");
172 case AbstractInterface::Wishbone:
173 str = QString("wishbone");
179 QString AbstractInterface::getDirectionString() {
182 case AbstractInterface::Input:
183 str = QString("input");
185 case AbstractInterface::Output:
186 str = QString("output");
188 case AbstractInterface::InOut:
189 str = QString("inout");
195 double AbstractInterface::getDoubleWidth() throw(QException) {
197 static QString fctName = "AbstractInterface::getDoubleWidth()";
199 cout << "call to " << qPrintable(fctName) << endl;
203 cout << "start AbstractInterface::getDoubleWidth()" << endl;
205 double width = getWidth().toDouble(&ok);
208 ArithmeticEvaluator *evaluator = new ArithmeticEvaluator;
209 cout << "evaluator created!" << endl;
210 evaluator->setExpression(getWidth());
211 cout << "expression defined!" << endl;
212 foreach(BlockParameter *param, getOwner()->getParameters()){
213 evaluator->setVariableValue(param->getName(), param->getIntValue());
214 cout << "param : " << param->getName().toStdString() << " evaluated!" << endl;
216 width = evaluator->evaluate();
217 cout << "expression evaluated succefully!" << endl;
219 cout << "real width : " << width << endl;
226 void AbstractInterface::setPurpose(int _purpose) {
227 if ((_purpose>=Data) && (_purpose <= Wishbone)) {
232 void AbstractInterface::setDirection(int _direction) {
233 if ((_direction > Input) && (_direction <= InOut)) {
234 direction = _direction;
238 bool AbstractInterface::setAssociatedIface(AbstractInterface* iface) {
239 if (purpose != Control) return false;
240 if (iface->purpose != Data) return false;
241 associatedIface = iface;
242 iface->associatedIface = this;
246 bool AbstractInterface::setClockIface(QString name) {
248 * - this is a Data interface
249 * - this is a Clock output (from a clkrstgen)
251 * iface must correspond to an existing clock interface name
252 * or a user parameter prepend with a $.
254 if ((purpose == Data) || ((purpose == Clock) && (direction == Output))) {
255 if (name.at(0) == '$') {
257 QList<BlockParameter* > params = owner->getUserParameters();
258 foreach(BlockParameter* p, params) {
259 if (p->getName() == name) {
261 clkIfaceType = ParameterName;
265 // error case: cannot found the input clock
269 QList<AbstractInterface*> clocks = owner->getInterfaces(Input, Clock);
270 foreach(AbstractInterface* iface, clocks) {
271 if (iface->getName() == name) {
273 clkIfaceType = ClockName;
277 // error case: cannot found the user paramter
282 clkIfaceType = NoName;
287 int AbstractInterface::getIntDirection(QString str) {
288 if(str == "input") return Input;
289 if(str == "output") return Output;
290 if(str == "inout") return InOut;
294 int AbstractInterface::getIntPurpose(QString str) {
295 if(str == "data") return Data;
296 else if(str == "clock") return Clock;
297 else if(str == "reset") return Reset;
298 else if(str == "wishbone") return Wishbone;
302 QString AbstractInterface::getTypeString() {
304 if (type == Boolean) {
307 else if (type == Natural) {
310 else if (type == Expression) {
313 else if (type == Inherited) {
316 return "invalid_type";
319 int AbstractInterface::typeFromString(const QString &_type) {
321 int ret = Expression; // default type
322 if (_type == "expression") {
325 else if (_type == "boolean") {
328 else if (_type == "natural") {
331 else if (_type == "inherited") {
337 QString AbstractInterface::toVHDL(IfaceVHDLContext context, int flags) throw(Exception) {
340 if (isReferenceInterface()) throw(Exception(IFACE_INVALID_TYPE));
347 //cout << "iface " << qPrintable(name) << " must be evaluated to vhdl :" << qPrintable(width) << " with type = " << qPrintable(getTypeString()) << endl;
349 if (context == Instance) {
350 if (direction == Output) {
351 ret = "from_"+owner->getName()+"_"+name;
353 else if (direction == InOut) {
354 ret = "fromto_"+owner->getName()+"_"+name;
359 // create the width part
360 QString widthStr = "";
361 if (type == Boolean) {
362 widthStr = "std_logic";
365 QString formatWidth = "";
366 if (endianess == LittleEndian) formatWidth = "std_logic_vector(%1 downto %2)";
367 else formatWidth = "std_logic_vector(%2 to %1)";
369 if (type == Natural) {
370 w = width.toInt(&ok);
372 throw(Exception(INVALID_VALUE));
377 widthStr = formatWidth.arg(wStr).arg(0);
380 else if (type == Expression) {
382 // NB: if for signal, must retrieve the real size, not the one with generics
383 if (context == Signal) {
385 if (w == -1) throw(Exception(INVALID_VALUE));
387 widthStr = "std_logic";
392 widthStr = formatWidth.arg(wStr).arg(0);
397 /* must check the following conditions :
398 - if it contains user/port parameters : must evaluate their numeric value
399 - if it contains generic parameters : just remove the $ -> the expression is not arithmetically evaluated.
402 QList<BlockParameter*> listGenerics = owner->getGenericParameters();
403 QList<BlockParameter*> listUsers = owner->getUserParameters();
404 QList<BlockParameter*> listPorts = owner->getPortParameters();
405 foreach(BlockParameter* p, listUsers) {
408 if (width.contains(var)) {
409 w = p->getValue().toInt(&ok);
410 if (!ok) throw(Exception(INVALID_VALUE));
411 wStr.replace(var,p->getValue().toString());
414 foreach(BlockParameter* p, listPorts) {
417 if (width.contains(var)) {
418 wStr.replace(var,p->toVHDL(0,0));
421 foreach(BlockParameter* p, listGenerics) {
424 if (width.contains(var)) {
425 wStr.replace(var,p->getName());
429 widthStr = formatWidth.arg(wStr).arg(0);
432 else if (type == Inherited) {
434 if (w == -1) throw(Exception(INVALID_VALUE));
436 widthStr = "std_logic";
441 widthStr = formatWidth.arg(wStr).arg(0);
446 if ((flags & NoComma) == 0) {
447 widthStr.append(";");
450 // generate for an Entity or Component port
451 if ((context == Entity) || (context == Component)) {
453 QString formatPort = "%1 : %2 ";
455 QString orientation="";
456 if (direction == Input) {
459 else if (direction == Output) {
463 orientation = "inout";
466 ret = formatPort.arg(name).arg(orientation);
469 else if (context == Signal) {
470 if (direction == Output) {
471 ret = "from_"+owner->getName()+"_"+name+" : "+widthStr;
473 else if (direction == InOut) {
474 ret = "fromto_"+owner->getName()+"_"+name+" : "+widthStr;
476 else if (direction == Input) {
477 ret = owner->getName()+"_"+name+" : "+widthStr;