Access attributes in parsetree

From Verific Design Automation FAQ
Jump to: navigation, search
#include "veri_file.h"
#include "VeriModule.h"
#include "VeriExpression.h"
#include "VeriMisc.h"
#include "VeriId.h"

#include "Map.h"
#include "Array.h"

#include "Strings.h"

#ifdef VERIFIC_NAMESPACE
using namespace Verific ;
#endif

void
PrintAttrs(const char *type, const char *name, const VeriTreeNode *node)
{
    if (!node) return ;

#if 1
    // Print all attributes:
    const Array *attr_insts = node->GetAttributeInstances() ;
    unsigned i ;
    const VeriAttributeInstance *attr_inst ;
    FOREACH_ARRAY_ITEM(attr_insts, i, attr_inst) {
        if (!attr_inst) continue ;
        char *str = attr_inst->GetPrettyPrintedString() ;
        node->Info("%s %s : Attribute : %s", ((type)?type:""), ((name)?name:""), str) ;
        Strings::free(str) ;
    }
#else
    // Print a specific attribute whose name is known:
    VeriExpression *attr_val = node->GetAttribute("attr1") ;
    if (attr_val) {
        char *str = attr_val->GetPrettyPrintedString() ;
        node->Info("%s %s : Attribute : attr = %s", ((type)?type:""), ((name)?name:""), str) ;
        Strings::free(str) ;
    }
#endif
}

int main(void)
{
    // Optional depending on flow - RuntimeFlags::SetVar("veri_do_not_touch_parse_tree", 1) ;
    // Optional depending on flow - RuntimeFlags::SetVar("veri_uniquify_all_instances", 0) ;

    if (!veri_file::Analyze("test.v")) return 1 ;
    if (!veri_file::ElaborateAllStatic()) return 2 ;

    MapIter mi ;
    VeriModule *mod ;
    FOREACH_VERILOG_MODULE(mi, mod) {
        if (!mod) continue ;
        PrintAttrs("Module", mod->Name(), mod) ;
        Array *mod_items = mod->GetModuleItems() ;
        unsigned i ;
        VeriModuleItem *item ;
        FOREACH_ARRAY_ITEM(mod_items, i, item) {
            if (!item) continue ;
            Array *ids = item->GetIds() ;
            VeriIdDef *id = (ids && ids->Size()) ? (VeriIdDef *)ids->GetFirst() : 0 ;
            PrintAttrs("Module item", ((id)?id->Name():0), item) ;
        }
    }

    return 0 ;
}
 
$ cat test.v
(*attr1="attr_1"*)module a(in1,in2);
   (*attr2="attr_2"*)input in1;
   input in2 ;
   parameter P = 0 ;
endmodule

module test ;
    a a1 (w1, w2) ;
    a #(1) a2 (w1, w2) ;
endmodule

$ test-linux
-- Analyzing Verilog file 'test.v' (VERI-1482)
test.v(7): INFO: compiling module 'test' (VERI-1018)
test.v(5): INFO: Module a : Attribute : (* attr1="attr_1" *)
test.v(2): INFO: Module item in1 : Attribute : (* attr2="attr_2" *)
test.v(5): INFO: Module a(P=1) : Attribute : (* attr1="attr_1" *)
test.v(2): INFO: Module item in1 : Attribute : (* attr2="attr_2" *)

$