Difference between revisions of "How to get full hierarchy ID path"
From Verific Design Automation FAQ
(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...") |
(No difference)
|
Latest revision as of 11:31, 23 June 2020
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}]