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 AbstractInterface* AbstractInterface::getClockIface() {
247 if (clkIfaceType == ClockName) {
248 return owner->getIfaceFromName(clkIface);
253 bool AbstractInterface::setClockIface(QString name) {
255 * - this is a Data interface
256 * - this is a Clock output (from a clkrstgen)
258 * iface must correspond to an existing clock interface name
259 * or a user parameter prepend with a $.
261 if ((purpose == Data) || ((purpose == Clock) && (direction == Output))) {
262 if (name.at(0) == '$') {
264 QList<BlockParameter* > params = owner->getUserParameters();
265 foreach(BlockParameter* p, params) {
266 if (p->getName() == name) {
268 clkIfaceType = ParameterName;
272 // error case: cannot found the input clock
276 QList<AbstractInterface*> clocks = owner->getInterfaces(Input, Clock);
277 foreach(AbstractInterface* iface, clocks) {
278 if (iface->getName() == name) {
280 clkIfaceType = ClockName;
284 // error case: cannot found the user paramter
289 clkIfaceType = NoName;
294 int AbstractInterface::getIntDirection(QString str) {
295 if(str == "input") return Input;
296 if(str == "output") return Output;
297 if(str == "inout") return InOut;
301 int AbstractInterface::getIntPurpose(QString str) {
302 if(str == "data") return Data;
303 else if(str == "clock") return Clock;
304 else if(str == "reset") return Reset;
305 else if(str == "wishbone") return Wishbone;
309 QString AbstractInterface::getTypeString() {
311 if (type == Boolean) {
314 else if (type == Natural) {
317 else if (type == Expression) {
320 else if (type == Inherited) {
323 return "invalid_type";
326 int AbstractInterface::typeFromString(const QString &_type) {
328 int ret = Expression; // default type
329 if (_type == "expression") {
332 else if (_type == "boolean") {
335 else if (_type == "natural") {
338 else if (_type == "inherited") {
344 QString AbstractInterface::toVHDL(IfaceVHDLContext context, int flags) throw(Exception) {
347 if (isReferenceInterface()) throw(Exception(IFACE_INVALID_TYPE));
354 //cout << "iface " << qPrintable(name) << " must be evaluated to vhdl :" << qPrintable(width) << " with type = " << qPrintable(getTypeString()) << endl;
356 if (context == Instance) {
357 if (direction == Output) {
358 ret = "from_"+owner->getName()+"_"+name;
360 else if (direction == InOut) {
361 ret = "fromto_"+owner->getName()+"_"+name;
366 // create the width part
367 QString widthStr = "";
368 if (type == Boolean) {
369 widthStr = "std_logic";
372 QString formatWidth = "";
373 if (endianess == LittleEndian) formatWidth = "std_logic_vector(%1 downto %2)";
374 else formatWidth = "std_logic_vector(%2 to %1)";
376 if (type == Natural) {
377 w = width.toInt(&ok);
379 throw(Exception(INVALID_VALUE));
384 widthStr = formatWidth.arg(wStr).arg(0);
387 else if (type == Expression) {
389 // NB: if for signal, must retrieve the real size, not the one with generics
390 if (context == Signal) {
392 if (w == -1) throw(Exception(INVALID_VALUE));
394 widthStr = "std_logic";
399 widthStr = formatWidth.arg(wStr).arg(0);
404 /* must check the following conditions :
405 - if it contains user/port parameters : must evaluate their numeric value
406 - if it contains generic parameters : just remove the $ -> the expression is not arithmetically evaluated.
409 QList<BlockParameter*> listGenerics = owner->getGenericParameters();
410 QList<BlockParameter*> listUsers = owner->getUserParameters();
411 QList<BlockParameter*> listPorts = owner->getPortParameters();
412 foreach(BlockParameter* p, listUsers) {
415 if (width.contains(var)) {
416 w = p->getValue().toInt(&ok);
417 if (!ok) throw(Exception(INVALID_VALUE));
418 wStr.replace(var,p->getValue().toString());
421 foreach(BlockParameter* p, listPorts) {
424 if (width.contains(var)) {
425 wStr.replace(var,p->toVHDL(0,0));
428 foreach(BlockParameter* p, listGenerics) {
431 if (width.contains(var)) {
432 wStr.replace(var,p->getName());
436 widthStr = formatWidth.arg(wStr).arg(0);
439 else if (type == Inherited) {
441 if (w == -1) throw(Exception(INVALID_VALUE));
443 widthStr = "std_logic";
448 widthStr = formatWidth.arg(wStr).arg(0);
453 if ((flags & NoComma) == 0) {
454 widthStr.append(";");
457 // generate for an Entity or Component port
458 if ((context == Entity) || (context == Component)) {
460 QString formatPort = "%1 : %2 ";
462 QString orientation="";
463 if (direction == Input) {
466 else if (direction == Output) {
470 orientation = "inout";
473 ret = formatPort.arg(name).arg(orientation);
476 else if (context == Signal) {
477 if (direction == Output) {
478 ret = "from_"+owner->getName()+"_"+name+" : "+widthStr;
480 else if (direction == InOut) {
481 ret = "fromto_"+owner->getName()+"_"+name+" : "+widthStr;
483 else if (direction == Input) {
484 ret = owner->getName()+"_"+name+" : "+widthStr;