diff --git a/Changes b/Changes index 418257f73..136ff26f9 100644 --- a/Changes +++ b/Changes @@ -7,7 +7,8 @@ The contributors that suggested a given feature are shown in []. Thanks! *** Support "ref" and "const ref" pins and functions, bug1360. [Jake Longo] -*** In --xml-only show the original unmodified names, msg2716. [Kanad Kanhere] +*** In --xml-only show the original unmodified names, and add module_files + and cells similar to Verilog-Perl, msg2719. [Kanad Kanhere] **** Fix --trace-lxt2 compile error on MinGW, msg2711. [HyungKi Jeong] diff --git a/src/V3EmitXml.cpp b/src/V3EmitXml.cpp index fe03f4824..863ee8e06 100644 --- a/src/V3EmitXml.cpp +++ b/src/V3EmitXml.cpp @@ -159,6 +159,126 @@ public: virtual ~EmitXmlFileVisitor() {} }; +//###################################################################### +// List of module files xml visitor + +class ModuleFilesXmlVisitor : public AstNVisitor { +private: + // MEMBERS + std::ostream& m_os; + std::set m_modulesCovered; + std::deque m_nodeModules; + + // METHODS + VL_DEBUG_FUNC; // Declare debug() + + // VISITORS + virtual void visit(AstNetlist* nodep) { + // Children are iterated backwards to ensure correct compilation order + iterateChildrenBackwards(nodep); + } + virtual void visit(AstNodeModule* nodep) { + // Only list modules and interfaces + // Assumes modules and interfaces list is already sorted level wise + if (!nodep->dead() + && (VN_IS(nodep, Module) || VN_IS(nodep, Iface)) + && m_modulesCovered.insert(nodep->fileline()->filename()).second) { + m_nodeModules.push_front(nodep->fileline()); + } + } + //----- + virtual void visit(AstNode* nodep) { + // All modules are present at root so no need to iterate on children + } + +public: + // CONSTRUCTORS + ModuleFilesXmlVisitor(AstNetlist* nodep, std::ostream& os) + : m_os(os), m_modulesCovered(), m_nodeModules() { + // Operate on whole netlist + nodep->accept(*this); + // Xml output + m_os<<"\n"; + for (std::deque::iterator it = m_nodeModules.begin(); + it != m_nodeModules.end(); it++) { + m_os<<"filenameLetters() + <<"\" filename=\""<<(*it)->filename() + <<"\" language=\""<<(*it)->language().ascii()<<"\"/>\n"; + } + m_os<<"\n"; + } + virtual ~ModuleFilesXmlVisitor() {} +}; + +//###################################################################### +// Hierarchy of Cells visitor + +class HierCellsXmlVisitor : public AstNVisitor { +private: + // MEMBERS + std::ostream& m_os; + std::string m_hier; + bool m_hasChildren; + + // METHODS + VL_DEBUG_FUNC; // Declare debug() + + // VISITORS + virtual void visit(AstNodeModule* nodep) { + if (nodep->level() >= 0 + && nodep->level() <=2 ) { // ==2 because we don't add wrapper when in XML mode + m_os<<"\n"; + m_os<<"fileline()->xml() + <<" name=\""<name()<<"\"" + <<" submodname=\""<name()<<"\"" + <<" hier=\""<name()<<"\""; + m_hier = nodep->name() + "."; + m_hasChildren = false; + iterateChildren(nodep); + if (m_hasChildren) { + m_os<<"\n"; + } else { + m_os<<"/>\n"; + } + m_os<<"\n"; + } + } + virtual void visit(AstCell* nodep) { + if (nodep->modp()->dead()) { + return; + } + if (!m_hasChildren) m_os<<">\n"; + m_os<<"fileline()->xml() + <<" name=\""<name()<<"\"" + <<" submodname=\""<modName()<<"\"" + <<" hier=\""<name()<<"\""; + std::string hier = m_hier; + m_hier += nodep->name() + "."; + m_hasChildren = false; + iterateChildren(nodep->modp()); + if (m_hasChildren) { + m_os<<"\n"; + } else { + m_os<<"/>\n"; + } + m_hier = hier; + m_hasChildren = true; + } + //----- + virtual void visit(AstNode* nodep) { + iterateChildren(nodep); + } + +public: + // CONSTRUCTORS + HierCellsXmlVisitor(AstNetlist* nodep, std::ostream& os) + : m_os(os), m_hier(""), m_hasChildren(false) { + // Operate on whole netlist + nodep->accept(*this); + } + virtual ~HierCellsXmlVisitor() {} +}; + //###################################################################### // EmitXml class functions @@ -174,6 +294,12 @@ void V3EmitXml::emitxml() { FileLine::fileNameNumMapDumpXml(sstr); of.puts(sstr.str()); } + { + std::stringstream sstr; + ModuleFilesXmlVisitor moduleFilesVisitor (v3Global.rootp(), sstr); + HierCellsXmlVisitor cellsVisitor (v3Global.rootp(), sstr); + of.puts(sstr.str()); + } EmitXmlFileVisitor visitor (v3Global.rootp(), &of); of.puts("\n"); } diff --git a/test_regress/t/t_xml_first.out b/test_regress/t/t_xml_first.out index 17ea974d8..1f4b543ae 100644 --- a/test_regress/t/t_xml_first.out +++ b/test_regress/t/t_xml_first.out @@ -9,6 +9,15 @@ + + + + + + + + + diff --git a/test_regress/t/t_xml_tag.out b/test_regress/t/t_xml_tag.out index e23100ee6..aed866106 100644 --- a/test_regress/t/t_xml_tag.out +++ b/test_regress/t/t_xml_tag.out @@ -9,6 +9,12 @@ + + + + + +