Difference between revisions of "Create DOT diagram of parse tree"

From Verific Design Automation FAQ
Jump to: navigation, search
 
(One intermediate revision by the same user not shown)
Line 13: Line 13:
 
#include "VeriId.h"
 
#include "VeriId.h"
 
#include "VeriExpression.h"
 
#include "VeriExpression.h"
#include "VeriVisitor.h"
 
 
#include "Map.h"
 
#include "Map.h"
  
Line 21: Line 20:
 
#endif
 
#endif
  
int main() {
+
int main()  
 
+
{
 
     char ppfile_nm[32] = "pp_out.dot";
 
     char ppfile_nm[32] = "pp_out.dot";
 
     char transition[64] ;
 
     char transition[64] ;
Line 39: Line 38:
 
     ofs << "  node [shape=plaintext]" << endl ;
 
     ofs << "  node [shape=plaintext]" << endl ;
 
     ofs << "  edge [dir=forward]" << endl ;
 
     ofs << "  edge [dir=forward]" << endl ;
 +
 +
    Array *tops = veri_file::GetTopModules() ;
  
 
     MapIter mi ;
 
     MapIter mi ;
 +
    VeriModule *mod, *top ;
 
     unsigned i ;
 
     unsigned i ;
    VeriModule *mod ;
+
     FOREACH_VERILOG_MODULE(mi, mod) {
 
+
        if (!mod || mod->IsPackage() || mod->IsRootModule()) continue ;
     FOREACH_VERILOG_MODULE(mi, mod)
+
 
         module_table.Insert(mod) ;
 
         module_table.Insert(mod) ;
 +
    }
  
     FOREACH_VERILOG_MODULE(mi, mod) {
+
     unsigned mc ;
         ofs << "  cell" << module_cnt ;
+
    FOREACH_ARRAY_ITEM(&module_table, mc, mod) {
         ofs << " [label=< <TABLE BORDER=\"0\" CELLBORDER=\"1\" CELLSPACING=\"0\">" << endl ;
+
         ofs << "  cell" << module_cnt ;  
         ofs << "      <TR> <TD ALIGN=\"left\" PORT=\"f" << field_cnt++ << "\" BGCOLOR=\"gray\">MODULE : " << mod->Name() << "</TD> </TR>" << endl ;
+
         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();
 
         Array *ports = mod->GetPorts();
Line 61: Line 76:
  
 
         Array *params = mod->GetParameters();
 
         Array *params = mod->GetParameters();
         if (params) {
+
         if (params) {  
 
             VeriIdDef *param ;
 
             VeriIdDef *param ;
 
             FOREACH_ARRAY_ITEM(params, i, param) {
 
             FOREACH_ARRAY_ITEM(params, i, param) {
 
                 ofs << "      <TR> <TD ALIGN=\"left\" PORT=\"f" << field_cnt++ << "\">  parameter : " << param->Name() ;
 
                 ofs << "      <TR> <TD ALIGN=\"left\" PORT=\"f" << field_cnt++ << "\">  parameter : " << param->Name() ;
 
                 VeriExpression *initvalue = param->GetInitialValue();
 
                 VeriExpression *initvalue = param->GetInitialValue();
                 if (initvalue)
+
                 if (initvalue)  
 
                     ofs << " = " << initvalue->GetPrettyPrintedString() << "</TD> </TR>" << endl ;
 
                     ofs << " = " << initvalue->GetPrettyPrintedString() << "</TD> </TR>" << endl ;
 
             }
 
             }
Line 81: Line 96:
 
                     VeriInstId *inst_id ;
 
                     VeriInstId *inst_id ;
 
                     FOREACH_ARRAY_ITEM(mod_inst->GetIds(), j, inst_id) {
 
                     FOREACH_ARRAY_ITEM(mod_inst->GetIds(), j, inst_id) {
                         if (!inst_id) continue ;
+
                         if (!inst_id) continue ;  
  
 
                         instantiation_table.Insert(inst_id) ;
 
                         instantiation_table.Insert(inst_id) ;
                         ofs << "      <TR> <TD ALIGN=\"left\" PORT=\"f" << field_cnt << "\">  instantiations : " << mod_inst->GetModuleName() << " : " << inst_id->InstName() << "</TD> </TR>" << endl ;
+
                         ofs << "      <TR> <TD ALIGN=\"left\" PORT=\"f" << field_cnt << "\">  instantiation : " << mod_inst->GetModuleName() << " : " << inst_id->InstName() << "</TD> </TR>" << endl ;
 
                         unsigned k ;
 
                         unsigned k ;
                         FOREACH_ARRAY_ITEM(&module_table, k, mod) {
+
VeriModule *inst ;
                             if (Strings::compare(inst_id->GetModuleReference(), mod->Name())) {
+
                         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) ;
 
                                 sprintf (transition, "  cell%d:f%d -> cell%d:f0 ;", module_cnt, field_cnt, k) ;
 
                                 char *trans = Strings::save(transition) ;
 
                                 char *trans = Strings::save(transition) ;

Latest revision as of 13:14, 28 August 2024

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 ;
}