@@ -58,6 +58,7 @@ static IdString is_imported;
5858static IdString is_simplified_wire;
5959static IdString low_high_bound;
6060static IdString is_type_parameter;
61+ static IdString is_elaborated_module;
6162}; // namespace attr_id
6263
6364// TODO(mglb): use attr_id::* directly everywhere and remove those methods.
@@ -68,6 +69,7 @@ static IdString is_type_parameter;
6869/* static*/ const IdString &UhdmAst::is_imported () { return attr_id::is_imported; }
6970/* static*/ const IdString &UhdmAst::is_simplified_wire () { return attr_id::is_simplified_wire; }
7071/* static*/ const IdString &UhdmAst::low_high_bound () { return attr_id::low_high_bound; }
72+ /* static*/ const IdString &UhdmAst::is_elaborated_module () { return attr_id::is_elaborated_module; }
7173
7274#define MAKE_INTERNAL_ID (X ) IdString(" $systemverilog_plugin$" #X)
7375
@@ -90,6 +92,7 @@ void attr_id_init()
9092 attr_id::is_simplified_wire = MAKE_INTERNAL_ID (is_simplified_wire);
9193 attr_id::low_high_bound = MAKE_INTERNAL_ID (low_high_bound);
9294 attr_id::is_type_parameter = MAKE_INTERNAL_ID (is_type_parameter);
95+ attr_id::is_elaborated_module = MAKE_INTERNAL_ID (is_elaborated_module);
9396}
9497
9598void attr_id_cleanup ()
@@ -103,6 +106,7 @@ void attr_id_cleanup()
103106 attr_id::packed_ranges = IdString ();
104107 attr_id::partial = IdString ();
105108 attr_id::is_type_parameter = IdString ();
109+ attr_id::is_elaborated_module = IdString ();
106110 attr_id::already_initialized = false ;
107111}
108112
@@ -145,7 +149,7 @@ static void delete_internal_attributes(AST::AstNode *node)
145149 return ;
146150
147151 for (auto &attr : {UhdmAst::partial (), UhdmAst::packed_ranges (), UhdmAst::unpacked_ranges (), UhdmAst::force_convert (), UhdmAst::is_imported (),
148- UhdmAst::is_simplified_wire (), UhdmAst::low_high_bound (), attr_id::is_type_parameter}) {
152+ UhdmAst::is_simplified_wire (), UhdmAst::low_high_bound (), attr_id::is_type_parameter, attr_id::is_elaborated_module }) {
149153 delete_attribute (node, attr);
150154 }
151155}
@@ -2187,6 +2191,8 @@ void UhdmAst::process_module()
21872191 [](auto node) { return node->type == AST::AST_INITIAL || node->type == AST::AST_ALWAYS; });
21882192 auto children_after_process = std::vector<AST::AstNode *>(process_it, current_node->children .end ());
21892193 current_node->children .erase (process_it, current_node->children .end ());
2194+ auto old_top = shared.current_top_node ;
2195+ shared.current_top_node = current_node;
21902196 visit_one_to_many ({vpiModule, vpiInterface, vpiParameter, vpiParamAssign, vpiPort, vpiNet, vpiArrayNet, vpiTaskFunc, vpiGenScopeArray,
21912197 vpiContAssign, vpiVariables},
21922198 obj_h, [&](AST::AstNode *node) {
@@ -2205,6 +2211,7 @@ void UhdmAst::process_module()
22052211 current_node->children .push_back (node);
22062212 }
22072213 });
2214+ shared.current_top_node = old_top;
22082215 current_node->children .insert (current_node->children .end (), children_after_process.begin (), children_after_process.end ());
22092216
22102217 delete_attribute (current_node, UhdmAst::partial ());
@@ -2310,6 +2317,10 @@ void UhdmAst::process_module()
23102317 module_node = module_node->clone ();
23112318 module_node->str = module_name;
23122319 }
2320+ } else if (auto attribute = get_attribute (module_node, attr_id::is_elaborated_module); attribute && attribute->integer == 1 ) {
2321+ // we already processed module with this parameters, just create cell node
2322+ make_cell (obj_h, current_node, module_node);
2323+ return ;
23132324 }
23142325 shared.top_nodes [module_node->str ] = module_node;
23152326 visit_one_to_many ({vpiParamAssign}, obj_h, [&](AST::AstNode *node) {
@@ -2352,6 +2363,7 @@ void UhdmAst::process_module()
23522363 });
23532364 make_cell (obj_h, current_node, module_node);
23542365 shared.current_top_node = old_top;
2366+ set_attribute (module_node, attr_id::is_elaborated_module, AST::AstNode::mkconst_int (1 , true ));
23552367 }
23562368}
23572369
@@ -2677,9 +2689,8 @@ void UhdmAst::process_enum_typespec()
26772689 // anonymous typespec
26782690 std::string typedef_name = " $systemverilog_plugin$anonymous_enum" + std::to_string (shared.next_anonymous_enum_typedef_id ());
26792691 current_node->str = typedef_name;
2680- auto current_scope = find_ancestor ({AST::AST_PACKAGE, AST::AST_MODULE, AST::AST_BLOCK, AST::AST_GENBLOCK});
2681- uhdmast_assert (current_scope != nullptr );
2682- move_type_to_new_typedef (current_scope, current_node);
2692+ uhdmast_assert (shared.current_top_node != nullptr );
2693+ move_type_to_new_typedef (shared.current_top_node , current_node);
26832694 current_node = make_node (AST::AST_WIRETYPE);
26842695 current_node->str = typedef_name;
26852696 shared.anonymous_enums [enum_object] = std::move (typedef_name);
0 commit comments