1 #include "AbstractInterface.h"
2 #include "BlockParameterPort.h"
3 #include "AbstractBlock.h"
5 AbstractInterface::AbstractInterface(AbstractBlock* _owner) {
13 endianess = LittleEndian;
14 associatedIface = NULL;
18 AbstractInterface::AbstractInterface(AbstractBlock* _owner, const QString& _name, int _direction, int _purpose, const QString& _type, const QString& _width, int _endianess) {
21 name = AbstractBlock::normalizeName(_name);
23 direction = _direction;
25 type = typeFromString(_type);
26 endianess = _endianess;
27 associatedIface = NULL;
30 AbstractInterface::AbstractInterface(AbstractInterface* other) {
32 name = AbstractBlock::normalizeName(other->name);
35 direction = other->direction;
36 purpose = other->purpose;
37 endianess = LittleEndian;
38 associatedIface = NULL;
41 void AbstractInterface::setName(const QString& _name) {
42 name = AbstractBlock::normalizeName(_name);
45 AbstractInterface::~AbstractInterface() {
49 bool AbstractInterface::isReferenceInterface() {
53 bool AbstractInterface::isFunctionalInterface() {
57 bool AbstractInterface::isGroupInterface() {
61 QString AbstractInterface::getEndianessString() {
62 QString str="unknown";
64 case AbstractInterface::LittleEndian:
65 str = QString("little");
67 case AbstractInterface::BigEndian:
74 QString AbstractInterface::getPurposeString() {
77 case AbstractInterface::AnyPurpose:
80 case AbstractInterface::Data:
81 str = QString("data");
83 case AbstractInterface::Control:
84 str = QString("control");
86 case AbstractInterface::Clock:
87 str = QString("clock");
89 case AbstractInterface::Reset:
90 str = QString("reset");
92 case AbstractInterface::Wishbone:
93 str = QString("wishbone");
99 QString AbstractInterface::getDirectionString() {
102 case AbstractInterface::Input:
103 str = QString("input");
105 case AbstractInterface::Output:
106 str = QString("output");
108 case AbstractInterface::InOut:
109 str = QString("inout");
115 double AbstractInterface::getDoubleWidth() throw(QException) {
117 static QString fctName = "AbstractInterface::getDoubleWidth()";
119 cout << "call to " << qPrintable(fctName) << endl;
123 cout << "start AbstractInterface::getDoubleWidth()" << endl;
125 double width = getWidth().toDouble(&ok);
128 ArithmeticEvaluator *evaluator = new ArithmeticEvaluator;
129 cout << "evaluator created!" << endl;
130 evaluator->setExpression(getWidth());
131 cout << "expression defined!" << endl;
132 foreach(BlockParameter *param, getOwner()->getParameters()){
133 evaluator->setVariableValue(param->getName(), param->getIntValue());
134 cout << "param : " << param->getName().toStdString() << " evaluated!" << endl;
136 width = evaluator->evaluate();
137 cout << "expression evaluated succefully!" << endl;
139 cout << "real width : " << width << endl;
146 void AbstractInterface::setPurpose(int _purpose) {
147 if ((_purpose>=Data) && (_purpose <= Wishbone)) {
152 void AbstractInterface::setDirection(int _direction) {
153 if ((_direction > Input) && (_direction <= InOut)) {
154 direction = _direction;
158 bool AbstractInterface::setAssociatedIface(AbstractInterface* iface) {
159 if (purpose != Control) return false;
160 if (iface->purpose != Data) return false;
161 associatedIface = iface;
162 iface->associatedIface = this;
167 int AbstractInterface::getIntDirection(QString str) {
168 if(str == "input") return Input;
169 if(str == "output") return Output;
170 if(str == "inout") return InOut;
174 int AbstractInterface::getIntPurpose(QString str) {
175 if(str == "data") return Data;
176 else if(str == "clock") return Clock;
177 else if(str == "reset") return Reset;
178 else if(str == "wishbone") return Wishbone;
182 QString AbstractInterface::getTypeString() {
184 if (type == Boolean) {
187 else if (type == Natural) {
190 else if (type == Expression) {
193 return "invalid_type";
196 int AbstractInterface::typeFromString(const QString &_type) {
198 int ret = Expression; // default type
199 if (_type == "expression") {
202 else if (_type == "boolean") {
205 else if (_type == "natural") {
208 else if (_type == "inherited") {
214 QString AbstractInterface::toVHDL(int context, int flags) throw(Exception) {
217 if (isReferenceInterface()) throw(Exception(IFACE_INVALID_TYPE));
222 cout << "iface " << qPrintable(name) << " must be evaluated to vhdl :" << qPrintable(msb) << " with type = " << qPrintable(getTypeString()) << endl;
224 if ((context == BlockParameter::Entity) || (context == BlockParameter::Component)) {
226 QString formatBool = "%1 : %2 std_logic";
227 QString formatVector = "";
228 if (endianess == LittleEndian) formatVector = "%1 : %2 std_logic_vector(%3 downto %4)";
229 else formatVector = "%1 : %2 std_logic_vector(%4 to %3)";
231 if ((flags & BlockParameter::NoComma) == 0) {
232 formatBool.append(";");
233 formatVector.append(";");
235 QString orientation="";
236 if (direction == Input) {
239 else if (direction == Output) {
243 orientation = "inout";
245 if (type == Boolean) {
246 ret = formatBool.arg(name).arg(orientation);
248 else if (type == Natural) {
249 int w = width.toInt(&ok);
251 throw(Exception(INVALID_VALUE));
255 ret = formatVector.arg(name).arg(orientation).arg(w).arg("0");
258 else if (type == Expression) {
261 /* must check the following conditions :
262 - if it contains user/port parameters : must evaluate their numeric value
263 - if it contains generic parameters : just remove the $ -> the expression is not arithmetically evaluated.
265 QList<BlockParameter*> listGenerics = owner->getGenericParameters();
266 QList<BlockParameter*> listUsers = owner->getUserParameters();
267 QList<BlockParameter*> listPorts = owner->getPortParameters();
268 foreach(BlockParameter* p, listUsers) {
271 if (width.contains(var)) {
272 int w = p->getValue().toInt(&ok);
273 if (!ok) throw(Exception(INVALID_VALUE));
274 msb.replace(var,p->getValue().toString());
277 foreach(BlockParameter* p, listPorts) {
280 if (width.contains(var)) {
281 msb.replace(var,p->toVHDL(0,0));
284 foreach(BlockParameter* p, listGenerics) {
287 if (width.contains(var)) {
288 msb.replace(var,p->getName());
292 cout << "iface size :" << qPrintable(msb) << endl;
293 ret = formatVector.arg(name).arg(orientation).arg(msb).arg("0");