]> AND Private Git Repository - blast.git/blobdiff - VHDLConverter.cpp
Logo AND Algorithmique Numérique Distribuée

Private GIT Repository
started top group gen, added project subdirs
[blast.git] / VHDLConverter.cpp
index d32ab152c0a6ce43f2c6bdc4f97bb8ffe57eb948..d3938b29e453c4fca1f19ec7a22b9c07af1a8760 100644 (file)
@@ -1,70 +1,66 @@
 #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
@@ -75,18 +71,19 @@ QString VHDLConverter::skipBlankAndComments(QTextStream &in) {
   \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
@@ -95,7 +92,7 @@ void VHDLConverter::readLibraries(QTextStream &in) throw(Exception) {
   line = skipBlankAndComments(in);\r
   if (line == "") {\r
     throw(Exception(VHDLFILE_CORRUPTED));\r
-  }    \r
+  }\r
   \r
   while (! line.contains("entity",Qt::CaseInsensitive)) {\r
     \r
@@ -107,21 +104,21 @@ void VHDLConverter::readLibraries(QTextStream &in) throw(Exception) {
       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
@@ -135,9 +132,8 @@ void VHDLConverter::readLibraries(QTextStream &in) throw(Exception) {
       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
@@ -147,21 +143,229 @@ void VHDLConverter::readLibraries(QTextStream &in) throw(Exception) {
     }\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
@@ -170,230 +374,503 @@ 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.\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
+    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(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
+    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
-    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
+\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
-    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
+  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
+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
+  for(int i=0;i<archLines.size();i++) {\r
+    QString line = archLines.at(i);\r
+    replaceSignalNames(line);\r
+    //line.replace(rxLT,"&lt;=");\r
+    //line.replace(rxGT,"=&gt;");\r
+    archLines.replace(i,line);\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