Type Range example with multi-dimensional arrays
From Verific Design Automation FAQ
Revision as of 18:25, 22 January 2020 by Hoa (Talk | contribs) (Created page with "For a design with multidimensional arrays, the application needs to create a data structure for mapping NetBus to TypeRange. C++: <nowiki> #include <iostream> #include "veri...")
For a design with multidimensional arrays, the application needs to create a data structure for mapping NetBus to TypeRange.
C++:
#include <iostream> #include "veri_file.h" #include "DataBase.h" #include "Map.h" #ifdef VERIFIC_NAMESPACE using namespace Verific ; #endif void CreateTypeRangeMapping(const Netlist *nl, Map &net_bus_vs_tr) { if (!nl) return ; // Get the Verilog id name vs Set of Net or NetBus created. // Runtime flag 'db_add_id_vs_netbus_map' needs to be set while elaborating the design: const Map *id_vs_nets = nl->GetIdNetsTable() ; const Map *id_vs_tr = nl->GetTypeRangeTable() ; // Get the Verilog id name vs its TypeRange if (!id_vs_tr) return ; MapIter mi ; const char *id_name ; const Set *net_or_netbus ; const TypeRange *tr ; FOREACH_MAP_ITEM(id_vs_nets, mi, &id_name, &net_or_netbus) { tr = (TypeRange *)id_vs_tr->GetValue(id_name) ; if (!tr) continue ; SetIter si ; DesignObj *obj ; FOREACH_SET_ITEM(net_or_netbus, si, &obj) { // Only insert for NetBusses, we do not need Nets: if (obj->IsNetBus()) (void) net_bus_vs_tr.Insert(obj, tr) ; } } } int main(int argc, const char **argv) { RuntimeFlags::SetVar("db_preserve_user_nets", 1) ; RuntimeFlags::SetVar("db_add_id_vs_netbus_map", 1) ; if (!veri_file::Read("test.v", "work", veri_file::SYSTEM_VERILOG)) return 1 ; Netlist *netlist = Netlist::PresentDesign() ; Map net_bus_vs_tr(POINTER_HASH) ; CreateTypeRangeMapping(netlist, net_bus_vs_tr) ; MapIter mi ; Net *net ; const TypeRange *tr ; FOREACH_NET_OF_NETLIST(netlist, mi, net) { if (!net || (net->IsUserDeclared() == 0)) { continue; } if (net->Bus()) { const char *name = net->Bus()->Name(); tr = (const TypeRange *)net_bus_vs_tr.GetValue(net->Bus()) ; if (!tr) continue ; // Something wrong happened // Find if it has unpacked and/or packed dimensions: if it is unpacked, it must be the last dimension: unsigned has_unpacked_dim = (tr->IsTypeArray() && tr->IsPackedDimensionRange()) ? 0 : 1 ; // Packed dimensions may be there after the unpacked dimensions, find if there: unsigned has_packed_dim = (tr->IsTypeArray() && tr->IsPackedDimensionRange()) ? 1 : 0 ; // Don't forget the last one const TypeRange *tr_run = tr ; while ((tr_run = tr_run->GetNext()) != 0) { if (tr_run->IsTypeArray() && tr_run->IsPackedDimensionRange()) { has_packed_dim = 1 ; // Found a packed dimension break ; } } if (has_packed_dim && !has_unpacked_dim) { net->Info("Net: %s (%s) : data1", name, net->Name()) ; } else if (!has_packed_dim && has_unpacked_dim) { net->Info("Net: %s (%s) : data2 or data4", name, net->Name()) ; } else if (has_packed_dim && has_unpacked_dim) { net->Info("Net: %s (%s) : data3", name, net->Name()) ; } } } return 0 ; }
test.v:
module test(); reg data0; reg [2:0] data1; reg data2 [2:0]; reg [2:0] data3 [2:0]; reg data4 [2:0][0:2]; endmodule
Run:
$ test-linux -- Analyzing Verilog file 'test.v' (VERI-1482) test.v(1): INFO: compiling module 'test' (VERI-1018) test.v(3): INFO: Net: data1 (data1[2]) : data1 test.v(3): INFO: Net: data1 (data1[1]) : data1 test.v(3): INFO: Net: data1 (data1[0]) : data1 test.v(4): INFO: Net: data2 (data2[2]) : data2 or data4 test.v(4): INFO: Net: data2 (data2[1]) : data2 or data4 test.v(4): INFO: Net: data2 (data2[0]) : data2 or data4 test.v(5): INFO: Net: data3[2] (data3[2][2]) : data3 test.v(5): INFO: Net: data3[2] (data3[2][1]) : data3 test.v(5): INFO: Net: data3[2] (data3[2][0]) : data3 test.v(5): INFO: Net: data3[1] (data3[1][2]) : data3 test.v(5): INFO: Net: data3[1] (data3[1][1]) : data3 test.v(5): INFO: Net: data3[1] (data3[1][0]) : data3 test.v(5): INFO: Net: data3[0] (data3[0][2]) : data3 test.v(5): INFO: Net: data3[0] (data3[0][1]) : data3 test.v(5): INFO: Net: data3[0] (data3[0][0]) : data3 test.v(6): INFO: Net: data4[2] (data4[2][0]) : data2 or data4 test.v(6): INFO: Net: data4[2] (data4[2][1]) : data2 or data4 test.v(6): INFO: Net: data4[2] (data4[2][2]) : data2 or data4 test.v(6): INFO: Net: data4[1] (data4[1][0]) : data2 or data4 test.v(6): INFO: Net: data4[1] (data4[1][1]) : data2 or data4 test.v(6): INFO: Net: data4[1] (data4[1][2]) : data2 or data4 test.v(6): INFO: Net: data4[0] (data4[0][0]) : data2 or data4 test.v(6): INFO: Net: data4[0] (data4[0][1]) : data2 or data4 test.v(6): INFO: Net: data4[0] (data4[0][2]) : data2 or data4 $