From: stephane Domas Date: Fri, 8 Dec 2017 16:50:39 +0000 (+0100) Subject: changes in output pattern comput X-Git-Url: https://bilbo.iut-bm.univ-fcomte.fr/and/gitweb/blast.git/commitdiff_plain/56f7c4239666506c59af42885f0bf0141d21a614 changes in output pattern comput --- diff --git a/AbstractInterface.cpp b/AbstractInterface.cpp index bdf342d..76654ff 100644 --- a/AbstractInterface.cpp +++ b/AbstractInterface.cpp @@ -10,11 +10,12 @@ AbstractInterface::AbstractInterface(AbstractBlock* _owner) { direction = Input; purpose = Data; type = Boolean; + endianess = LittleEndian; associatedIface = NULL; } -AbstractInterface::AbstractInterface(AbstractBlock* _owner, const QString& _name, const QString& _type, const QString& _width, int _direction, int _purpose) { +AbstractInterface::AbstractInterface(AbstractBlock* _owner, const QString& _name, int _direction, int _purpose, const QString& _type, const QString& _width, int _endianess) { owner = _owner; name = _name; @@ -22,6 +23,7 @@ AbstractInterface::AbstractInterface(AbstractBlock* _owner, const QString& _name direction = _direction; purpose = _purpose; type = typeFromString(_type); + endianess = _endianess; associatedIface = NULL; } @@ -32,6 +34,7 @@ AbstractInterface::AbstractInterface(AbstractInterface* other) { width = other->width; direction = other->direction; purpose = other->purpose; + endianess = LittleEndian; associatedIface = NULL; } @@ -51,23 +54,42 @@ bool AbstractInterface::isGroupInterface() { return false; } +QString AbstractInterface::getEndianessString() { + QString str="unknown"; + switch(endianess){ + case AbstractInterface::LittleEndian: + str = QString("little"); + break; + case AbstractInterface::BigEndian: + str = QString("big"); + break; + } + return str; +} + QString AbstractInterface::getPurposeString() { - QString str; - switch(purpose){ - case AbstractInterface::Data: - str = QString("data"); - break; - case AbstractInterface::Clock: - str = QString("clock"); - break; - case AbstractInterface::Reset: - str = QString("reset"); - break; - case AbstractInterface::Wishbone: - str = QString("wishbone"); - break; - } - return str; + QString str; + switch(purpose){ + case AbstractInterface::AnyPurpose: + str = QString("any"); + break; + case AbstractInterface::Data: + str = QString("data"); + break; + case AbstractInterface::Control: + str = QString("control"); + break; + case AbstractInterface::Clock: + str = QString("clock"); + break; + case AbstractInterface::Reset: + str = QString("reset"); + break; + case AbstractInterface::Wishbone: + str = QString("wishbone"); + break; + } + return str; } QString AbstractInterface::getDirectionString() { diff --git a/AbstractInterface.h b/AbstractInterface.h index 2c914d4..b318f92 100644 --- a/AbstractInterface.h +++ b/AbstractInterface.h @@ -25,6 +25,7 @@ class AbstractInterface { public : enum IfaceWidthType { Expression = 1, Boolean, Natural, Inherited}; //! Inherited is only for Group interface + enum IfaceWidthDir { LittleEndian = 1, BigEndian}; //! LittleEndian = X downto 0, BigEndian = 0 to X enum IfacePurpose { AnyPurpose = 0, Data = 1, Control, Clock, Reset, Wishbone }; enum IfaceDirection { AnyDirection = 0, Input = 1, Output = 2, InOut = 3 }; enum IfaceVHDLContext {AnyContext = 0, Entity = 1, Component = 2, Architecture = 3 }; // NB : 3 is when creating an instance of the block that owns this iface @@ -34,7 +35,7 @@ public : static int getIntPurpose(QString str); AbstractInterface(AbstractBlock* _owner); - AbstractInterface(AbstractBlock* _owner, const QString& _name, const QString& _type, const QString& _width, int _direction, int _purpose); + AbstractInterface(AbstractBlock* _owner, const QString& _name, int _direction, int _purpose, const QString& _type, const QString& _width, int _endianess = LittleEndian); AbstractInterface(AbstractInterface* other); virtual ~AbstractInterface(); @@ -42,6 +43,8 @@ public : inline QString getName() { return name;} inline int getType() { return type; } QString getTypeString(); + inline int getEndianess() { return endianess; } + QString getEndianessString(); inline QString getWidth() { return width;} inline int getPurpose() { return purpose;} QString getPurposeString(); @@ -58,6 +61,7 @@ public : inline void setName(const QString& _name) { name = _name; } inline void setWidth(const QString& _width) { width = _width; } inline void setType(int _type) { type = _type;} + inline void setEndianess(int _endianess) { endianess = _endianess;} inline void setType(const QString& _type) { type = typeFromString(_type);} void setPurpose(int _purpose); void setDirection(int _direction); @@ -77,10 +81,12 @@ public : protected: QString name; - int type; - QString width; int purpose; int direction; + int type; + QString width; + int endianess; + AbstractBlock* owner; /*! diff --git a/ConnectedInterface.cpp b/ConnectedInterface.cpp index 948388a..017401a 100644 --- a/ConnectedInterface.cpp +++ b/ConnectedInterface.cpp @@ -10,7 +10,7 @@ ConnectedInterface::ConnectedInterface(AbstractBlock* _owner) : AbstractInterfac } -ConnectedInterface::ConnectedInterface(AbstractBlock* _owner, const QString& _name, const QString& _type, const QString& _width, int _direction, int _purpose) : AbstractInterface(_owner, _name, _type, _width, _direction, _purpose) { +ConnectedInterface::ConnectedInterface(AbstractBlock* _owner, const QString& _name, int _direction, int _purpose, const QString& _type, const QString& _width) : AbstractInterface(_owner, _name, _direction, _purpose, _type, _width) { connectedFrom = NULL; outputPattern = NULL; } diff --git a/ConnectedInterface.h b/ConnectedInterface.h index 7866a8f..64afb9e 100644 --- a/ConnectedInterface.h +++ b/ConnectedInterface.h @@ -23,7 +23,7 @@ class ConnectedInterface : public AbstractInterface { public : ConnectedInterface(AbstractBlock* _owner); - ConnectedInterface(AbstractBlock* _owner, const QString& _name, const QString& _type, const QString& _width, int _direction, int _purpose); + ConnectedInterface(AbstractBlock* _owner, const QString& _name, int _direction, int _purpose, const QString& _type, const QString& _width); ~ConnectedInterface(); // getters diff --git a/Dispatcher.cpp b/Dispatcher.cpp index 1df7ded..a416f95 100644 --- a/Dispatcher.cpp +++ b/Dispatcher.cpp @@ -421,7 +421,7 @@ void Dispatcher::duplicateInterfaceItem(InterfaceItem *item) { // creating control interface if needed if (refI->getAssociatedIface() != NULL) { QString ctlName = cloneIface->getName()+"_enb"; - ReferenceInterface* ctlIface = new ReferenceInterface(refB,ctlName,"boolean","1",cloneIface->getDirection(), AbstractInterface::Control, 1); + ReferenceInterface* ctlIface = new ReferenceInterface(refB,ctlName,cloneIface->getDirection(), AbstractInterface::Control,"boolean","1", AbstractInterface::LittleEndian, 1); refB->addInterface(ctlIface); if (! ctlIface->setAssociatedIface(cloneIface)) { cerr << "Abnormal case while cloning an interface and creating its associated control interface" << endl; diff --git a/FunctionalBlock.cpp b/FunctionalBlock.cpp index 534625d..7be000a 100644 --- a/FunctionalBlock.cpp +++ b/FunctionalBlock.cpp @@ -142,7 +142,15 @@ void FunctionalBlock::createPatterns() throw(Exception) { } catch(Exception e) { throw(e); - } + } + cout << "PP of " << qPrintable(name) << endl; + QMapIterator* > it(productionPattern); + while (it.hasNext()) { + it.next(); + QList* pat = it.value(); + foreach(char c, *pat) cout << (int)c; + cout << endl; + } } void FunctionalBlock::createDelta() throw(Exception) { @@ -308,7 +316,7 @@ QList* FunctionalBlock::expandPattern(const QString& patternIn) throw(Exce int offset = 0; QList* patternOut = new QList(); try { - expandPatternRecur(p,&offset, patternOut); + patternOut->append(expandPatternRecur(p,&offset)); } catch(Exception e) { throw(e); @@ -317,28 +325,30 @@ QList* FunctionalBlock::expandPattern(const QString& patternIn) throw(Exce return patternOut; } -void FunctionalBlock::expandPatternRecur(const QString& patternIn, int *offset, QList* patternOut) throw(Exception) { +QList FunctionalBlock::expandPatternRecur(const QString& patternIn, int *offset) throw(Exception) { + QList patternOut; + while ((*offset < patternIn.size()) && (patternIn.at(*offset) != ')')) { QChar c = patternIn.at(*offset); if (c == '(') { *offset += 1; try { - expandPatternRecur(patternIn,offset, patternOut); + patternOut.append(expandPatternRecur(patternIn,offset)); } catch(Exception e) { throw(e); } } else if (c == '0') { - patternOut->append(0); + patternOut.append(0); } else if (c == '1') { - patternOut->append(1); + patternOut.append(1); } else if (c == 'X') { - patternOut->append(-1); + patternOut.append(-1); } else if (c == '{') { *offset += 1; @@ -358,11 +368,11 @@ void FunctionalBlock::expandPatternRecur(const QString& patternIn, int *offset, throw(e); } // repeat just the last value in currentGroup - char last = patternOut->last(); + char last = patternOut.last(); //cout << "repeat last char " << repeat << " times : " << (int)last << endl; for(int i=1;i<(int)repeat;i++) { - patternOut->append(last); + patternOut.append(last); } } *offset += 1; @@ -391,11 +401,12 @@ void FunctionalBlock::expandPatternRecur(const QString& patternIn, int *offset, foreach (char c, currentGroup) cout <<(int)c; cout << endl; */ - QList single = *patternOut; + QList single = patternOut; for(int i=1;i<(int)repeat;i++) { - patternOut->append(single); + patternOut.append(single); } } + return patternOut; } double FunctionalBlock::evaluateExpression(const QString& expression) throw(Exception) { @@ -722,6 +733,132 @@ void FunctionalBlock::computeOutputPattern(int nbExec) throw(Exception) { } } +/* + +void FunctionalBlock::computeOutputPattern(int nbExec) throw(Exception) { + static QString fctName = "FunctionalBlock::computeOutputPattern()"; +#ifdef DEBUG_FCTNAME + cout << "call to " << qPrintable(fctName) << endl; +#endif + + // 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()) { + FunctionalInterface* connIface = AI_TO_FUN(iface); + // create output pattern + QList* pp = productionPattern.value(connIface); + QList* pattern = new QList(*pp); + for(int i=1;iappend(*pp); + // assign pattern to interface + connIface->setOutputPattern(pattern); + // store it in QMap + outputPattern.insert(connIface,pattern); + } + } + else { + cout << "computing output pattern of " << qPrintable(name) << endl; + + // in case of inputPattern not created, do it + if (lengthIP <= 0) { + // collect the input patterns for each input + try { + createInputPattern(); + } + catch(Exception e) { + throw(e); + } + cout << "input pattern array initialized with min. len " << lengthIP << endl; + } + + // initialize the output pattern + lengthOP = 0; + foreach(AbstractInterface* iface, getControlOutputs()) { + FunctionalInterface* connIface = AI_TO_FUN(iface); + lengthOP = lengthIP+productionPattern.value(connIface)->size(); + QList* pattern = new QList(); + for(int i=0;iappend(0); + connIface->setOutputPattern(pattern); + outputPattern.insert(connIface,pattern); + } + cout << "output pattern array initialized" << endl; + + int clock = 0; + nbExec = 0; + // search for the beginning of the first execution. + while ((clock < lengthIP) && (! isValidDataGroup(inputPattern,clock))) clock++; + cout << "found 1st exec clock: " << clock << endl; + + while (clock < lengthIP) { + // initialize counters for current execution. + int p = 0; // index in production pattern + int o = 0; // clock+o will give the clock cycle of each output group + int cip = 0; // clock+cip give the clock cycle of an input group + int ccp = 0; // ccp give a column in the consumptio pattern + int nip = 0; // number of input data groups already consumed during the current execution, used while exploring IP + int ncp = 0; // number of input data groups already consumed during the current execution, used while exploring CP + bool cannotCompleteExec = false; + for(int m=0;m* >& patternSrc, int srcCol, const QMap* >& patternDest, int destCol) { if (patternSrc.size() != patternDest.size()) return false; diff --git a/FunctionalBlock.h b/FunctionalBlock.h index 440c154..b3cfbc4 100644 --- a/FunctionalBlock.h +++ b/FunctionalBlock.h @@ -75,7 +75,7 @@ private: double evaluateExpression(const QString& expression) throw(Exception); QList* expandPattern(const QString& patternIn) throw(Exception); - void expandPatternRecur(const QString& patternIn, int* offset, QList *patternOut) throw(Exception); + QList expandPatternRecur(const QString& patternIn, int* offset) throw(Exception); /*! * \brief samePatterns * \param patternSrc the pattern that must be tested with patternDest (is patternDest == patternDest) diff --git a/FunctionalInterface.cpp b/FunctionalInterface.cpp index 145b86a..2fc093e 100644 --- a/FunctionalInterface.cpp +++ b/FunctionalInterface.cpp @@ -17,6 +17,7 @@ FunctionalInterface::FunctionalInterface(AbstractBlock* _owner, ReferenceInterfa reference = _reference; name = reference->getName(); + endianess = reference->getEndianess(); width = reference->getWidth(); direction = reference->getDirection(); purpose = reference->getPurpose(); diff --git a/GroupInterface.cpp b/GroupInterface.cpp index ecc6ba7..e87c14a 100644 --- a/GroupInterface.cpp +++ b/GroupInterface.cpp @@ -2,7 +2,7 @@ #include "FunctionalInterface.h" #include "GroupBlock.h" -GroupInterface::GroupInterface(AbstractBlock* _owner, const QString& _name, int _direction, int _purpose) throw(Exception) : ConnectedInterface(_owner,_name,"inherited","",_direction,_purpose) { +GroupInterface::GroupInterface(AbstractBlock* _owner, const QString& _name, int _direction, int _purpose) throw(Exception) : ConnectedInterface(_owner,_name,_direction,_purpose,"inherited","") { if (! _owner->isGroupBlock()) throw(Exception(BLOCK_INVALID_TYPE)); connectedFrom = NULL; diff --git a/GroupScene.cpp b/GroupScene.cpp index 48de27e..778a0b0 100644 --- a/GroupScene.cpp +++ b/GroupScene.cpp @@ -38,6 +38,17 @@ GroupScene::~GroupScene() { groupItem = NULL; } +/* +void GroupScene::mouseMoveEvent(QGraphicsSceneMouseEvent *event) { + + //QGraphicsScene::mouseMoveEvent(event); + + QPointF p = event->scenePos(); + cout << p.x() << "," << p.y() << endl; + +} +*/ + void GroupScene::setSelectedInterface(int id, InterfaceItem* iface) { if ((id < 1)|| (id > 2)) return; selectedInterfaces[id-1] = iface; @@ -211,11 +222,11 @@ void GroupScene::unselecteInterfaces() { if (selectedInterfaces[0] != NULL) { selectedInterfaces[0]->selected = false; - selectedInterfaces[0] == NULL; + selectedInterfaces[0] = NULL; } if (selectedInterfaces[1] != NULL) { selectedInterfaces[1]->selected = false; - selectedInterfaces[1] == NULL; + selectedInterfaces[1] = NULL; } } diff --git a/GroupScene.h b/GroupScene.h index a691a6d..e32dd53 100644 --- a/GroupScene.h +++ b/GroupScene.h @@ -47,6 +47,8 @@ public: GroupScene(GroupScene* _parentScene, GroupWidget* _window, Dispatcher* _dispatcher, Parameters* _params, bool topScene = false, QObject *parent = 0); ~GroupScene(); + //void mouseMoveEvent(QGraphicsSceneMouseEvent *event); + // attributes getters inline GroupItem* getGroupItem() {return groupItem;} inline QList getBoxItems() { return boxItems; } diff --git a/ReferenceBlock.cpp b/ReferenceBlock.cpp index a31db67..037c644 100644 --- a/ReferenceBlock.cpp +++ b/ReferenceBlock.cpp @@ -215,6 +215,7 @@ void ReferenceBlock::loadInterfaces(QDomElement &elt) throw(Exception) { QString nameStr; QString typeStr; QString widthStr; + QString endianStr; QString purposeStr; int purpose; QString multStr; @@ -232,6 +233,17 @@ void ReferenceBlock::loadInterfaces(QDomElement &elt) throw(Exception) { nameStr = eltInput.attribute("name","none"); typeStr = eltInput.attribute("type","none"); widthStr = eltInput.attribute("width","none"); + endianStr = eltInput.attribute("endian","none"); + int endianess; + if ((endianStr == "none") || (endianStr == "little")) { + endianess = AbstractInterface::LittleEndian; + } + else if (endianStr == "big") { + endianess = AbstractInterface::BigEndian; + } + else { + throw (Exception(BLOCKFILE_CORRUPTED)); + } purposeStr = eltInput.attribute("purpose","none"); cout << "block : " << this->getName().toStdString() << endl; cout << "purpose for " << nameStr.toStdString() << " : " << purposeStr.toStdString() << endl; @@ -240,7 +252,7 @@ void ReferenceBlock::loadInterfaces(QDomElement &elt) throw(Exception) { multStr = eltInput.attribute("multiplicity","none"); mult = ReferenceInterface::translateMultiplicity(multStr); - inter = new ReferenceInterface(this,nameStr,typeStr,widthStr,AbstractInterface::Input, purpose, mult); + inter = new ReferenceInterface(this,nameStr,AbstractInterface::Input, purpose, typeStr, widthStr, endianess, mult); inputs.append(inter); } // getting each control @@ -252,7 +264,7 @@ void ReferenceBlock::loadInterfaces(QDomElement &elt) throw(Exception) { AbstractInterface* dataIface = getIfaceFromName(nameStr); if (dataIface == NULL) throw (Exception(BLOCKFILE_CORRUPTED)); nameStr = dataIface->getName()+"_enb"; - inter = new ReferenceInterface(this,nameStr,"boolean","1",AbstractInterface::Input, AbstractInterface::Control, 1); + inter = new ReferenceInterface(this,nameStr,AbstractInterface::Input, AbstractInterface::Control,"boolean","1", AbstractInterface::LittleEndian, 1); if (!inter->setAssociatedIface(dataIface)) { throw (Exception(BLOCKFILE_CORRUPTED)); } @@ -267,12 +279,23 @@ void ReferenceBlock::loadInterfaces(QDomElement &elt) throw(Exception) { nameStr = eltOutput.attribute("name","none"); typeStr = eltOutput.attribute("type","none"); widthStr = eltOutput.attribute("width","none"); + endianStr = eltOutput.attribute("endian","none"); + int endianess; + if ((endianStr == "none") || (endianStr == "little")) { + endianess = AbstractInterface::LittleEndian; + } + else if (endianStr == "big") { + endianess = AbstractInterface::BigEndian; + } + else { + throw (Exception(BLOCKFILE_CORRUPTED)); + } purposeStr = eltOutput.attribute("purpose","none"); purpose = ReferenceInterface::translatePurpose(purposeStr); multStr = eltOutput.attribute("multiplicity","none"); mult = ReferenceInterface::translateMultiplicity(multStr); - inter = new ReferenceInterface(this,nameStr,typeStr,widthStr,AbstractInterface::Output, purpose, mult); + inter = new ReferenceInterface(this,nameStr,AbstractInterface::Output, purpose,typeStr,widthStr, endianess, mult); outputs.append(inter); } // getting each control @@ -284,7 +307,7 @@ void ReferenceBlock::loadInterfaces(QDomElement &elt) throw(Exception) { AbstractInterface* dataIface = getIfaceFromName(nameStr); if (dataIface == NULL) throw (Exception(BLOCKFILE_CORRUPTED)); nameStr = dataIface->getName()+"_enb"; - inter = new ReferenceInterface(this,nameStr,"boolean","1",AbstractInterface::Output, AbstractInterface::Control, 1); + inter = new ReferenceInterface(this,nameStr,AbstractInterface::Output, AbstractInterface::Control,"boolean","1",AbstractInterface::LittleEndian, 1); if (!inter->setAssociatedIface(dataIface)) { throw (Exception(BLOCKFILE_CORRUPTED)); } @@ -300,12 +323,23 @@ void ReferenceBlock::loadInterfaces(QDomElement &elt) throw(Exception) { nameStr = eltBidir.attribute("name","none"); typeStr = eltBidir.attribute("type","none"); widthStr = eltBidir.attribute("width","none"); + endianStr = eltBidir.attribute("endian","none"); + int endianess; + if ((endianStr == "none") || (endianStr == "little")) { + endianess = AbstractInterface::LittleEndian; + } + else if (endianStr == "big") { + endianess = AbstractInterface::BigEndian; + } + else { + throw (Exception(BLOCKFILE_CORRUPTED)); + } purposeStr = eltBidir.attribute("purpose","none"); purpose = ReferenceInterface::translatePurpose(purposeStr); multStr = eltBidir.attribute("multiplicity","none"); mult = ReferenceInterface::translateMultiplicity(multStr); - inter = new ReferenceInterface(this,nameStr,typeStr,widthStr,AbstractInterface::InOut, purpose, mult); + inter = new ReferenceInterface(this,nameStr,AbstractInterface::InOut, purpose,typeStr,widthStr, endianess, mult); bidirs.append(inter); } } @@ -320,11 +354,11 @@ void ReferenceBlock::createInterfaceForParameters() throw(Exception){ cout << "creating interface for parameter wb " << qPrintable(p->getName()) << endl; if (p->getWBAccess() == BlockParameter::Read) { - iface = new ReferenceInterface(this,p->getName(),p->getTypeString(),p->getWidth(), AbstractInterface::Output, AbstractInterface::Wishbone,1); + iface = new ReferenceInterface(this,p->getName(), AbstractInterface::Output, AbstractInterface::Wishbone, p->getTypeString(),p->getWidth(), AbstractInterface::LittleEndian, 1); outputs.append(iface); } else if (p->getWBAccess() == BlockParameter::Write) { - iface = new ReferenceInterface(this,p->getName(),p->getTypeString(),p->getWidth(), AbstractInterface::Input, AbstractInterface::Wishbone,1); + iface = new ReferenceInterface(this,p->getName(), AbstractInterface::Input, AbstractInterface::Wishbone,p->getTypeString(),p->getWidth(),AbstractInterface::LittleEndian,1); inputs.append(iface); } else { diff --git a/ReferenceInterface.cpp b/ReferenceInterface.cpp index a0f50ca..8936952 100644 --- a/ReferenceInterface.cpp +++ b/ReferenceInterface.cpp @@ -7,12 +7,14 @@ ReferenceInterface::ReferenceInterface(AbstractBlock* _owner) throw(Exception) } ReferenceInterface::ReferenceInterface(AbstractBlock* _owner, - const QString& _name, const QString&_type, - const QString& _width, + const QString& _name, int _direction, int _purpose, + const QString& _type, + const QString& _width, + int _endianess, int _multiplicity) -throw (Exception) : AbstractInterface(_owner, _name, _type, _width, _direction, _purpose) { +throw (Exception) : AbstractInterface(_owner, _name, _direction, _purpose, _type, _width) { if (_owner->isReferenceBlock()) throw(Exception(BLOCK_INVALID_TYPE)); diff --git a/ReferenceInterface.h b/ReferenceInterface.h index d5219b6..1ba21ed 100644 --- a/ReferenceInterface.h +++ b/ReferenceInterface.h @@ -19,7 +19,7 @@ class ReferenceInterface : public AbstractInterface { public : ReferenceInterface(AbstractBlock *_owner) throw(Exception); - ReferenceInterface(AbstractBlock* _owner, const QString& _name, const QString& _type, const QString& _width, int _direction, int _purpose, int _multiplicity=1) throw (Exception); + ReferenceInterface(AbstractBlock* _owner, const QString& _name, int _direction, int _purpose, const QString& _type, const QString& _width, int _endianess = LittleEndian, int _multiplicity=1) throw (Exception); // getters inline int getMultiplicity() { return multiplicity; } diff --git a/VHDLConverter.cpp b/VHDLConverter.cpp index ea8991e..42fff3a 100644 --- a/VHDLConverter.cpp +++ b/VHDLConverter.cpp @@ -1,56 +1,66 @@ #include "VHDLConverter.h" +#include "BlockParameterGeneric.h" +#include "BlockParameterUser.h" +#include "BlockParameterWishbone.h" +#include "ReferenceInterface.h" using namespace std; using namespace Qt; VHDLConverter::VHDLConverter(QWidget *parent) : QWidget(parent) { - - QLabel *labelAppli, *lblBrief, *lblDesc, *lblName, *lblPort, *lblGen; - - loadBut = new QPushButton("load VHDL"); - genBut = new QPushButton("generate XML"); - QHBoxLayout *widgetLayout = new QHBoxLayout; - QVBoxLayout *left = new QVBoxLayout; - QVBoxLayout *right = new QVBoxLayout; - - scrollDataPort = new QScrollArea; - scrollDataPort->setWidgetResizable(true); - twDataPort = new QTableWidget(this); - scrollDataPort->setWidget(twDataPort); - scrollGenerics = new QScrollArea; - scrollGenerics->setWidgetResizable(true); - twGenerics = new QTableWidget(this); - scrollGenerics->setWidget(twGenerics); - teName = new QTextEdit; - teBrief = new QTextEdit; - teDesc = new QTextEdit; - lblName = new QLabel("Block name :"); - lblBrief = new QLabel("Enter a brief description : "); - lblDesc = new QLabel("Enter a detailled description : "); - lblPort = new QLabel("Ports :"); - lblGen = new QLabel("Generics :"); - - connect(loadBut, SIGNAL(clicked()),this, SLOT(loadVHDLFile())); - connect(genBut, SIGNAL(clicked()), this, SLOT(generateXml())); - - left->addWidget(loadBut); - left->addWidget(lblPort); - left->addWidget(scrollDataPort); - left->addWidget(lblGen); - left->addWidget(scrollGenerics); - - right->addWidget(lblName); - right->addWidget(teName); - right->addWidget(lblBrief); - right->addWidget(teBrief); - right->addWidget(lblDesc); - right->addWidget(teDesc); - right->addWidget(genBut); - - widgetLayout->addLayout(left); - widgetLayout->addLayout(right); - setLayout(widgetLayout); - show(); + + QLabel *labelAppli, *lblBrief, *lblDesc, *lblEntName, *lblLongName, *lblPort, *lblGen; + + loadBut = new QPushButton("load VHDL"); + genBut = new QPushButton("generate XML"); + QHBoxLayout *widgetLayout = new QHBoxLayout; + QVBoxLayout *left = new QVBoxLayout; + QVBoxLayout *right = new QVBoxLayout; + + scrollPorts = new QScrollArea; + scrollPorts->setWidgetResizable(true); + twPorts = new QTableWidget(this); + twPorts->setColumnCount(5); + scrollPorts->setWidget(twPorts); + scrollGenerics = new QScrollArea; + scrollGenerics->setWidgetResizable(true); + twGenerics = new QTableWidget(this); + twGenerics->setColumnCount(3); + scrollGenerics->setWidget(twGenerics); + editEntityName = new QLineEdit; + editLongName = new QLineEdit; + teBrief = new QTextEdit; + teDesc = new QTextEdit; + lblEntName = new QLabel("Entity name :"); + lblLongName = new QLabel("Block long name :"); + lblBrief = new QLabel("Enter a brief description : "); + lblDesc = new QLabel("Enter a detailled description : "); + lblPort = new QLabel("Ports :"); + lblGen = new QLabel("Generics :"); + + connect(loadBut, SIGNAL(clicked()),this, SLOT(loadVHDLFile())); + connect(genBut, SIGNAL(clicked()), this, SLOT(generateXml())); + + left->addWidget(loadBut); + left->addWidget(lblPort); + left->addWidget(scrollPorts); + left->addWidget(lblGen); + left->addWidget(scrollGenerics); + + right->addWidget(lblEntName); + right->addWidget(editEntityName); + right->addWidget(lblLongName); + right->addWidget(editLongName); + right->addWidget(lblBrief); + right->addWidget(teBrief); + right->addWidget(lblDesc); + right->addWidget(teDesc); + right->addWidget(genBut); + + widgetLayout->addLayout(left); + widgetLayout->addLayout(right); + setLayout(widgetLayout); + show(); } VHDLConverter::~VHDLConverter() { @@ -61,7 +71,7 @@ QString VHDLConverter::skipBlankAndComments(QTextStream &in) { QString line = ""; - // skipping blank/comment lines + // skipping blank/comment lines while ( (line.isEmpty()) || ((line.at(0) == '-') && (line.at(1) == '-')) ) { if (in.atEnd()) { return ""; @@ -82,7 +92,7 @@ QString VHDLConverter::readLibraries(QTextStream &in) throw(Exception) { line = skipBlankAndComments(in); if (line == "") { throw(Exception(VHDLFILE_CORRUPTED)); - } + } while (! line.contains("entity",Qt::CaseInsensitive)) { @@ -94,21 +104,21 @@ QString VHDLConverter::readLibraries(QTextStream &in) throw(Exception) { QString libName = matchLib.captured(1); libName = libName.toLower(); - cout << "matching library: " << qPrintable(libName) << endl; + cout << "matching library: " << qPrintable(libName) << endl; - if (!packages.contains(libName)) { - packages.insert(libName,new QList()); - } + if (!packages.contains(libName)) { + packages.insert(libName,new QList()); + } } else if (matchPack.hasMatch()) { cout << "matching packages" << endl; QString libName = matchPack.captured(1); - QString packName = matchPack.captured(2); + QString packName = matchPack.captured(2); libName = libName.toLower(); - packName = packName.toLower(); - + packName = packName.toLower(); + if (libName == "work") { if (!packages.contains("work")) { packages.insert("work",new QList()); @@ -122,9 +132,8 @@ QString VHDLConverter::readLibraries(QTextStream &in) throw(Exception) { else if (!packages.contains(libName)) throw(Exception(VHDLFILE_CORRUPTED)); QList* lstPack = packages.value(libName); - QString s = libName + "." + packName; - lstPack->append(s); - cout << qPrintable(s) << endl; + lstPack->append(packName); + cout << qPrintable(packName) << endl; } @@ -150,7 +159,7 @@ QString VHDLConverter::readEntity(QTextStream &in) throw(Exception) { throw(Exception(VHDLFILE_CORRUPTED)); } - while (! line.contains("architecture",Qt::CaseInsensitive)) { + while (! line.startsWith("architecture",Qt::CaseInsensitive)) { QRegularExpressionMatch matchGen = rxGen.match(line); QRegularExpressionMatch matchPorts = rxPorts.match(line); @@ -202,8 +211,12 @@ void VHDLConverter::readGenerics(QTextStream &in) throw(Exception) { cout << "matching generic value" << endl; QString genName = matchGen.captured(1); QString genType = matchGen.captured(2); + genType = genType.toLower(); QString genValue = matchGen.captured(4); + genValue = genValue.toLower(); cout << qPrintable(genName) << " " << qPrintable(genType) << " " << qPrintable(genValue) << endl; + BlockParameter* param = new BlockParameterGeneric(block,genName,genType,genValue); + block->addParameter(param); } line = skipBlankAndComments(in); @@ -211,13 +224,15 @@ void VHDLConverter::readGenerics(QTextStream &in) throw(Exception) { throw(Exception(VHDLFILE_CORRUPTED)); } line = line.remove(' '); - cout << "read line = " << qPrintable(line) << endl; + cout << "read line = " << qPrintable(line) << endl; } } void VHDLConverter::readPorts(QTextStream &in) throw(Exception) { - QRegularExpression rxPort("^([^:]+):(in|out|inout)([a-zA-Z0-9_]+)(\\([^:)]*\\))?(:=)?([^;]*);?$",QRegularExpression::CaseInsensitiveOption); + QRegularExpression rxPort("^([^ :]+) ?: ?(in|out|inout) ([a-zA-Z0-9_]+) ?(\\([^:)]*\\))? ?(:=)? ?([^;]*) ?;?$",QRegularExpression::CaseInsensitiveOption); + QRegularExpression rxSizeDownTo("^\\((.*) downto (.*)\\)$",QRegularExpression::CaseInsensitiveOption); + QRegularExpression rxSizeTo("^\\((.*) to (.*)\\)$",QRegularExpression::CaseInsensitiveOption); QString line = ""; @@ -225,10 +240,11 @@ void VHDLConverter::readPorts(QTextStream &in) throw(Exception) { if (line == "") { throw(Exception(VHDLFILE_CORRUPTED)); } - line = line.remove(' '); while (! line.contains(QRegExp("^\\);$"))) { + line = line.toLower(); + QRegularExpressionMatch matchPort = rxPort.match(line); if (matchPort.hasMatch()) { @@ -238,20 +254,118 @@ void VHDLConverter::readPorts(QTextStream &in) throw(Exception) { QString portType = matchPort.captured(3); QString portSize = matchPort.captured(4); QString portValue = matchPort.captured(6); - cout << qPrintable(portName) << " " << qPrintable(portDir) << " " << qPrintable(portType) << " " << qPrintable(portSize) << " " << qPrintable(portValue) << endl; + cout << qPrintable(portName) << "|" << qPrintable(portDir) << "|" << qPrintable(portType) << "|" << qPrintable(portSize) << "|" << qPrintable(portValue) << endl; + ReferenceInterface* iface = NULL; + bool isOk = true; + int direction = AbstractInterface::AnyDirection; + int endianess = AbstractInterface::LittleEndian; + int purpose = AbstractInterface::AnyPurpose; + + QString widthStr = "a"; + + if (portDir == "in") { + direction = AbstractInterface::Input; + } + else if (portDir == "out") { + direction = AbstractInterface::Output; + } + else if (portDir == "inout") { + direction = AbstractInterface::InOut; + } + else { + cerr << "Unknown direction for port " << qPrintable(portName) << endl; + isOk = false; + } + QString typeStr=""; + if (portType == "std_logic") { + typeStr = "boolean"; + widthStr="1"; + } + else if (portType == "std_logic_vector") { + + if (portSize.contains("downto")) { + QRegularExpressionMatch matchSize = rxSizeDownTo.match(portSize); + endianess = AbstractInterface::LittleEndian; + if (matchSize.captured(2) != "0") { + cerr << "invalid size for port " << qPrintable(portName) << endl; + isOk = false; + } + else { + widthStr = matchSize.captured(1); + } + } + else if (portSize.contains("to")) { + QRegularExpressionMatch matchSize = rxSizeTo.match(portSize); + endianess = AbstractInterface::BigEndian; + if (matchSize.captured(1) != "0") { + cerr << "invalid size for port " << qPrintable(portName) << endl; + isOk = false; + } + else { + widthStr = matchSize.captured(2); + } + } + else { + cerr << "invalid size for port " << qPrintable(portName) << endl; + isOk = false; + } + + QVariant msb(widthStr); + bool ok; + int size = msb.toInt(&ok); + if (ok) { + typeStr = "natural"; + } + else { + typeStr ="expression"; + } + } + else { + cerr << "Unknown type for port " << qPrintable(portName) << endl; + isOk = false; + } + + if (isOk) { + // trying to guess the purpose from name + if ((portName.contains("clk"))||(portName.contains("clock"))) { + purpose = AbstractInterface::Clock; + } + else if ((portName.contains("rst"))||(portName.contains("reset"))) { + purpose = AbstractInterface::Reset; + } + else if (portName.endsWith("_enb")) { + purpose = AbstractInterface::Control; + } + else if (portName.startsWith("wb_")) { + purpose = AbstractInterface::Wishbone; + } + else { + purpose = AbstractInterface::Data; + } + iface = new ReferenceInterface(block,portName,direction,purpose,typeStr,widthStr,endianess,1); + block->addInterface(iface); + } } line = skipBlankAndComments(in); if (line == "") { throw(Exception(VHDLFILE_CORRUPTED)); } - line = line.remove(' '); - cout << "read line = " << qPrintable(line) << endl; + cout << "read line = " << qPrintable(line) << endl; } } void VHDLConverter::readArchitecture(QTextStream &in) throw(Exception) { + + QString line = ""; + QString endLine = "end "+archName; + + while (!line.startsWith(endLine)) { + line = in.readLine(); + if (!line.isEmpty()) line = line.simplified(); + archLines.append(line); + } } @@ -260,258 +374,502 @@ void VHDLConverter::readArchitecture(QTextStream &in) throw(Exception) { // You can edit the descriptions in the right, one for the brief description, the other for the detailled. void VHDLConverter::loadVHDLFile() { - QString line, portName, portType, portId, genName, genType, genValue; - QStringList *portNameList, *portTypeList, *portIdList, *genNameList, *genTypeList, *genValueList; - cpt = 0; - twDataPort->setColumnCount(3); - twDataPort->setRowCount(cpt); - twGenerics->setColumnCount(3); - twGenerics->setRowCount(cpt); - portNameList = new QStringList; - portTypeList = new QStringList; - portIdList = new QStringList; - genNameList = new QStringList; - genTypeList = new QStringList; - genValueList = new QStringList; - - - fileName = QFileDialog::getOpenFileName(this, - tr("Open File"), QDir::homePath() , tr("Files (*.txt *.vhd)")); - QFile file(fileName); - - if(!file.open(QIODevice::ReadOnly | QIODevice::Text)) - return; - QTextStream ts(&file); - - QString entityLine = ""; - try { - entityLine = readLibraries(ts); + QString fileName = QFileDialog::getOpenFileName(this, + tr("Open File"), QDir::homePath() , tr("Files (*.txt *.vhd)")); + QFile file(fileName); + + if(!file.open(QIODevice::ReadOnly | QIODevice::Text)) + return; + QTextStream ts(&file); + + block = new ReferenceBlock(fileName); + + QString entityLine = ""; + try { + entityLine = readLibraries(ts); + } + catch(Exception e) { + cerr << "VHDL seems to be malformed" << endl; + return; + } + + QRegularExpression rxEnt("^entity (.+) is$",QRegularExpression::CaseInsensitiveOption); + QRegularExpressionMatch matchEnt = rxEnt.match(entityLine); + if (!matchEnt.hasMatch()) { + cerr << "VHDL seems to be malformed" << endl; + return; + } + entityName = matchEnt.captured(1); + cout << "found entity " << qPrintable(entityName) << endl; + + QString archLine = ""; + try { + archLine = readEntity(ts); + } + catch(Exception e) { + cerr << "VHDL seems to be malformed" << endl; + return; + } + + QRegularExpression rxArch("^architecture (.+) of (.+) is$",QRegularExpression::CaseInsensitiveOption); + QRegularExpressionMatch matchArch = rxArch.match(archLine); + if (!matchArch.hasMatch()) { + cerr << "VHDL seems to be malformed" << endl; + return; + } + archName = matchArch.captured(1); + cout << "found arch " << qPrintable(archName) << " for entity " << qPrintable(matchArch.captured(2)) << endl; + + try { + readArchitecture(ts); + } + catch(Exception e) { + cerr << "VHDL seems to be malformed" << endl; + return; + } + file.close(); + + + QList lstGenerics = block->getGenericParameters(); + twGenerics->setRowCount(lstGenerics.size()); + int i = 0; + foreach(BlockParameter* param, lstGenerics) { + twGenerics->setItem(i, 0, new QTableWidgetItem(param->getName())); + twGenerics->setItem(i, 1, new QTableWidgetItem(param->getTypeString())); + twGenerics->setItem(i, 2, new QTableWidgetItem(param->getValue().toString())); + i++; + } + + lstIface = block->getInputs(); + lstIface.append(block->getOutputs()); + lstIface.append(block->getBidirs()); + + twPorts->setRowCount(lstIface.size()); + purposeDelegate = new IfacePurposeDelegate(); + twPorts->setItemDelegateForColumn(3,purposeDelegate); + + i=0; + foreach(AbstractInterface* iface, lstIface) { + twPorts->setItem(i, 0, new QTableWidgetItem(iface->getName())); + twPorts->setItem(i, 1, new QTableWidgetItem(iface->getDirectionString())); + QString widthStr=""; + if (iface->getType() == AbstractInterface::Boolean) { + widthStr = "std_logic"; } - catch(Exception e) { - cerr << "VHDL seems to be malformed" << endl; - return; + else { + widthStr = "std_logic_vector("; + if (iface->getEndianess() == AbstractInterface::LittleEndian) { + widthStr += iface->getWidth(); + widthStr += " downto 0)"; + } + else { + widthStr += "0 to "; + widthStr += iface->getWidth(); + widthStr += ")"; + } + } + twPorts->setItem(i, 2, new QTableWidgetItem(widthStr)); + + QTableWidgetItem* item = new QTableWidgetItem(iface->getPurposeString()); + twPorts->setItem(i, 3, item); + + // trying to find wihch other iface this one controls + QString assoInter = "N/A"; + if (iface->getPurpose() == AbstractInterface::Control) { + QString name = iface->getName(); + name.remove(name.size()-4,4); // remove _enb at the end + foreach(AbstractInterface* inter, lstIface) { + if ((inter != iface) && (inter->getName().contains(name))) { + assoInter = inter->getName(); + iface->setAssociatedIface(inter); + } + } + } + QTableWidgetItem* itemAsso = new QTableWidgetItem(assoInter); + if (iface->getPurpose() != AbstractInterface::Control) { + itemAsso->setFlags(Qt::NoItemFlags); } + twPorts->setItem(i, 4, itemAsso); - QRegularExpression rxEnt("^entity[\\s\\t]+(.+)[\\s\\t]+is$",QRegularExpression::CaseInsensitiveOption); - QRegularExpressionMatch matchEnt = rxEnt.match(entityLine); - if (!matchEnt.hasMatch()) { - cerr << "VHDL seems to be malformed" << endl; - return; + i++; + } + + connect(twPorts,SIGNAL(itemChanged(QTableWidgetItem*)),this,SLOT(searchAssociatedPort(QTableWidgetItem*))); + + //file.close(); + + //scrollPorts->setWidget(twPorts); + editEntityName->setText(entityName); + editLongName->setText(entityName); + return; +} + +void VHDLConverter::searchAssociatedPort(QTableWidgetItem *item) { + + bool ok; + int col = item->column(); + int row = item->row(); + + // searching for the real interface object linked to the item + AbstractInterface* iface = NULL; + QString ifaceName = twPorts->item(row,0)->text(); + foreach(AbstractInterface* inter,lstIface) { + if (inter->getName() == ifaceName) { + iface = inter; + break; } - entityName = matchEnt.captured(1); - cout << "foudn entity " << qPrintable(entityName) << endl; + } + + if (col == 3) { - QString archLine = ""; - try { - archLine = readEntity(ts); + QString assoInter = "N/A"; + iface->setAssociatedIface(NULL); + + cout << qPrintable(item->text()) << endl; + + if (item->text() == "data") { + iface->setPurpose(AbstractInterface::Data); + } + else if (item->text() == "control") { + iface->setPurpose(AbstractInterface::Control); + } + else if (item->text() == "clock") { + iface->setPurpose(AbstractInterface::Clock); + } + else if (item->text() == "reset") { + iface->setPurpose(AbstractInterface::Reset); } - catch(Exception e) { - cerr << "VHDL seems to be malformed" << endl; - return; + else if (item->text() == "wishbone") { + iface->setPurpose(AbstractInterface::Wishbone); } - - /* - while (!ts.atEnd()) - { - line = ts.readLine(); - if(rxComment->indexIn(line) != -1) { - line = rxComment->cap(1); - } + if (item->text() == "control") { - if(rxEnt->indexIn(line)!= -1) { - - entName = rxEnt->cap(1); - teName->setText(entName); - QSize size = teName->document()->size().toSize(); - teName->setMaximumSize(size); - - while(rxEnd->indexIn(line) == -1) { - line = ts.readLine(); - if(rxComment->indexIn(line) != -1) { - line = rxComment->cap(1); - } - if(rxComma->indexIn(line) != -1) { - line = rxComma->cap(1); - } - if(rxGeneric->indexIn(line) != -1) { - while(rxEndGen->indexIn(line) == -1) { - line = ts.readLine(); - if(rxComment->indexIn(line) != -1) { - line = rxComment->cap(1); - } - if(rxComma->indexIn(line) != -1) { - line = rxComma->cap(1); - } - if(rxGen->indexIn(line) != -1) { - genName = rxGen->cap(1).simplified(); - genType = rxGen->cap(2).simplified(); - genValue = rxGen->cap(3).simplified(); - - genNameList->append(genName); - genTypeList->append(genType); - genValueList->append(genValue); - } - } - } - if(rxPort->indexIn(line) != -1) { - if(rxComment->indexIn(line) != -1) { - line = rxComment->cap(1); - } - if(rxComma->indexIn(line) != -1) { - line = rxComma->cap(1); - } - portName = rxPort->cap(1).simplified(); - portId = rxPort->cap(2).simplified(); - portType = rxPort->cap(3).simplified(); - portNameList->append(portName); - portIdList->append(portId); - portTypeList->append(portType); - } - } + QString name = twPorts->item(row,0)->text(); + name.remove(name.size()-4,4); // remove _enb at the end + int i=0; + foreach(AbstractInterface* inter, lstIface) { + if ((i != row) && (inter->getName().contains(name))) { + assoInter = inter->getName(); + iface->setAssociatedIface(inter); } + i++; + } } - */ - twGenerics->setRowCount(genNameList->size()); - for(int i = 0; i < genNameList->size(); i++) { - twGenerics->setItem(i, 0, new QTableWidgetItem(genNameList->at(i))); - twGenerics->setItem(i, 1, new QTableWidgetItem(genTypeList->at(i))); - twGenerics->setItem(i, 2, new QTableWidgetItem(genValueList->at(i))); + QTableWidgetItem* itemAsso = twPorts->item(row,4); + itemAsso->setText(assoInter); + + if (item->text() == "control") { + itemAsso->setFlags(Qt::ItemIsEnabled|Qt::ItemIsEditable); } - twDataPort->setRowCount(portNameList->size()); - for(int i = 0; i < portNameList->size(); i++) { - twDataPort->setItem(i, 0, new QTableWidgetItem(portIdList->at(i))); - twDataPort->setItem(i, 1, new QTableWidgetItem(portNameList->at(i))); - twDataPort->setItem(i, 2, new QTableWidgetItem(portTypeList->at(i))); + else { + itemAsso->setFlags(Qt::NoItemFlags); } + } + else if (col == 4) { - file.close(); - scrollDataPort->setWidget(twDataPort); - return; + QString nameAsso = item->text(); + if (nameAsso == "N/A") return; + + bool found = false; + + int i=0; + foreach(AbstractInterface* inter, lstIface) { + if ((i != row) && (inter->getName().contains(nameAsso))) { + found = true; + iface->setAssociatedIface(inter); + } + } + if (!found) { + QTableWidgetItem* itemAsso = twPorts->item(row,4); + itemAsso->setText("N/A"); + } + } } -// This function gets the informations in the table and the descriptions, and creates a XML file with this content -void VHDLConverter::generateXml() { -/* - QString portName, portType, portId, genName, genType, genValue; - QStringList *portNameList, *portTypeList, *portIdList, *genNameList, *genTypeList, *genValueList; - int x, y, width; - brief = teBrief->toPlainText(); - desc = teDesc->toPlainText(); - entName = teName->toPlainText(); - - portNameList = new QStringList; - portTypeList = new QStringList; - portIdList = new QStringList; - genNameList = new QStringList; - genTypeList = new QStringList; - genValueList = new QStringList; - for(int i = 0; i < twGenerics->rowCount(); i++) { - genNameList->append(twGenerics->item(i,0)->text()); - genTypeList->append(twGenerics->item(i,1)->text()); - genValueList->append(twGenerics->item(i,2)->text()); - } - - for(int i = 0; i < twDataPort->rowCount(); i++) { - portIdList->append(twDataPort->item(i,0)->text()); - portNameList->append(twDataPort->item(i,1)->text()); - portTypeList->append(twDataPort->item(i,2)->text()); - } - - QDomDocument doc (entName); - QDomElement block = doc.createElement("block"); - block.setAttribute("name",entName); - block.setAttribute("version", "0.1"); - doc.appendChild(block); - - QDomElement comments = doc.createElement("comments"); - QDomElement category = doc.createElement("caterory"); - category.setAttribute("ids",""); - comments.appendChild(category); - - QDomElement eBrief = doc.createElement("brief"); - if(!brief.isEmpty()) { - QDomText txtBrief = doc.createTextNode(brief); - eBrief.appendChild(txtBrief); - comments.appendChild(eBrief); - } - QDomElement eDesc = doc.createElement("description"); - if(!desc.isEmpty()) { - QDomText txtDesc = doc.createTextNode(desc); - eDesc.appendChild(txtDesc); - comments.appendChild(eDesc); - } - block.appendChild(comments); - - QDomElement parameters = doc.createElement("parameters"); - QDomElement interfaces = doc.createElement("interfaces"); +void VHDLConverter::generateRefXml(QDomDocument& doc) { + + QDomElement eBlock = doc.createElement("block"); + eBlock.setAttribute("version", "0.1"); + doc.appendChild(eBlock); + + // creating infos + QDomElement infos = doc.createElement("informations"); + eBlock.appendChild(infos); + + QDomElement eName = doc.createElement("name"); + QDomText tName = doc.createTextNode(editLongName->text()); + eName.appendChild(tName); + infos.appendChild(eName); + + QDomElement category = doc.createElement("category"); + category.setAttribute("ids",""); + infos.appendChild(category); + + QDomElement eDesc = doc.createElement("description"); + QString brief = teBrief->toPlainText(); + QString detailed = teDesc->toPlainText(); + QDomElement eBrief = doc.createElement("brief"); + if(!brief.isEmpty()) { + QDomText txtBrief = doc.createTextNode(brief); + eBrief.appendChild(txtBrief); + eDesc.appendChild(eBrief); + } + QDomElement eDetailed = doc.createElement("detailed"); + if(!detailed.isEmpty()) { + QDomText txtDetailed = doc.createTextNode(detailed); + eDetailed.appendChild(txtDetailed); + eDesc.appendChild(eDetailed); + } + infos.appendChild(eDesc); + + + + QDomElement parameters = doc.createElement("parameters"); + eBlock.appendChild(parameters); + + QList lstGenerics = block->getGenericParameters(); + foreach(BlockParameter* param, lstGenerics) { + QDomElement parameter = doc.createElement("parameter"); + parameter.setAttribute("name",param->getName()); + parameter.setAttribute("type",param->getTypeString()); + parameter.setAttribute("value",param->getValue().toString()); + parameter.setAttribute("context","generic"); + parameters.appendChild(parameter); + } + + QDomElement interfaces = doc.createElement("interfaces"); + eBlock.appendChild(interfaces); + + if (block->getInputs().size() > 0) { QDomElement inputs = doc.createElement("inputs"); - QDomElement outputs = doc.createElement("outputs"); - QDomElement bidirs = doc.createElement("bidirs"); - block.appendChild(parameters); - block.appendChild(interfaces); interfaces.appendChild(inputs); + foreach(AbstractInterface* iface, block->getInputs()) { + + if (iface->getPurpose() != AbstractInterface::Control) { + QDomElement input = doc.createElement("input"); + input.setAttribute("name",iface->getName()); + input.setAttribute("type",iface->getTypeString()); + input.setAttribute("width",iface->getWidth()); + input.setAttribute("multiplicity","1"); + input.setAttribute("purpose",iface->getPurposeString()); + input.setAttribute("endian",iface->getEndianessString()); + inputs.appendChild(input); + } + else { + QDomElement ctl = doc.createElement("control"); + ctl.setAttribute("iface",iface->getAssociatedIface()->getName()); + inputs.appendChild(ctl); + } + } + } + + if (block->getOutputs().size() > 0) { + QDomElement outputs = doc.createElement("outputs"); interfaces.appendChild(outputs); + foreach(AbstractInterface* iface, block->getOutputs()) { + if (iface->getPurpose() != AbstractInterface::Control) { + QDomElement output = doc.createElement("output"); + output.setAttribute("name",iface->getName()); + output.setAttribute("type",iface->getTypeString()); + output.setAttribute("width",iface->getWidth()); + output.setAttribute("multiplicity","1"); + output.setAttribute("purpose",iface->getPurposeString()); + output.setAttribute("endian",iface->getEndianessString()); + outputs.appendChild(output); + } + else { + QDomElement ctl = doc.createElement("control"); + ctl.setAttribute("iface",iface->getAssociatedIface()->getName()); + outputs.appendChild(ctl); + } + } + } + + if (block->getBidirs().size() > 0) { + QDomElement bidirs = doc.createElement("bidirs"); interfaces.appendChild(bidirs); + foreach(AbstractInterface* iface, block->getBidirs()) { + if (iface->getPurpose() != AbstractInterface::Control) { + QDomElement bidir = doc.createElement("bidir"); + bidir.setAttribute("name",iface->getName()); + bidir.setAttribute("type",iface->getTypeString()); + bidir.setAttribute("width",iface->getWidth()); + bidir.setAttribute("multiplicity","1"); + bidir.setAttribute("purpose",iface->getPurposeString()); + bidir.setAttribute("endian",iface->getEndianessString()); + bidirs.appendChild(bidir); + } + else { + QDomElement ctl = doc.createElement("control"); + ctl.setAttribute("iface",iface->getAssociatedIface()->getName()); + bidirs.appendChild(ctl); + } + } + } +} - for(int i = 0; i < twGenerics->rowCount(); i++) { - genName = genNameList->at(i); - genType = genTypeList->at(i); - genValue = genValueList->at(i); - QDomElement parameter = doc.createElement("parameter"); - parameter.setAttribute("name",genName); - parameter.setAttribute("type",genType); - parameter.setAttribute("value",genValue); - parameter.setAttribute("context","generic"); - parameters.appendChild(parameter); - } - - for(int i = 0; i < portIdList->size(); i++) { - portId = portIdList->at(i); - portName = portNameList->at(i); - portType = portTypeList->at(i); - if(rxWidth->indexIn(portType) != -1) { - x = rxWidth->cap(1).toInt(); - y = rxWidth->cap(3).toInt(); - if(x < y) - width = y - x + 1; - else if(x > y) - width = x - y + 1; - else - width = 1; - } +void VHDLConverter::generateImplXml(QDomDocument& doc) { - if(portId.compare("in", CaseInsensitive) == 0) { - QDomElement input = doc.createElement("input"); - input.setAttribute("name",portName); - input.setAttribute("width", width); - inputs.appendChild(input); - } - else if(portId.compare("out", CaseInsensitive) == 0) { - QDomElement output = doc.createElement("output"); - output.setAttribute("name",portName); - output.setAttribute("width", width); - outputs.appendChild(output); - } - else if(portId.compare("inout", CaseInsensitive) == 0) { - QDomElement bidir = doc.createElement("bidir"); - bidir.setAttribute("name",portName); - bidir.setAttribute("width", width); - bidirs.appendChild(bidir); - } + QRegularExpression rxPack("^([^.]+)[.](.+)$",QRegularExpression::CaseInsensitiveOption); + + QDomElement eBlock = doc.createElement("block_impl"); + eBlock.setAttribute("ref_name", entityName+".xml"); + eBlock.setAttribute("ref_md5", ""); + doc.appendChild(eBlock); + + // creating infos + QDomElement comments = doc.createElement("comments"); + eBlock.appendChild(comments); + + QDomElement author = doc.createElement("author"); + author.setAttribute("firstname",""); + author.setAttribute("lastname",""); + author.setAttribute("mail",""); + comments.appendChild(author); + + QDomElement date = doc.createElement("date"); + date.setAttribute("creation",""); + comments.appendChild(date); + + QString brief = teBrief->toPlainText(); + QString detailed = teDesc->toPlainText(); + QDomElement eDesc = doc.createElement("description"); + if(!brief.isEmpty()) { + QDomText txtBrief = doc.createTextNode(brief); + eDesc.appendChild(txtBrief); + comments.appendChild(eDesc); + } + QDomElement eNotes = doc.createElement("notes"); + if(!detailed.isEmpty()) { + QDomText txtDetailed = doc.createTextNode(detailed); + eNotes.appendChild(txtDetailed); + comments.appendChild(eNotes); + } + + QDomElement libs = doc.createElement("libraries"); + eBlock.appendChild(libs); + + QHashIterator* > it(packages); + + while (it.hasNext()) { + it.next(); + QString libName = it.key(); + cout << qPrintable(libName) << endl; + QList* packList = it.value(); + QDomElement lib = doc.createElement("library"); + lib.setAttribute("name", libName); + libs.appendChild(lib); + + foreach(QString packName, *packList) { + QDomElement pack = doc.createElement("package"); + lib.appendChild(pack); + QRegularExpressionMatch matchPack = rxPack.match(packName); + if (matchPack.hasMatch()) { + QString name = matchPack.captured(1); + QString subName = matchPack.captured(2); + name = name.toLower(); + subName = subName.toLower(); + pack.setAttribute("name",name); + pack.setAttribute("use",subName); + } + } + } + + QDomElement archi = doc.createElement("architecture"); + eBlock.appendChild(archi); + QDomText tName = doc.createTextNode(""); + foreach(QString line, archLines) { + tName.appendData(line+"\n"); + } + archi.appendChild(tName); + + QDomElement patterns = doc.createElement("patterns"); + eBlock.appendChild(patterns); + QDomElement delta = doc.createElement("delta"); + delta.setAttribute("value","to_define"); + patterns.appendChild(delta); + QDomElement cons = doc.createElement("consumption"); + foreach(AbstractInterface* iface, lstIface) { + if ((iface->getDirection() == AbstractInterface::Input) && (iface->getPurpose() == AbstractInterface::Control)) { + QDomElement input = doc.createElement("input"); + input.setAttribute("name",iface->getName()); + input.setAttribute("pattern","to_define"); + cons.appendChild(input); + } + } + patterns.appendChild(cons); + QDomElement prod = doc.createElement("production"); + prod.setAttribute("counter","to_define"); + foreach(AbstractInterface* iface, lstIface) { + if ((iface->getDirection() == AbstractInterface::Output) && (iface->getPurpose() == AbstractInterface::Control)) { + QDomElement output = doc.createElement("output"); + output.setAttribute("name",iface->getName()); + output.setAttribute("pattern","to_define"); + prod.appendChild(output); } + } + patterns.appendChild(prod); +} - fileName = QFileDialog::getOpenFileName(this, tr("Open File"), - "C:", tr("Files (*.xml)")); - QFile file(fileName); - if(!file.open(QIODevice::WriteOnly | QIODevice::Text)) - return; - QTextStream ts(&file); - doc.save(ts,QDomNode::EncodingFromTextStream); - file.close(); +void VHDLConverter::replaceSignalNames(QString& line) { + foreach(AbstractInterface* iface, lstIface) { + QString pattern = iface->getName() + "([^a-zA-Z0-9_])"; + QString repl = "@{"+iface->getName()+"}\\1"; + QRegularExpression rxPort(pattern,QRegularExpression::CaseInsensitiveOption); + line.replace(rxPort,repl); + } + +} + +void VHDLConverter::updateArchitecture() { + QRegularExpression rxLT("<=",QRegularExpression::CaseInsensitiveOption); + QRegularExpression rxGT("=>",QRegularExpression::CaseInsensitiveOption); + foreach(QString line, archLines) { + replaceSignalNames(line); + line.replace(rxLT,"<="); + line.replace(rxGT,"=>"); + + cout << qPrintable(line) << endl; + } +} + +// This function gets the informations in the table and the descriptions, and creates a XML file with this content +void VHDLConverter::generateXml() { + + + updateArchitecture(); + + // creating reference xml + QDomDocument docRef(entityName); + generateRefXml(docRef); + + // creating implementation xml + QDomDocument docImpl(entityName); + generateImplXml(docImpl); + + QString dir = QFileDialog::getExistingDirectory(this,tr("Save file in"),".",QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks); + + QString fileName = dir + "/"+ entityName + ".xml"; + + QFile fileRef(fileName); + if(!fileRef.open(QIODevice::WriteOnly | QIODevice::Text)) { + cerr << "Cannot save in " << qPrintable(fileName) << endl; + return; + } + QTextStream tsRef(&fileRef); + docRef.save(tsRef,QDomNode::EncodingFromTextStream); + fileRef.close(); + + fileName = dir + "/"+ entityName + "_impl.xml"; + QFile fileImpl(fileName); + if(!fileImpl.open(QIODevice::WriteOnly | QIODevice::Text)) { + cerr << "Cannot save in " << qPrintable(fileName) << endl; + return; + } + QTextStream tsImpl(&fileImpl); + docImpl.save(tsImpl,QDomNode::EncodingFromTextStream); + fileImpl.close(); - QLabel *popup = new QLabel("Votre fichier XML est rempli"); - popup->show(); - */ } diff --git a/VHDLConverter.h b/VHDLConverter.h index ff9defe..fd57649 100644 --- a/VHDLConverter.h +++ b/VHDLConverter.h @@ -12,6 +12,8 @@ #include "Parameters.h" #include "Exception.h" +#include "ReferenceBlock.h" +#include "IfacePurposeDelegate.h" class VHDLConverter : public QWidget { Q_OBJECT @@ -25,33 +27,31 @@ private: // entity related QString entityName; + QString longName; + QLineEdit* editEntityName; + QLineEdit* editLongName; - // clk & rst ports related - QTextEdit* clkNameEdit; - QTextEdit* rstNameEdit; - QComboBox* clkCombo; - QComboBox* rstCombo; - // data ports related - QScrollArea *scrollDataPort; - QTableWidget* twDataPort; - - // wishbone ports related - QScrollArea *scrollWBPort; - QTableWidget* twWBPort; + QScrollArea *scrollPorts; + QTableWidget* twPorts; + IfacePurposeDelegate* purposeDelegate; // generics related QScrollArea* scrollGenerics; QTableWidget* twGenerics; + + // arch related + QString archName; + QList archLines; - int cptIn, cptOut, cptInout, cpt; - QString fileName, txt, s, entName, brief, desc; - - QHash* > packages; + // libraries related + QHash* > packages; - QWidget *wid; - - QTextEdit *teBrief, *teDesc, *teName; + QTextEdit *teBrief, *teDesc; + + ReferenceBlock* block; + + QList lstIface; QString readLibraries(QTextStream& in) throw(Exception); QString readEntity(QTextStream& in) throw(Exception); @@ -60,12 +60,21 @@ private: void readArchitecture(QTextStream& in) throw(Exception); QString skipBlankAndComments(QTextStream& in); - + + void generateRefXml(QDomDocument& doc); + void generateImplXml(QDomDocument& doc); + void replaceSignalNames(QString& line); + + void updateArchitecture(); + signals: public slots: void loadVHDLFile(); void generateXml(); + +private slots: + void searchAssociatedPort(QTableWidgetItem* item); }; #endif // __VHDLCONVERTER_H__ diff --git a/blast.creator.user b/blast.creator.user index 8b99581..25bfe7c 100755 --- a/blast.creator.user +++ b/blast.creator.user @@ -1,10 +1,10 @@ - + EnvironmentId - {c8006d66-d34f-42be-ad10-d0207752286d} + {3701e197-5b6c-48ea-9e98-a6cf6de18672} ProjectExplorer.Project.ActiveTarget @@ -61,7 +61,7 @@ Desktop Desktop - {2c9bf876-3476-44eb-8065-1f0844704dda} + {ed04208c-8774-456b-99b9-4a02094ca7a4} 0 0 0 diff --git a/blast.files b/blast.files index 1dbb3f1..22c212e 100755 --- a/blast.files +++ b/blast.files @@ -12,6 +12,8 @@ BlockImplementation.h BlockImplementation.cpp GroupScene.cpp GroupScene.h +IfacePurposeDelegate.cpp +IfacePurposeDelegate.h ReferenceBlock.cpp ReferenceBlock.h AbstractInterface.h diff --git a/lib/implementations/average-Nx3_impl.xml b/lib/implementations/average-Nx3_impl.xml index 981529b..a19842c 100644 --- a/lib/implementations/average-Nx3_impl.xml +++ b/lib/implementations/average-Nx3_impl.xml @@ -28,7 +28,7 @@ - + diff --git a/lib/implementations/impls.bmf b/lib/implementations/impls.bmf index 8d7e296..7ae3752 100644 Binary files a/lib/implementations/impls.bmf and b/lib/implementations/impls.bmf differ diff --git a/lib/implementations/rgb216bits_impl.xml b/lib/implementations/rgb216bits_impl.xml deleted file mode 100644 index d5203d5..0000000 --- a/lib/implementations/rgb216bits_impl.xml +++ /dev/null @@ -1,37 +0,0 @@ - - - - - - - - This component converts a RGB pixel into a 16 bits pixel - - - No notes - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/object-files.txt b/object-files.txt index b46c2d8..47af6ad 100644 --- a/object-files.txt +++ b/object-files.txt @@ -33,6 +33,8 @@ COMMON-OBJ = $(BUILDPATH)/AbstractBlock.o \ $(BUILDPATH)/ArithmeticEvaluator.o \ $(BUILDPATH)/VHDLConverter.o \ $(BUILDPATH)/moc_VHDLConverter.o \ + $(BUILDPATH)/IfacePurposeDelegate.o \ + $(BUILDPATH)/moc_IfacePurposeDelegate.o \ $(BUILDPATH)/GroupWidget.o \ $(BUILDPATH)/moc_GroupWidget.o \ $(BUILDPATH)/Parameters.o \