* and has at least one data output.\r
* By the way, blocks that have no data input/output\r
* (like clkrstgen) are not sources !\r
+ * A source may also be a block of special type source.\r
*/\r
bool AbstractBlock::isSourceBlock() {\r
+ if (specialType == Source) return true;\r
if (getDataInputs().size() > 0) return false;\r
if (getDataOutputs().size() == 0) return false;\r
return true;\r
virtual bool isGroupBlock();\r
virtual bool isStimuliBlock(); //! a stimuli block is outside the top group and simulates a peripheral (NB: this is also a source)\r
virtual bool isTopGroupBlock();\r
- bool isSourceBlock(); //! a source block has no data inputs and thus executes infinitely\r
+ bool isSourceBlock(); //! a source block is either a block that has no data inputs or that is of special type source. Thus it executes infinitely\r
bool isSinkBlock(); //! a sink block has no data outputs and just collects what it receives (i.e. no compatibility check)\r
bool isWBConfigurable();\r
\r
type = Boolean;
endianess = LittleEndian;
associatedIface = NULL;
- clkIface = "";
- clkIfaceType = 0;
+ clkIfaceName = "";
+ clkIfaceType = NoName;
}
type = typeFromString(_type);
endianess = _endianess;
associatedIface = NULL;
- clkIface = "";
- clkIfaceType = 0;
+ clkIfaceName = "";
+ clkIfaceType = NoName;
}
AbstractInterface::AbstractInterface(AbstractInterface* other) {
purpose = other->purpose;
endianess = LittleEndian;
associatedIface = NULL;
- clkIface = other->clkIface;
+ clkIfaceName = other->clkIfaceName;
clkIfaceType = other->clkIfaceType;
}
AbstractInterface* AbstractInterface::getClockIface() {
if (clkIfaceType == ClockName) {
- return owner->getIfaceFromName(clkIface);
+ return owner->getIfaceFromName(clkIfaceName);
}
return NULL;
}
int idClock = -1;
if (clkIfaceType == ParameterName) {
- BlockParameter* param = owner->getParameterFromName(clkIface);
+ BlockParameter* param = owner->getParameterFromName(clkIfaceName);
if (!param->isUserParameter()) throw(Exception(IFACE_INVALID_CLKFREQ,this));
bool ok;
double freq = param->getDoubleValue(&ok);
}
-bool AbstractInterface::setClockIface(QString name) {
- /* 2 cases :
- * - this is a Data interface
- * - this is a Clock output (from a clkrstgen)
- *
- * iface must correspond to an existing clock interface name
- * or a user parameter prepend with a $.
- */
- if ((purpose == Data) || ((purpose == Clock) && (direction == Output))) {
- if (name.at(0) == '$') {
- name.remove(0,1);
- QList<BlockParameter* > params = owner->getUserParameters();
- foreach(BlockParameter* p, params) {
- if (p->getName() == name) {
- clkIface = name;
- clkIfaceType = ParameterName;
- return true;
- }
- }
- // error case: cannot found the input clock
- return false;
- }
- else {
- QList<AbstractInterface*> clocks = owner->getInterfaces(Input, Clock);
- foreach(AbstractInterface* iface, clocks) {
- if (iface->getName() == name) {
- clkIface = name;
- clkIfaceType = ClockName;
- return true;
- }
- }
- // error case: cannot found the user paramter
- return false;
- }
- }
- clkIface = "";
- clkIfaceType = NoName;
- return true;
-}
-
int AbstractInterface::getIntDirection(QString str) {
if(str == "input") return Input;
//cout << "iface " << qPrintable(name) << " must be evaluated to vhdl :" << qPrintable(width) << " with type = " << qPrintable(getTypeString()) << endl;
if (context == Instance) {
- if (direction == Output) {
+ if (direction == Input) {
+ ret = owner->getName()+"_"+name;
+ }
+ else if (direction == Output) {
ret = "from_"+owner->getName()+"_"+name;
}
else if (direction == InOut) {
enum IfaceDirection { AnyDirection = 0, Input = 1, Output = 2, InOut = 3 };
enum IfaceVHDLContext {AnyContext = 0, Entity = 1, Component = 2, Instance = 3, Signal = 4 };
enum IfaceVHDLFlags { NoComma = 1 };
- enum IfaceClockName { NoName = 0, ClockName, ParameterName };
+ enum IfaceClockName { NoName = 0, ClockName, ParameterName, InheritedName };
static int getIntDirection(QString str);
static int getIntPurpose(QString str);
QString getDirectionString();
inline AbstractBlock *getOwner() { return owner;}
inline AbstractInterface* getAssociatedIface() { return associatedIface; }
- inline QString getClockIfaceString() { return clkIface; }
+ inline QString getClockIfaceString() { return clkIfaceName; }
inline int getClockIfaceType() { return clkIfaceType; }
AbstractInterface* getClockIface();
virtual int getClockDomain() throw(Exception) = 0; // determine on which clock domain is sync this interface
void setPurpose(int _purpose);
void setDirection(int _direction);
bool setAssociatedIface(AbstractInterface* iface);
- bool setClockIface(QString name);
+ inline void setClockIfaceType(int type) { clkIfaceType = type; }
+ inline void setClockIfaceName(QString name) { clkIfaceName = name; }
// testers
virtual bool isReferenceInterface();
* Nevertheless, the designer has the possibility to connect the block taht owns this interface to another clkrstgen block. Moreover,
* some blocks may have several clocks, e.g. dual port RAMs, FIFOs.
*/
- QString clkIface;
+ QString clkIfaceName;
int clkIfaceType; // 0 for not affected, 1 for clock input name, 2 for user param name
ret = formatNoValue.arg(name).arg(typeStr);\r
}\r
}\r
+ else if (type == String) {\r
+ typeStr = "string";\r
+ if (!userValue.isNull()) {\r
+ valueStr = "\""+userValue.toString()+"\"";\r
+ ret = formatValue.arg(name).arg(typeStr).arg(valueStr);\r
+ }\r
+ else if (!defaultValue.isNull()) {\r
+ valueStr = "\""+defaultValue.toString()+"\"";\r
+ ret = formatValue.arg(name).arg(typeStr).arg(valueStr);\r
+ }\r
+ else {\r
+ ret = formatNoValue.arg(name).arg(typeStr);\r
+ }\r
+ }\r
else {\r
typeStr = getTypeString();\r
if (!userValue.isNull()) {\r
if ((type == Boolean)||(type == Bit)) {\r
ret = format.arg(name).arg("'"+userValue.toString()+"'");\r
}\r
+ else if (type == String) {\r
+ ret = format.arg(name).arg("\""+userValue.toString()+"\"");\r
+ }\r
else {\r
ret = format.arg(name).arg(userValue.toString());\r
}\r
if ((type == Boolean)||(type == Bit)) {\r
ret = format.arg(name).arg("'"+defaultValue.toString()+"'");\r
}\r
+ else if (type == String) {\r
+ ret = format.arg(name).arg("\""+defaultValue.toString()+"\"");\r
+ }\r
else {\r
ret = format.arg(name).arg(defaultValue.toString());\r
}\r
inline bool isConnectedTo(){return connectedTo.length() != 0;}
inline bool isConnectedToMany(){return connectedTo.length()>=2;}
inline bool isConnectedFrom(){return connectedFrom != NULL;}
- virtual bool canConnectTo(AbstractInterface* iface) = 0;
- virtual bool canConnectFrom(AbstractInterface* iface) = 0;
+ virtual bool canConnectTo(AbstractInterface* iface, bool testClock) = 0;
+ virtual bool canConnectFrom(AbstractInterface* iface, bool testClock) = 0;
// others
void resetOutputPattern() { outputPattern = NULL; }
dm2.setNum(delayLength-2);\r
dm3.setNum(delayLength-3);\r
QString ret="";\r
- QString clkName = "clk";\r
- QString resetName = "reset";\r
+ int idClock = toIface->getClockDomain();\r
+ QString clkName = "ext_clk_"+QString::number(idClock);\r
+ QString resetName = "ext_reset_"+QString::number(idClock);\r
if (toIface->getOwner()->getParent()->isTopGroupBlock()) {\r
- clkName = "from_clkrstgen_clk";\r
- resetName ="from_clkrstgen_reset";\r
+ clkName = "from_clkrstgen_"+QString::number(idClock)+"_clk";\r
+ resetName ="from_clkrstgen_"+QString::number(idClock)+"_reset";\r
}\r
\r
if (context == Architecture) {\r
}
bool Dispatcher::createConnection(Context context, InterfaceItem *iface1, InterfaceItem *iface2, bool visible) {
-
+ static QString fctName = "Dispatcher::createConnection()";
+#ifdef DEBUG_FCTNAME
+ cout << "call to " << qPrintable(fctName) << endl;
+#endif
+
+ bool testClock = false;
+ if (context == Design) {
+ testClock = true;
+ }
+
ConnectedInterface* ref1 = iface1->refInter;
ConnectedInterface* ref2 = iface2->refInter;
// connect both interface
bool ok1 = false;
bool ok2 = false;
+ cout << "trying to create a connection between " << qPrintable(ref1->getOwner()->getName()) << "/" << qPrintable(ref1->getName());
+ cout << " and " << qPrintable(ref2->getOwner()->getName()) << "/" << qPrintable(ref2->getName());
+
// test the ref1->ref2 connection
- if ((ref1->canConnectTo(ref2)) && (ref2->canConnectFrom(ref1))) {
+ if ((ref1->canConnectTo(ref2,testClock)) && (ref2->canConnectFrom(ref1,testClock))) {
ref1->connectTo(ref2);
ok1 = true;
}
// if the first one did not work, test ref2->ref1
- if ((ok1 == false) && (ref2->canConnectTo(ref1)) && (ref1->canConnectFrom(ref2))) {
+ if ((ok1 == false) && (ref2->canConnectTo(ref1,testClock)) && (ref1->canConnectFrom(ref2,testClock))) {
ref2->connectTo(ref1);
ok2 = true;
}
if ((ok1 == true) || (ok2 == true)) {
if (ok1) {
- cout << "trying to create a connection from " << qPrintable(ref1->getOwner()->getName()) << "/" << qPrintable(ref1->getName());
+ cout << " ... done with " << qPrintable(ref1->getOwner()->getName()) << "/" << qPrintable(ref1->getName());
cout << " to " << qPrintable(ref2->getOwner()->getName()) << "/" << qPrintable(ref2->getName());
iface1->getOwner()->getScene()->createConnectionItem(iface1,iface2, visible);
}
else {
- cout << "trying to create a connection from " << qPrintable(ref2->getOwner()->getName()) << "/" << qPrintable(ref2->getName());
+ cout << "... done with " << qPrintable(ref2->getOwner()->getName()) << "/" << qPrintable(ref2->getName());
cout << " to " << qPrintable(ref1->getOwner()->getName()) << "/" << qPrintable(ref1->getName());
iface2->getOwner()->getScene()->createConnectionItem(iface2,iface1, visible);
}
- cout << " ... done." << endl;
+ cout << endl;
unselectAllItems(context);
params->unsaveModif = true;
#ifdef DEBUG_FCTNAME
cout << "call to " << qPrintable(fctName) << endl;
#endif
+ /* NB: only called in Design context */
+ if (context != Design) {
+ cout << "Abnormal case: call to " << qPrintable(fctName) << " not in Design context" << endl;
+ return;
+ }
+
QDir baseDir(params->projectPath);
QDir srcDir(params->projectPath+"/src");
#ifdef DEBUG_FCTNAME
cout << "call to " << qPrintable(fctName) << endl;
#endif
+ /* NB: only called in Design context */
+ if (context != Design) {
+ cout << "Abnormal case: call to " << qPrintable(fctName) << " not in Design context" << endl;
+ return;
+ }
+
if (item->getRefBlock()->isFunctionalBlock()) {
FunctionalBlock* block = AB_TO_FUN(item->getRefBlock());
#ifdef DEBUG_FCTNAME
cout << "call to " << qPrintable(fctName) << endl;
#endif
+ /* NB: only called in Design context */
+ if (context != Design) {
+ cout << "Abnormal case: call to " << qPrintable(fctName) << " not in Design context" << endl;
+ return;
+ }
+
GroupWidget* win = item->getScene()->getGroupWidget();
#ifdef DEBUG_FCTNAME
cout << "call to " << qPrintable(fctName) << endl;
#endif
+ /* NB: only called in Design context */
+ if (context != Design) {
+ cout << "Abnormal case: call to " << qPrintable(fctName) << " not in Design context" << endl;
+ return;
+ }
+
GroupWidget* win = item->getScene()->getGroupWidget();
#ifdef DEBUG_FCTNAME
cout << "call to " << qPrintable(fctName) << endl;
#endif
+ /* NB: only called in Design context */
+ if (context != Design) {
+ cout << "Abnormal case: call to " << qPrintable(fctName) << " not in Design context" << endl;
+ return;
+ }
+
GroupWidget* win = item->getScene()->getGroupWidget();
#ifdef DEBUG_FCTNAME
cout << "call to " << qPrintable(fctName) << endl;
#endif
+ /* NB: only called in Design context */
+ if (context != Design) {
+ cout << "Abnormal case: call to " << qPrintable(fctName) << " not in Design context" << endl;
+ return;
+ }
GroupWidget* win = item->getOwner()->getScene()->getGroupWidget();
#ifdef DEBUG_FCTNAME
cout << "call to " << qPrintable(fctName) << endl;
#endif
+ /* NB: only called in Design context */
+ if (context != Design) {
+ cout << "Abnormal case: call to " << qPrintable(fctName) << " not in Design context" << endl;
+ return;
+ }
+
QString msg = "";
if (item->refInter->getDirection() == AbstractInterface::Input) {
msg = "Input pattern of iface ";
#ifdef DEBUG_FCTNAME
cout << "call to " << qPrintable(fctName) << endl;
#endif
+ /* NB: only called in Design context */
+ if (context != Design) {
+ cout << "Abnormal case: call to " << qPrintable(fctName) << " not in Design context" << endl;
+ return;
+ }
+
QString msg = "";
ConnectedInterface* assoIface = AI_TO_CON(item->refInter->getAssociatedIface());
AbstractInputModifier* mod = assoIface->getInputModifier();
}
void Dispatcher::removeModifier(Context context, InterfaceItem *item) {
- static QString fctName = "Dispatcher::showModifier()";
+ static QString fctName = "Dispatcher::removeModifier()";
#ifdef DEBUG_FCTNAME
cout << "call to " << qPrintable(fctName) << endl;
#endif
+ /* NB: only called in Design context */
+ if (context != Design) {
+ cout << "Abnormal case: call to " << qPrintable(fctName) << " not in Design context" << endl;
+ return;
+ }
+
ConnectedInterface* assoIface = AI_TO_CON(item->refInter->getAssociatedIface());
assoIface->clearInputModifier();
#ifdef DEBUG_FCTNAME
cout << "call to " << qPrintable(fctName) << endl;
#endif
+ /* NB: only called in Design context */
+ if (context != Design) {
+ cout << "Abnormal case: call to " << qPrintable(fctName) << " not in Design context" << endl;
+ return;
+ }
+
GroupScene *scene = item->getScene();
AbstractBlock* block = item->getRefBlock();
#ifdef DEBUG_FCTNAME
cout << "call to " << qPrintable(fctName) << endl;
#endif
+ /* NB: only called in Design context */
+ if (context != Design) {
+ cout << "Abnormal case: call to " << qPrintable(fctName) << " not in Design context" << endl;
+ return;
+ }
+
GroupScene *scene = item->getScene();
AbstractBlock* block = item->getRefBlock();
#ifdef DEBUG_FCTNAME
cout << "call to " << qPrintable(fctName) << endl;
#endif
+ /* NB: only called in Design context */
+ if (context != Design) {
+ cout << "Abnormal case: call to " << qPrintable(fctName) << " not in Design context" << endl;
+ return;
+ }
+
AbstractInterface *refI = item->refInter;
if (! refI->isFunctionalInterface()) return;
#ifdef DEBUG_FCTNAME
cout << "call to " << qPrintable(fctName) << endl;
#endif
-
- if (context != Design) return;
+ /* NB: only called in Design context */
+ if (context != Design) {
+ cout << "Abnormal case: call to " << qPrintable(fctName) << " not in Design context" << endl;
+ return;
+ }
/* a BoxItem (group of func) can be removed only if none of its
interfaces is connected to a group interface that is itself
#ifdef DEBUG_FCTNAME
cout << "call to " << qPrintable(fctName) << endl;
#endif
+ /* NB: only called in Design context */
+ if (context != Design) {
+ cout << "Abnormal case: call to " <<qPrintable(fctName) << " not in Design context" << endl;
+ return;
+ }
foreach(InterfaceItem* ifaceItem, item->getInterfaces()) {
foreach(ConnectionItem* conn, ifaceItem->connections) {
#ifdef DEBUG_FCTNAME
cout << "call to " << qPrintable(fctName) << endl;
#endif
+ /* NB: only called in Design context */
+ if (context != Design) {
+ cout << "Abnormal case: call to " <<qPrintable(fctName) << " not in Design context" << endl;
+ return;
+ }
QString msg = "Removing stimmuli ";
#ifdef DEBUG_FCTNAME
cout << "call to " << qPrintable(fctName) << endl;
#endif
+ /* NB: only called in Design context */
+ if (context != Design) {
+ cout << "Abnormal case: call to " <<qPrintable(fctName) << " not in Design context" << endl;
+ return;
+ }
+
InterfaceItem* fromIfaceItem = connItem->getFromInterfaceItem();
InterfaceItem* toIfaceItem = connItem->getToInterfaceItem();
void Dispatcher::connectBoxItemClock(Context context, BoxItem *item, QString clkName, int idGen) throw(Exception) {
+ static QString fctName = "Dispatcher::connectBoxItemClock()";
+#ifdef DEBUG_FCTNAME
+ cout << "call to " << qPrintable(fctName) << endl;
+#endif
+ /* NB: only called in Design context */
+ if (context != Design) {
+ cout << "Abnormal case: call to " <<qPrintable(fctName) << " not in Design context" << endl;
+ return;
+ }
+
InterfaceItem* fromIfaceItemClk = NULL;
InterfaceItem* toIfaceItemClk = item->searchInterfaceItemByName(clkName);
GroupItem* parentGroup = item->getScene()->getGroupItem();
}
void Dispatcher::connectBoxItemReset(Context context, BoxItem *item, QString rstName, int idGen) throw(Exception) {
+
+ static QString fctName = "Dispatcher::connectBoxItemReset()";
+#ifdef DEBUG_FCTNAME
+ cout << "call to " << qPrintable(fctName) << endl;
+#endif
+ /* NB: only called in Design context */
+ if (context != Design) {
+ cout << "Abnormal case: call to " <<qPrintable(fctName) << " not in Design context" << endl;
+ return;
+ }
+
InterfaceItem* fromIfaceItemRst = NULL;
InterfaceItem* toIfaceItemRst = item->searchInterfaceItemByName(rstName);
GroupItem* parentGroup = item->getScene()->getGroupItem();
}
void Dispatcher::connectStimuliItemClock(Context context, StimuliItem *item, QString clkName, int idGen) throw(Exception) {
+
+ static QString fctName = "Dispatcher::connectStimuliItemClock()";
+#ifdef DEBUG_FCTNAME
+ cout << "call to " << qPrintable(fctName) << endl;
+#endif
+ /* NB: only called in Design context */
+ if (context != Design) {
+ cout << "Abnormal case: call to " <<qPrintable(fctName) << " not in Design context" << endl;
+ return;
+ }
+
InterfaceItem* fromIfaceItemClk = NULL;
InterfaceItem* toIfaceItemClk = item->searchInterfaceItemByName(clkName);
BoxItem* clkrstItem = NULL;
}
void Dispatcher::connectStimuliItemReset(Context context, StimuliItem *item, QString rstName, int idGen) throw(Exception) {
+ static QString fctName = "Dispatcher::connectStimuliItemReset()";
+#ifdef DEBUG_FCTNAME
+ cout << "call to " << qPrintable(fctName) << endl;
+#endif
+ /* NB: only called in Design context */
+ if (context != Design) {
+ cout << "Abnormal case: call to " <<qPrintable(fctName) << " not in Design context" << endl;
+ return;
+ }
+
InterfaceItem* fromIfaceItemRst = NULL;
InterfaceItem* toIfaceItemRst = item->searchInterfaceItemByName(rstName);
BoxItem* clkrstItem = NULL;
}
void Dispatcher::showProperties(Context context, InterfaceItem *inter) {
+
+ static QString fctName = "Dispatcher::showProperties()";
+#ifdef DEBUG_FCTNAME
+ cout << "call to " << qPrintable(fctName) << endl;
+#endif
+ /* NB: only called in Design context */
+ if (context != Design) {
+ cout << "Abnormal case: call to " <<qPrintable(fctName) << " not in Design context" << endl;
+ return;
+ }
+
QDialog* dial = new InterfacePropertiesDialog(inter);
dial->exec();
}
*/
void Dispatcher::connectInterToGroup(Context context, InterfaceItem *item){
+ static QString fctName = "Dispatcher::connectInterToGroup()";
+#ifdef DEBUG_FCTNAME
+ cout << "call to " << qPrintable(fctName) << endl;
+#endif
+ /* NB: only called in Design context */
+ if (context != Design) {
+ cout << "Abnormal case: call to " <<qPrintable(fctName) << " not in Design context" << endl;
+ return;
+ }
+
// getting the GroupBlock and GroupItem that are parent of the block that owns item
ConnectedInterface *refInter = item->refInter;
cout << "owner of iface = " << qPrintable(refInter->getOwner()->getName()) << endl;
parentItem->addInterfaceItem(groupIfaceItem,true);
// creating the connection, in graph and with an item
- createConnection(context, item, groupIfaceItem);
+ /* NOTE:
+ Since the group interface is for now unconnected, it is impossible to determine
+ its clock domain. Thus, the connection must be created without testing the clock domain
+ consistency. For that, we cheat by changing the context to Load because it implies no clock test.
+ */
+ createConnection(Load, item, groupIfaceItem);
// if groupItem is not topGroup, must also add a new interface to the parent BlockItem
BoxItem* parent2Item = parentItem->getParentItem();
#ifdef DEBUG_FCTNAME
cout << "call to " << qPrintable(fctName) << endl;
#endif
+ /* NB: only called in Design context */
+ if (context != Design) {
+ cout << "Abnormal case: call to " <<qPrintable(fctName) << " not in Design context" << endl;
+ return;
+ }
/* first, remove all connections from item
NB: if there is a connection to a group interface, then this
#ifdef DEBUG_FCTNAME
cout << "call to " << qPrintable(fctName) << endl;
#endif
+ /* NB: only called in Design context */
+ if (context != Design) {
+ cout << "Abnormal case: call to " <<qPrintable(fctName) << " not in Design context" << endl;
+ return;
+ }
/* NB: just remove all connections from/to this item, since when there are no more
ones to a GroupItem, it is automatically deleted.
#ifdef DEBUG_FCTNAME
cout << "call to " << qPrintable(fctName) << endl;
#endif
+ /* NB: only called in Design context */
+ if (context != Design) {
+ cout << "Abnormal case: call to " <<qPrintable(fctName) << " not in Design context" << endl;
+ return;
+ }
block->computeAdmittanceDelays();
// get the block item that is associated to block
QDomElement eltModif = nodeModif.toElement();\r
}\r
out << "-- Description : " << endl;\r
- out << reference->getDescription() << endl;\r
+ QStringList lines = reference->getDescription().split("\n");\r
+ foreach(QString line, lines) {\r
+ out << "-- " << line << endl;\r
+ }\r
out << "--" << endl;\r
QDomElement eltNote = eltLog.nextSiblingElement("notes");\r
QDomElement note = eltNote.firstChildElement();\r
QString noteTxt = note.text();\r
- out << "-- Notes :\n"<<noteTxt<<endl;\r
+ out << "-- Notes :" << endl;\r
+ lines = noteTxt.split("\n");\r
+ foreach(QString line, lines) {\r
+ out << "-- " << line << endl;\r
+ }\r
out << "--" << endl;\r
for(int i = 0; i < 50; i++) {\r
out << "--";\r
\r
// testers\r
bool isFunctionalBlock();\r
- bool isStimuliBlock(); //! a stimuli block has no parent and has no data inputs\r
+ bool isStimuliBlock(); //! a stimuli block has no parent and is out of the top group\r
\r
// others\r
\r
width = reference->getWidthString();\r
direction = reference->getDirection();\r
purpose = reference->getPurpose(); \r
- connectedFrom = NULL; \r
+ connectedFrom = NULL;\r
+ clkIfaceName = reference->getClockIfaceString();\r
+ clkIfaceType = reference->getClockIfaceType();\r
}\r
\r
bool FunctionalInterface::isFunctionalInterface() {\r
return inter;\r
}\r
\r
-bool FunctionalInterface::canConnectTo(AbstractInterface *iface) {\r
+bool FunctionalInterface::canConnectTo(AbstractInterface *iface, bool testClock) {\r
+ static QString fctName = "FunctionalInterface::canConnectTo()";\r
+#ifdef DEBUG_FCTNAME\r
+ cout << "call to " << qPrintable(fctName) << endl;\r
+#endif\r
+\r
\r
/* NOTE :\r
necessary conditions :\r
2.2 - both are inout\r
3 - this is owned by a source block and iface is owned by the top group\r
\r
+ + if testClock is true, must test if both ifaces are in the same clock domain. Note that a group interface\r
+ has always\r
special case : clk/reset from clkrstgen can connect to stimuli clk/reset\r
\r
*/\r
+ bool ok = false;\r
+\r
if (direction == Input) return false;\r
if (iface->isReferenceInterface()) return false;\r
ConnectedInterface* connIface = AI_TO_CON(iface);\r
if (connIface->getConnectedFrom() != NULL) return false;\r
- // special case\r
+\r
+ // special case, NB: never tests clocks\r
if ((getOwner()->getName().startsWith("clkrstgen")) && (iface->getOwner()->isStimuliBlock())) {\r
if ((direction == Output) && (iface->getDirection() == Input)) {\r
if ((purpose == AbstractInterface::Clock) && (iface->getPurpose() == AbstractInterface::Clock)) return true;\r
// first case: interface of blocks within the same group\r
if (getOwner()->getParent() == iface->getOwner()->getParent()) {\r
\r
- if ((direction == Output) && (iface->getDirection() == Input) && (purpose == iface->getPurpose())) return true;\r
- if ((direction == InOut) && (iface->getDirection() == InOut) && (purpose == iface->getPurpose())) return true;\r
+\r
+\r
+ if ((direction == Output) && (iface->getDirection() == Input) && (purpose == iface->getPurpose())) ok = true;\r
+ if ((direction == InOut) && (iface->getDirection() == InOut) && (purpose == iface->getPurpose())) ok = true;\r
}\r
// second case: iface = interface of the group that contains owner of this\r
else if (getOwner()->getParent() == iface->getOwner()) {\r
- if ((direction == Output) && (iface->getDirection() == Output) && (purpose == iface->getPurpose())) return true;\r
- if ((direction == InOut) && (iface->getDirection() == InOut) && (purpose == iface->getPurpose())) return true;\r
+ if ((direction == Output) && (iface->getDirection() == Output) && (purpose == iface->getPurpose())) ok = true;\r
+ if ((direction == InOut) && (iface->getDirection() == InOut) && (purpose == iface->getPurpose())) ok = true;\r
}\r
else if ((getOwner()->isStimuliBlock()) && (iface->getOwner()->isTopGroupBlock())) {\r
- if ((direction == Output) && (iface->getDirection() == Input) && (purpose == iface->getPurpose())) return true;\r
+ if ((direction == Output) && (iface->getDirection() == Input) && (purpose == iface->getPurpose())) ok = true;\r
}\r
\r
+ if (ok) {\r
+ if (testClock) {\r
+ int dom1 = -1,dom2 = -2;\r
+ try {\r
+ dom1 = getClockDomain();\r
+ dom2 = iface->getClockDomain();\r
+ }\r
+ catch(Exception e) {\r
+ cerr << qPrintable(fctName) << " - " << qPrintable(e.getMessage()) << endl;\r
+ return false;\r
+ }\r
+ if (dom1 != dom2) {\r
+ cout << "cannot connect interface that are in different clock domains" << endl;\r
+ return false;\r
+ }\r
+ }\r
+ return true;\r
+ }\r
return false;\r
\r
}\r
\r
-bool FunctionalInterface::canConnectFrom(AbstractInterface *iface) {\r
+bool FunctionalInterface::canConnectFrom(AbstractInterface *iface, bool testClock) {\r
+\r
+ static QString fctName = "FunctionalInterface::canConnectFrom()";\r
+#ifdef DEBUG_FCTNAME\r
+ cout << "call to " << qPrintable(fctName) << endl;\r
+#endif\r
\r
/* NOTE :\r
necessary conditions :\r
\r
special case : clk/reset of stimuli can connect from clk/reset of clkrstgen\r
*/\r
+ bool ok = false;\r
+\r
if (direction == Output) return false;\r
if (iface->isReferenceInterface()) return false;\r
if (connectedFrom != NULL) return false;\r
\r
- // special case\r
+ // special case, NB: never tests clock\r
if ((iface->getOwner()->getName().startsWith("clkrstgen")) && (getOwner()->isStimuliBlock())) {\r
if ((direction == Input) && (iface->getDirection() == Output)) {\r
if ((purpose == AbstractInterface::Clock) && (iface->getPurpose() == AbstractInterface::Clock)) return true;\r
}\r
}\r
\r
- if (getOwner()->getParent() == iface->getOwner()->getParent()) {\r
-\r
- if ((direction == Input) && (iface->getDirection() == Output) && (purpose == iface->getPurpose())) return true;\r
- if ((direction == InOut) && (iface->getDirection() == InOut) && (purpose == iface->getPurpose())) return true;\r
+ if (getOwner()->getParent() == iface->getOwner()->getParent()) { \r
+ if ((direction == Input) && (iface->getDirection() == Output) && (purpose == iface->getPurpose())) ok = true;\r
+ if ((direction == InOut) && (iface->getDirection() == InOut) && (purpose == iface->getPurpose())) ok = true;\r
}\r
else if (getOwner()->getParent() == iface->getOwner()) {\r
- if ((direction == Input) && (iface->getDirection() == Input) && (purpose == iface->getPurpose())) return true;\r
- if ((direction == InOut) && (iface->getDirection() == InOut) && (purpose == iface->getPurpose())) return true;\r
+ if ((direction == Input) && (iface->getDirection() == Input) && (purpose == iface->getPurpose())) ok = true;\r
+ if ((direction == InOut) && (iface->getDirection() == InOut) && (purpose == iface->getPurpose())) ok = true;\r
+ }\r
+\r
+ if (ok) {\r
+ if (testClock) {\r
+ int dom1 = -1,dom2 = -2;\r
+ try {\r
+ dom1 = getClockDomain();\r
+ dom2 = iface->getClockDomain();\r
+ }\r
+ catch(Exception e) {\r
+ cerr << qPrintable(e.getMessage()) << endl;\r
+ return false;\r
+ }\r
+ if (dom1 != dom2) {\r
+ cout << "cannot connect interfaces that are in different clock domains" << endl;\r
+ return false;\r
+ }\r
+ }\r
+ return true;\r
}\r
\r
return false;\r
if (connFrom == NULL) throw(Exception(IFACE_INVALID_CLKFREQ,this));\r
\r
if (connFrom->getOwner()->isFunctionalBlock()) {\r
- QString name = connFrom->getOwner()->getName();\r
- cout << "conn from clkrstgen: searching for clkdomain in " << qPrintable(name) << endl;\r
- name.remove(0,10);\r
- bool ok;\r
- idClock = name.toInt(&ok);\r
+ QString domName = connFrom->getOwner()->getName();\r
+ domName.remove(0,10);\r
+ cout << "conn from clkrstgen: searching for clkdomain in " << qPrintable(domName) << endl;\r
+\r
+ bool ok = true;\r
+ idClock = domName.toInt(&ok);\r
+ cout << "id clock = " << idClock << endl;\r
if (!ok) throw(Exception(IFACE_INVALID_CLKFREQ,this));\r
}\r
- else {\r
- QString name = connFrom->getName();\r
- cout << "conn from group: searching for clkdomain in " << qPrintable(name) << endl;\r
- name.remove(0,8);\r
- bool ok;\r
- idClock = name.toInt(&ok);\r
+ else if (connFrom->getOwner()->isGroupBlock()) {\r
+ QString domName = connFrom->getName();\r
+ domName.remove(0,8);\r
+ cout << "conn from group: searching for clkdomain in " << qPrintable(domName) << endl;\r
+\r
+ bool ok = true;\r
+ idClock = domName.toInt(&ok);\r
if (!ok) throw(Exception(IFACE_INVALID_CLKFREQ,this));\r
}\r
+ else {\r
+ cout << "abnormal case while searching for clkdomain" << endl;\r
+ }\r
}\r
\r
return idClock;\r
\r
// testers\r
bool isFunctionalInterface();\r
- bool canConnectTo(AbstractInterface* iface);\r
- bool canConnectFrom(AbstractInterface* iface);\r
+ bool canConnectTo(AbstractInterface* iface, bool testClock);\r
+ bool canConnectFrom(AbstractInterface* iface, bool testClock);\r
\r
// others\r
\r
#include "ReferenceBlock.h"
#include "FunctionalBlock.h"
#include "SpecialBlock.h"
+#include "BlockParameter.h"
+#include "ConnectedInterface.h"
Graph::Graph() {
topGroup = NULL;
out << "use IEEE.numeric_std.all;" << endl;
out << "entity " << projectName << "_tb is" << endl;
out << "end entity " << projectName << "_tb;" << endl << endl;
+
out << "architecture " << projectName << "_tb_1 of " << projectName << "_tb is" << endl << endl;
out << " component clock_gen" << endl;
out << " end component;" << endl << endl;
topGroup->generateComponent(out,false);
+ foreach(FunctionalBlock* block, stimulis) {
+ block->generateComponent(out,false);
+ }
+
+ out << " ----------------------------" << endl;
+ out << " -- SIGNALS" << endl;
+ out << " ----------------------------" << endl << endl;
+
+ out << " -- signals to reset stimulis" << endl;
+ foreach(FunctionalBlock* block, stimulis) {
+ out << " signal reset_" << block->getName() << " : std_logic;" << endl;
+ }
+ out << endl;
+
+ out << " -- signals for external clocks/reset" << endl;
+ for(int i=0;i<clocks.size();i++) {
+ out << " signal ext_clk_" << i << " : std_logic;" << endl;
+ out << " signal ext_reset_" << i << " : std_logic;" << endl;
+ }
+ out << endl;
+
+ // signals out of stimulis blocks
+ foreach(FunctionalBlock* block, stimulis) {
+ /* NB: normally, a stimuli has at least an input interface of type data
+ that is used to trigger the generation. It is necessarily called start.
+ It may have an additional input that is necessarily called stop.
+ */
+ try {
+ out << " -- signals from input ports of " << block->getName() << endl;
+ QList<AbstractInterface*> listInputs = block->getInputs();
+ foreach(AbstractInterface* iface, listInputs) {
+ if (iface->getPurpose() == AbstractInterface::Data) {
+ out << " signal " << iface->toVHDL(AbstractInterface::Signal,0) << endl;
+ }
+ }
+ }
+ catch(Exception e) {
+ throw(e);
+ }
+ try {
+ out << " -- signals from output ports of " << block->getName() << endl;
+ QList<AbstractInterface*> listOutputs = block->getOutputs();
+ foreach(AbstractInterface* iface, listOutputs) {
+ if ((iface->getPurpose() == AbstractInterface::Data)||(iface->getPurpose() == AbstractInterface::Control)) {
+ out << " signal " << iface->toVHDL(AbstractInterface::Signal,0) << endl;
+ }
+ }
+ }
+ catch(Exception e) {
+ throw(e);
+ }
+ out << endl;
+ }
+ out << endl;
+
+ // signals out of top group
+ try {
+ out << " -- signals from output ports of " << topGroup->getName() << endl;
+ QList<AbstractInterface*> listOutputs = topGroup->getOutputs();
+ foreach(AbstractInterface* iface, listOutputs) {
+ if ((iface->getPurpose() == AbstractInterface::Data)||(iface->getPurpose() == AbstractInterface::Control)) {
+ out << " signal " << iface->toVHDL(AbstractInterface::Signal,0) << endl;
+ }
+ }
+ }
+ catch(Exception e) {
+ throw(e);
+ }
+ out << endl;
+
+ // signals out of top group
+ try {
+ out << " -- signals from inout ports of " << topGroup->getName() << endl;
+ QList<AbstractInterface*> listBidirs = topGroup->getBidirs();
+ foreach(AbstractInterface* iface, listBidirs) {
+ if (iface->getPurpose() == AbstractInterface::Data) {
+ out << " signal " << iface->toVHDL(AbstractInterface::Signal,0) << endl;
+ }
+ }
+ }
+ catch(Exception e) {
+ throw(e);
+ }
+ out << endl;
+
+ out << "begin" << endl;
+ // for now assign all external resets to fixed 0 because of clkrstgen in top group
+ for(int i=0;i<clocks.size();i++) {
+ out << " ext_reset_" << i << " <= '0';" << endl;
+ }
+ out << endl;
+ // generate clock instances
+ for(int i=0;i<clocks.size();i++) {
+ double halfPer = 500.0/clocks.at(i);
+ out << " clock_" << i << " : clock_gen" << endl;
+ out << " generic map (" << endl;
+ out << " Tps => " << halfPer << " ns" << endl;
+ out << " )" << endl;
+ out << " port map (" << endl;
+ out << " phase => ext_clk_" << i << endl;
+ out << " );" << endl << endl;
+ }
+ // generate instances of stimulis
+ foreach(FunctionalBlock* block, stimulis) {
+ try {
+ out << " " << block->getName() << "_1 : " << block->getName() << endl;
+
+ QList<BlockParameter*> listGenerics = block->getGenericParameters();
+ QList<AbstractInterface*> listInputs = block->getInputs();
+ QList<AbstractInterface*> listOutputs = block->getOutputs();
+
+ if (!listGenerics.isEmpty()) {
+ out << " generic map (" << endl;
+ int i;
+ for(i=0;i<listGenerics.size()-1;i++) {
+ out << " " << listGenerics.at(i)->toVHDL(BlockParameter::Instance, BlockParameter::NoComma) << "," << endl;
+ }
+ out << " " << listGenerics.at(i)->toVHDL(BlockParameter::Instance,BlockParameter::NoComma) << endl;
+ out << " )" << endl;
+ }
+
+ out << " port map (" << endl;
+ QString portMap = "";
+
+ for(int i=0;i<listInputs.size();i++) {
+ ConnectedInterface* connIface = AI_TO_CON(listInputs.at(i));
+ if ( (connIface->getPurpose() == AbstractInterface::Data) || (connIface->getPurpose() == AbstractInterface::Control)) {
+ portMap += " " + connIface->getName() + " => " + connIface->toVHDL(AbstractInterface::Instance, AbstractInterface::NoComma) + ",\n";
+ }
+ else if (connIface->getPurpose() == AbstractInterface::Clock) {
+ // get the "fake" clkrstgen from which it is connected
+ ConnectedInterface* fromIface = connIface->getConnectedFrom();
+ QString clkrstName = fromIface->getOwner()->getName();
+ clkrstName.remove(0,10);
+ portMap += " " + connIface->getName() + " => ext_clk_" + clkrstName + ",\n";
+ }
+ else if (connIface->getPurpose() == AbstractInterface::Reset) {
+ portMap += " " + connIface->getName() + " => reset_" + block->getName()+",\n";
+ }
+ }
+ for(int i=0;i<listOutputs.size();i++) {
+ ConnectedInterface* connIface = AI_TO_CON(listOutputs.at(i));
+ portMap += " " + connIface->getName() + " => " + connIface->toVHDL(AbstractInterface::Instance, AbstractInterface::NoComma) + ",\n";
+ }
+ portMap.chop(2);
+ out << portMap << endl;
+
+
+ out << " );" << endl;
+ }
+ catch(Exception e) {
+ throw(e);
+ }
+ out << endl;
+ }
+ out << endl;
+ // generate instance of top group
+ try {
+ out << " " << topGroup->getName() << "_1 : " << topGroup->getName() << endl;
+
+ QList<BlockParameter*> listGenerics = topGroup->getGenericParameters();
+ QList<AbstractInterface*> listInputs = topGroup->getInputs();
+ QList<AbstractInterface*> listOutputs = topGroup->getOutputs();
+ QList<AbstractInterface*> listBidirs = topGroup->getBidirs();
+
+ if (!listGenerics.isEmpty()) {
+ out << " generic map (" << endl;
+ int i;
+ for(i=0;i<listGenerics.size()-1;i++) {
+ out << " " << listGenerics.at(i)->toVHDL(BlockParameter::Instance, BlockParameter::NoComma) << "," << endl;
+ }
+ out << " " << listGenerics.at(i)->toVHDL(BlockParameter::Instance,BlockParameter::NoComma) << endl;
+ out << " )" << endl;
+ }
+
+ out << " port map (" << endl;
+ QString portMap = "";
+
+ for(int i=0;i<listInputs.size();i++) {
+ ConnectedInterface* connIface = AI_TO_CON(listInputs.at(i));
+ if ( (connIface->getPurpose() == AbstractInterface::Data) || (connIface->getPurpose() == AbstractInterface::Control)) {
+ ConnectedInterface* fromIface = connIface->getConnectedFrom();
+ portMap += " " + connIface->getName() + " => " + fromIface->toVHDL(AbstractInterface::Instance, AbstractInterface::NoComma) + ",\n";
+ }
+ else if ( (connIface->getPurpose() == AbstractInterface::Clock) || (connIface->getPurpose() == AbstractInterface::Reset)) {
+ portMap += " " + connIface->getName() + " => " + connIface->getName() + ",\n";
+ }
+ }
+ for(int i=0;i<listOutputs.size();i++) {
+ ConnectedInterface* connIface = AI_TO_CON(listOutputs.at(i));
+ portMap += " " + connIface->getName() + " => " + connIface->toVHDL(AbstractInterface::Instance, AbstractInterface::NoComma) + ",\n";
+ }
+ for(int i=0;i<listBidirs.size();i++) {
+ ConnectedInterface* connIface = AI_TO_CON(listBidirs.at(i));
+ portMap += " " + connIface->getName() + " => " + connIface->toVHDL(AbstractInterface::Instance, AbstractInterface::NoComma) + ",\n";
+ }
+ portMap.chop(2);
+ out << portMap << endl;
+
+
+ out << " );" << endl;
+ }
+ catch(Exception e) {
+ throw(e);
+ }
+ out << endl;
+
+ // generate process for stimulis
+ foreach(FunctionalBlock* block, stimulis) {
+ // getting the start input
+ AbstractInterface* startIface = block->getIfaceFromName("start");
+ if (startIface == NULL) continue;
+ double per = 1000.0/startIface->getClockFrequency();
+ QString startName = block->getName()+"_start";
+ out << " from_" << block->getName() << " : process" << endl;
+ out << " variable pclk : time := " << per << " ns;" << endl;
+ out << " begin" << endl;
+ out << " reset_" << block->getName() << " <= '0';" << endl;
+ out << " " << startName << " <= '0';" << endl;
+ out << " wait for 2*pclk;" << endl;
+ out << " reset_" << block->getName() << " <= '1';" << endl;
+ out << " wait for 1*pclk;" << endl;
+ out << " reset_" << block->getName() << " <= '0';" << endl;
+ out << " wait for 5*pclk;" << endl;
+ out << " " << startName << " <= '1';" << endl;
+ out << " wait for pclk;" << endl;
+ out << " " << startName << " <= '0';" << endl << endl;
+ out << " wait for 100000 us;" << endl;
+ out << " end process from_" << block->getName() << ";" << endl;
+ }
+ out << "end architecture " << projectName << "_tb_1;" << endl;
vhdlBench.close();
}
#include <sstream>
#include "Parameters.h"
#include "DelayInputModifier.h"
+#include "Graph.h"
int GroupBlock::counter = 1;
out << " -- SIGNALS" << endl;
out << " ----------------------------" << endl << endl;
- // signals to synchronize inputs
- out << " -- signals to synchronize inputs" << endl;
- foreach(AbstractInterface* iface, getInputs()) {
- if ((iface->getPurpose() == AbstractInterface::Data)||(iface->getPurpose() == AbstractInterface::Control)) {
- QString name = iface->toVHDL(AbstractInterface::Signal,0);
- name.replace(" : ","_sync : ");
- out << " signal " << name<< endl;
+ // if this is top group, signals to synchronize inputs
+ if (topGroup) {
+ out << " -- signals to synchronize inputs" << endl;
+ foreach(AbstractInterface* iface, getInputs()) {
+ if ((iface->getPurpose() == AbstractInterface::Data)||(iface->getPurpose() == AbstractInterface::Control)) {
+ QString name = iface->toVHDL(AbstractInterface::Signal,0);
+ name.replace(" : ","_sync : ");
+ out << " signal " << name<< endl;
+ }
}
+ out << endl;
}
- out << endl;
// "normal" signals
foreach(AbstractBlock* block, blocks) {
if ((iface->getPurpose() == AbstractInterface::Data)||(iface->getPurpose() == AbstractInterface::Control)) {
out << " signal " << iface->toVHDL(AbstractInterface::Signal,0) << endl;
}
- else if (block->getName() == "clkrstgen") {
+ else if (block->getName().startsWith("clkrstgen")) {
if ((iface->getPurpose() == AbstractInterface::Clock)||(iface->getPurpose() == AbstractInterface::Reset)) {
out << " signal " << iface->toVHDL(AbstractInterface::Signal,0) << endl;
}
}
if (topGroup) {
- // generate input sync process
+ // generate input sync process for each clock domain
out << " -- process to synchronize inputs of top group" << endl;
- out << "sync_inputs : process(from_clkrstgen_clk,from_clkrstgen_reset)" << endl;
- out << " begin" << endl;
- out << " if from_clkrstgen_reset = '1' then" << endl;
- foreach(AbstractInterface* iface, getInputs()) {
- if ((iface->getPurpose() == AbstractInterface::Data)||(iface->getPurpose() == AbstractInterface::Control)) {
- if (iface->getWidth() == 0) {
- out << " " << name << "_" << iface->getName() << "_sync <= '0';" << endl;
- }
- else {
- out << " " << name << "_" << iface->getName() << "_sync <= (others => '0');" << endl;
+ for(int i=0;i<graph->getClocks().size();i++) {
+ // check if there are some inputs that must be sync with clock domain i
+ bool mustSync = false;
+ foreach(AbstractInterface* iface, getInputs()) {
+ if ((iface->getPurpose() == AbstractInterface::Data)||(iface->getPurpose() == AbstractInterface::Control)) {
+ if (iface->getClockDomain() == i) {
+ mustSync = true;
+ break;
+ }
}
}
- }
- out << " elsif rising_edge(from_clkrstgen_clk) then" << endl;
- foreach(AbstractInterface* iface, getInputs()) {
- if ((iface->getPurpose() == AbstractInterface::Data)||(iface->getPurpose() == AbstractInterface::Control)) {
- if (iface->getWidth() == 0) {
- out << " " << name << "_" << iface->getName() << "_sync <= " << iface->getName() << ";" << endl;
+ if (mustSync) {
+ out << "sync_inputs_" << i << " : process(from_clkrstgen_" << i << "_clk,from_clkrstgen_" << i << "_reset)" << endl;
+ out << " begin" << endl;
+ out << " if from_clkrstgen_" << i << "_reset = '1' then" << endl;
+ foreach(AbstractInterface* iface, getInputs()) {
+ if ((iface->getPurpose() == AbstractInterface::Data)||(iface->getPurpose() == AbstractInterface::Control)) {
+ if (iface->getClockDomain() == i) {
+ if (iface->getWidth() == 0) {
+ out << " " << name << "_" << iface->getName() << "_sync <= '0';" << endl;
+ }
+ else {
+ out << " " << name << "_" << iface->getName() << "_sync <= (others => '0');" << endl;
+ }
+ }
+ }
}
- else {
- out << " " << name << "_" << iface->getName() << "_sync <= " << iface->getName() << ";" << endl;
+ out << " elsif rising_edge(from_clkrstgen_" << i << "_clk) then" << endl;
+ foreach(AbstractInterface* iface, getInputs()) {
+ if ((iface->getPurpose() == AbstractInterface::Data)||(iface->getPurpose() == AbstractInterface::Control)) {
+ if (iface->getClockDomain() == i) {
+ if (iface->getWidth() == 0) {
+ out << " " << name << "_" << iface->getName() << "_sync <= " << iface->getName() << ";" << endl;
+ }
+ else {
+ out << " " << name << "_" << iface->getName() << "_sync <= " << iface->getName() << ";" << endl;
+ }
+ }
+ }
}
+ out << " end if;" << endl;
+ out << " end process sync_inputs_" << i << ";" << endl;
+
+ out << endl;
}
}
- out << " end if;" << endl;
- out << " end process sync_inputs;" << endl;
-
- out << endl;
}
out << "end architecture rtl;" << endl;
if ((purpose == Clock) || (purpose == Reset)) {
type = Boolean;
}
+ clkIfaceType = InheritedName;
}
bool GroupInterface::isGroupInterface() {
return w;
}
-bool GroupInterface::canConnectTo(AbstractInterface *iface) {
+bool GroupInterface::canConnectTo(AbstractInterface *iface, bool testClock) {
/* NOTE :
necessary conditions :
2.1 - this is an output, iface is an output of the group
2.2 - both are inout
-
+ NB: testClock is useless since a group interface has always a clkIfaceType inherited.
+ Thus, it is always possible
*/
+ bool ok = false;
+
if (iface->isReferenceInterface()) return false;
ConnectedInterface* connIface = AI_TO_CON(iface);
if (connIface->getConnectedFrom() != NULL) return false;
if (this->getOwner() == iface->getOwner()->getParent()) {
- if ((direction == Input) && (iface->getDirection() == Input) && (purpose == iface->getPurpose())) return true;
- if ((direction == InOut) && (iface->getDirection() == InOut) && (purpose == iface->getPurpose())) return true;
+ if ((direction == Input) && (iface->getDirection() == Input) && (purpose == iface->getPurpose())) ok = true;
+ if ((direction == InOut) && (iface->getDirection() == InOut) && (purpose == iface->getPurpose())) ok = true;
}
else if (this->getOwner()->getParent() == iface->getOwner()->getParent()) {
- if ((direction == Output) && (iface->getDirection() == Input) && (purpose == iface->getPurpose())) return true;
- if ((direction == InOut) && (iface->getDirection() == InOut) && (purpose == iface->getPurpose())) return true;
+ if ((direction == Output) && (iface->getDirection() == Input) && (purpose == iface->getPurpose())) ok = true;
+ if ((direction == InOut) && (iface->getDirection() == InOut) && (purpose == iface->getPurpose())) ok = true;
}
else if (this->getOwner()->getParent() == iface->getOwner()) {
- if ((direction == Output) && (iface->getDirection() == Output) && (purpose == iface->getPurpose())) return true;
- if ((direction == InOut) && (iface->getDirection() == InOut) && (purpose == iface->getPurpose())) return true;
+ if ((direction == Output) && (iface->getDirection() == Output) && (purpose == iface->getPurpose())) ok = true;
+ if ((direction == InOut) && (iface->getDirection() == InOut) && (purpose == iface->getPurpose())) ok = true;
}
+ if (ok) {
+ if (testClock) {
+ int dom1 = -1,dom2 = -2;
+ try {
+ dom1 = getClockDomain();
+ dom2 = iface->getClockDomain();
+ }
+ catch(Exception e) {
+ cerr << qPrintable(e.getMessage()) << endl;
+ return false;
+ }
+ if (dom1 != dom2) {
+ cout << "cannot connect interface that are in different clock domains" << endl;
+ return false;
+ }
+ }
+ return true;
+ }
return false;
}
-bool GroupInterface::canConnectFrom(AbstractInterface *iface) {
+bool GroupInterface::canConnectFrom(AbstractInterface *iface, bool testClock) {
/* NOTE :
necessary conditions :
2.2 - both are inout
4 - this is owned by top group and iface is an output of a source block
*/
+ bool ok = false;
+
if (iface->isReferenceInterface()) return false;
if (getConnectedFrom() != NULL) return false;
if (this->getOwner() == iface->getOwner()->getParent()) {
- if ((direction == Output) && (iface->getDirection() == Output) && (purpose == iface->getPurpose())) return true;
- if ((direction == InOut) && (iface->getDirection() == InOut) && (purpose == iface->getPurpose())) return true;
+ if ((direction == Output) && (iface->getDirection() == Output) && (purpose == iface->getPurpose())) ok = true;
+ if ((direction == InOut) && (iface->getDirection() == InOut) && (purpose == iface->getPurpose())) ok = true;
}
else if (this->getOwner()->getParent() == iface->getOwner()->getParent()) {
- if ((direction == Input) && (iface->getDirection() == Output) && (purpose == iface->getPurpose())) return true;
- if ((direction == InOut) && (iface->getDirection() == InOut) && (purpose == iface->getPurpose())) return true;
+ if ((direction == Input) && (iface->getDirection() == Output) && (purpose == iface->getPurpose())) ok = true;
+ if ((direction == InOut) && (iface->getDirection() == InOut) && (purpose == iface->getPurpose())) ok = true;
}
else if (this->getOwner()->getParent() == iface->getOwner()) {
- if ((direction == Input) && (iface->getDirection() == Input) && (purpose == iface->getPurpose())) return true;
- if ((direction == InOut) && (iface->getDirection() == InOut) && (purpose == iface->getPurpose())) return true;
+ if ((direction == Input) && (iface->getDirection() == Input) && (purpose == iface->getPurpose())) ok = true;
+ if ((direction == InOut) && (iface->getDirection() == InOut) && (purpose == iface->getPurpose())) ok = true;
}
else if ((getOwner()->isTopGroupBlock()) && (iface->getOwner()->isStimuliBlock())) {
- if ((direction == Input) && (iface->getDirection() == Output) && (purpose == iface->getPurpose())) return true;
+ if ((direction == Input) && (iface->getDirection() == Output) && (purpose == iface->getPurpose())) ok = true;
+ }
+
+ if (ok) {
+ if (testClock) {
+ int dom1 = -1,dom2 = -2;
+ try {
+ dom1 = getClockDomain();
+ dom2 = iface->getClockDomain();
+ }
+ catch(Exception e) {
+ cerr << qPrintable(e.getMessage()) << endl;
+ return false;
+ }
+ if (dom1 != dom2) {
+ cout << "cannot connect interface that are in different clock domains" << endl;
+ return false;
+ }
+ }
+ return true;
}
return false;
int GroupInterface::getClockDomain() throw(Exception) {
+ /* For clk/rst interfaces, the clock domain can be deduced
+ from the interface name.
+ Otherwise, we can search backward/forward for a functional
+ interface. Since a group interface cannot exist if it is not
+ connected to and/or from a functional interface (either directly
+ or through a sequence of subgroups) there is at least such a functional
+ interface.
+ */
int idClock = -1;
-
- GroupInterface* iface = NULL;
- if (clkIfaceType == ClockName) {
- iface = AI_TO_GRP(getClockIface());
- }
- else if ((direction == Input) && (purpose == Clock)) {
- iface = this;
- }
-
- if ( iface != NULL) {
-
- QString name = iface->getName();
- name.remove(0,8);
+ if ((purpose == Clock) || (purpose == Reset)) {
+ QString domName = name;
+ domName.remove(0,8);
bool ok;
- idClock = name.toInt(&ok);
+ idClock = domName.toInt(&ok);
if (!ok) throw(Exception(IFACE_INVALID_CLKFREQ,this));
-
+ }
+ else {
+ // start by searching backward
+ ConnectedInterface* connFrom = connectedFrom;
+ while ((connFrom != NULL) && (connFrom->isGroupInterface())) {
+ connFrom = connFrom->getConnectedFrom();
+ }
+ if (connFrom != NULL) {
+ idClock = connFrom->getClockDomain();
+ }
+ //searching forward
+ else {
+ QList<ConnectedInterface*> lstIfaces = getForwardFunctionalInterfaces(this);
+ if (lstIfaces.isEmpty()) throw(Exception(IFACE_INVALID_CLKFREQ,this));
+ foreach(ConnectedInterface* iface, lstIfaces) {
+ // test if all ifaces are in the same clock domain
+ if (idClock == -1) {
+ idClock = iface->getClockDomain();
+ }
+ else if (idClock != iface->getClockDomain()) throw(Exception(IFACE_INVALID_CLKFREQ,this));
+ }
+ }
}
return idClock;
}
+QList<ConnectedInterface*> GroupInterface::getForwardFunctionalInterfaces(GroupInterface* groupIface) {
+ QList<ConnectedInterface*> lstIfaces;
+ foreach(ConnectedInterface* iface, groupIface->getConnectedTo()) {
+ if (iface->isFunctionalInterface()) {
+ lstIfaces.append(iface);
+ }
+ else if (iface->isGroupInterface()) {
+ lstIfaces.append(getForwardFunctionalInterfaces(AI_TO_GRP(iface)));
+ }
+ }
+ return lstIfaces;
+}
void GroupInterface::connectionsValidation(QStack<AbstractInterface*> *interfacetoValidate, QList<AbstractInterface*> *validatedInterfaces) throw(Exception) {
cout << "group interface connection validation" << endl;
#include "Exception.h"
class Exception;
+
using namespace std;
using namespace Qt;
// testers
bool isGroupInterface();
- bool canConnectTo(AbstractInterface* iface);
- bool canConnectFrom(AbstractInterface* iface);
+ bool canConnectTo(AbstractInterface* iface, bool testClock);
+ bool canConnectFrom(AbstractInterface* iface, bool testClock);
// others
AbstractInterface *clone();
+ QList<ConnectedInterface *> getForwardFunctionalInterfaces(GroupInterface* groupIface);
+
void connectionsValidation(QStack<AbstractInterface *> *interfacetoValidate, QList<AbstractInterface *> *validatedInterfaces) throw(Exception);
};
layProp->addWidget(new QLabel(inter->refInter->getPurposeString()), 5, 1);
layProp->addWidget(new QLabel("Type :"), 6, 0);
layProp->addWidget(new QLabel(inter->refInter->getTypeString()), 6, 1);
+ layProp->addWidget(new QLabel("related to clock :"), 7, 0);
+ layProp->addWidget(new QLabel(inter->refInter->getClockIfaceString()), 7, 1);
QHBoxLayout* layBottom = new QHBoxLayout;
layBottom->addStretch();
params->save(projectFile);
}
-void MainWindow::slotLoadProject(){
+void MainWindow::slotLoadProject(QString fileName){
- params->projectFile = QFileDialog::getOpenFileName(0, "select a project file", "save/",tr("sauvegardes (*.xml)"));
+ if (fileName == "") {
+ params->projectFile = QFileDialog::getOpenFileName(0, "select a project file", "save/",tr("sauvegardes (*.xml)"));
+ }
+ else {
+ params->projectFile = fileName;
+ }
if(! params->projectFile.isEmpty()){
GroupWidget* topGroup = dispatcher->loadProject(params->projectFile);
public slots:
void enableProjectActions(bool enbMenu, quint16 mask = 0, quint8 op = 0); // default : add nothing
void enableAnalysisActions(bool enbMenu, quint16 mask = 0, quint8 op = 0); // default : add nothing
+ void slotLoadProject(QString fileName = "");
private slots:
- void slotNewProject();
- void slotLoadProject();
+ void slotNewProject();
void slotSaveProject();
void slotSaveAsProject();
bool slotCloseProject();
// create interfaces that correspond to a wishbone parameter, if any.
try {
- createInterfaceForParameters();
+ createInterfaceForWishbone();
}
catch(int err) {
throw(err);
int purpose;
QString multStr;
int mult;
- AbstractInterface* inter;
+ ReferenceInterface* iface;
if ((elt.isNull()) || (elt.tagName() != "interfaces")) throw (Exception(BLOCKFILE_CORRUPTED));
purposeStr = eltInput.attribute("purpose","none");
if (purposeStr == "clock") {
nameStr = eltInput.attribute("name","none");
- inter = new ReferenceInterface(this,nameStr,AbstractInterface::Input, AbstractInterface::Clock, "boolean", "1", AbstractInterface::LittleEndian, 1);
- inputs.append(inter);
- clocks.append(inter);
+ iface = new ReferenceInterface(this,nameStr,AbstractInterface::Input, AbstractInterface::Clock, "boolean", "1", AbstractInterface::LittleEndian, 1);
+ if (! iface->checkSetClockIface(nameStr)) {
+ throw (Exception(BLOCKFILE_CORRUPTED));
+ }
+ inputs.append(iface);
+ clocks.append(iface);
}
}
cout << "number of clocks: " << clocks.size() << endl;
multStr = eltInput.attribute("multiplicity","none");
mult = ReferenceInterface::translateMultiplicity(multStr);
- inter = new ReferenceInterface(this,nameStr, AbstractInterface::Input, purpose, typeStr, widthStr, endianess, mult);
+ iface = new ReferenceInterface(this,nameStr, AbstractInterface::Input, purpose, typeStr, widthStr, endianess, mult);
if (clockStr == "none") {
- // no clock given, take the first one (hope that there is a single one !)
+ if (clocks.size() > 1) {
+ // if several clocks, the associated one MUST be given
+ throw (Exception(BLOCKFILE_CORRUPTED));
+ }
+ // no clock given, take the single one
clockStr = clocks.at(0)->getName();
}
- if (! inter->setClockIface(clockStr)) {
+ if (! iface->checkSetClockIface(clockStr)) {
throw (Exception(BLOCKFILE_CORRUPTED));
}
- inputs.append(inter);
+ inputs.append(iface);
}
}
// getting each control
nameStr = eltInput.attribute("iface","none");
AbstractInterface* dataIface = getIfaceFromName(nameStr);
if (dataIface == NULL) throw (Exception(BLOCKFILE_CORRUPTED));
- nameStr = dataIface->getName()+"_enb";
- inter = new ReferenceInterface(this,nameStr,AbstractInterface::Input, AbstractInterface::Control,"boolean","1", AbstractInterface::LittleEndian, 1);
- if (!inter->setAssociatedIface(dataIface)) {
+ QString nameEnbStr = dataIface->getName()+"_enb";
+ iface = new ReferenceInterface(this,nameEnbStr,AbstractInterface::Input, AbstractInterface::Control,"boolean","1", AbstractInterface::LittleEndian, 1);
+ if (!iface->setAssociatedIface(dataIface)) {
throw (Exception(BLOCKFILE_CORRUPTED));
}
- cout << "created a control input named " << qPrintable(inter->getName()) << endl;
- inputs.append(inter);
+ clockStr = dataIface->getClockIfaceString();
+ if (! iface->checkSetClockIface(clockStr)) {
+ throw (Exception(BLOCKFILE_CORRUPTED));
+ }
+ cout << "created a control input named " << qPrintable(iface->getName()) << endl;
+ inputs.append(iface);
}
QDomElement eltOutputs = eltInputs.nextSiblingElement("outputs");
QDomNodeList listNodeOutputs = eltOutputs.elementsByTagName("output");
multStr = eltOutput.attribute("multiplicity","none");
mult = ReferenceInterface::translateMultiplicity(multStr);
- inter = new ReferenceInterface(this,nameStr,AbstractInterface::Output, purpose,typeStr,widthStr, endianess, mult);
+ iface = new ReferenceInterface(this,nameStr,AbstractInterface::Output, purpose,typeStr,widthStr, endianess, mult);
if (clockStr == "none") {
- // no clock given, take the first one (hope that there is a single one !)
+ if (clocks.size() > 1) {
+ // if several clocks, the associated one MUST be given
+ throw (Exception(BLOCKFILE_CORRUPTED));
+ }
+ // no clock given, take the single one
clockStr = clocks.at(0)->getName();
}
- if (! inter->setClockIface(clockStr)) {
+ if (! iface->checkSetClockIface(clockStr)) {
throw (Exception(BLOCKFILE_CORRUPTED));
}
- outputs.append(inter);
+
+ outputs.append(iface);
}
// getting each control
QDomNodeList listNodeOutCtl = eltOutputs.elementsByTagName("control");
AbstractInterface* dataIface = getIfaceFromName(nameStr);
if (dataIface == NULL) throw (Exception(BLOCKFILE_CORRUPTED));
nameStr = dataIface->getName()+"_enb";
- inter = new ReferenceInterface(this,nameStr,AbstractInterface::Output, AbstractInterface::Control,"boolean","1",AbstractInterface::LittleEndian, 1);
- if (!inter->setAssociatedIface(dataIface)) {
+ iface = new ReferenceInterface(this,nameStr,AbstractInterface::Output, AbstractInterface::Control,"boolean","1",AbstractInterface::LittleEndian, 1);
+ if (!iface->setAssociatedIface(dataIface)) {
throw (Exception(BLOCKFILE_CORRUPTED));
}
- cout << "created a control output named " << qPrintable(inter->getName()) << endl;
- outputs.append(inter);
+ clockStr = dataIface->getClockIfaceString();
+ if (! iface->checkSetClockIface(clockStr)) {
+ throw (Exception(BLOCKFILE_CORRUPTED));
+ }
+ cout << "created a control output named " << qPrintable(iface->getName()) << endl;
+ outputs.append(iface);
}
QDomElement eltBidirs = eltInputs.nextSiblingElement("bidirs");
multStr = eltBidir.attribute("multiplicity","none");
mult = ReferenceInterface::translateMultiplicity(multStr);
- inter = new ReferenceInterface(this,nameStr,AbstractInterface::InOut, purpose,typeStr,widthStr, endianess, mult);
+ iface = new ReferenceInterface(this,nameStr,AbstractInterface::InOut, purpose,typeStr,widthStr, endianess, mult);
if (clockStr == "none") {
- // no clock given, take the first one (hope that there is a single one !)
+ if (clocks.size() > 1) {
+ // if several clocks, the associated one MUST be given
+ throw (Exception(BLOCKFILE_CORRUPTED));
+ }
+ // no clock given, take the single one
clockStr = clocks.at(0)->getName();
}
- if (! inter->setClockIface(clockStr)) {
+ if (! iface->checkSetClockIface(clockStr)) {
throw (Exception(BLOCKFILE_CORRUPTED));
}
- bidirs.append(inter);
+
+ bidirs.append(iface);
}
}
-void ReferenceBlock::createInterfaceForParameters() throw(Exception){
+void ReferenceBlock::createInterfaceForWishbone() throw(Exception){
ReferenceInterface* iface = NULL;
foreach(BlockParameter* param, params) {
toWrite << iface->getClockIfaceString();
}
}
- // secondly, write other ifaces
+ // thirdly, write other ifaces
for(int i=0; i<b.inputs.size(); i++){
ReferenceInterface *iface = (ReferenceInterface *)(b.inputs.at(i));
if ((iface->getPurpose() != AbstractInterface::Control) && (iface->getPurpose() != AbstractInterface::Clock)) {
QString clk;
in >> clkType;
in >> clk;
- if (clkType == AbstractInterface::ParameterName) {
- clk = "$"+clk;
- }
- if (! iface->setClockIface(clk)) {
- cerr << "Abnormal case while reading a reference block in library: cannot set ref clock for an interface" << endl;
- }
-
+ iface->setClockIfaceName(clk);
+ iface->setClockIfaceType(clkType);
b.inputs.append(iface);
if (iface->getPurpose() == AbstractInterface::Data) {
QString ctlRefName = iface->getName()+"_enb";
QString clk;
in >> clkType;
in >> clk;
- if (clkType == AbstractInterface::ParameterName) {
- clk = "$"+clk;
- }
- if (! iface->setClockIface(clk)) {
- cerr << "Abnormal case while reading a reference block in library: cannot set ref clock for an interface" << endl;
- }
+ iface->setClockIfaceName(clk);
+ iface->setClockIfaceType(clkType);
b.outputs.append(iface);
if (iface->getPurpose() == AbstractInterface::Data) {
QString ctlRefName = iface->getName()+"_enb";
QString clk;
in >> clkType;
in >> clk;
- if (clkType == AbstractInterface::ParameterName) {
- clk = "$"+clk;
- }
- if (! iface->setClockIface(clk)) {
- cerr << "Abnormal case while reading a reference block in library: cannot set ref clock for an interface" << endl;
- }
+ iface->setClockIfaceName(clk);
+ iface->setClockIfaceType(clkType);
b.bidirs.append(iface);
}
void loadInformations(QDomElement &elt) throw(Exception);
void loadParameters(QDomElement &elt) throw(Exception);
void loadInterfaces(QDomElement &elt) throw(Exception);
- void createInterfaceForParameters() throw(Exception);
+ void createInterfaceForWishbone() throw(Exception);
friend QDataStream &operator<<(QDataStream &out, const ReferenceBlock &b);
friend QDataStream &operator>>(QDataStream &in, ReferenceBlock &b);
#include "ReferenceInterface.h"
#include "AbstractBlock.h"
+#include "BlockParameter.h"
ReferenceInterface::ReferenceInterface(AbstractBlock* _owner) throw(Exception) : AbstractInterface(_owner) {
if (_owner->isReferenceBlock()) throw(Exception(BLOCK_INVALID_TYPE));
throw(Exception(IFACE_INVALID_TYPE,this));
}
+
+/* NOTE on clock associated to each interface:
+
+ Each interface must be associated to a clock so that blast can determine
+ if there are no problems with clocks domains. This clock must correspond to
+ the name of a clock interface owned by the same block or to a user parameter
+ for which the value indicate the clock frequency. This latter case is used only
+ for input interfaces of blocks that will be directly linked to the outside of top group
+ (NB: directly only means that there are no others functional blocks between the
+ mentionnned block and the outside, but it can be within subgroups) and with these interfaces
+ that receives a data signal synchronized on an outside clock that is not provided to the design.
+ For example, on the APF27 board, there is a link between imx and spartan 3 and signals are at 133MHz.
+ But there is no clock provided to the FPGA.
+
+ Reference blocks are created with:
+ - input clocks are associated to themselves.
+ - output clocks are associated to one of the clock.
+ - reset are associated to one of the clock (since they are generated
+ by clkrstgen, they are really synchronized with a clock)
+ - all other signals are associated to one of the clock or to a parameter
+ The name of the associated clock is given in the xml description file. If not
+ indicated it is by default the name of the input clock. In case of there are
+ several input clocks, the xml is incoherent if other signal do not indicate the name of
+ the associated clock.
+
+ Functional block are created by cloning a reference thus they follow the same rules as
+ reference blocks.
+
+ A group is created with interfaces that have an inherited clock name thus, setting a name
+ is meaningless and an iterative process must be used to retrieve the clock domain from
+ the interface that is connected from the group interface (cf. GroupBlock::getClockDomain())
+
+ The following method checks if these rules are applied correctly.
+
+*/
+bool ReferenceInterface::checkSetClockIface(QString _name) {
+
+ /* 3 cases :
+ - this is a clock input: name must be the same as the iface name
+ - this is an output clock or reset: name must be an existing clock name.
+ - other cases: name must ba a parameter name or an exisiting clock name
+
+ NB: if it's a parameter it must be prepend with a $.
+ */
+ if ((purpose == Clock) && (direction == Input)) {
+ if (_name == name) {
+ clkIfaceName = _name;
+ clkIfaceType = ClockName;
+ return true;
+ }
+ }
+ else if ((purpose == Reset) || ((purpose == Clock) && (direction == Output))) {
+ QList<AbstractInterface*> clocks = owner->getInterfaces(Input, Clock);
+ foreach(AbstractInterface* iface, clocks) {
+ if (iface->getName() == _name) {
+ clkIfaceName = _name;
+ clkIfaceType = ClockName;
+ return true;
+ }
+ }
+ }
+ else {
+ if (_name.at(0) == '$') {
+ _name.remove(0,1);
+ QList<BlockParameter* > params = owner->getUserParameters();
+ foreach(BlockParameter* p, params) {
+ if (p->getName() == _name) {
+ clkIfaceName = _name;
+ clkIfaceType = ParameterName;
+ return true;
+ }
+ }
+ }
+ else {
+ QList<AbstractInterface*> clocks = owner->getInterfaces(Input, Clock);
+ foreach(AbstractInterface* iface, clocks) {
+ if (iface->getName() == _name) {
+ clkIfaceName = _name;
+ clkIfaceType = ClockName;
+ return true;
+ }
+ }
+ }
+ }
+ clkIfaceName = "";
+ clkIfaceType = NoName;
+ return false;
+}
+
bool isReferenceInterface();
// others
+ bool checkSetClockIface(QString _name);
static int translatePurpose(const QString& txt);
static int translateMultiplicity(const QString& txt);
MainWindow w;
w.show();
+ if (argc == 2) {
+ w.slotLoadProject(argv[1]);
+ }
return a.exec();
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE QtCreatorProject>
-<!-- Written by QtCreator 4.2.0, 2018-05-09T18:21:40. -->
+<!-- Written by QtCreator 4.2.0, 2018-05-15T19:43:34. -->
<qtcreator>
<data>
<variable>EnvironmentId</variable>
<config>
<categories>
<category name="root" id="0" parent="-1"/>
- <category name="math" id="1" parent="0"/>
+ <category name="stimulis" id="1" parent="0"/>
<category name="trigonemetric" id="2" parent="1"/>
<category name="arithmetics" id="3" parent="1"/>
<category name="filters" id="4" parent="0"/>
<category name="wishbone" id="5" parent="0"/>
- <category name="generators" id="6" parent="0"/>
+ <category name="math" id="6" parent="0"/>
<category name="observers" id="7" parent="0"/>
<category name="special" id="8" parent="0"/>
<category name="clock related" id="9" parent="8"/>
end if;
end if;
end process read_fifo;
-
-end architecture clkdomain_convert_1024x8_1;
</architecture>
<patterns>
<delta value="1"/>
item_count := 0;
line_count := 0;
last_line := '0';
-out_enb <= '0';
+@{out_val_enb} <= '0';
dly_item_count := 0;
dly_line_count := 0;
item_count_enb := '0';
elsif rising_edge(@{clk}) then
-out_enb <= '0';
+@{out_val_enb} <= '0';
if do_read = '1' then
else
read(l, in_val);
out_s <= to_unsigned(in_val, item_width);
-out_enb <= '1';
+@{out_val_enb} <= '1';
item_count := item_count + 1;
if (item_count < item_per_line) then
read(l, comma);
end if;
end if;
-elsif start_read = '1' then
+elsif @{start} = '1' then
-- reading the first line
readline(in_data, l);
line_count := line_count + 1;
end if;
end process read_data;
-
-end architecture read_csv_a;
</architecture>
<patterns>
<delta value="$nb_lines*$item_per_line"/>
This IP allows to pass 8 bits values from a clock domain to another. It uses a FIFO of 1024 entries.
</description>
</informations>
- <parameters>
- <parameter type="real" context="generic" name="clk_in_freq" value="100"/>
- <parameter type="real" context="generic" name="clk_out_freq" value="100"/>
- </parameters>
+ <parameters />
<interfaces>
<inputs>
<input width="1" multiplicity="1" endian="little" type="boolean" name="clk_in" purpose="clock"/>
<input width="1" multiplicity="1" endian="little" type="boolean" name="clk_out" purpose="clock"/>
- <input width="1" multiplicity="1" endian="little" type="boolean" name="reset" purpose="reset"/>
+ <input width="1" multiplicity="1" endian="little" type="boolean" name="reset" purpose="reset" clock="clk_in"/>
<input width="8" multiplicity="1" endian="little" type="natural" name="data_in" purpose="data" clock="clk_in"/>
<control iface="data_in"/>
</inputs>
<name>
generator-cst
</name>
- <category ids="6" />
+ <category ids="1" />
<description>
generates V consecutives constant values, followed by Z idle cycles
</description>
<inputs>
<input name="clk" width="1" purpose="clock" />
<input name="rst" width="1" purpose="reset" />
+ <input purpose="data" name="start" width="1" multiplicity="1" endian="little" type="boolean"/>
</inputs>
<outputs>
<output name="data_o" width="$data_width"/>
<name>
generator-img
</name>
- <category ids="6" />
+ <category ids="1" />
<description>
generates a RGB image, reading if from a csv file
</description>
<inputs>
<input name="clk" width="1" purpose="clock" />
<input name="rst" width="1" purpose="reset" />
+ <input purpose="data" name="start" width="1" multiplicity="1" endian="little" type="boolean"/>
</inputs>
<outputs>
<output name="r_o" width="8"/>
<block version="0.1" special="source">
<informations>
<name>read_csv</name>
- <category ids="6"/>
+ <category ids="1"/>
<description>
read a csv file
</description>
<inputs>
<input purpose="clock" name="clk" width="1" multiplicity="1" endian="little" type="boolean"/>
<input purpose="reset" name="reset" width="1" multiplicity="1" endian="little" type="boolean"/>
+ <input purpose="data" name="start" width="1" multiplicity="1" endian="little" type="boolean"/>
+
</inputs>
<outputs>
<output purpose="data" name="out_val" width="$item_width" multiplicity="1" endian="little" type="expression"/>