Visiting Hierarchical References (VeriSelectedName)

From Verific Design Automation FAQ
Jump to: navigation, search

In Verilog parsetree, hierarchical references are of type VeriSelectedName. Note that the "_suffix_id" fields are resolved only in statically-elaborated parsetree. In other words, static elaboration has to be run in this application.

C++:

#include <iostream>
#include "VeriCopy.h"       // Make class VeriMapForCopy available
#include "Map.h"            // Make class Map available
#include "Message.h"        // Make message handlers available
#include "veri_file.h"      // Make verilog reader available
#include "VeriModule.h"     // Definition of a VeriModule and VeriPrimitive
#include "VeriLibrary.h"
#include "Array.h"          // Make class Array available
#include "VeriId.h"         // Definitions of all verilog identifier nodes
#include "Strings.h"        // Definition of class to manipulate copy, concatenate, create etc...

#ifdef VERIFIC_NAMESPACE
using namespace Verific ;
#endif

class HierRefVisitor : public VeriVisitor
{
public:
    HierRefVisitor() {}
    virtual ~HierRefVisitor() {}

    virtual void VERI_VISIT(VeriSelectedName, node)
    {
        VeriIdDef *suffix_id = node.GetId() ;
        node.PrettyPrint(std::cout, 0) ;
        std::cout << std::endl ;

        if (suffix_id) {
            std::cout << "  Suffix id is " << suffix_id->GetName() << std::endl ;
        } else {
            std::cout << "  Suffix id is NOT FOUND " << std::endl ;
        }
        VeriName *prefix = node.GetPrefix() ;
        if (prefix) prefix->Accept(*this) ;
    }
} ;

int main(int argc, char **argv)
{
    if (argc < 2) Message::PrintLine("Default input file: test.sv. Specify command line argument to override") ;

    const char *file_name = 0 ;
    if (argc>1) {
        file_name = argv[1] ; // Set the file name as specified by the user
    } else {
        file_name = "test.sv" ; // Set default file name
    }

    if (!veri_file::Analyze(file_name, veri_file::SYSTEM_VERILOG)) return 1 ;

    // Return in case of failure.
    if (!veri_file::ElaborateAllStatic("work")) {
        return 1 ;
    }

    MapIter mi ;
    VeriModule *mod ;
    FOREACH_VERILOG_MODULE(mi, mod) {
        if (!mod || !mod->IsStaticElaborated()) continue ;
        std::cout << "Traversing module " << mod->GetName() << std::endl ;
        HierRefVisitor visit_obj ;
        mod->Accept(visit_obj) ;
    }

    return 0 ;
}
 

test.sv

module foo(input in, output out);
test ii1(in, out);
endmodule

module top(input in, output out, out1);
foo i1(in, out);
assign out1 = i1.ii1.in1;
endmodule

module test(input in1, output out);
assign out = in1;
endmodule
 

Run:

[hoa@awing0 200117_VisitSelectedName]$ test-linux
-- Default input file: test.sv. Specify command line argument to override
-- Analyzing Verilog file 'test.sv' (VERI-1482)
test.sv(5): INFO: compiling module 'top' (VERI-1018)
Traversing module foo
Traversing module top
i1.ii1.in1
  Suffix id is in1
i1.ii1
  Suffix id is ii1
Traversing module test
[hoa@awing0 200117_VisitSelectedName]$