From 18fecf25efe710631fabecbb9f689c2997fdfe18 Mon Sep 17 00:00:00 2001 From: stephane Domas Date: Thu, 22 Mar 2018 08:51:47 +0100 Subject: [PATCH] moved vhdl gen. into block --- BlockImplementation.cpp | 306 ---------------------------------------- BlockImplementation.h | 9 +- Dispatcher.cpp | 4 +- FunctionalBlock.cpp | 286 ++++++++++++++++++++++++++++++++++++- GroupBlock.cpp | 13 +- ReferenceBlock.cpp | 2 +- blast.creator.user | 21 +-- 7 files changed, 307 insertions(+), 334 deletions(-) diff --git a/BlockImplementation.cpp b/BlockImplementation.cpp index 1553ebb..5ae6eda 100644 --- a/BlockImplementation.cpp +++ b/BlockImplementation.cpp @@ -102,312 +102,6 @@ bool BlockImplementation::checkPatterns() { return true; } -void BlockImplementation::generateVHDL(FunctionalBlock* _block, const QString &path) throw(Exception) { - - block = _block; - - QFile implFile(xmlFile); - - // reading in into QDomDocument - QDomDocument document("implFile"); - - if (!implFile.open(QIODevice::ReadOnly)) { - throw(Exception(IMPLFILE_NOACCESS)); - } - if (!document.setContent(&implFile)) { - implFile.close(); - throw(Exception(IMPLFILE_NOACCESS)); - } - implFile.close(); - - bool genController = false; - QString coreFile = ""; - QString controllerFile = ""; - - if (reference->isWBConfigurable()) { - genController = true; - controllerFile = path; - controllerFile += "/"; - controllerFile.append(block->getName()); - controllerFile.append("_ctrl.vhd"); - } - else { - controllerFile = "nofile.vhd"; - } - coreFile = path; - coreFile += "/"; - coreFile.append(block->getName()); - coreFile.append(".vhd"); - - QFile vhdlCore(coreFile); - QFile vhdlController(controllerFile); - - if (!vhdlCore.open(QIODevice::WriteOnly)) { - throw(Exception(VHDLFILE_NOACCESS)); - } - - if (genController) { - if (!vhdlController.open(QIODevice::WriteOnly)) { - throw(Exception(VHDLFILE_NOACCESS)); - } - } - QTextStream outCore(&vhdlCore); - QTextStream outController; - if (genController) { - outController.setDevice(&vhdlController); - } - - try { - - - //Get the root element - QDomElement impl = document.documentElement(); - QDomElement eltComments = impl.firstChildElement("comments"); - generateComments(eltComments, coreFile, outCore); - QDomElement eltLibs = eltComments.nextSiblingElement("libraries"); - generateLibraries(eltLibs, outCore); - generateEntity(outCore, genController); - QDomElement eltArch = eltLibs.nextSiblingElement("architecture"); - generateArchitecture(eltArch, outCore); - if (genController) { - generateController(outController); - } - } - catch(Exception err) { - throw(err); - } - - vhdlCore.close(); - vhdlController.close(); -} - -// This function generates the comments part of the VHDL document -void BlockImplementation::generateComments(QTextStream& out, QDomElement &elt, QString coreFile) throw(Exception) { - - for(int i = 0; i < 50; i++) { - out << "--"; - } - out << "\n--" << endl; - QString fileName = coreFile; - 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) : "<getName(); - //QList listParams = reference->getParameters(); - QList listInputs = block->getInputs(); - QList listOutputs = block->getOutputs(); - QList listBidirs = block->getBidirs(); - QString typePort, namePort; - - out << "entity " << nameEnt << " is" << endl; - - - /* TODO : rewrite the generation to take into acocunt the new object hierarchy */ - - // Generation of the generics - QList listGenerics = block->getGenericParameters(); - if ((!listGenerics.isEmpty()) || (hasController)) { - out << " generic (" << endl; - if (hasController) { - out << " wb_data_width : integer = 16;" << endl; - out << " wb_addr_width : integer = 12"; - if (!listGenerics.isEmpty()) out << ";"; - out << 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; - } - } - - if (hasController) { - // Generation of the wishbone signals - out << " -- registers r/w via wishbone" << endl; - QList listWB = reference->getWishboneParameters(); - for(i=0;itoVHDL(BlockParameter::Entity, 0) << endl; - } - out << " " << listWB.at(i)->toVHDL(BlockParameter::Entity,BlockParameter::NoComma) << endl; - } - - - int count = 0; - foreach(AbstractInterface* iface, block->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 " << nameEnt << ";" << endl << endl; -} - -// This function generates the architecture part of the VHDL document -void BlockImplementation::generateArchitecture(QTextStream& out, QDomElement &elt) throw(Exception) { - - QString expr; - QString code = elt.text(); - cout << qPrintable(code) << endl; - out << "architecture rtl of " << nameEnt << " is" << endl; - - QStringList listLine = code.split("\n"); - for(int i =0; i < listLine.size(); i++) { - QString line = listLine.at(i).simplified(); - - /* - if(listLine.at(i).contains(QRegularExpression("@foreach{"))) { - while(listLine.at(i).compare("@endforeach") != -1) { - expr = expr + listLine.at(i) + '\n'; - i++; - } - expr = expr + listLine.at(i); - out << evalComplex(expr, 1) << '\n'; - } - if(listLine.at(i).contains(QRegularExpression("@caseeach{"))) { - while(listLine.at(i).compare("@endcaseeach") != -1) { - expr = expr + listLine.at(i) + '\n'; - i++; - } - expr = expr + listLine.at(i); - out << evalComplex(expr, 2) << '\n'; - } -*/ - if(line.contains("@{")) { - out << line << endl; - } - } -} - -void BlockImplementation::generateController(QTextStream &out) throw(Exception) { -} - QString BlockImplementation::eval(QString line, QTextStream& out) { QString res, s, begLine, endLine, expr; evaluator->setExpression(line); diff --git a/BlockImplementation.h b/BlockImplementation.h index 8bbc297..fb9c77c 100644 --- a/BlockImplementation.h +++ b/BlockImplementation.h @@ -52,8 +52,7 @@ public: inline void setReference(ReferenceBlock* _reference) { reference = _reference; } void loadPatterns(QDomElement &root) throw(Exception); - bool checkPatterns(); - void generateVHDL(FunctionalBlock* _block, const QString& path) throw(Exception); // main entry to generate the VHDL code + bool checkPatterns(); private: @@ -70,12 +69,6 @@ private: QHash productionPattern; // key = reference interface name, value = pattern expression QString productionCounter; - void generateComments(QTextStream& out, QDomElement &elt, QString coreFile) throw(Exception); // generates comments from element - void generateLibraries(QTextStream& out, QDomElement &elt) throw(Exception); // generates libraries from element - void generateEntity(QTextStream& out, bool hasController=false) throw(Exception); // generate the entity using reference - void generateArchitecture(QTextStream& out, QDomElement &elt ) throw(Exception); // generate the architecture using element - void generateController(QTextStream& out) throw(Exception); // generate the wishbone controller of the block - QString getIfaceUserName(AbstractInterface* refIface); // get the name of an interface given by the user, from the reference interface friend QDataStream &operator<<(QDataStream &out, const BlockImplementation &impl); diff --git a/Dispatcher.cpp b/Dispatcher.cpp index 638c991..946f5ec 100644 --- a/Dispatcher.cpp +++ b/Dispatcher.cpp @@ -179,10 +179,8 @@ void Dispatcher::generateBlockVHDL(BoxItem *item){ if (item->getRefBlock()->isFunctionalBlock()) { FunctionalBlock* block = AB_TO_FUN(item->getRefBlock()); - ReferenceBlock* ref = block->getReference(); - BlockImplementation* impl = ref->getImplementations().at(0); try { - impl->generateVHDL(block,params->projectPath); + block->generateVHDL(params->projectPath); } catch(Exception e) { cout << qPrintable(e.getMessage()) << endl; diff --git a/FunctionalBlock.cpp b/FunctionalBlock.cpp index b54e4e3..2d455db 100644 --- a/FunctionalBlock.cpp +++ b/FunctionalBlock.cpp @@ -1314,20 +1314,302 @@ int FunctionalBlock::createTriggers() { } void FunctionalBlock::generateVHDL(const QString& path) throw(Exception){ + + BlockImplementation* impl = reference->getImplementations().at(0); // for now only take first impl available + QFile implFile(impl->getXmlFile()); + + // reading in into QDomDocument + QDomDocument document("implFile"); + + if (!implFile.open(QIODevice::ReadOnly)) { + throw(Exception(IMPLFILE_NOACCESS)); + } + if (!document.setContent(&implFile)) { + implFile.close(); + throw(Exception(IMPLFILE_NOACCESS)); + } + implFile.close(); + + bool genController = false; + QString coreFile = ""; + QString controllerFile = ""; + + if (reference->isWBConfigurable()) { + genController = true; + controllerFile = path; + controllerFile += "/"; + controllerFile.append(name); + controllerFile.append("_ctrl.vhd"); + } + else { + controllerFile = "nofile.vhd"; + } + coreFile = path; + coreFile += "/"; + coreFile.append(name); + coreFile.append(".vhd"); + + QFile vhdlCore(coreFile); + QFile vhdlController(controllerFile); + + if (!vhdlCore.open(QIODevice::WriteOnly)) { + throw(Exception(VHDLFILE_NOACCESS)); + } + + if (genController) { + if (!vhdlController.open(QIODevice::WriteOnly)) { + throw(Exception(VHDLFILE_NOACCESS)); + } + } + QTextStream outCore(&vhdlCore); + QTextStream outController; + if (genController) { + outController.setDevice(&vhdlController); + } + + try { + //Get the root element + QDomElement impl = document.documentElement(); + QDomElement eltComments = impl.firstChildElement("comments"); + generateComments(outCore,eltComments, coreFile); + QDomElement eltLibs = eltComments.nextSiblingElement("libraries"); + generateLibraries(outCore, eltLibs); + generateEntity(outCore, genController); + QDomElement eltArch = eltLibs.nextSiblingElement("architecture"); + generateArchitecture(outCore, eltArch ); + if (genController) { + generateController(outController); + } + } + catch(Exception err) { + throw(err); + } + + vhdlCore.close(); + vhdlController.close(); + } void FunctionalBlock::generateComments(QTextStream& out, QDomElement &elt, QString coreFile) throw(Exception) { + for(int i = 0; i < 50; i++) { + out << "--"; + } + out << "\n--" << endl; + QString fileName = coreFile; + 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) : "< listParams = reference->getParameters(); + QList listInputs = getInputs(); + QList listOutputs = getOutputs(); + QList listBidirs = getBidirs(); + QString typePort, namePort; + + out << "entity " << name << " is" << endl; + + + /* TODO : rewrite the generation to take into acocunt the new object hierarchy */ + + // Generation of the generics + QList listGenerics = getGenericParameters(); + if ((!listGenerics.isEmpty()) || (hasController)) { + out << " generic (" << endl; + if (hasController) { + out << " wb_data_width : integer = 16;" << endl; + out << " wb_addr_width : integer = 12"; + if (!listGenerics.isEmpty()) out << ";"; + out << 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; + } + } + + if (hasController) { + // Generation of the wishbone signals + out << " -- registers r/w via wishbone" << endl; + QList listWB = reference->getWishboneParameters(); + for(i=0;itoVHDL(BlockParameter::Entity, 0) << endl; + } + out << " " << listWB.at(i)->toVHDL(BlockParameter::Entity,BlockParameter::NoComma) << 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 FunctionalBlock::generateArchitecture(QTextStream& out, QDomElement &elt ) throw(Exception) { + QString expr; + QString code = elt.text(); + cout << qPrintable(code) << endl; + out << "architecture rtl of " << name << " is" << endl; + + QStringList listLine = code.split("\n"); + for(int i =0; i < listLine.size(); i++) { + QString line = listLine.at(i).simplified(); + /* + if(listLine.at(i).contains(QRegularExpression("@foreach{"))) { + while(listLine.at(i).compare("@endforeach") != -1) { + expr = expr + listLine.at(i) + '\n'; + i++; + } + expr = expr + listLine.at(i); + out << evalComplex(expr, 1) << '\n'; + } + if(listLine.at(i).contains(QRegularExpression("@caseeach{"))) { + while(listLine.at(i).compare("@endcaseeach") != -1) { + expr = expr + listLine.at(i) + '\n'; + i++; + } + expr = expr + listLine.at(i); + out << evalComplex(expr, 2) << '\n'; + } +*/ + if(line.contains("@{")) { + out << line << endl; + } + } } + +void FunctionalBlock::generateController(QTextStream &out) throw(Exception) { + +} + diff --git a/GroupBlock.cpp b/GroupBlock.cpp index a3966bd..17b7bba 100644 --- a/GroupBlock.cpp +++ b/GroupBlock.cpp @@ -281,11 +281,12 @@ void GroupBlock::generateVHDL(const QString& path) throw(Exception) { QTextStream outCore(&vhdlCore); + QDomElement dummyElt; try { - generateComments(outCore); - generateLibraries(outCore); + generateComments(outCore,dummyElt,""); + generateLibraries(outCore,dummyElt); generateEntity(outCore); - generateArchitecture(outCore); + generateArchitecture(outCore,dummyElt); } catch(Exception err) { throw(err); @@ -307,7 +308,7 @@ void GroupBlock::generateLibraries(QTextStream& out, QDomElement &elt) throw(Exc } -void GroupBlock::generateEntity(QTextStream& out) throw(Exception) { +void GroupBlock::generateEntity(QTextStream& out, bool hasController) throw(Exception) { int i; @@ -414,3 +415,7 @@ void GroupBlock::generateArchitecture(QTextStream& out, QDomElement &elt) throw( } +void GroupBlock::generateController(QTextStream &out) throw(Exception) { + +} + diff --git a/ReferenceBlock.cpp b/ReferenceBlock.cpp index f6fd9c7..70677df 100644 --- a/ReferenceBlock.cpp +++ b/ReferenceBlock.cpp @@ -648,7 +648,7 @@ void ReferenceBlock::generateLibraries(QTextStream& out, QDomElement &elt) throw throw(Exception(INVALID_REFBLOCK_USE)); } -void ReferenceBlock::generateEntity(QTextStream& out, bool hasController=false) throw(Exception) { +void ReferenceBlock::generateEntity(QTextStream& out, bool hasController) throw(Exception) { throw(Exception(INVALID_REFBLOCK_USE)); } diff --git a/blast.creator.user b/blast.creator.user index 37faf88..1aea169 100644 --- a/blast.creator.user +++ b/blast.creator.user @@ -1,10 +1,10 @@ - + EnvironmentId - {94112477-caab-4897-8f75-5f412f2c883a} + {3701e197-5b6c-48ea-9e98-a6cf6de18672} ProjectExplorer.Project.ActiveTarget @@ -19,7 +19,7 @@ Cpp - CppGlobal + qt2 @@ -31,7 +31,7 @@ 2 UTF-8 false - 4 + 2 false 80 true @@ -43,12 +43,12 @@ true true 0 - 8 - true + 4 + false 1 true true - true + false false @@ -61,7 +61,7 @@ Desktop Desktop - {c934e180-ebc6-41ed-be82-502cc94f41f6} + {ed04208c-8774-456b-99b9-4a02094ca7a4} 0 0 0 @@ -128,7 +128,7 @@ false false - 1000 + 0 true @@ -169,8 +169,9 @@ + false %{buildDir} - Custom Executable + Exécutable personnalisé ProjectExplorer.CustomExecutableRunConfiguration 3768 -- 2.39.5