Prettyprint all modules in the design hierarchy
From Verific Design Automation FAQ
There is an API to prettyprint a module, and there is an API to prettyprint all modules in a library.
But there is no single API to prettyprint all modules in the design hierarchy.
To do so, you need to:
- Statically elaborate the top module (this step is optional).
- Traverse the design hierarchy and save all the modules in a Set.
- Iterate over all items (modules) of the Set, and prettyprint each of them.
C++:
#include <iostream> #include <fstream> using namespace std; // Verific utilities #include "Array.h" // Make class Array available #include "Set.h" // Make class Set available #include "Message.h" // Make message handlers available #include "Strings.h" // Definition of class to manipulate copy, concatenate, create etc... // Verific Verilog parser #include "veri_file.h" // Make verilog reader available #include "VeriModule.h" // Definition of a VeriModule and VeriPrimitive #include "VeriExpression.h" // Definition of VeriName #include "VeriId.h" // Definitions of all verilog identifier nodes #include "VeriScope.h" #ifdef VERIFIC_NAMESPACE using namespace Verific ; #endif void Accumulate(VeriModule *module, Set &done); int main() { const char *file_name = "test.v" ; const char *top_name = "top" ; const char *work_lib = "work" ; if (!veri_file::Analyze(file_name, veri_file::VERILOG_2K /*Verilog 2000*/)) return 1 ; if (veri_file::GetModule(top_name)) { // Optional - statically elaborate all the top Verilog module. Return if any error shows up. if (!veri_file::ElaborateStatic(top_name)) return 2 ; // statically elaborates all verilog modules in the "work" libarary VeriModule *top_module = veri_file::GetModule(top_name) ; // Get the pointer to the top-level module if (!top_module) { return 3 ; // Exit from application if there is no top module by the given name in the given Verilog designs } // Prettyprint only top module char *topfilename = Strings::save(top_module->Name(), "_pp.v"); veri_file::PrettyPrint(topfilename, top_module->Name(), work_lib); Strings::free(topfilename); top_module->Info("Start collecting modules in '%s' hierachy", top_module->Name()) ; Set modules(POINTER_HASH); Accumulate(top_module, modules); top_module->Info("Prettyprint all modules in '%s' hierachy", top_module->Name()) ; // Prettyprint all modules in the design hiearchy under top_module char *tophierfilename = Strings::save(top_module->Name(), "_hier_pp.v"); std::ofstream f(tophierfilename, std::ios::out) ; VeriModule *module ; SetIter si ; // FOREACH_SET_ITEM(&modules, si, &module) { // if you want to prettyprint top module last FOREACH_SET_ITEM_BACK(&modules, si, &module) { // if you want to prettyprint top module first if (module) { Message::PrintLine("Prettyprinting module : ", module->Name()) ; f << "// Printing module " << module->Name() << endl; module->PrettyPrint(f, 0); } } f.close(); Strings::free(tophierfilename); } return 0 ; // all good } // This function is recursive in nature, and collects all other // modules that the incoming module depends on in a container. void Accumulate(VeriModule *module, Set &done) { if (!module) return ; // Ignore NULL netlists SetItem *item = done.GetItem(module) ; if (item) { // Message::PrintLine("Been in module ", module->Name(), " before. Returning....") ; return ; // We've already been here } // Get the scope of the module: VeriScope *scope = module->GetScope() ; // Find all the declared ids in this scope: Map *ids = scope ? scope->DeclArea() : 0 ; MapIter mi ; VeriIdDef *id ; FOREACH_MAP_ITEM(ids, mi, 0, &id) { // Traverse declared ids if (!id || !id->IsInst()) continue ; // Consider only the instance ids VeriModuleInstantiation *mod_inst = id->GetModuleInstance() ; // Take the module instance VeriModule *mod = mod_inst ? mod_inst->GetInstantiatedModule() : 0 ; // The module instance is a module if (mod) { // This is verilog module instantiation: need to go into that module // Message::PrintLine("In module ", module->Name()) ; // Message::PrintLine("Processing instance ", id->Name(), " of module ", mod->Name()); //, " in module ", module->Name()) ; Accumulate(mod, done) ; // Traverse the instantiated module } } // Insert the traversed module // Message::PrintLine("Inserting module ", module->Name()) ; done.Insert(module) ; }
Input file test.v:
module top(a, b, c, d, e, f, out, m, n, o) ; input a, b, c, d, e, f, m, n ; output out, o ; wire tmp1, tmp2 ; mid1 i1(a, b, c, d, tmp1) ; mid1 i2(a, d, e, f, tmp2) ; mid1 i3(tmp1, tmp2, e, f, out) ; bot bi(o, m, n); endmodule module mid1 (mid1_inp1, mid1_inp2, mid1_inp3, mid1_inp4, mid1_out, mid1b_inp1, mid1b_inp2, mid1b_out) ; input mid1_inp1, mid1_inp2, mid1_inp3, mid1_inp4 ; output mid1_out ; input mid1b_inp1, mid1b_inp2 ; output mid1b_out ; wire tmp1, tmp2 ; mid2 m1(mid1_inp1, mid1_inp2, tmp1) ; mid2 m2(mid1_inp3, mid1_inp4, tmp2) ; mid2 m3(tmp1, tmp2, mid1_out) ; bot b(mid1b_inp1, mid1b_inp2, mid1b_out) ; endmodule module mid2 (mid2_inp1, mid2_inp2, mid2_out) ; input mid2_inp1, mid2_inp2 ; output mid2_out ; bot b(mid2_inp1, mid2_inp2, mid2_out) ; endmodule module bot (bot_inp1, bot_inp2, bot_out) ; input bot_inp1, bot_inp2 ; output bot_out ; assign bot_out = bot_inp1 & bot_inp2 ; endmodule
Output file top_hier_pp.v:
// Printing module top module top (a, b, c, d, e, f, out, m, n, o) ; input a, b, c, d, e, f, m, n ; output out, o ; wire tmp1, tmp2 ; mid1 i1 (a, b, c, d, tmp1) ; mid1 i2 (a, d, e, f, tmp2) ; mid1 i3 (tmp1, tmp2, e, f, out) ; bot bi (o, m, n) ; endmodule // Printing module mid1 module mid1 (mid1_inp1, mid1_inp2, mid1_inp3, mid1_inp4, mid1_out, mid1b_inp1, mid1b_inp2, mid1b_out) ; input mid1_inp1, mid1_inp2, mid1_inp3, mid1_inp4 ; output mid1_out ; input mid1b_inp1, mid1b_inp2 ; output mid1b_out ; wire tmp1, tmp2 ; mid2 m1 (mid1_inp1, mid1_inp2, tmp1) ; mid2 m2 (mid1_inp3, mid1_inp4, tmp2) ; mid2 m3 (tmp1, tmp2, mid1_out) ; bot b (mid1b_inp1, mid1b_inp2, mid1b_out) ; endmodule // Printing module mid2 module mid2 (mid2_inp1, mid2_inp2, mid2_out) ; input mid2_inp1, mid2_inp2 ; output mid2_out ; bot b (mid2_inp1, mid2_inp2, mid2_out) ; endmodule // Printing module bot module bot (bot_inp1, bot_inp2, bot_out) ; input bot_inp1, bot_inp2 ; output bot_out ; assign bot_out = (bot_inp1 & bot_inp2) ; endmodule