X-Git-Url: https://bilbo.iut-bm.univ-fcomte.fr/and/gitweb/blast.git/blobdiff_plain/c85843afb9bd492b46d6fe87a8287157097483f5..18fecf25efe710631fabecbb9f689c2997fdfe18:/FunctionalBlock.cpp

diff --git a/FunctionalBlock.cpp b/FunctionalBlock.cpp
index 8ecd6a3..2d455db 100644
--- a/FunctionalBlock.cpp
+++ b/FunctionalBlock.cpp
@@ -1312,3 +1312,304 @@ int FunctionalBlock::createTriggers() {
   }      
   return triggers.size();
 }
+
+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)   : "<<firstName+" "<<lastName<<" ("<<mail<<")" << endl;
+  out << "--" << endl;
+  QDomElement eltDate = eltAuthor.nextSiblingElement("date");
+  QString crea = eltDate.attribute("creation","");
+  out << "--  Creation Date   : "<<crea<< endl;
+  out << "--" << endl;
+  QDomElement eltRelated = eltDate.nextSiblingElement("related_files");
+  QString relateds = eltRelated.attribute("list","");
+  out << "--  Related files   :\n"<<relateds<<endl;
+  out << "--" << endl;
+  QDomElement eltDesc = eltRelated.nextSiblingElement("description");
+  QDomElement desc = eltDesc.firstChildElement();
+  QString descTxt = desc.text();
+  out << "--  Decription      :\n"<<descTxt<<endl;
+  out << "--" << endl;
+  QDomElement eltNote = eltDesc.nextSiblingElement("description");
+  QDomElement note = eltNote.firstChildElement();
+  QString noteTxt = note.text();
+  out << "--  Note          :\n"<<noteTxt<<endl;
+  out << "--" << endl;
+  for(int i = 0; i < 50; i++) {
+    out << "--";
+  }
+  out << endl << endl;
+}
+
+void FunctionalBlock::generateLibraries(QTextStream& out, QDomElement &elt) throw(Exception) {
+  
+  QDomNodeList listLib = elt.elementsByTagName("library");
+  for(int i = 0; i < listLib.length(); i++) {
+    QDomNode nodeLib = listLib.item(i);
+    QDomElement eltLib = nodeLib.toElement();
+    QString nameLib = eltLib.attribute("name","none");
+    out << "library " << nameLib << ";" << endl;
+    QDomNodeList listPack = eltLib.elementsByTagName("package");
+    for(int j = 0; j < listPack.length(); j++) {
+      QDomNode nodePack = listPack.item(j);
+      QDomElement eltPack = nodePack.toElement();
+      QString namePack = eltPack.attribute("name","none");
+      QString usePack = eltPack.attribute("use","none");
+      out << "use " << nameLib << "." << namePack << "." << usePack << endl;
+    }
+    out << endl;
+  }
+}
+
+void FunctionalBlock::generateEntity(QTextStream& out, bool hasController) throw(Exception) {
+
+  int i=0;
+  
+  //QList<BlockParameter*> listParams = reference->getParameters();
+  QList<AbstractInterface*> listInputs = getInputs();
+  QList<AbstractInterface*> listOutputs = getOutputs();
+  QList<AbstractInterface*> 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<BlockParameter*> 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;i<listGenerics.size()-1;i++) {
+      out << "    " << listGenerics.at(i)->toVHDL(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<BlockParameter*> listWB = reference->getWishboneParameters();
+    for(i=0;i<listWB.size()-1;i++) {
+      out << "    " << listWB.at(i)->toVHDL(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) {
+  
+}
+