Create DOT diagram of parse tree

From Verific Design Automation FAQ
Revision as of 17:57, 12 January 2024 by Vince (Talk | contribs) (Created page with "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 th...")

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

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'. For the output of the application below you would run

   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 "VeriVisitor.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 ;

    MapIter mi ;
    unsigned i ;
    VeriModule *mod ;

    FOREACH_VERILOG_MODULE(mi, mod)
        module_table.Insert(mod) ;

    FOREACH_VERILOG_MODULE(mi, mod) {
        ofs << "   cell" << module_cnt ;
        ofs << " [label=< <TABLE BORDER=\"0\" CELLBORDER=\"1\" CELLSPACING=\"0\">" << endl ;  
        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 << "\">   instantiations : " << mod_inst->GetModuleName() << " : " << inst_id->InstName() << "</TD> </TR>" << endl ;
                        unsigned k ;
                        FOREACH_ARRAY_ITEM(&module_table, k, mod) {
                            if (Strings::compare(inst_id->GetModuleReference(), mod->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 ;
}