From: stephane Domas Date: Wed, 24 Jan 2018 12:27:01 +0000 (+0100) Subject: add clk/rst to groups X-Git-Url: https://bilbo.iut-bm.univ-fcomte.fr/and/gitweb/blast.git/commitdiff_plain/756baf5c8eaf003e8271dab9c395de2b0e704857 add clk/rst to groups --- diff --git a/AbstractBlock.cpp b/AbstractBlock.cpp index f551b30..cdde69f 100644 --- a/AbstractBlock.cpp +++ b/AbstractBlock.cpp @@ -10,7 +10,7 @@ AbstractBlock::AbstractBlock() { } AbstractBlock::AbstractBlock(const QString& _name) { - name = _name; + name = normalizeName(_name); parent = NULL; } @@ -25,7 +25,7 @@ AbstractBlock::~AbstractBlock() { } void AbstractBlock::setName(const QString& str) { - name = str; + name = normalizeName(str); } void AbstractBlock::setParent(AbstractBlock* _parent) { @@ -235,3 +235,11 @@ QList AbstractBlock::getWishboneParameters() { return lst; } +QString AbstractBlock::normalizeName(const QString &name) { + QString s = name; + s.replace(QRegularExpression("[^a-zA-Z0-9_]"),"_"); + s.replace(QRegularExpression("[_]+"),"_"); + return s; +} + + diff --git a/AbstractBlock.h b/AbstractBlock.h index 80e0413..042a598 100644 --- a/AbstractBlock.h +++ b/AbstractBlock.h @@ -56,6 +56,8 @@ public: bool isWBConfigurable(); // others + static QString normalizeName(const QString& name); + virtual void parametersValidation(QList* checkedBlocks, QList* blocksToConfigure) = 0; // ugly but usefull void addParameter(BlockParameter *param); @@ -98,6 +100,8 @@ protected: // NB: only GroupBlock and FunctionalBlock have a real parent, except sources that have no parents AbstractBlock* parent; + + }; #endif // __ABSTRACTBLOCK_H__ diff --git a/AbstractInputModifier.cpp b/AbstractInputModifier.cpp index aa9c9a2..67578e6 100644 --- a/AbstractInputModifier.cpp +++ b/AbstractInputModifier.cpp @@ -1,8 +1,9 @@ #include "AbstractInputModifier.h" -AbstractInputModifier::AbstractInputModifier() { +AbstractInputModifier::AbstractInputModifier(ConnectedInterface *_associatedIface) { pattern = new QList(); + associatedIface = _associatedIface; } AbstractInputModifier::~AbstractInputModifier() { diff --git a/AbstractInputModifier.h b/AbstractInputModifier.h index bbc5bdd..6f3abe8 100644 --- a/AbstractInputModifier.h +++ b/AbstractInputModifier.h @@ -5,14 +5,21 @@ #include +#include "Exception.h" + +class ConnectedInterface; + using namespace std; using namespace Qt; class AbstractInputModifier { -public: +public: + + enum ModifierVHDLContext {AnyContext = 0, Entity = 1, Component = 2, Architecture = 3 }; + enum ModifierVHDLFlags { NoComma = 1 }; - AbstractInputModifier(); + AbstractInputModifier(ConnectedInterface* _associatedIface); virtual ~AbstractInputModifier(); //getters @@ -29,9 +36,11 @@ public: // others virtual QList* getModifiedInput(QList* input) = 0; + virtual QString toVHDL(int context, int flags) throw(Exception) = 0; protected: QList* pattern; // the pattern modified by this + ConnectedInterface* associatedIface; }; #endif // __ABSTRACTINPUTMODIFIER_H__ diff --git a/AbstractInterface.cpp b/AbstractInterface.cpp index c03cba9..1d1e41d 100644 --- a/AbstractInterface.cpp +++ b/AbstractInterface.cpp @@ -18,7 +18,7 @@ AbstractInterface::AbstractInterface(AbstractBlock* _owner) { AbstractInterface::AbstractInterface(AbstractBlock* _owner, const QString& _name, int _direction, int _purpose, const QString& _type, const QString& _width, int _endianess) { owner = _owner; - name = _name; + name = AbstractBlock::normalizeName(_name); width = _width; direction = _direction; purpose = _purpose; @@ -29,7 +29,7 @@ AbstractInterface::AbstractInterface(AbstractBlock* _owner, const QString& _name AbstractInterface::AbstractInterface(AbstractInterface* other) { owner = NULL; - name = other->name; + name = AbstractBlock::normalizeName(other->name); type = other->type; width = other->width; direction = other->direction; @@ -38,6 +38,10 @@ AbstractInterface::AbstractInterface(AbstractInterface* other) { associatedIface = NULL; } +void AbstractInterface::setName(const QString& _name) { + name = AbstractBlock::normalizeName(_name); +} + AbstractInterface::~AbstractInterface() { } diff --git a/AbstractInterface.h b/AbstractInterface.h index b318f92..a214831 100644 --- a/AbstractInterface.h +++ b/AbstractInterface.h @@ -58,7 +58,7 @@ public : // setters inline void setOwner(AbstractBlock* _owner) { owner = _owner; } - inline void setName(const QString& _name) { name = _name; } + void setName(const QString& _name); inline void setWidth(const QString& _width) { width = _width; } inline void setType(int _type) { type = _type;} inline void setEndianess(int _endianess) { endianess = _endianess;} diff --git a/BlockCategory.cpp b/BlockCategory.cpp index 0de4d86..1e70385 100644 --- a/BlockCategory.cpp +++ b/BlockCategory.cpp @@ -34,7 +34,7 @@ QList BlockCategory::getAllChilds() return childs; } -ReferenceBlock *BlockCategory::getBlock(int index) { +ReferenceBlock *BlockCategory::getBlockById(int index) { if ((index >=0) && (index < blocks.size()) ) { return blocks.at(index); } @@ -42,6 +42,14 @@ ReferenceBlock *BlockCategory::getBlock(int index) { return NULL; } +ReferenceBlock *BlockCategory::getBlockByName(QString name) { + foreach(ReferenceBlock* block, blocks) { + if (block->getName() == name) return block; + } + cout << "block null!" << endl; + return NULL; +} + QDomElement BlockCategory::save(QDomDocument &doc) { } diff --git a/BlockCategory.h b/BlockCategory.h index 78f646e..aa1c0c4 100644 --- a/BlockCategory.h +++ b/BlockCategory.h @@ -27,7 +27,8 @@ public : BlockCategory* getChild(int index); QList getAllChilds(); inline QList getBlocks() { return blocks; } - ReferenceBlock *getBlock(int index); + ReferenceBlock *getBlockById(int index); + ReferenceBlock *getBlockByName(QString name); // setters void addChild(BlockCategory* child); diff --git a/BlockImplementation.cpp b/BlockImplementation.cpp index f71297f..46c9722 100644 --- a/BlockImplementation.cpp +++ b/BlockImplementation.cpp @@ -127,6 +127,7 @@ void BlockImplementation::generateVHDL(FunctionalBlock* _block, const QString &p if (reference->isWBConfigurable()) { genController = true; controllerFile = path; + controllerFile += "/"; controllerFile.append(block->getName()); controllerFile.append("_ctrl.vhd"); } @@ -134,6 +135,7 @@ void BlockImplementation::generateVHDL(FunctionalBlock* _block, const QString &p controllerFile = "nofile.vhd"; } coreFile = path; + coreFile += "/"; coreFile.append(block->getName()); coreFile.append(".vhd"); @@ -185,38 +187,38 @@ void BlockImplementation::generateComments(QDomElement &elt, QString coreFile, Q for(int i = 0; i < 50; i++) { out << "--"; } - out << "\n--\n"; + out << "\n--" << endl; QString fileName = coreFile; - out << "-- File : " << fileName << "\n"; - out << "--\n"; + out << "-- File : " << fileName << endl; + out << "--" << endl; QDomElement eltAuthor = elt.firstChildElement("author"); QString firstName = eltAuthor.attribute("firstname",""); QString lastName = eltAuthor.attribute("lastname",""); QString mail = eltAuthor.attribute("mail",""); - out << "-- Author(s) : "< listBidirs = block->getBidirs(); QString typePort, namePort; - out << "entity " << nameEnt << " is\n"; + out << "entity " << nameEnt << " is" << endl; /* TODO : rewrite the generation to take into acocunt the new object hierarchy */ diff --git a/BoxItem.cpp b/BoxItem.cpp index 34b567a..4471c86 100644 --- a/BoxItem.cpp +++ b/BoxItem.cpp @@ -572,11 +572,14 @@ void BoxItem::contextMenuEvent(QGraphicsSceneContextMenuEvent * event) { } } - if (iface->getInputModifier() != NULL) { - removeModifier = menu.addAction("Remove input modifier"); - } - if (iface->getInputModifier() != NULL) { - showModifier = menu.addAction("Show input modifier parameters"); + if (iface->getAssociatedIface() != NULL) { + ConnectedInterface* assoIface = AI_TO_CON(iface->getAssociatedIface()); + if (assoIface->getInputModifier() != NULL) { + removeModifier = menu.addAction("Remove input modifier"); + } + if (assoIface->getInputModifier() != NULL) { + showModifier = menu.addAction("Show input modifier parameters"); + } } } diff --git a/ConnectedInterface.h b/ConnectedInterface.h index f0a36a4..c9e03e8 100644 --- a/ConnectedInterface.h +++ b/ConnectedInterface.h @@ -46,6 +46,7 @@ public : virtual bool canConnectFrom(AbstractInterface* iface) = 0; // others + void resetOutputPattern() { outputPattern = NULL; } void connectTo(ConnectedInterface* iface); void disconnectTo(ConnectedInterface* iface); //bool connectFrom(ConnectedInterface* iface); diff --git a/DelayInputModifier.cpp b/DelayInputModifier.cpp index a35aa21..e035c38 100644 --- a/DelayInputModifier.cpp +++ b/DelayInputModifier.cpp @@ -1,6 +1,7 @@ #include "DelayInputModifier.h" +#include "ConnectedInterface.h" -DelayInputModifier::DelayInputModifier(int _delayLength) : AbstractInputModifier() { +DelayInputModifier::DelayInputModifier(ConnectedInterface *_associatedInterface, int _delayLength) : AbstractInputModifier(_associatedInterface) { setDelayLength(_delayLength); } @@ -17,6 +18,10 @@ QList* DelayInputModifier::getModifiedInput(QList* input) { return pattern; } +QString DelayInputModifier::toVHDL(int context, int flags) throw(Exception) { + +} + QString DelayInputModifier::getTypeStr() { return "delay"; } diff --git a/DelayInputModifier.h b/DelayInputModifier.h index 1fda2ec..c5595f6 100644 --- a/DelayInputModifier.h +++ b/DelayInputModifier.h @@ -5,6 +5,7 @@ #include #include "AbstractInputModifier.h" + using namespace std; using namespace Qt; @@ -12,7 +13,7 @@ class DelayInputModifier : public AbstractInputModifier { public: - DelayInputModifier(int _delayLength = 1); + DelayInputModifier(ConnectedInterface* _associatedInterface, int _delayLength = 1); // getters inline int getDelayLength() { return delayLength; } // setters @@ -22,6 +23,7 @@ public: // others QList* getModifiedInput(QList* input); + QString toVHDL(int context, int flags) throw(Exception); QString getTypeStr(); QString getParametersStr(); diff --git a/Dispatcher.cpp b/Dispatcher.cpp index a552f20..a9beb48 100644 --- a/Dispatcher.cpp +++ b/Dispatcher.cpp @@ -85,7 +85,7 @@ void Dispatcher::closeCurrentProject() { sceneCounter = 0; } -bool Dispatcher::createConnection(InterfaceItem *iface1, InterfaceItem *iface2) { +bool Dispatcher::createConnection(InterfaceItem *iface1, InterfaceItem *iface2, bool visible) { ConnectedInterface* ref1 = iface1->refInter; ConnectedInterface* ref2 = iface2->refInter; @@ -106,7 +106,7 @@ bool Dispatcher::createConnection(InterfaceItem *iface1, InterfaceItem *iface2) } if ((ok1 == true) || (ok2 == true)) { - iface1->getOwner()->getScene()->createConnectionItem(iface1,iface2); + iface1->getOwner()->getScene()->createConnectionItem(iface1,iface2, visible); unselectAllItems(); params->unsaveModif = true; @@ -182,7 +182,7 @@ void Dispatcher::generateBlockVHDL(BoxItem *item){ ReferenceBlock* ref = block->getReference(); BlockImplementation* impl = ref->getImplementations().at(0); try { - impl->generateVHDL(block,"/home/sdomas/"); + impl->generateVHDL(block,params->projectPath); } catch(Exception e) { cout << qPrintable(e.getMessage()) << endl; @@ -371,10 +371,18 @@ void Dispatcher::showPatterns(InterfaceItem *item) { msg += " owned by "; msg += item->refInter->getOwner()->getName(); msg += " is:\n"; - ConnectedInterface* iface = AI_TO_CON(item->refInter->getAssociatedIface()); - ConnectedInterface* fromIface = iface->getConnectedFrom(); - if (fromIface->getOutputPattern() == NULL) return; - foreach(char c, *(fromIface->getOutputPattern())) { + // get the precursor output pattern + ConnectedInterface* connIface = AI_TO_CON(item->refInter->getAssociatedIface()); + QList* out = connIface->getConnectedFrom()->getOutputPattern(); + // get the modifier + AbstractInputModifier* modifier = connIface->getInputModifier(); + // check if the input is modified + if (modifier != NULL) { + + out = modifier->getModifiedInput(out); + } + + foreach(char c, *out) { msg += QString::number((int)c); } msg += "\n"; @@ -401,7 +409,8 @@ void Dispatcher::showModifier(InterfaceItem *item) { cout << "call to " << qPrintable(fctName) << endl; #endif QString msg = ""; - AbstractInputModifier* mod = item->refInter->getInputModifier(); + ConnectedInterface* assoIface = AI_TO_CON(item->refInter->getAssociatedIface()); + AbstractInputModifier* mod = assoIface->getInputModifier(); if (mod->isDelay()) { DelayInputModifier* delay = (DelayInputModifier *)mod; msg = "Pattern of iface "; @@ -421,7 +430,8 @@ void Dispatcher::removeModifier(InterfaceItem *item) { cout << "call to " << qPrintable(fctName) << endl; #endif - item->refInter->clearInputModifier(); + ConnectedInterface* assoIface = AI_TO_CON(item->refInter->getAssociatedIface()); + assoIface->clearInputModifier(); } @@ -546,7 +556,16 @@ GroupWidget *Dispatcher::createTopScene(){ // creating the model part of the group Graph* graph = params->createGraph(); - GroupBlock *refBlock = graph->getTopGroup(); + GroupBlock *topBlock = graph->getTopGroup(); + // creating the clkrstgen block + ReferenceBlock* ref = params->getHiddenReferenceBlock("clkrstgen"); + FunctionalBlock* newOne = params->getGraph()->createFunctionalBlock(topBlock, ref); + ConnectedInterface* fromIface = AI_TO_CON(topBlock->getIfaceFromName("ext_clk")); + ConnectedInterface* toIface = AI_TO_CON(newOne->getIfaceFromName("ext_clk")); + fromIface->connectTo(toIface); + fromIface = AI_TO_CON(topBlock->getIfaceFromName("ext_reset")); + toIface = AI_TO_CON(newOne->getIfaceFromName("ext_reset")); + fromIface->connectTo(toIface); // creating a fake and not connected interface //AbstractInterface* iface = new GroupInterface(refBlock,"grp_iface",AbstractInterface::Input,AbstractInterface::Top); @@ -560,7 +579,7 @@ GroupWidget *Dispatcher::createTopScene(){ params->setTopScene(scene); params->setCurrentScene(scene); // creating the view part of the group - GroupItem *group = new GroupItem(NULL,refBlock,this,params); + GroupItem *group = new GroupItem(NULL,topBlock,this,params); // adding the fake interface to the top group item @@ -1073,10 +1092,12 @@ void Dispatcher::connectInterToGroup(InterfaceItem *item){ // creating/adding the group interface in the graph model GroupInterface *groupInter = new GroupInterface(parentBlock,refInter->getName()+"_group",refInter->getDirection(),refInter->getPurpose()); parentItem->getRefBlock()->addInterface(groupInter); - // creating/adding the group control interface in the graph model - GroupInterface *groupCtlInter = new GroupInterface(parentBlock,refInter->getName()+"_group_enb",refInter->getDirection(),AbstractInterface::Control); - groupCtlInter->setAssociatedIface(groupInter); - parentItem->getRefBlock()->addInterface(groupCtlInter); + // creating/adding the group control interface in the graph model if the purpose is data + if (refInter->getPurpose() == AbstractInterface::Data) { + GroupInterface *groupCtlInter = new GroupInterface(parentBlock,refInter->getName()+"_group_enb",refInter->getDirection(),AbstractInterface::Control); + groupCtlInter->setAssociatedIface(groupInter); + parentItem->getRefBlock()->addInterface(groupCtlInter); + } // creating/adding the group interface in the current scene model, and connection item InterfaceItem *groupIfaceItem = new InterfaceItem(0,item->getOrientation(),groupInter,parentItem,params); parentItem->addInterfaceItem(groupIfaceItem,true); @@ -1216,8 +1237,9 @@ void Dispatcher::findGraphModifications(FunctionalBlock *block) { QList* delay = iterD.value(); if (delay->at(0) > 0) { // create delay and associate it to the connected input - AbstractInputModifier* mod = new DelayInputModifier(delay->at(0)); - ConnectedInterface* toIface = AI_TO_CON(iterD.key()->getAssociatedIface()); + + ConnectedInterface* toIface = AI_TO_CON(iterD.key()); + AbstractInputModifier* mod = new DelayInputModifier(toIface, delay->at(0)); cout << "modify input of " << qPrintable(toIface->getName()) << endl; toIface->setInputModifier(mod); // repaint diff --git a/Dispatcher.h b/Dispatcher.h index ae4cc64..538ee66 100644 --- a/Dispatcher.h +++ b/Dispatcher.h @@ -119,7 +119,7 @@ public slots: void removeModifier(InterfaceItem* item); // connection ops - bool createConnection(InterfaceItem *iface1, InterfaceItem *iface2); + bool createConnection(InterfaceItem *iface1, InterfaceItem *iface2, bool visible = true); void removeAllBlockConnections(AbstractBoxItem *item); void removeConnection(ConnectionItem *conn); diff --git a/FunctionalBlock.cpp b/FunctionalBlock.cpp index 91f4e03..b494784 100644 --- a/FunctionalBlock.cpp +++ b/FunctionalBlock.cpp @@ -649,9 +649,7 @@ void FunctionalBlock::createInputPattern() throw(Exception) { } // get the precursor output pattern QList* out = connIface->getConnectedFrom()->getOutputPattern(); - - ConnectedInterface* assoIface = AI_TO_CON(connIface->getAssociatedIface()); - AbstractInputModifier* modifier = assoIface->getInputModifier(); + AbstractInputModifier* modifier = connIface->getInputModifier(); // check if the input is modified if (modifier != NULL) { @@ -815,12 +813,13 @@ void FunctionalBlock::computeOutputPattern(int nbExec) throw(Exception) { #ifdef DEBUG_FCTNAME cout << "call to " << qPrintable(fctName) << endl; #endif - + + clearOutputPattern(); + /* case 1: the block is a generator for which output pattern must be computed for a nbExec following executions */ - - + if (nbExec > 0) { cout << "computing output pattern of " << qPrintable(name) << " for " << nbExec << " executions" << endl; foreach(AbstractInterface* iface, getControlOutputs()) { @@ -1243,6 +1242,20 @@ void FunctionalBlock::clearInputPattern() { lengthIP = -1; } +void FunctionalBlock::clearOutputPattern() { + + QMapIterator* > iterO(outputPattern); + while (iterO.hasNext()) { + iterO.next(); + ConnectedInterface* connIface = AI_TO_CON(iterO.key()); + connIface->resetOutputPattern(); + QList* pattern = iterO.value(); + if (pattern != NULL) delete pattern; + } + outputPattern.clear(); + lengthOP = -1; +} + void FunctionalBlock::clearAdmittanceDelays() { QMapIterator* > iterA(admittanceDelays); while (iterA.hasNext()) { diff --git a/FunctionalBlock.h b/FunctionalBlock.h index 404ce17..c51ff77 100644 --- a/FunctionalBlock.h +++ b/FunctionalBlock.h @@ -74,6 +74,7 @@ private: void clearProductionPattern(); void createInputPattern() throw(Exception); void clearInputPattern(); + void clearOutputPattern(); void clearAdmittanceDelays(); int createTriggers(); // compute the clock cycle at which the block is triggered diff --git a/GroupBlock.cpp b/GroupBlock.cpp index b515b54..422cf97 100644 --- a/GroupBlock.cpp +++ b/GroupBlock.cpp @@ -2,6 +2,7 @@ #include "BlockParameterGeneric.h" #include "AbstractInterface.h" #include "ConnectedInterface.h" +#include "GroupInterface.h" #include "string.h" #include @@ -17,6 +18,12 @@ GroupBlock::GroupBlock(GroupBlock *_parent) throw(Exception) : AbstractBlock() else { topGroup = true; name = QString("top_group"); + // creating external clk/rst interfaces + GroupInterface* clk = new GroupInterface(this,"ext_clk", AbstractInterface::Input, AbstractInterface::Clock); + GroupInterface* rst = new GroupInterface(this,"ext_reset", AbstractInterface::Input, AbstractInterface::Reset); + addInterface(clk); + addInterface(rst); + // creating clkrstgen block : done in Dispatcher since this has no access to library } parent = _parent; if (parent != NULL) { @@ -239,5 +246,154 @@ void GroupBlock::computeOutputPattern(int nbExec) throw(Exception) { } setPatternComputed(true); } +} + +void GroupBlock::generateVHDL(const QString& path) throw(Exception) { + + QString coreFile = ""; + + coreFile = path; + coreFile.append(normalizeName(name)); + coreFile.append(".vhd"); + + QFile vhdlCore(coreFile); + + if (!vhdlCore.open(QIODevice::WriteOnly)) { + throw(Exception(VHDLFILE_NOACCESS)); + } + + QTextStream outCore(&vhdlCore); + + try { + generateComments(outCore); + generateLibraries(outCore); + generateEntity(outCore); + generateArchitecture(outCore); + } + catch(Exception err) { + throw(err); + } + + vhdlCore.close(); +} + + +void GroupBlock::generateComments(QTextStream& out) throw(Exception) { + out << " -- VHDL generated automatically for " << name << " --" << endl << endl; +} + +void GroupBlock::generateLibraries(QTextStream& out) throw(Exception) { + + out << "library IEEE;" << endl; + out << "use IEEE.STD_LOGIC_1164.all;" << endl; + out << "use IEEE.numeric_std.all;" << endl; + +} + +void GroupBlock::generateEntity(QTextStream& out) throw(Exception) { + + int i; + + out << "entity " << name << " is " << endl; + + QList listGenerics = getGenericParameters(); + QList listInputs = getInputs(); + QList listOutputs = getOutputs(); + QList listBidirs = getBidirs(); + + if (!listGenerics.isEmpty()) { + out << " generic (" << endl; + for(i=0;itoVHDL(BlockParameter::Entity, 0) << endl; + } + out << " " << listGenerics.at(i)->toVHDL(BlockParameter::Entity,BlockParameter::NoComma) << endl; + out << " );" << endl; + } + + out << " port (" << endl; + + // Generation of the clk & rst signals + out << " -- clk/rst" << endl; + foreach(AbstractInterface* iface, listInputs) { + if(iface->getPurpose() == AbstractInterface::Clock || iface->getPurpose() == AbstractInterface::Reset) { + out << " " << iface->getName() << " : in std_logic;" << endl; + } + } + + int count = 0; + foreach(AbstractInterface* iface, getInterfaces()) { + if((iface->getPurpose() == AbstractInterface::Data)||(iface->getPurpose() == AbstractInterface::Control)) count++; + } + // Generation of the data/control signals + + int flag = 0; + bool first = true; + + foreach(AbstractInterface* iface, listInputs) { + if(iface->getPurpose() == AbstractInterface::Data) { + if (first) { + out << " -- input data ports" << endl; + first = false; + } + count--; + if (count == 0) flag = AbstractInterface::NoComma; + out << " " << iface->toVHDL(AbstractInterface::Entity, flag) << endl; + } + } + first = true; + foreach(AbstractInterface* iface, listInputs) { + if(iface->getPurpose() == AbstractInterface::Control) { + if (first) { + out << " -- input control ports" << endl; + first = false; + } + count--; + if (count == 0) flag = AbstractInterface::NoComma; + out << " " << iface->toVHDL(AbstractInterface::Entity, flag) << endl; + } + } + first = true; + foreach(AbstractInterface* iface, listOutputs) { + if(iface->getPurpose() == AbstractInterface::Data) { + if (first) { + out << " -- output data ports" << endl; + first = false; + } + count--; + if (count == 0) flag = AbstractInterface::NoComma; + out << " " << iface->toVHDL(AbstractInterface::Entity, flag) << endl; + } + } + first = true; + foreach(AbstractInterface* iface, listOutputs) { + if(iface->getPurpose() == AbstractInterface::Control) { + if (first) { + out << " -- output control ports" << endl; + first = false; + } + count--; + if (count == 0) flag = AbstractInterface::NoComma; + out << " " << iface->toVHDL(AbstractInterface::Entity, flag) << endl; + } + } + first = true; + foreach(AbstractInterface* iface, listBidirs) { + if(iface->getPurpose() == AbstractInterface::Data) { + if (first) { + out << " -- bidirs data ports" << endl; + first = false; + } + count--; + if (count == 0) flag = AbstractInterface::NoComma; + out << " " << iface->toVHDL(AbstractInterface::Entity, flag) << endl; + } + } + out << " );" << endl << endl; + out << "end " << name << ";" << endl << endl; + +} + +void GroupBlock::generateArchitecture(QTextStream& out) throw(Exception) { } + diff --git a/GroupBlock.h b/GroupBlock.h index f7a9c2c..0f0d206 100644 --- a/GroupBlock.h +++ b/GroupBlock.h @@ -46,6 +46,8 @@ public: void computeOutputPattern(int nbExec = -1) throw(Exception); void computeAdmittanceDelays() throw(Exception); + void generateVHDL(const QString& path) throw(Exception); // main entry to generate the VHDL code + private: // patterns /* NB: in opposition to FunctionalBlock, the input pattern and output pattern of a block @@ -62,7 +64,11 @@ private: * found by taking the output pattern of the connectedFrom interface. */ void createInputPattern(); - + void generateComments(QTextStream& out) throw(Exception); + void generateLibraries(QTextStream& out) throw(Exception); + void generateEntity(QTextStream& out) throw(Exception); + void generateArchitecture(QTextStream& out) throw(Exception); + bool topGroup; QList blocks; // contains instances of FunctionalBlock or GroupBlock that are children of this group diff --git a/GroupScene.cpp b/GroupScene.cpp index 778a0b0..2ceb21f 100644 --- a/GroupScene.cpp +++ b/GroupScene.cpp @@ -166,10 +166,11 @@ void GroupScene::removeSourceItem(SourceItem* item) { sourceItems.removeAll(item); } -void GroupScene::createConnectionItem(InterfaceItem *iface1, InterfaceItem *iface2) { +void GroupScene::createConnectionItem(InterfaceItem *iface1, InterfaceItem *iface2, bool visible) { ConnectionItem* conn = NULL; conn = new ConnectionItem(iface1,iface2, dispatcher, params); + conn->setVisible(visible); addItem(conn); addConnectionItem(conn); } diff --git a/GroupScene.h b/GroupScene.h index e32dd53..e2e4763 100644 --- a/GroupScene.h +++ b/GroupScene.h @@ -79,7 +79,7 @@ public: void removeBoxItem(BoxItem* item); // ConnectionItem related - void createConnectionItem(InterfaceItem* iface1, InterfaceItem* iface2); + void createConnectionItem(InterfaceItem* iface1, InterfaceItem* iface2, bool visible = true); ConnectionItem* searchConnectionItem(InterfaceItem* iface1, InterfaceItem* iface2); void addConnectionItem(ConnectionItem* item); void removeConnectionItem(ConnectionItem* item); diff --git a/InterfaceItem.cpp b/InterfaceItem.cpp index 443cee0..18397f3 100644 --- a/InterfaceItem.cpp +++ b/InterfaceItem.cpp @@ -118,19 +118,22 @@ void InterfaceItem::paint(QPainter *painter) { } // draw arrows - if(refInter->getDirection() == AbstractInterface::Input) { - painter->drawPath(params->inArrow); + if ( (refInter->getPurpose() == AbstractInterface::Clock) || (refInter->getPurpose() == AbstractInterface::Reset)) { + painter->drawPath(params->clkrstArrow); + } + else if(refInter->getDirection() == AbstractInterface::Input) { + painter->drawPath(params->dataArrowIn); } else if(refInter->getDirection() == AbstractInterface::Output) { - painter->drawPath(params->outArrow); + painter->drawPath(params->dataArrowOut); } else if(refInter->getDirection() == AbstractInterface::InOut) { - painter->drawPath(params->inArrow); - painter->drawPath(params->outArrow); + painter->drawPath(params->dataArrowIn); + painter->drawPath(params->dataArrowOut); } // paint modifier box if needed - - if (refInter->getInputModifier() != NULL) { + ConnectedInterface* connIface = AI_TO_CON(refInter->getAssociatedIface()); + if ((connIface != NULL) && (connIface->getInputModifier() != NULL)) { painter->save(); painter->translate(params->arrowWidth+params->arrowLineLength,0); painter->drawRect(0,-5,10,10); diff --git a/Parameters.cpp b/Parameters.cpp index d3a8dd4..c60a927 100644 --- a/Parameters.cpp +++ b/Parameters.cpp @@ -81,7 +81,15 @@ ReferenceBlock* Parameters::getReferenceBlock(int idCategory, int idBlock) { BlockCategory* blockCat = categoryTree->searchCategory(idCategory); if (blockCat == NULL) return NULL; - ReferenceBlock* ref = blockCat->getBlock(idBlock); + ReferenceBlock* ref = blockCat->getBlockById(idBlock); + return ref; +} + +ReferenceBlock* Parameters::getHiddenReferenceBlock(QString blockName) { + + BlockCategory* blockCat = categoryTree->searchCategory(100); + if (blockCat == NULL) return NULL; + ReferenceBlock* ref = blockCat->getBlockByName(blockName); return ref; } @@ -237,6 +245,16 @@ GroupWidget *Parameters::loadProject(QDomElement root) throw(Exception) { GroupBlock *groupBlock = NULL; GroupWidget* topGroup = NULL; + + QString path = root.attribute("project_path","none"); + if (path != "none") { + QDir dir(path); + if (dir.exists()) { + projectPath = path; + + } + cout << "project path set to " << qPrintable(projectPath) << endl; + } /********************************************************** 1 : getting scene and creating associated group widgets ***********************************************************/ @@ -457,23 +475,25 @@ GroupWidget *Parameters::loadProject(QDomElement root) throw(Exception) { QString paramsStr = currentModifierNode.attribute("params","none"); if(!ok) throw(Exception(PROJECTFILE_CORRUPTED)); - AbstractInputModifier* mod = NULL; - if (typeStr == "delay") { - int delay = paramsStr.toInt(&ok); - if(!ok) throw(Exception(PROJECTFILE_CORRUPTED)); - mod = new DelayInputModifier(delay); - } - /* NB: just adding delays for now. To be cont'd */ InterfaceItem *iface = searchInterfaceItemById(id,topScene); - if(iface != NULL ) { - iface->refInter->setInputModifier(mod); + if ((iface == NULL ) || (iface->refInter == NULL) || (iface->refInter->getAssociatedIface() == NULL)) { + cout << "modified interface not found, modifiers setup canceled!" << endl; + } + else { + ConnectedInterface* connIface = AI_TO_CON(iface->refInter->getAssociatedIface()); - } else { - cout << "interfaces not found, modifiers setup canceled!" << endl; + AbstractInputModifier* mod = NULL; + if (typeStr == "delay") { + int delay = paramsStr.toInt(&ok); + if(!ok) throw(Exception(PROJECTFILE_CORRUPTED)); + mod = new DelayInputModifier(connIface, delay); + connIface->setInputModifier(mod); + } } } + cout << "modifiers loaded and created succefully!" << endl; return topGroup; @@ -1092,8 +1112,13 @@ void Parameters::setArrowPathes() { _inArrow.lineTo(arrowLineLength+arrowWidth,-arrowHeight/2); _inArrow.lineTo(arrowLineLength+arrowWidth,arrowHeight/2); _inArrow.lineTo(arrowLineLength,0); - _inArrow.closeSubpath(); - inArrow = _inArrow; + //_inArrow.closeSubpath(); + dataArrowIn = _inArrow; + + QPainterPath _inArrowC; + _inArrowC.lineTo(arrowLineLength,0); + _inArrowC.addEllipse(arrowLineLength,-arrowHeight/2,arrowHeight-1,arrowHeight-1); + clkrstArrow = _inArrowC; QPainterPath _outArrow; _outArrow.lineTo(arrowLineLength,0); @@ -1101,8 +1126,8 @@ void Parameters::setArrowPathes() { _outArrow.lineTo(arrowLineLength+arrowWidth,0); _outArrow.lineTo(arrowLineLength,arrowHeight/2); _outArrow.lineTo(arrowLineLength,0); - _outArrow.closeSubpath(); - outArrow = _outArrow; + //_outArrow.closeSubpath(); + dataArrowOut = _outArrow; } diff --git a/Parameters.h b/Parameters.h index 8a71cfb..ccd24ff 100644 --- a/Parameters.h +++ b/Parameters.h @@ -110,8 +110,10 @@ public : QString defaultIfaceFontName; int defaultIfaceFontSize; int connGapLength; - QPainterPath inArrow; - QPainterPath outArrow; + QPainterPath dataArrowIn; + QPainterPath dataArrowOut; + QPainterPath clkrstArrow; + /*************************************************** attributes that are specific for the current project @@ -128,6 +130,7 @@ public : void destroyGraph(); inline Graph* getGraph() { return graph; } ReferenceBlock* getReferenceBlock(int idCategory, int idBlock); // get the reference block from its category and index + ReferenceBlock* getHiddenReferenceBlock(QString blockName); // get a hidden block by name, i.e. in category 100 FunctionalBlock* duplicateFunctionalBlock(FunctionalBlock* block); // adding a copy of a functional block to current group diff --git a/blast.creator.user b/blast.creator.user index 91a1bca..709b7ca 100755 --- a/blast.creator.user +++ b/blast.creator.user @@ -1,6 +1,6 @@ - + EnvironmentId diff --git a/lib/implementations/boxfilter_3x3_impl.xml b/lib/implementations/boxfilter_3x3_impl.xml index 6776fc1..50d2d0c 100644 --- a/lib/implementations/boxfilter_3x3_impl.xml +++ b/lib/implementations/boxfilter_3x3_impl.xml @@ -387,8 +387,6 @@ end process final_div_process; @{pix_out} <= std_logic_vector(mult_result(24 downto 17)); @{pix_out_enb} <= do_out; - -end rtl; diff --git a/lib/implementations/checker_impl.xml b/lib/implementations/checker_impl.xml index 2f6167a..a9d780d 100644 --- a/lib/implementations/checker_impl.xml +++ b/lib/implementations/checker_impl.xml @@ -55,8 +55,6 @@ end if; end if; end process check_process; - -end rtl; diff --git a/lib/implementations/clkrstgen_impl.xml b/lib/implementations/clkrstgen_impl.xml new file mode 100644 index 0000000..7e9d15a --- /dev/null +++ b/lib/implementations/clkrstgen_impl.xml @@ -0,0 +1,36 @@ + + + + + + + implementation of cljrstgen that does the connection between + external and internal clock and reset + none + + + + + + + + +signal dly : std_logic := '0'; +signal rst : std_logic := '0'; + +begin + + process(ext_clk) + begin + if(rising_edge(ext_clk)) then + dly <= (not(ext_reset) and dly and not(rst)) + or (not(ext_reset) and not(dly) and rst); + + rst <= (not(ext_reset) and not(dly) and not(rst)); + end if; + end process; + + clk <= ext_clk; + reset <= rst xor invert_reset; + + diff --git a/lib/implementations/deserializer_3x1_impl.xml b/lib/implementations/deserializer_3x1_impl.xml index 83971ef..9b48470 100644 --- a/lib/implementations/deserializer_3x1_impl.xml +++ b/lib/implementations/deserializer_3x1_impl.xml @@ -64,8 +64,6 @@ end process deser_process; @{data1_out_enb} <= do_out; @{data2_out_enb} <= do_out; @{data3_out_enb} <= do_out; - -end rtl; diff --git a/lib/implementations/impls.bmf b/lib/implementations/impls.bmf index 4c1682a..c49e68f 100644 Binary files a/lib/implementations/impls.bmf and b/lib/implementations/impls.bmf differ diff --git a/lib/implementations/logical_AND_3_impl.xml b/lib/implementations/logical_AND_3_impl.xml index 71aedf6..8d6e479 100644 --- a/lib/implementations/logical_AND_3_impl.xml +++ b/lib/implementations/logical_AND_3_impl.xml @@ -37,8 +37,6 @@ end if; end if; end process and_process; - -end rtl; diff --git a/lib/implementations/rgb3sx8_to_gs_impl.xml b/lib/implementations/rgb3sx8_to_gs_impl.xml index 4032757..26e171a 100644 --- a/lib/implementations/rgb3sx8_to_gs_impl.xml +++ b/lib/implementations/rgb3sx8_to_gs_impl.xml @@ -72,8 +72,6 @@ end process mult_process; @{gs_out} <= std_logic_vector(result(dsp_in_width+7 downto dsp_in_width)); @{gs_out_enb} <= do_out; - -end rtl; diff --git a/lib/implementations/rgb3sx8_to_ycbcr_3DSP_impl.xml b/lib/implementations/rgb3sx8_to_ycbcr_3DSP_impl.xml index 3db4b59..e186114 100644 --- a/lib/implementations/rgb3sx8_to_ycbcr_3DSP_impl.xml +++ b/lib/implementations/rgb3sx8_to_ycbcr_3DSP_impl.xml @@ -304,8 +304,6 @@ std_logic_vector(cb_dly1(7 downto 0)) when do_out_cb = '1' else std_logic_vector(cr(7 downto 0)) when do_out_cr = '1' else (others => '0'); @{ycbcr_out_enb} <= do_out_y or do_out_cb or do_out_cr; - -end rtl; diff --git a/lib/implementations/threshold_extctl_impl.xml b/lib/implementations/threshold_extctl_impl.xml index a136203..e417446 100644 --- a/lib/implementations/threshold_extctl_impl.xml +++ b/lib/implementations/threshold_extctl_impl.xml @@ -43,8 +43,6 @@ end if; end if; end if; end process threshold_process; - -end rtl; diff --git a/lib/references/apf27-wb-master.xml b/lib/references/apf27-wb-master.xml index 60a381d..8c770f8 100644 --- a/lib/references/apf27-wb-master.xml +++ b/lib/references/apf27-wb-master.xml @@ -2,9 +2,9 @@ - wishbone master for apf27 + clkrstgen - + This block is the wishbone master of the design, connected to the i.MX of APF27 diff --git a/lib/references/clkrstgen.xml b/lib/references/clkrstgen.xml new file mode 100644 index 0000000..79b60a9 --- /dev/null +++ b/lib/references/clkrstgen.xml @@ -0,0 +1,34 @@ + + + + + clkrstgen + + + + + This block generate a reset signal synchronous to clock + + + This block generate a reset signal synchronous to clock and is the entry point + of the external clock and asynchronous reset. + + + + + + + + + + + + + + + + + + + + diff --git a/lib/references/references.bmf b/lib/references/references.bmf index b01fb7c..201d7b6 100644 Binary files a/lib/references/references.bmf and b/lib/references/references.bmf differ diff --git a/projectfile.xsd b/projectfile.xsd index de6ec42..02ba8fd 100644 --- a/projectfile.xsd +++ b/projectfile.xsd @@ -229,7 +229,8 @@ - + + @@ -465,6 +466,7 @@ + diff --git a/threshold_extctl.vhd b/threshold_extctl.vhd deleted file mode 100644 index 90daeae..0000000 --- a/threshold_extctl.vhd +++ /dev/null @@ -1,77 +0,0 @@ -------------------------------------------------------------------------------- --- --- File : threshold _extctl.vhd --- Related files : --- --- Author(s) : stephane Domas (sdomas@univ-fcomte.fr) --- --- Creation Date : 2017/10/16 --- --- Description : This IP does a threshold based on a external signal --- --- --- Note : input data is kept as is depending on the fact that --- the keep_in signal is asserted to 1 or not. It it is not, --- then input is replaced by the default_value given as a --- generic. Note that keep_in_enb and data_in_enb must be --- asserted to 1 at the same time so that the block gives an output --- -------------------------------------------------------------------------------- - -library IEEE; -use IEEE.std_logic_1164.all; -use IEEE.numeric_std.all; - -entity threshold_extctl is - generic( - in_width : natural := 8; - default_value : natural := 0 - ); - port( - clk : in std_logic; - reset : in std_logic; - data_in : in std_logic_vector(in_width-1 downto 0); - data_in_enb : in std_logic; - keep_in : in std_logic; - keep_in_enb : in std_logic; - data_out : out std_logic_vector(in_width-1 downto 0); - data_out_enb : out std_logic - - ); -end threshold_extctl; - - -architecture rtl of threshold_extctl is - - -- Signals - signal def_val : unsigned(in_width-1 downto 0); - -begin - - def_val <= to_unsigned(default_value, in_width); - - threshold_process : process (clk, reset) - begin - if reset = '1' then - - data_out_enb <= '0'; - data_out <= (others => '0'); - - elsif rising_edge(clk) then - - data_out_enb <= '0'; - - if data_in_enb = '1' and keep_in_enb = '1' then - - if keep_in = '1' then - data_out <= data_in; - else - data_out <= std_logic_vector(def_val); - end if; - data_out_enb <= '1'; - end if; - end if; - end process threshold_process; - -end rtl; -