Difference between revisions of "Prettyprint all modules in the design hierarchy"

From Verific Design Automation FAQ
Jump to: navigation, search
Line 40: Line 40:
 
     const char *work_lib = "work" ;
 
     const char *work_lib = "work" ;
  
     if (!veri_file::Analyze(file_name, veri_file::VERILOG_2K /*Verilog 2000*/)) return 1 ;  
+
     if (!veri_file::Analyze(file_name, veri_file::VERILOG_2K /*Verilog 2000*/)) return 1 ;
  
 
     if (veri_file::GetModule(top_name)) {
 
     if (veri_file::GetModule(top_name)) {
         // Statically elaborate all the top Verilog module. Return if any error shows up.  
+
         // 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
 
         if (!veri_file::ElaborateStatic(top_name)) return 2 ; // statically elaborates all verilog modules in the "work" libarary
  
Line 60: Line 60:
 
         Accumulate(top_module, modules);
 
         Accumulate(top_module, modules);
  
        // Prettyprint all modules in the design hiearchy under top_module
 
 
         top_module->Info("Prettyprint all modules in '%s' hierachy", top_module->Name()) ;
 
         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");
 
         char *tophierfilename = Strings::save(top_module->Name(), "_hier_pp.v");
 
         std::ofstream f(tophierfilename, std::ios::out) ;
 
         std::ofstream f(tophierfilename, std::ios::out) ;
Line 76: Line 76:
 
         f.close();
 
         f.close();
 
         Strings::free(tophierfilename);
 
         Strings::free(tophierfilename);
 +
 
     }
 
     }
  
Line 87: Line 88:
 
