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

From Verific Design Automation FAQ
Jump to: navigation, search
 
(2 intermediate revisions by the same user not shown)
Line 1: Line 1:
 
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.
 
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 view the output of the C++ application below  
+
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
 
     dot -Tpdf pp_out.dot -o r4000.pdf
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 14: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 ;
}