X-Git-Url: https://bilbo.iut-bm.univ-fcomte.fr/and/gitweb/blast.git/blobdiff_plain/77e28a24d444098399304f0175b1aba43c83017f..6e2b3026c6a496e81642c373796bd39dad33d2a6:/AbstractInterface.cpp?ds=sidebyside diff --git a/AbstractInterface.cpp b/AbstractInterface.cpp index a32f78e..6c51907 100644 --- a/AbstractInterface.cpp +++ b/AbstractInterface.cpp @@ -59,6 +59,79 @@ bool AbstractInterface::isGroupInterface() { return false; } +int AbstractInterface::getWidth() { + + bool ok; + int w = -1; + + QString expr = width; + + /* CAUTION : + + Since VHDL allows to write std_logic_vector(O downto 0) + which is different from std_logic, we have to differentiate + a size of 1 that is really a boolean and thus a std_logic, from + a std_logic_vector of size 1. + + For this reason, if it is boolean, 0 is returned instead of 1. + */ + if (type == Boolean) { + return 0; + } + else if (type == Natural) { + w = width.toInt(&ok); + if (!ok) return -1; + } + else if (type == Expression) { + + QList listGenerics = owner->getGenericParameters(); + QList listUsers = owner->getUserParameters(); + QList listPorts = owner->getPortParameters(); + + foreach(BlockParameter* p, listUsers) { + QString var = "$"; + var += p->getName(); + if (width.contains(var)) { + int tmp = p->getValue().toInt(&ok); + if (!ok) return -1; // user parameter cannot be converted to an int + expr.replace(var,p->getValue().toString()); + } + } + foreach(BlockParameter* p, listPorts) { + QString var = "$"; + var += p->getName(); + if (width.contains(var)) { + expr.replace(var,p->toVHDL(0,0)); + } + } + foreach(BlockParameter* p, listGenerics) { + QString var = "$"; + var += p->getName(); + if (width.contains(var)) { + int tmp = p->getValue().toInt(&ok); + if (!ok) return -1; + QString s=""; + s.setNum(tmp); + expr.replace(var,s); + } + } + // now evaluate the whole expression + ArithmeticEvaluator evaluator; + + try { + evaluator.setVariableMarkers("$"); + evaluator.setExpression(expr); + w = (int)(evaluator.evaluate()); + cout << "iface size :" << w << endl; + } + catch(int e) { + cerr << "invalid expression in size of interface " << qPrintable(name) << " at character " << e << endl; + w = -1; + } + } + return w; +} + QString AbstractInterface::getEndianessString() { QString str="unknown"; switch(endianess){ @@ -191,6 +264,9 @@ QString AbstractInterface::getTypeString() { else if (type == Expression) { return "expression"; } + else if (type == Inherited) { + return "inherited"; + } return "invalid_type"; } @@ -217,83 +293,130 @@ QString AbstractInterface::toVHDL(int context, int flags) throw(Exception) { if (isReferenceInterface()) throw(Exception(IFACE_INVALID_TYPE)); - QString msb = width; + int w; + QString wStr = ""; QString ret=""; - bool ok; - cout << "iface " << qPrintable(name) << " must be evaluated to vhdl :" << qPrintable(msb) << " with type = " << qPrintable(getTypeString()) << endl; - if ((context == BlockParameter::Entity) || (context == BlockParameter::Component)) { + bool ok; + cout << "iface " << qPrintable(name) << " must be evaluated to vhdl :" << qPrintable(width) << " with type = " << qPrintable(getTypeString()) << endl; - QString formatBool = "%1 : %2 std_logic"; - QString formatVector = ""; - if (endianess == LittleEndian) formatVector = "%1 : %2 std_logic_vector(%3 downto %4)"; - else formatVector = "%1 : %2 std_logic_vector(%4 to %3)"; + // create the width part + QString widthStr = ""; + if (type == Boolean) { + widthStr = "std_logic"; + } + else { + QString formatWidth = ""; + if (endianess == LittleEndian) formatWidth = "std_logic_vector(%1 downto %2)"; + else formatWidth = "std_logic_vector(%2 to %1)"; - if ((flags & BlockParameter::NoComma) == 0) { - formatBool.append(";"); - formatVector.append(";"); - } - QString orientation=""; - if (direction == Input) { - orientation = "in"; - } - else if (direction == Output) { - orientation = "out"; - } - else { - orientation = "inout"; - } - if (type == Boolean) { - ret = formatBool.arg(name).arg(orientation); - } - else if (type == Natural) { - int w = width.toInt(&ok); + if (type == Natural) { + w = width.toInt(&ok); if (!ok) { throw(Exception(INVALID_VALUE)); } else { w -= 1; - ret = formatVector.arg(name).arg(orientation).arg(w).arg("0"); + wStr.setNum(w); + widthStr = formatWidth.arg(wStr).arg(0); } } else if (type == Expression) { - - /* must check the following conditions : - - if it contains user/port parameters : must evaluate their numeric value - - if it contains generic parameters : just remove the $ -> the expression is not arithmetically evaluated. - */ - QList listGenerics = owner->getGenericParameters(); - QList listUsers = owner->getUserParameters(); - QList listPorts = owner->getPortParameters(); - foreach(BlockParameter* p, listUsers) { - QString var = "$"; - var += p->getName(); - if (width.contains(var)) { - int w = p->getValue().toInt(&ok); - if (!ok) throw(Exception(INVALID_VALUE)); - msb.replace(var,p->getValue().toString()); + // NB: if for signal, must retrieve the real size, not the one with generics + if (context == Signal) { + w = getWidth(); + if (w == -1) throw(Exception(INVALID_VALUE)); + if (w == 0) { + widthStr = "std_logic"; } - } - foreach(BlockParameter* p, listPorts) { - QString var = "$"; - var += p->getName(); - if (width.contains(var)) { - msb.replace(var,p->toVHDL(0,0)); + else { + w--; + wStr.setNum(w); + widthStr = formatWidth.arg(wStr).arg(0); } } - foreach(BlockParameter* p, listGenerics) { - QString var = "$"; - var += p->getName(); - if (width.contains(var)) { - msb.replace(var,p->getName()); + else { + + /* must check the following conditions : + - if it contains user/port parameters : must evaluate their numeric value + - if it contains generic parameters : just remove the $ -> the expression is not arithmetically evaluated. + */ + wStr = width; + QList listGenerics = owner->getGenericParameters(); + QList listUsers = owner->getUserParameters(); + QList listPorts = owner->getPortParameters(); + foreach(BlockParameter* p, listUsers) { + QString var = "$"; + var += p->getName(); + if (width.contains(var)) { + w = p->getValue().toInt(&ok); + if (!ok) throw(Exception(INVALID_VALUE)); + wStr.replace(var,p->getValue().toString()); + } + } + foreach(BlockParameter* p, listPorts) { + QString var = "$"; + var += p->getName(); + if (width.contains(var)) { + wStr.replace(var,p->toVHDL(0,0)); + } } + foreach(BlockParameter* p, listGenerics) { + QString var = "$"; + var += p->getName(); + if (width.contains(var)) { + wStr.replace(var,p->getName()); + } + } + wStr += "-1"; + widthStr = formatWidth.arg(wStr).arg(0); + } + } + else if (type == Inherited) { + w = getWidth(); + if (w == -1) throw(Exception(INVALID_VALUE)); + if (w == 0) { + widthStr = "std_logic"; + } + else { + w--; + wStr.setNum(w); + widthStr = formatWidth.arg(wStr).arg(0); } - msb += "-1"; - cout << "iface size :" << qPrintable(msb) << endl; - ret = formatVector.arg(name).arg(orientation).arg(msb).arg("0"); } } + + if ((flags & NoComma) == 0) { + widthStr.append(";"); + } + + // generate for an Entity or Component port + if ((context == Entity) || (context == Component)) { + + QString formatPort = "%1 : %2 "; + + QString orientation=""; + if (direction == Input) { + orientation = "in"; + } + else if (direction == Output) { + orientation = "out"; + } + else { + orientation = "inout"; + } + + ret = formatPort.arg(name).arg(orientation); + ret += widthStr; + } + else if (context == Signal) { + ret = widthStr; + } + else if (context == Architecture) { + + } + return ret; }