Using TypeRange table to retrieve the originating type-range for an id
From Verific Design Automation FAQ
C++:
#include "veri_file.h" #include "DataBase.h" #include "Map.h" #include "Set.h" #ifdef VERIFIC_NAMESPACE using namespace Verific ; #endif int main() { RuntimeFlags::SetVar("db_preserve_user_nets", 1) ; // Need to set this flag RuntimeFlags::SetVar("db_add_id_vs_netbus_map", 1) ; if (!veri_file::Analyze("test.sv", veri_file::SYSTEM_VERILOG)) return 1 ; if (!veri_file::ElaborateAll()) return 2 ; Netlist *netlist = Netlist::PresentDesign() ; if (!netlist) return 3 ; const char *id_name = 0 ; const TypeRange *type_range = 0 ; char *tr_str = 0 ; #if 1 // To get the originating type-range for an id (e.g. 'a[0].AW') id_name = "a[0].AW" ; type_range = netlist->GetTypeRange(id_name, 1) ; tr_str = (type_range) ? type_range->Dump() : 0 ; netlist->Info("'%s' is created from type '%s'", id_name, tr_str) ; Strings::free(tr_str) ; #else // To get the originating type-ranges for all nets/buses const Map *type_ranges = netlist->GetTypeRangeTable() ; if (!type_ranges) return 4 ; const Map *id_vs_nets = netlist->GetIdNetsTable() ; if (!id_vs_nets) return 5 ; // Create a mapping of all nets/buses to Verilog id from where they are created: Map net_or_bus_2_id(POINTER_HASH) ; MapIter mi ; const Set *net_or_buses ; DesignObj *net_or_bus ; FOREACH_MAP_ITEM(id_vs_nets, mi, &id_name, &net_or_buses) { SetIter si ; FOREACH_SET_ITEM(net_or_buses, si, &net_or_bus) { (void) net_or_bus_2_id.Insert(net_or_bus, id_name) ; } } // Now get the id-name of all nets/buses from the above mapping and find them from the type-range table. Set done_buses(POINTER_HASH) ; const Net *net ; const NetBus *bus ; FOREACH_NET_OF_NETLIST(netlist, mi, net) { if (!net || !net->IsUserDeclared()) continue ; bus = net->Bus() ; if (bus && !done_buses.Insert(bus)) continue ; net_or_bus = (bus) ? (DesignObj*)bus : (DesignObj*)net ; id_name = (const char *)net_or_bus_2_id.GetValue(net_or_bus) ; if (!id_name) { net_or_bus->Error("'%s' does not have an associated id", net_or_bus->Name()) ; continue ; } type_range = (const TypeRange *)type_ranges->GetValue(id_name) ; if (!type_range) { net_or_bus->Error("'%s' created from '%s' does not have an associated type-range info", net_or_bus->Name(), id_name) ; continue ; } tr_str = type_range->Dump() ; net_or_bus->Info("'%s' is created from '%s' of type '%s'", net_or_bus->Name(), id_name, tr_str) ; Strings::free(tr_str) ; } #endif return 0 ; }
pkg.sv:
package pkg; typedef struct packed { reg [1:0] AA; reg [1:0] BB; } t1; typedef struct packed { reg [5:0] CC; reg DD; } t2; typedef struct packed { t1 AW; t2 BW; } mst; endpackage // pkg
test.sv:
`include "pkg.sv" module top ( input clk, rst, input [5:0] a_in, input [5:0] b_in ); wire pkg::mst a[3:0]; assign a[0].AW.AA = a_in[1:0]; assign a[0].AW.BB = a_in[4:2]; assign a[0].BW.CC = a_in | b_in; assign a[0].BW.DD = 1; endmodule
Run:
$ test-linux -- Analyzing Verilog file 'test.sv' (VERI-1482) test.sv(1): INFO: analyzing included file 'pkg.sv' (VERI-1328) test.sv(1): INFO: back to file 'test.sv' (VERI-2320) test.sv(2): INFO: compiling module 'top' (VERI-1018) test.sv(9): WARNING: expression size 3 truncated to fit in target size 2 (VERI-1209) test.sv(2): INFO: 'a[0].AW' is created from type ' {struct packed <t1> {AA : [1:0] reg, BB : [1:0] reg}}' $