#include "VHDLConverter.h"\r
+#include "BlockParameterGeneric.h"\r
+#include "BlockParameterUser.h"\r
+#include "BlockParameterWishbone.h"\r
+#include "ReferenceInterface.h"\r
\r
using namespace std;\r
using namespace Qt;\r
\r
VHDLConverter::VHDLConverter(QWidget *parent) : QWidget(parent) {\r
\r
- rxComment = new QRegExp("(.*)--.*");\r
- rxComma = new QRegExp("(.*)[;]");\r
- rxPort = new QRegExp("[\\s\\t]*(.*)[\\s\\t]*:[\\s\\t]*(in|out|inout)[\\s\\t]*(.*)",CaseInsensitive,QRegExp::RegExp);\r
- rxEnt = new QRegExp("[\\s\\t]*entity[\\s\\t]*(.*)[\\s\\t]*is",CaseInsensitive,QRegExp::RegExp);\r
- rxArch = new QRegExp("[\\s\\t]*architecture[\\s\\t]*(.*)[\\s\\t]*of (.*)[\\s\\t]*is",CaseInsensitive,QRegExp::RegExp);\r
- rxComp = new QRegExp("[\\s\\t]*component[\\s\\t]*(.*)[\\s\\t]*",CaseInsensitive,QRegExp::RegExp);\r
- rxEnd = new QRegExp("[\\s\\t]*end(.*)",CaseInsensitive,QRegExp::RegExp);\r
- rxComp = new QRegExp("[\\s\\t]*end component;",CaseInsensitive,QRegExp::RegExp);\r
- rxGeneric = new QRegExp("[\\s\\t]*generic[\\s\\t]*[(][\\s\\t]*",CaseInsensitive,QRegExp::RegExp);\r
- rxEndGen = new QRegExp("[\\s\\t]*[)]",CaseInsensitive,QRegExp::RegExp);\r
- rxGen = new QRegExp("[\\s\\t]*(.*)[\\s\\t]*:[\\s\\t]*(.*)[\\s\\t]*:=[\\s\\t]*(.*)",CaseInsensitive,QRegExp::RegExp);\r
- rxConst = new QRegExp("[\\s\\t]*constant[\\s\\t]*(.*)[\\s\\t]*:[\\s\\t]*(.)*[\\s\\t]*:=[\\s\\t]*(.*)",CaseInsensitive,QRegExp::RegExp);\r
- rxWidth = new QRegExp(".*[(](.*)(downto|to)(.*)[)]",CaseInsensitive,QRegExp::RegExp);\r
- \r
- QLabel *labelAppli, *lblBrief, *lblDesc, *lblName, *lblPort, *lblGen;\r
-\r
- loadBut = new QPushButton("load VHDL");\r
- genBut = new QPushButton("generate XML");\r
- QHBoxLayout *widgetLayout = new QHBoxLayout;\r
- QVBoxLayout *left = new QVBoxLayout;\r
- QVBoxLayout *right = new QVBoxLayout;\r
-\r
- scrollDataPort = new QScrollArea;\r
- scrollDataPort->setWidgetResizable(true);\r
- twDataPort = new QTableWidget(this);\r
- scrollDataPort->setWidget(twDataPort);\r
- scrollGenerics = new QScrollArea;\r
- scrollGenerics->setWidgetResizable(true);\r
- twGenerics = new QTableWidget(this);\r
- scrollGenerics->setWidget(twGenerics);\r
- teName = new QTextEdit;\r
- teBrief = new QTextEdit;\r
- teDesc = new QTextEdit;\r
- lblName = new QLabel("Block name :");\r
- lblBrief = new QLabel("Enter a brief description : ");\r
- lblDesc = new QLabel("Enter a detailled description : ");\r
- lblPort = new QLabel("Ports :");\r
- lblGen = new QLabel("Generics :");\r
-\r
- connect(loadBut, SIGNAL(clicked()),this, SLOT(loadVHDLFile()));\r
- connect(genBut, SIGNAL(clicked()), this, SLOT(generateXml()));\r
-\r
- left->addWidget(loadBut);\r
- left->addWidget(lblPort);\r
- left->addWidget(scrollDataPort);\r
- left->addWidget(lblGen);\r
- left->addWidget(scrollGenerics);\r
-\r
- right->addWidget(lblName);\r
- right->addWidget(teName);\r
- right->addWidget(lblBrief);\r
- right->addWidget(teBrief);\r
- right->addWidget(lblDesc);\r
- right->addWidget(teDesc);\r
- right->addWidget(genBut);\r
-\r
- widgetLayout->addLayout(left);\r
- widgetLayout->addLayout(right);\r
- setLayout(widgetLayout);\r
- show();\r
+ QLabel *labelAppli, *lblBrief, *lblDesc, *lblEntName, *lblLongName, *lblPort, *lblGen;\r
+\r
+ loadBut = new QPushButton("load VHDL");\r
+ genBut = new QPushButton("generate XML");\r
+ QHBoxLayout *widgetLayout = new QHBoxLayout;\r
+ QVBoxLayout *left = new QVBoxLayout;\r
+ QVBoxLayout *right = new QVBoxLayout;\r
+\r
+ scrollPorts = new QScrollArea;\r
+ scrollPorts->setWidgetResizable(true);\r
+ twPorts = new QTableWidget(this);\r
+ twPorts->setColumnCount(5);\r
+ scrollPorts->setWidget(twPorts);\r
+ scrollGenerics = new QScrollArea;\r
+ scrollGenerics->setWidgetResizable(true);\r
+ twGenerics = new QTableWidget(this);\r
+ twGenerics->setColumnCount(3);\r
+ scrollGenerics->setWidget(twGenerics);\r
+ editEntityName = new QLineEdit;\r
+ editLongName = new QLineEdit;\r
+ teBrief = new QTextEdit;\r
+ teDesc = new QTextEdit;\r
+ lblEntName = new QLabel("Entity name :");\r
+ lblLongName = new QLabel("Block long name :");\r
+ lblBrief = new QLabel("Enter a brief description : ");\r
+ lblDesc = new QLabel("Enter a detailled description : ");\r
+ lblPort = new QLabel("Ports :");\r
+ lblGen = new QLabel("Generics :");\r
+\r
+ connect(loadBut, SIGNAL(clicked()),this, SLOT(loadVHDLFile()));\r
+ connect(genBut, SIGNAL(clicked()), this, SLOT(generateXml()));\r
+\r
+ left->addWidget(loadBut);\r
+ left->addWidget(lblPort);\r
+ left->addWidget(scrollPorts);\r
+ left->addWidget(lblGen);\r
+ left->addWidget(scrollGenerics);\r
+\r
+ right->addWidget(lblEntName);\r
+ right->addWidget(editEntityName);\r
+ right->addWidget(lblLongName);\r
+ right->addWidget(editLongName);\r
+ right->addWidget(lblBrief);\r
+ right->addWidget(teBrief);\r
+ right->addWidget(lblDesc);\r
+ right->addWidget(teDesc);\r
+ right->addWidget(genBut);\r
+\r
+ widgetLayout->addLayout(left);\r
+ widgetLayout->addLayout(right);\r
+ setLayout(widgetLayout);\r
+ show();\r
}\r
\r
VHDLConverter::~VHDLConverter() {\r
\r
QString line = "";\r
\r
- // skipping blank/comment lines \r
+ // skipping blank/comment lines\r
while ( (line.isEmpty()) || ((line.at(0) == '-') && (line.at(1) == '-')) ) {\r
if (in.atEnd()) {\r
return "";\r
}\r
line = in.readLine();\r
- if (!line.isEmpty()) line = line.trimmed();\r
- } \r
+ if (!line.isEmpty()) line = line.simplified();\r
+ }\r
+ line.remove(QRegularExpression("--.*$"));\r
return line;\r
}\r
\r
-void VHDLConverter::readLibraries(QTextStream &in) throw(Exception) {\r
+QString VHDLConverter::readLibraries(QTextStream &in) throw(Exception) {\r
\r
QRegularExpression rxLib("^library[\\s\\t]*(.+);$",QRegularExpression::CaseInsensitiveOption);\r
QRegularExpression rxPack("^use[\\s\\t]*([^.]+)[.](.+);$",QRegularExpression::CaseInsensitiveOption);\r
line = skipBlankAndComments(in);\r
if (line == "") {\r
throw(Exception(VHDLFILE_CORRUPTED));\r
- } \r
+ }\r
\r
while (! line.contains("entity",Qt::CaseInsensitive)) {\r
\r
QString libName = matchLib.captured(1);\r
libName = libName.toLower();\r
\r
- cout << "matching library: " << qPrintable(libName) << endl; \r
+ cout << "matching library: " << qPrintable(libName) << endl;\r
\r
- if (!packages.contains(libName)) { \r
- packages.insert(libName,new QList<QString>()); \r
- } \r
+ if (!packages.contains(libName)) {\r
+ packages.insert(libName,new QList<QString>());\r
+ }\r
}\r
else if (matchPack.hasMatch()) {\r
cout << "matching packages" << endl;\r
\r
QString libName = matchPack.captured(1);\r
- QString packName = matchPack.captured(2); \r
+ QString packName = matchPack.captured(2);\r
\r
libName = libName.toLower();\r
- packName = packName.toLower(); \r
- \r
+ packName = packName.toLower();\r
+\r
if (libName == "work") {\r
if (!packages.contains("work")) {\r
packages.insert("work",new QList<QString>());\r
else if (!packages.contains(libName)) throw(Exception(VHDLFILE_CORRUPTED));\r
\r
QList<QString>* lstPack = packages.value(libName);\r
- QString s = libName + "." + packName; \r
- lstPack->append(s);\r
- cout << qPrintable(s) << endl;\r
+ lstPack->append(packName);\r
+ cout << qPrintable(packName) << endl;\r
\r
}\r
\r
}\r
cout << "read line = " << qPrintable(line) << endl;\r
}\r
+\r
+ return line;\r
}\r
\r
-void VHDLConverter::readEntity(QTextStream &in) throw(Exception) {\r
- \r
+QString VHDLConverter::readEntity(QTextStream &in) throw(Exception) {\r
+\r
+ QRegularExpression rxGen("^generic[\\s\\t]*[(](.*)$",QRegularExpression::CaseInsensitiveOption);\r
+ QRegularExpression rxPorts("^port[\\s\\t]*[(](.*)$",QRegularExpression::CaseInsensitiveOption);\r
+\r
+ QString line = "";\r
+\r
+ line = skipBlankAndComments(in);\r
+ if (line == "") {\r
+ throw(Exception(VHDLFILE_CORRUPTED));\r
+ }\r
+\r
+ while (! line.startsWith("architecture",Qt::CaseInsensitive)) {\r
+\r
+ QRegularExpressionMatch matchGen = rxGen.match(line);\r
+ QRegularExpressionMatch matchPorts = rxPorts.match(line);\r
+\r
+ if (matchGen.hasMatch()) {\r
+ cout << "matching generics" << endl;\r
+ if (matchGen.captured(1).length() > 0) {\r
+ cerr << "Please, modify VHDL source so that the generic list does not begin at the same line as generic (" << endl;\r
+ throw(Exception(VHDLFILE_CORRUPTED));\r
+ }\r
+ readGenerics(in);\r
+ }\r
+ else if (matchPorts.hasMatch()) {\r
+ cout << "matching ports" << endl;\r
+ if (matchPorts.captured(1).length() > 0) {\r
+ cerr << "Please, modify VHDL source so that the port list does not begin at the same line as port (" << endl;\r
+ throw(Exception(VHDLFILE_CORRUPTED));\r
+ }\r
+ readPorts(in);\r
+ }\r
+\r
+ line = skipBlankAndComments(in);\r
+ if (line == "") {\r
+ throw(Exception(VHDLFILE_CORRUPTED));\r
+ }\r
+ cout << "read line = " << qPrintable(line) << endl;\r
+ }\r
+\r
+ return line;\r
}\r
\r
void VHDLConverter::readGenerics(QTextStream &in) throw(Exception) {\r
- \r
+\r
+ QRegularExpression rxGen("^([^:]+):([^:]+)(:=)?([^;]*);?$",QRegularExpression::CaseInsensitiveOption);\r
+\r
+ QString line = "";\r
+\r
+ line = skipBlankAndComments(in);\r
+ if (line == "") {\r
+ throw(Exception(VHDLFILE_CORRUPTED));\r
+ }\r
+ line = line.remove(' ');\r
+\r
+ while (! line.contains(QRegExp("\\);"))) {\r
+\r
+ QRegularExpressionMatch matchGen = rxGen.match(line);\r
+\r
+ if (matchGen.hasMatch()) {\r
+ cout << "matching generic value" << endl;\r
+ QString genName = matchGen.captured(1);\r
+ QString genType = matchGen.captured(2);\r
+ genType = genType.toLower();\r
+ QString genValue = matchGen.captured(4);\r
+ genValue = genValue.toLower();\r
+ cout << qPrintable(genName) << " " << qPrintable(genType) << " " << qPrintable(genValue) << endl;\r
+ BlockParameter* param = new BlockParameterGeneric(block,genName,genType,genValue);\r
+ block->addParameter(param);\r
+ }\r
+\r
+ line = skipBlankAndComments(in);\r
+ if (line == "") {\r
+ throw(Exception(VHDLFILE_CORRUPTED));\r
+ }\r
+ line = line.remove(' ');\r
+ cout << "read line = " << qPrintable(line) << endl;\r
+ }\r
}\r
\r
void VHDLConverter::readPorts(QTextStream &in) throw(Exception) {\r
- \r
+\r
+ QRegularExpression rxPort("^([^ :]+) ?: ?(in|out|inout) ([a-zA-Z0-9_]+) ?(\\([^:)]*\\))? ?(:=)? ?([^;]*) ?;?$",QRegularExpression::CaseInsensitiveOption);\r
+ QRegularExpression rxSizeDownTo("^\\((.*) downto (.*)\\)$",QRegularExpression::CaseInsensitiveOption);\r
+ QRegularExpression rxSizeTo("^\\((.*) to (.*)\\)$",QRegularExpression::CaseInsensitiveOption);\r
+\r
+ QString line = "";\r
+\r
+ line = skipBlankAndComments(in);\r
+ if (line == "") {\r
+ throw(Exception(VHDLFILE_CORRUPTED));\r
+ }\r
+\r
+ while (! line.contains(QRegExp("^\\);$"))) {\r
+\r
+ line = line.toLower();\r
+\r
+ QRegularExpressionMatch matchPort = rxPort.match(line);\r
+\r
+ if (matchPort.hasMatch()) {\r
+ cout << "matching port value" << endl;\r
+ QString portName = matchPort.captured(1);\r
+ QString portDir = matchPort.captured(2);\r
+ QString portType = matchPort.captured(3);\r
+ QString portSize = matchPort.captured(4);\r
+ QString portValue = matchPort.captured(6);\r
+ cout << qPrintable(portName) << "|" << qPrintable(portDir) << "|" << qPrintable(portType) << "|" << qPrintable(portSize) << "|" << qPrintable(portValue) << endl;\r
+ ReferenceInterface* iface = NULL;\r
+ bool isOk = true;\r
+ int direction = AbstractInterface::AnyDirection;\r
+ int endianess = AbstractInterface::LittleEndian;\r
+ int purpose = AbstractInterface::AnyPurpose;\r
+\r
+ QString widthStr = "a";\r
+\r
+ if (portDir == "in") {\r
+ direction = AbstractInterface::Input;\r
+ }\r
+ else if (portDir == "out") {\r
+ direction = AbstractInterface::Output;\r
+ }\r
+ else if (portDir == "inout") {\r
+ direction = AbstractInterface::InOut;\r
+ }\r
+ else {\r
+ cerr << "Unknown direction for port " << qPrintable(portName) << endl;\r
+ isOk = false;\r
+ }\r
+ QString typeStr="";\r
+ if (portType == "std_logic") {\r
+ typeStr = "boolean";\r
+ widthStr="1";\r
+ }\r
+ else if (portType == "std_logic_vector") {\r
+\r
+ if (portSize.contains("downto")) {\r
+ QRegularExpressionMatch matchSize = rxSizeDownTo.match(portSize);\r
+ endianess = AbstractInterface::LittleEndian;\r
+ if (matchSize.captured(2) != "0") {\r
+ cerr << "invalid size for port " << qPrintable(portName) << endl;\r
+ isOk = false;\r
+ }\r
+ else {\r
+ widthStr = matchSize.captured(1);\r
+ }\r
+ }\r
+ else if (portSize.contains("to")) {\r
+ QRegularExpressionMatch matchSize = rxSizeTo.match(portSize);\r
+ endianess = AbstractInterface::BigEndian;\r
+ if (matchSize.captured(1) != "0") {\r
+ cerr << "invalid size for port " << qPrintable(portName) << endl;\r
+ isOk = false;\r
+ }\r
+ else {\r
+ widthStr = matchSize.captured(2);\r
+ }\r
+ }\r
+ else {\r
+ cerr << "invalid size for port " << qPrintable(portName) << endl;\r
+ isOk = false;\r
+ }\r
+\r
+ QVariant msb(widthStr);\r
+ bool ok;\r
+ int size = msb.toInt(&ok);\r
+ if (ok) {\r
+ typeStr = "natural";\r
+ }\r
+ else {\r
+ typeStr ="expression";\r
+ }\r
+ }\r
+ else {\r
+ cerr << "Unknown type for port " << qPrintable(portName) << endl;\r
+ isOk = false;\r
+ }\r
+\r
+ if (isOk) {\r
+ // trying to guess the purpose from name\r
+ if ((portName.contains("clk"))||(portName.contains("clock"))) {\r
+ purpose = AbstractInterface::Clock;\r
+ }\r
+ else if ((portName.contains("rst"))||(portName.contains("reset"))) {\r
+ purpose = AbstractInterface::Reset;\r
+ }\r
+ else if (portName.endsWith("_enb")) {\r
+ purpose = AbstractInterface::Control;\r
+ }\r
+ else if (portName.startsWith("wb_")) {\r
+ purpose = AbstractInterface::Wishbone;\r
+ }\r
+ else {\r
+ purpose = AbstractInterface::Data;\r
+ }\r
+ iface = new ReferenceInterface(block,portName,direction,purpose,typeStr,widthStr,endianess,1);\r
+ block->addInterface(iface);\r
+ }\r
+ }\r
+\r
+ line = skipBlankAndComments(in);\r
+ if (line == "") {\r
+ throw(Exception(VHDLFILE_CORRUPTED));\r
+ }\r
+ cout << "read line = " << qPrintable(line) << endl;\r
+ }\r
+\r
}\r
\r
void VHDLConverter::readArchitecture(QTextStream &in) throw(Exception) {\r
+\r
+ QString line = "";\r
+ QString endLine = "end "+archName;\r
+\r
+ while (!line.startsWith(endLine)) {\r
+ line = in.readLine();\r
+ if (!line.isEmpty()) line = line.simplified();\r
+ archLines.append(line);\r
+ }\r
\r
}\r
\r
// You can edit the descriptions in the right, one for the brief description, the other for the detailled.\r
void VHDLConverter::loadVHDLFile() {\r
\r
- QString line, portName, portType, portId, genName, genType, genValue;\r
- QStringList *portNameList, *portTypeList, *portIdList, *genNameList, *genTypeList, *genValueList;\r
- cpt = 0;\r
- twDataPort->setColumnCount(3);\r
- twDataPort->setRowCount(cpt);\r
- twGenerics->setColumnCount(3);\r
- twGenerics->setRowCount(cpt);\r
- portNameList = new QStringList;\r
- portTypeList = new QStringList;\r
- portIdList = new QStringList;\r
- genNameList = new QStringList;\r
- genTypeList = new QStringList;\r
- genValueList = new QStringList;\r
-\r
- fileName = QFileDialog::getOpenFileName(this,\r
- tr("Open File"), "C:", tr("Files (*.txt *.vhd)"));\r
- QFile file(fileName);\r
-\r
- if(!file.open(QIODevice::ReadOnly | QIODevice::Text))\r
- return;\r
- QTextStream ts(&file);\r
- \r
- readLibraries(ts);\r
- \r
- /*\r
- while (!ts.atEnd())\r
- {\r
- line = ts.readLine();\r
- if(rxComment->indexIn(line) != -1) {\r
- line = rxComment->cap(1);\r
+ QString fileName = QFileDialog::getOpenFileName(this,\r
+ tr("Open File"), QDir::homePath() , tr("Files (*.txt *.vhd)"));\r
+ QFile file(fileName);\r
+\r
+ if(!file.open(QIODevice::ReadOnly | QIODevice::Text))\r
+ return;\r
+ QTextStream ts(&file);\r
+\r
+ block = new ReferenceBlock(fileName);\r
+\r
+ QString entityLine = "";\r
+ try {\r
+ entityLine = readLibraries(ts);\r
+ }\r
+ catch(Exception e) {\r
+ cerr << "VHDL seems to be malformed" << endl;\r
+ return;\r
+ }\r
+\r
+ QRegularExpression rxEnt("^entity (.+) is$",QRegularExpression::CaseInsensitiveOption);\r
+ QRegularExpressionMatch matchEnt = rxEnt.match(entityLine);\r
+ if (!matchEnt.hasMatch()) {\r
+ cerr << "VHDL seems to be malformed" << endl;\r
+ return;\r
+ }\r
+ entityName = matchEnt.captured(1);\r
+ cout << "found entity " << qPrintable(entityName) << endl;\r
+\r
+ QString archLine = "";\r
+ try {\r
+ archLine = readEntity(ts);\r
+ }\r
+ catch(Exception e) {\r
+ cerr << "VHDL seems to be malformed" << endl;\r
+ return;\r
+ }\r
+\r
+ QRegularExpression rxArch("^architecture (.+) of (.+) is$",QRegularExpression::CaseInsensitiveOption);\r
+ QRegularExpressionMatch matchArch = rxArch.match(archLine);\r
+ if (!matchArch.hasMatch()) {\r
+ cerr << "VHDL seems to be malformed" << endl;\r
+ return;\r
+ }\r
+ archName = matchArch.captured(1);\r
+ cout << "found arch " << qPrintable(archName) << " for entity " << qPrintable(matchArch.captured(2)) << endl;\r
+\r
+ try {\r
+ readArchitecture(ts);\r
+ }\r
+ catch(Exception e) {\r
+ cerr << "VHDL seems to be malformed" << endl;\r
+ return;\r
+ }\r
+ file.close();\r
+\r
+\r
+ QList<BlockParameter*> lstGenerics = block->getGenericParameters();\r
+ twGenerics->setRowCount(lstGenerics.size());\r
+ int i = 0;\r
+ foreach(BlockParameter* param, lstGenerics) {\r
+ twGenerics->setItem(i, 0, new QTableWidgetItem(param->getName()));\r
+ twGenerics->setItem(i, 1, new QTableWidgetItem(param->getTypeString()));\r
+ twGenerics->setItem(i, 2, new QTableWidgetItem(param->getValue().toString()));\r
+ i++;\r
+ }\r
+\r
+ lstIface = block->getInputs();\r
+ lstIface.append(block->getOutputs());\r
+ lstIface.append(block->getBidirs());\r
+\r
+ twPorts->setRowCount(lstIface.size());\r
+ purposeDelegate = new IfacePurposeDelegate();\r
+ twPorts->setItemDelegateForColumn(3,purposeDelegate);\r
+\r
+ i=0;\r
+ foreach(AbstractInterface* iface, lstIface) {\r
+ twPorts->setItem(i, 0, new QTableWidgetItem(iface->getName()));\r
+ twPorts->setItem(i, 1, new QTableWidgetItem(iface->getDirectionString()));\r
+ QString widthStr="";\r
+ if (iface->getType() == AbstractInterface::Boolean) {\r
+ widthStr = "std_logic";\r
+ }\r
+ else {\r
+ widthStr = "std_logic_vector(";\r
+ if (iface->getEndianess() == AbstractInterface::LittleEndian) {\r
+ widthStr += iface->getWidth();\r
+ widthStr += " downto 0)";\r
+ }\r
+ else {\r
+ widthStr += "0 to ";\r
+ widthStr += iface->getWidth();\r
+ widthStr += ")";\r
+ }\r
+ }\r
+ twPorts->setItem(i, 2, new QTableWidgetItem(widthStr));\r
+\r
+ QTableWidgetItem* item = new QTableWidgetItem(iface->getPurposeString());\r
+ twPorts->setItem(i, 3, item);\r
+\r
+ // trying to find wihch other iface this one controls\r
+ QString assoInter = "N/A";\r
+ if (iface->getPurpose() == AbstractInterface::Control) {\r
+ QString name = iface->getName();\r
+ name.remove(name.size()-4,4); // remove _enb at the end\r
+ foreach(AbstractInterface* inter, lstIface) {\r
+ if ((inter != iface) && (inter->getName().contains(name))) {\r
+ assoInter = inter->getName();\r
+ iface->setAssociatedIface(inter);\r
}\r
+ }\r
+ }\r
+ QTableWidgetItem* itemAsso = new QTableWidgetItem(assoInter);\r
+ if (iface->getPurpose() != AbstractInterface::Control) {\r
+ itemAsso->setFlags(Qt::NoItemFlags);\r
+ }\r
+ twPorts->setItem(i, 4, itemAsso);\r
\r
- if(rxEnt->indexIn(line)!= -1) {\r
-\r
- entName = rxEnt->cap(1);\r
- teName->setText(entName);\r
- QSize size = teName->document()->size().toSize();\r
- teName->setMaximumSize(size);\r
-\r
- while(rxEnd->indexIn(line) == -1) {\r
- line = ts.readLine();\r
- if(rxComment->indexIn(line) != -1) {\r
- line = rxComment->cap(1);\r
- }\r
- if(rxComma->indexIn(line) != -1) {\r
- line = rxComma->cap(1);\r
- }\r
- if(rxGeneric->indexIn(line) != -1) {\r
- while(rxEndGen->indexIn(line) == -1) {\r
- line = ts.readLine();\r
- if(rxComment->indexIn(line) != -1) {\r
- line = rxComment->cap(1);\r
- }\r
- if(rxComma->indexIn(line) != -1) {\r
- line = rxComma->cap(1);\r
- }\r
- if(rxGen->indexIn(line) != -1) {\r
- genName = rxGen->cap(1).simplified();\r
- genType = rxGen->cap(2).simplified();\r
- genValue = rxGen->cap(3).simplified();\r
-\r
- genNameList->append(genName);\r
- genTypeList->append(genType);\r
- genValueList->append(genValue);\r
- }\r
- }\r
- }\r
- if(rxPort->indexIn(line) != -1) {\r
- if(rxComment->indexIn(line) != -1) {\r
- line = rxComment->cap(1);\r
- }\r
- if(rxComma->indexIn(line) != -1) {\r
- line = rxComma->cap(1);\r
- }\r
- portName = rxPort->cap(1).simplified();\r
- portId = rxPort->cap(2).simplified();\r
- portType = rxPort->cap(3).simplified();\r
- portNameList->append(portName);\r
- portIdList->append(portId);\r
- portTypeList->append(portType);\r
- }\r
- }\r
+ i++;\r
+ }\r
+\r
+ connect(twPorts,SIGNAL(itemChanged(QTableWidgetItem*)),this,SLOT(searchAssociatedPort(QTableWidgetItem*)));\r
+\r
+ //file.close();\r
+\r
+ //scrollPorts->setWidget(twPorts);\r
+ editEntityName->setText(entityName);\r
+ editLongName->setText(entityName);\r
+ return;\r
+}\r
+\r
+void VHDLConverter::searchAssociatedPort(QTableWidgetItem *item) {\r
+\r
+ bool ok;\r
+ int col = item->column();\r
+ int row = item->row();\r
+\r
+ // searching for the real interface object linked to the item\r
+ AbstractInterface* iface = NULL;\r
+ QString ifaceName = twPorts->item(row,0)->text();\r
+ foreach(AbstractInterface* inter,lstIface) {\r
+ if (inter->getName() == ifaceName) {\r
+ iface = inter;\r
+ break;\r
+ }\r
+ }\r
+\r
+ if (col == 3) {\r
+\r
+ QString assoInter = "N/A";\r
+ iface->setAssociatedIface(NULL);\r
+\r
+ cout << qPrintable(item->text()) << endl;\r
+\r
+ if (item->text() == "data") {\r
+ iface->setPurpose(AbstractInterface::Data);\r
+ }\r
+ else if (item->text() == "control") {\r
+ iface->setPurpose(AbstractInterface::Control);\r
+ }\r
+ else if (item->text() == "clock") {\r
+ iface->setPurpose(AbstractInterface::Clock);\r
+ }\r
+ else if (item->text() == "reset") {\r
+ iface->setPurpose(AbstractInterface::Reset);\r
+ }\r
+ else if (item->text() == "wishbone") {\r
+ iface->setPurpose(AbstractInterface::Wishbone);\r
+ }\r
+\r
+ if (item->text() == "control") {\r
+\r
+ QString name = twPorts->item(row,0)->text();\r
+ name.remove(name.size()-4,4); // remove _enb at the end\r
+ int i=0;\r
+ foreach(AbstractInterface* inter, lstIface) {\r
+ if ((i != row) && (inter->getName().contains(name))) {\r
+ assoInter = inter->getName();\r
+ iface->setAssociatedIface(inter);\r
}\r
+ i++;\r
+ }\r
}\r
- */\r
\r
- twGenerics->setRowCount(genNameList->size());\r
- for(int i = 0; i < genNameList->size(); i++) {\r
- twGenerics->setItem(i, 0, new QTableWidgetItem(genNameList->at(i)));\r
- twGenerics->setItem(i, 1, new QTableWidgetItem(genTypeList->at(i)));\r
- twGenerics->setItem(i, 2, new QTableWidgetItem(genValueList->at(i)));\r
+ QTableWidgetItem* itemAsso = twPorts->item(row,4);\r
+ itemAsso->setText(assoInter);\r
+\r
+ if (item->text() == "control") {\r
+ itemAsso->setFlags(Qt::ItemIsEnabled|Qt::ItemIsEditable);\r
}\r
- twDataPort->setRowCount(portNameList->size());\r
- for(int i = 0; i < portNameList->size(); i++) {\r
- twDataPort->setItem(i, 0, new QTableWidgetItem(portIdList->at(i)));\r
- twDataPort->setItem(i, 1, new QTableWidgetItem(portNameList->at(i)));\r
- twDataPort->setItem(i, 2, new QTableWidgetItem(portTypeList->at(i)));\r
+ else {\r
+ itemAsso->setFlags(Qt::NoItemFlags);\r
}\r
+ }\r
+ else if (col == 4) {\r
\r
- file.close();\r
- scrollDataPort->setWidget(twDataPort);\r
- return;\r
+ QString nameAsso = item->text();\r
+ if (nameAsso == "N/A") return;\r
+\r
+ bool found = false;\r
+\r
+ int i=0;\r
+ foreach(AbstractInterface* inter, lstIface) {\r
+ if ((i != row) && (inter->getName().contains(nameAsso))) {\r
+ found = true;\r
+ iface->setAssociatedIface(inter);\r
+ }\r
+ }\r
+ if (!found) {\r
+ QTableWidgetItem* itemAsso = twPorts->item(row,4);\r
+ itemAsso->setText("N/A");\r
+ }\r
+ }\r
}\r
\r
-// This function gets the informations in the table and the descriptions, and creates a XML file with this content\r
-void VHDLConverter::generateXml() {\r
+void VHDLConverter::generateRefXml(QDomDocument& doc) {\r
+\r
+ QDomElement eBlock = doc.createElement("block");\r
+ eBlock.setAttribute("version", "0.1");\r
+ doc.appendChild(eBlock);\r
+\r
+ // creating infos\r
+ QDomElement infos = doc.createElement("informations");\r
+ eBlock.appendChild(infos);\r
+\r
+ QDomElement eName = doc.createElement("name");\r
+ QDomText tName = doc.createTextNode(editLongName->text());\r
+ eName.appendChild(tName);\r
+ infos.appendChild(eName);\r
+\r
+ QDomElement category = doc.createElement("category");\r
+ category.setAttribute("ids","");\r
+ infos.appendChild(category);\r
+\r
+ QDomElement eDesc = doc.createElement("description");\r
+ QString brief = teBrief->toPlainText();\r
+ QString detailed = teDesc->toPlainText();\r
+ QDomElement eBrief = doc.createElement("brief");\r
+ if(!brief.isEmpty()) {\r
+ QDomText txtBrief = doc.createTextNode(brief);\r
+ eBrief.appendChild(txtBrief);\r
+ eDesc.appendChild(eBrief);\r
+ }\r
+ QDomElement eDetailed = doc.createElement("detailed");\r
+ if(!detailed.isEmpty()) {\r
+ QDomText txtDetailed = doc.createTextNode(detailed);\r
+ eDetailed.appendChild(txtDetailed);\r
+ eDesc.appendChild(eDetailed);\r
+ }\r
+ infos.appendChild(eDesc);\r
+\r
+\r
\r
- QString portName, portType, portId, genName, genType, genValue;\r
- QStringList *portNameList, *portTypeList, *portIdList, *genNameList, *genTypeList, *genValueList;\r
- int x, y, width;\r
- brief = teBrief->toPlainText();\r
- desc = teDesc->toPlainText();\r
- entName = teName->toPlainText();\r
-\r
- portNameList = new QStringList;\r
- portTypeList = new QStringList;\r
- portIdList = new QStringList;\r
- genNameList = new QStringList;\r
- genTypeList = new QStringList;\r
- genValueList = new QStringList;\r
- for(int i = 0; i < twGenerics->rowCount(); i++) {\r
- genNameList->append(twGenerics->item(i,0)->text());\r
- genTypeList->append(twGenerics->item(i,1)->text());\r
- genValueList->append(twGenerics->item(i,2)->text());\r
- }\r
-\r
- for(int i = 0; i < twDataPort->rowCount(); i++) {\r
- portIdList->append(twDataPort->item(i,0)->text());\r
- portNameList->append(twDataPort->item(i,1)->text());\r
- portTypeList->append(twDataPort->item(i,2)->text());\r
- }\r
-\r
- QDomDocument doc (entName);\r
- QDomElement block = doc.createElement("block");\r
- block.setAttribute("name",entName);\r
- block.setAttribute("version", "0.1");\r
- doc.appendChild(block);\r
-\r
- QDomElement comments = doc.createElement("comments");\r
- QDomElement category = doc.createElement("caterory");\r
- category.setAttribute("ids","");\r
- comments.appendChild(category);\r
-\r
- QDomElement eBrief = doc.createElement("brief");\r
- if(!brief.isEmpty()) {\r
- QDomText txtBrief = doc.createTextNode(brief);\r
- eBrief.appendChild(txtBrief);\r
- comments.appendChild(eBrief);\r
- }\r
- QDomElement eDesc = doc.createElement("description");\r
- if(!desc.isEmpty()) {\r
- QDomText txtDesc = doc.createTextNode(desc);\r
- eDesc.appendChild(txtDesc);\r
- comments.appendChild(eDesc);\r
- }\r
- block.appendChild(comments);\r
-\r
- QDomElement parameters = doc.createElement("parameters");\r
- QDomElement interfaces = doc.createElement("interfaces");\r
+ QDomElement parameters = doc.createElement("parameters");\r
+ eBlock.appendChild(parameters);\r
+\r
+ QList<BlockParameter*> lstGenerics = block->getGenericParameters();\r
+ foreach(BlockParameter* param, lstGenerics) {\r
+ QDomElement parameter = doc.createElement("parameter");\r
+ parameter.setAttribute("name",param->getName());\r
+ parameter.setAttribute("type",param->getTypeString());\r
+ parameter.setAttribute("value",param->getValue().toString());\r
+ parameter.setAttribute("context","generic");\r
+ parameters.appendChild(parameter);\r
+ }\r
+\r
+ QDomElement interfaces = doc.createElement("interfaces");\r
+ eBlock.appendChild(interfaces);\r
+\r
+ if (block->getInputs().size() > 0) {\r
QDomElement inputs = doc.createElement("inputs");\r
- QDomElement outputs = doc.createElement("outputs");\r
- QDomElement bidirs = doc.createElement("bidirs");\r
- block.appendChild(parameters);\r
- block.appendChild(interfaces);\r
interfaces.appendChild(inputs);\r
+ foreach(AbstractInterface* iface, block->getInputs()) {\r
+\r
+ if (iface->getPurpose() != AbstractInterface::Control) {\r
+ QDomElement input = doc.createElement("input");\r
+ input.setAttribute("name",iface->getName());\r
+ input.setAttribute("type",iface->getTypeString());\r
+ input.setAttribute("width",iface->getWidth());\r
+ input.setAttribute("multiplicity","1");\r
+ input.setAttribute("purpose",iface->getPurposeString());\r
+ input.setAttribute("endian",iface->getEndianessString());\r
+ inputs.appendChild(input);\r
+ }\r
+ else {\r
+ QDomElement ctl = doc.createElement("control");\r
+ ctl.setAttribute("iface",iface->getAssociatedIface()->getName());\r
+ inputs.appendChild(ctl);\r
+ }\r
+ }\r
+ }\r
+\r
+ if (block->getOutputs().size() > 0) {\r
+ QDomElement outputs = doc.createElement("outputs");\r
interfaces.appendChild(outputs);\r
+ foreach(AbstractInterface* iface, block->getOutputs()) {\r
+ if (iface->getPurpose() != AbstractInterface::Control) {\r
+ QDomElement output = doc.createElement("output");\r
+ output.setAttribute("name",iface->getName());\r
+ output.setAttribute("type",iface->getTypeString());\r
+ output.setAttribute("width",iface->getWidth());\r
+ output.setAttribute("multiplicity","1");\r
+ output.setAttribute("purpose",iface->getPurposeString());\r
+ output.setAttribute("endian",iface->getEndianessString());\r
+ outputs.appendChild(output);\r
+ }\r
+ else {\r
+ QDomElement ctl = doc.createElement("control");\r
+ ctl.setAttribute("iface",iface->getAssociatedIface()->getName());\r
+ outputs.appendChild(ctl);\r
+ }\r
+ }\r
+ }\r
+\r
+ if (block->getBidirs().size() > 0) {\r
+ QDomElement bidirs = doc.createElement("bidirs");\r
interfaces.appendChild(bidirs);\r
+ foreach(AbstractInterface* iface, block->getBidirs()) {\r
+ if (iface->getPurpose() != AbstractInterface::Control) {\r
+ QDomElement bidir = doc.createElement("bidir");\r
+ bidir.setAttribute("name",iface->getName());\r
+ bidir.setAttribute("type",iface->getTypeString());\r
+ bidir.setAttribute("width",iface->getWidth());\r
+ bidir.setAttribute("multiplicity","1");\r
+ bidir.setAttribute("purpose",iface->getPurposeString());\r
+ bidir.setAttribute("endian",iface->getEndianessString());\r
+ bidirs.appendChild(bidir);\r
+ }\r
+ else {\r
+ QDomElement ctl = doc.createElement("control");\r
+ ctl.setAttribute("iface",iface->getAssociatedIface()->getName());\r
+ bidirs.appendChild(ctl);\r
+ }\r
+ }\r
+ }\r
+}\r
\r
- for(int i = 0; i < twGenerics->rowCount(); i++) {\r
- genName = genNameList->at(i);\r
- genType = genTypeList->at(i);\r
- genValue = genValueList->at(i);\r
- QDomElement parameter = doc.createElement("parameter");\r
- parameter.setAttribute("name",genName);\r
- parameter.setAttribute("type",genType);\r
- parameter.setAttribute("value",genValue);\r
- parameter.setAttribute("context","generic");\r
- parameters.appendChild(parameter);\r
- }\r
-\r
- for(int i = 0; i < portIdList->size(); i++) {\r
- portId = portIdList->at(i);\r
- portName = portNameList->at(i);\r
- portType = portTypeList->at(i);\r
- if(rxWidth->indexIn(portType) != -1) {\r
- x = rxWidth->cap(1).toInt();\r
- y = rxWidth->cap(3).toInt();\r
- if(x < y)\r
- width = y - x + 1;\r
- else if(x > y)\r
- width = x - y + 1;\r
- else\r
- width = 1;\r
- }\r
+void VHDLConverter::generateImplXml(QDomDocument& doc) {\r
\r
- if(portId.compare("in", CaseInsensitive) == 0) {\r
- QDomElement input = doc.createElement("input");\r
- input.setAttribute("name",portName);\r
- input.setAttribute("width", width);\r
- inputs.appendChild(input);\r
- }\r
- else if(portId.compare("out", CaseInsensitive) == 0) {\r
- QDomElement output = doc.createElement("output");\r
- output.setAttribute("name",portName);\r
- output.setAttribute("width", width);\r
- outputs.appendChild(output);\r
- }\r
- else if(portId.compare("inout", CaseInsensitive) == 0) {\r
- QDomElement bidir = doc.createElement("bidir");\r
- bidir.setAttribute("name",portName);\r
- bidir.setAttribute("width", width);\r
- bidirs.appendChild(bidir);\r
- }\r
+ QRegularExpression rxPack("^([^.]+)[.](.+)$",QRegularExpression::CaseInsensitiveOption);\r
+\r
+ QDomElement eBlock = doc.createElement("block_impl");\r
+ eBlock.setAttribute("ref_name", entityName+".xml");\r
+ eBlock.setAttribute("ref_md5", "");\r
+ doc.appendChild(eBlock);\r
+\r
+ // creating infos\r
+ QDomElement comments = doc.createElement("comments");\r
+ eBlock.appendChild(comments);\r
+\r
+ QDomElement author = doc.createElement("author");\r
+ author.setAttribute("firstname","");\r
+ author.setAttribute("lastname","");\r
+ author.setAttribute("mail","");\r
+ comments.appendChild(author);\r
+\r
+ QDomElement date = doc.createElement("date");\r
+ date.setAttribute("creation","");\r
+ comments.appendChild(date);\r
+\r
+ QString brief = teBrief->toPlainText();\r
+ QString detailed = teDesc->toPlainText();\r
+ QDomElement eDesc = doc.createElement("description");\r
+ if(!brief.isEmpty()) {\r
+ QDomText txtBrief = doc.createTextNode(brief);\r
+ eDesc.appendChild(txtBrief);\r
+ comments.appendChild(eDesc);\r
+ }\r
+ QDomElement eNotes = doc.createElement("notes");\r
+ if(!detailed.isEmpty()) {\r
+ QDomText txtDetailed = doc.createTextNode(detailed);\r
+ eNotes.appendChild(txtDetailed);\r
+ comments.appendChild(eNotes);\r
+ }\r
+\r
+ QDomElement libs = doc.createElement("libraries");\r
+ eBlock.appendChild(libs);\r
+\r
+ QHashIterator<QString,QList<QString>* > it(packages);\r
+\r
+ while (it.hasNext()) {\r
+ it.next();\r
+ QString libName = it.key();\r
+ cout << qPrintable(libName) << endl;\r
+ QList<QString>* packList = it.value();\r
+ QDomElement lib = doc.createElement("library");\r
+ lib.setAttribute("name", libName);\r
+ libs.appendChild(lib);\r
+\r
+ foreach(QString packName, *packList) {\r
+ QDomElement pack = doc.createElement("package");\r
+ lib.appendChild(pack);\r
+ QRegularExpressionMatch matchPack = rxPack.match(packName);\r
+ if (matchPack.hasMatch()) {\r
+ QString name = matchPack.captured(1);\r
+ QString subName = matchPack.captured(2);\r
+ name = name.toLower();\r
+ subName = subName.toLower();\r
+ pack.setAttribute("name",name);\r
+ pack.setAttribute("use",subName);\r
+ }\r
}\r
+ }\r
+\r
+ QDomElement archi = doc.createElement("architecture");\r
+ eBlock.appendChild(archi);\r
+ QDomText tName = doc.createTextNode("");\r
+ foreach(QString line, archLines) {\r
+ tName.appendData(line+"\n");\r
+ }\r
+ archi.appendChild(tName);\r
+\r
+ QDomElement patterns = doc.createElement("patterns");\r
+ eBlock.appendChild(patterns);\r
+ QDomElement delta = doc.createElement("delta");\r
+ delta.setAttribute("value","to_define");\r
+ patterns.appendChild(delta);\r
+ QDomElement cons = doc.createElement("consumption");\r
+ foreach(AbstractInterface* iface, lstIface) {\r
+ if ((iface->getDirection() == AbstractInterface::Input) && (iface->getPurpose() == AbstractInterface::Control)) {\r
+ QDomElement input = doc.createElement("input");\r
+ input.setAttribute("name",iface->getName());\r
+ input.setAttribute("pattern","to_define");\r
+ cons.appendChild(input);\r
+ }\r
+ }\r
+ patterns.appendChild(cons);\r
+ QDomElement prod = doc.createElement("production");\r
+ prod.setAttribute("counter","to_define");\r
+ foreach(AbstractInterface* iface, lstIface) {\r
+ if ((iface->getDirection() == AbstractInterface::Output) && (iface->getPurpose() == AbstractInterface::Control)) {\r
+ QDomElement output = doc.createElement("output");\r
+ output.setAttribute("name",iface->getName());\r
+ output.setAttribute("pattern","to_define");\r
+ prod.appendChild(output);\r
+ }\r
+ }\r
+ patterns.appendChild(prod);\r
+}\r
\r
- fileName = QFileDialog::getOpenFileName(this, tr("Open File"),\r
- "C:", tr("Files (*.xml)"));\r
- QFile file(fileName);\r
- if(!file.open(QIODevice::WriteOnly | QIODevice::Text))\r
- return;\r
- QTextStream ts(&file);\r
- doc.save(ts,QDomNode::EncodingFromTextStream);\r
- file.close();\r
+void VHDLConverter::replaceSignalNames(QString& line) {\r
+ foreach(AbstractInterface* iface, lstIface) {\r
+ QString pattern = iface->getName() + "([^a-zA-Z0-9_])";\r
+ QString repl = "@{"+iface->getName()+"}\\1";\r
+ QRegularExpression rxPort(pattern,QRegularExpression::CaseInsensitiveOption);\r
+ line.replace(rxPort,repl);\r
+ }\r
+\r
+}\r
+\r
+void VHDLConverter::updateArchitecture() {\r
+ QRegularExpression rxLT("<=",QRegularExpression::CaseInsensitiveOption);\r
+ QRegularExpression rxGT("=>",QRegularExpression::CaseInsensitiveOption);\r
+ foreach(QString line, archLines) {\r
+ replaceSignalNames(line);\r
+ line.replace(rxLT,"<=");\r
+ line.replace(rxGT,"=>");\r
+\r
+ cout << qPrintable(line) << endl;\r
+ }\r
+}\r
+\r
+// This function gets the informations in the table and the descriptions, and creates a XML file with this content\r
+void VHDLConverter::generateXml() {\r
+\r
+\r
+ updateArchitecture();\r
+\r
+ // creating reference xml\r
+ QDomDocument docRef(entityName);\r
+ generateRefXml(docRef);\r
+\r
+ // creating implementation xml\r
+ QDomDocument docImpl(entityName);\r
+ generateImplXml(docImpl);\r
+\r
+ QString dir = QFileDialog::getExistingDirectory(this,tr("Save file in"),".",QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);\r
+\r
+ QString fileName = dir + "/"+ entityName + ".xml";\r
+\r
+ QFile fileRef(fileName);\r
+ if(!fileRef.open(QIODevice::WriteOnly | QIODevice::Text)) {\r
+ cerr << "Cannot save in " << qPrintable(fileName) << endl;\r
+ return;\r
+ }\r
+ QTextStream tsRef(&fileRef);\r
+ docRef.save(tsRef,QDomNode::EncodingFromTextStream);\r
+ fileRef.close();\r
+\r
+ fileName = dir + "/"+ entityName + "_impl.xml";\r
+ QFile fileImpl(fileName);\r
+ if(!fileImpl.open(QIODevice::WriteOnly | QIODevice::Text)) {\r
+ cerr << "Cannot save in " << qPrintable(fileName) << endl;\r
+ return;\r
+ }\r
+ QTextStream tsImpl(&fileImpl);\r
+ docImpl.save(tsImpl,QDomNode::EncodingFromTextStream);\r
+ fileImpl.close();\r
\r
- QLabel *popup = new QLabel("Votre fichier XML est rempli");\r
- popup->show();\r
}\r