{
 
{
 
     if (!module) return ; // Ignore NULL netlists
 
     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:
 
     // Get the scope of the module:
Line 96: Line 102:
 
     FOREACH_MAP_ITEM(ids, mi, 0, &id) { // Traverse declared ids
 
     FOREACH_MAP_ITEM(ids, mi, 0, &id) { // Traverse declared ids
 
         if (!id || !id->IsInst()) continue ; // Consider only the instance ids
 
         if (!id || !id->IsInst()) continue ; // Consider only the instance ids
         VeriModuleInstantiation *mod_inst = id->GetModuleInstance() ; // Take the moduleinstance
+
         VeriModuleInstantiation *mod_inst = id->GetModuleInstance() ; // Take the module instance
 
         VeriModule *mod = mod_inst ? mod_inst->GetInstantiatedModule() : 0 ; // The module instance is a module
 
         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
+
         if (mod) { // This is verilog module instantiation: need to go into that module
             Message::PrintLine("Processing instance : ", id->Name(), ", module: ", mod->Name()) ;
+
             // Message::PrintLine("In module ", module->Name()) ;
            SetItem *item = done.GetItem(module) ;
+
            // Message::PrintLine("Processing instance ", id->Name(), " of module ", mod->Name()); //, " in module ", module->Name()) ;
            if (item) {
+
                return ; // We've already been here
+
            }
+
 
+
 
             Accumulate(mod, done) ; // Traverse the instantiated module
 
             Accumulate(mod, done) ; // Traverse the instantiated module
 
         }
 
         }
Line 110: Line 112:
  
 
     // Insert the traversed module
 
     // Insert the traversed module
 +
    // Message::PrintLine("Inserting module ", module->Name()) ;
 
     done.Insert(module) ;
 
     done.Insert(module) ;
 
}
 
}
Line 116: Line 119:
 
Input file test.v:
 
Input file test.v:
 
  <nowiki>
 
  <nowiki>
module top(a, b, c, d, e, f, out) ;
+
module top(a, b, c, d, e, f, out, m, n, o) ;
     input a, b, c, d, e, f ;
+
     input a, b, c, d, e, f, m, n ;
     output out ;
+
     output out, o ;
  
 
     wire tmp1, tmp2 ;
 
     wire tmp1, tmp2 ;
Line 125: Line 128:
 
     mid1 i2(a, d, e, f, tmp2) ;
 
     mid1 i2(a, d, e, f, tmp2) ;
 
     mid1 i3(tmp1, tmp2, e, f, out) ;
 
     mid1 i3(tmp1, tmp2, e, f, out) ;
 +
    bot bi(o, m, n);
  
 
endmodule
 
endmodule
  
module mid1 (mid1_inp1, mid1_inp2, mid1_inp3, mid1_inp4, mid1_out) ;
+
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 ;
 
     input mid1_inp1, mid1_inp2, mid1_inp3, mid1_inp4 ;
 
     output mid1_out ;
 
     output mid1_out ;
 
+
    input mid1b_inp1, mid1b_inp2 ;
 +
    output mid1b_out ;
 +
   
 
     wire tmp1, tmp2 ;
 
     wire tmp1, tmp2 ;
  
Line 137: Line 144:
 
     mid2 m2(mid1_inp3, mid1_inp4, tmp2) ;
 
     mid2 m2(mid1_inp3, mid1_inp4, tmp2) ;
 
     mid2 m3(tmp1, tmp2, mid1_out) ;
 
     mid2 m3(tmp1, tmp2, mid1_out) ;
 +
    bot b(mid1b_inp1, mid1b_inp2, mid1b_out) ;
  
 
endmodule
 
endmodule
Line 161: Line 169:
 
// Printing module top
 
// Printing module top
  
module top (a, b, c, d, e, f, out) ;
+
module top (a, b, c, d, e, f, out, m, n, o) ;
     input a, b, c, d, e, f ;
+
     input a, b, c, d, e, f, m, n ;  
     output out ;
+
     output out, o ;  
     wire tmp1, tmp2 ;
+
     wire tmp1, tmp2 ;  
     mid1 i1 (a, b, c, d, tmp1) ;
+
     mid1 i1 (a, b, c, d, tmp1) ;  
     mid1 i2 (a, d, e, f, tmp2) ;
+
     mid1 i2 (a, d, e, f, tmp2) ;  
     mid1 i3 (tmp1, tmp2, e, f, out) ;
+
     mid1 i3 (tmp1, tmp2, e, f, out) ;
 +
    bot bi (o, m, n) ;  
 
endmodule
 
endmodule
  
Line 173: Line 182:
 
// Printing module mid1
 
// Printing module mid1
  
module mid1 (mid1_inp1, mid1_inp2, mid1_inp3, mid1_inp4, mid1_out) ;
+
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 ;
+
     input mid1_inp1, mid1_inp2, mid1_inp3, mid1_inp4 ;  
     output mid1_out ;
+
     output mid1_out ;
     wire tmp1, tmp2 ;
+
    input mid1b_inp1, mid1b_inp2 ;
     mid2 m1 (mid1_inp1, mid1_inp2, tmp1) ;
+
    output mid1b_out ;  
     mid2 m2 (mid1_inp3, mid1_inp4, tmp2) ;
+
     wire tmp1, tmp2 ;  
     mid2 m3 (tmp1, tmp2, mid1_out) ;
+
     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
 
endmodule
  
Line 186: Line 198:
  
 
module mid2 (mid2_inp1, mid2_inp2, mid2_out) ;
 
module mid2 (mid2_inp1, mid2_inp2, mid2_out) ;
     input mid2_inp1, mid2_inp2 ;
+
     input mid2_inp1, mid2_inp2 ;  
     output mid2_out ;
+
     output mid2_out ;  
     bot b (mid2_inp1, mid2_inp2, mid2_out) ;
+
     bot b (mid2_inp1, mid2_inp2, mid2_out) ;  
 
endmodule
 
endmodule
  
Line 195: Line 207:
  
 
module bot (bot_inp1, bot_inp2, bot_out) ;
 
module bot (bot_inp1, bot_inp2, bot_out) ;
     input bot_inp1, bot_inp2 ;
+
     input bot_inp1, bot_inp2 ;  
     output bot_out ;
+
     output bot_out ;  
     assign bot_out = (bot_inp1 & bot_inp2) ;
+
     assign bot_out = (bot_inp1 & bot_inp2) ;  
 
endmodule
 
endmodule
 
  </nowiki>
 
  </nowiki>

Revision as of 13:02, 30 July 2019

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.
- 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)) {
        // 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