Difference between revisions of "Create DOT diagram of parse tree"
From Verific Design Automation FAQ
| Line 13: | Line 13: | ||
#include "VeriId.h" | #include "VeriId.h" | ||
#include "VeriExpression.h" | #include "VeriExpression.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 ; | ||
| − | + | 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) ; | ||
| + | } | ||
| − | + | 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 << "\"> | + | 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, | + | VeriModule *inst ; |
| − | if (Strings::compare(inst_id->GetModuleReference(), | + | 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) ; | ||
| Line 93: | Line 109: | ||
} | } | ||
} | } | ||
| + | |||
field_cnt++ ; | field_cnt++ ; | ||
} | } | ||
Revision as of 13:12, 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 ;
}