How to get full hierarchy ID path
From Verific Design Automation FAQ
Revision as of 11:31, 23 June 2020 by Hoa (Talk | contribs) (Created page with "Note that this code sample requires "Hierarchy Tree" feature. C++ code: <nowiki> #include "VerificSystem.h" #include "veri_file.h" #include "VeriModuleItem.h" #include "Veri...")
Note that this code sample requires "Hierarchy Tree" feature.
C++ code:
#include "VerificSystem.h" #include "veri_file.h" #include "VeriModuleItem.h" #include "VeriModule.h" #include "VeriId.h" #include "VeriExpression.h" #include "hier_tree.h" #include "HierTreeNode.h" #include "HierId.h" #include <iostream> using namespace Verific ; using namespace std ; void PrintHierIdPath(HierTreeNode *tree_node, HierId *hier_id) { if (!tree_node || !hier_id) return ; std::cerr << "HierId " << hier_id->GetVeriNameRef()->GetPrettyPrintedString() << " full path nodes: "; Array *path_ids = hier_id->GetVeriElementIds(tree_node) ; Array* path = hier_id->FullPath() ; Map actual_vs_formal(POINTER_HASH) ; HierTreeNode *node ; VeriIdDef *interface_formal = 0 ; HierTreeNode *interface_actual = 0 ; VeriIdDef *id ; unsigned i ; // Here we assumed there can be only a single interface port in a hier path // This may not be true for a corner out of LRM case but still allowed by LRM // Eg: A interface has another interface instance inside it which has an interface // port. In that case we have to collect all such ports and iterate over it in the // next loop. FOREACH_ARRAY_ITEM(path_ids, i, id) { if (id && id->IsInterfacePort()) { interface_formal = id ; break ; } } FOREACH_ARRAY_ITEM(path, i, node) { if (!node) continue ; // Node actual {formal} std::cerr << " (" << node->GetName() ; if (interface_formal) { // find respective actual for this formal InterfaceInfo *id_info = node->GetParamValue(interface_formal) ; HierTreeNode *id_actual = (id_info) ? id_info->GetScope() : 0 ; if (id_actual) interface_actual = id_actual ; } if (interface_actual == node) std::cerr << " {" << interface_formal->GetName() << "}" ; std::cerr << ") " ; // Index actual {formal} if (node->IsArrayInstance() && i+1 < path->Size() && path->At(i+1)) { // works for single index std::cerr << " [" << node->GetChildName((HierTreeNode*)path->At(++i)) ; int pos = Strings::atoi(node->GetChildName((HierTreeNode*)path->At(i))) ; if (interface_formal) { VeriIdDef *actual = node->GetVeriInstanceId() ; // Obtain dimensions of formal and actual Ids VeriRange *actual_range = (actual) ? actual->GetDimensions() : 0 ; VeriRange *formal_range = interface_formal->GetDimensions() ; if (actual_range && formal_range) { // Find corresponding index of formal wrt actual int actual_left = actual_range->EvaluateLeft(0) ; int offset = std::abs(actual_left - pos) ; int formal_left = formal_range->EvaluateLeft(0) ; int formal_right = formal_range->EvaluateRight(0) ; if (formal_left > formal_right) std::cerr << " {" << (formal_left - offset) << "}" ; else std::cerr << " {" << (formal_left + offset) << "}" ; } } std::cerr << "]"; } } std::cerr<<std::endl; } void TraverseAndCollect(HierTreeNode *node, Array *instance_nodes, Array *path_name_stack) { if (!node || !instance_nodes || !path_name_stack) return ; if (node->GetClassId() == ID_VERIINSTANCEHIERTREENODE) { instance_nodes->Insert(node) ; SetIter si ; HierId *hier_id ; FOREACH_SET_ITEM(node->GetHierIdTab(), si, &hier_id) { PrintHierIdPath(node, hier_id) ; } } MapIter mi ; char *inst_name ; HierTreeNode *child_node ; FOREACH_MAP_ITEM(node->GetChildren(), mi, &inst_name, &child_node) { if (!inst_name || !child_node) continue ; path_name_stack->InsertLast(inst_name) ; TraverseAndCollect(child_node, instance_nodes, path_name_stack) ; (void) path_name_stack->RemoveLast() ; } } int main() { if (!veri_file::Analyze("test.v", veri_file::SYSTEM_VERILOG)) return 1 ; Array *top_modules = veri_file::GetTopModules() ; if (!top_modules) return 1 ; const Map *top_ht_nodes = hier_tree::CreateHierarchicalTree(top_modules, 0, 0) ; Array *instance_nodes = new Array(POINTER_HASH) ; HierTreeNode *root ; MapIter mi ; FOREACH_MAP_ITEM(top_ht_nodes, mi, 0, &root) { if (!root) continue ; Array path_name_stack ; path_name_stack.InsertLast(root->GetName()) ; TraverseAndCollect(root, instance_nodes, &path_name_stack) ; (void) path_name_stack.RemoveLast() ; } return 0 ; }
Testcase:
interface i; bit b; endinterface module m0 (i ip [-1:0]); endmodule module m1 (i ip [ 1:0]); assert property (m0i.ip[-1].b == ip[1].b); endmodule module top; i ii [1:0] (); m0 m0i (ii); m1 m1i (ii); endmodule
Output:
-- Analyzing Verilog file 'test.v' (VERI-1482) HierId ii full path nodes: (top) (ii) HierId ii full path nodes: (top) (ii) HierId m0i.ip[(-1)].b full path nodes: (top) (m0i) (ii {ip}) [1 {-1}] HierId ip[1].b full path nodes: (top) (m1i) (ii {ip}) [1 {1}]