Create DOT diagram of parse tree
From Verific Design Automation FAQ
This example parses the r4000 design in the <verific>/example_designs/verilog directory and writes out a Graphviz DOT-format file that represents a simple diagram view of the design.
There are several tools that can visualize DOT files. On Linux distributions you can install 'dot'. You would run this command to create a PDF output of the C++ application below
dot -Tpdf pp_out.dot -o r4000.pdf
C++:
#include <iostream> #include "veri_file.h" #include "VeriModule.h" #include "VeriId.h" #include "VeriExpression.h" #include "Map.h" using namespace std ; #ifdef VERIFIC_NAMESPACE using namespace Verific ; #endif int main() { char ppfile_nm[32] = "pp_out.dot"; char transition[64] ; unsigned module_cnt = 0 ; unsigned field_cnt = 0 ; Array transition_table ; Array instantiation_table ; Array module_table ; ofstream ofs(ppfile_nm, std::ios::out) ; if (!veri_file::Analyze("r4000.v", veri_file::SYSTEM_VERILOG)) return 1 ; ofs << "digraph Verific {" << endl ; ofs << " rankdir = LR" << endl ; ofs << " node [shape=plaintext]" << endl ; ofs << " edge [dir=forward]" << endl ; Array *tops = veri_file::GetTopModules() ; MapIter mi ; VeriModule *mod, *top ; unsigned i ; FOREACH_VERILOG_MODULE(mi, mod) { if (!mod || mod->IsPackage() || mod->IsRootModule()) continue ; module_table.Insert(mod) ; } unsigned mc ; FOREACH_ARRAY_ITEM(&module_table, mc, mod) { ofs << " cell" << module_cnt ; ofs << " [label=< <TABLE BORDER=\"0\" CELLBORDER=\"1\" CELLSPACING=\"0\">" << endl ; unsigned found = 0 ; FOREACH_ARRAY_ITEM(tops, i, top) { if (Strings::compare(top->Name(), mod->Name())) { found = 1 ; break ; } } if (found) ofs << " <TR> <TD ALIGN=\"left\" PORT=\"f" << field_cnt++ << "\" COLOR=\"red\" BGCOLOR=\"yellow\"> <FONT COLOR=\"red\">MODULE : " << mod->Name() << "</FONT> </TD> </TR>" << endl ; else ofs << " <TR> <TD ALIGN=\"left\" PORT=\"f" << field_cnt++ << "\" BGCOLOR=\"gray\">MODULE : " << mod->Name() << "</TD> </TR>" << endl ; Array *ports = mod->GetPorts(); if (ports) { VeriIdDef *port ; FOREACH_ARRAY_ITEM(ports, i, port) { ofs << " <TR> <TD ALIGN=\"left\" PORT=\"f" << field_cnt++ << "\"> port : " << port->Name() << "</TD> </TR>" << endl ; } } Array *params = mod->GetParameters(); if (params) { VeriIdDef *param ; FOREACH_ARRAY_ITEM(params, i, param) { ofs << " <TR> <TD ALIGN=\"left\" PORT=\"f" << field_cnt++ << "\"> parameter : " << param->Name() ; VeriExpression *initvalue = param->GetInitialValue(); if (initvalue) ofs << " = " << initvalue->GetPrettyPrintedString() << "</TD> </TR>" << endl ; } } Array *module_items = mod->GetModuleItems() ; VeriModuleItem *module_item ; FOREACH_ARRAY_ITEM(module_items, i, module_item) { switch (module_item->GetClassId()) { case ID_VERIMODULEINSTANTIATION: { VeriModuleInstantiation *mod_inst = static_cast<VeriModuleInstantiation*>(module_item) ; unsigned j ; VeriInstId *inst_id ; FOREACH_ARRAY_ITEM(mod_inst->GetIds(), j, inst_id) { if (!inst_id) continue ; instantiation_table.Insert(inst_id) ; ofs << " <TR> <TD ALIGN=\"left\" PORT=\"f" << field_cnt << "\"> instantiation : " << mod_inst->GetModuleName() << " : " << inst_id->InstName() << "</TD> </TR>" << endl ; unsigned k ; VeriModule *inst ; FOREACH_ARRAY_ITEM(&module_table, k, inst) { if (Strings::compare(inst_id->GetModuleReference(), inst->Name())) { sprintf (transition, " cell%d:f%d -> cell%d:f0 ;", module_cnt, field_cnt, k) ; char *trans = Strings::save(transition) ; transition_table.Insert(trans) ; } } field_cnt++ ; } } default : ; } } ofs << " </TABLE> >] ;" << endl ; field_cnt = 0 ; module_cnt++ ; } ofs << endl ; char *trans ; FOREACH_ARRAY_ITEM(&transition_table, i, trans) { ofs << trans << endl ; } ofs << "}" << endl ; ofs.close(); return 0 ; }