Skip to content

Commit cb6c855

Browse files
committed
systemverilog-plugin: fix anonymous enum when declared in submodules
Signed-off-by: Kamil Rakoczy <[email protected]>
1 parent 4ace42c commit cb6c855

File tree

2 files changed

+16
-4
lines changed

2 files changed

+16
-4
lines changed

systemverilog-plugin/UhdmAst.cc

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ static IdString is_imported;
5858
static IdString is_simplified_wire;
5959
static IdString low_high_bound;
6060
static 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

9598
void 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);

systemverilog-plugin/UhdmAst.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,7 @@ class UhdmAst
201201
static const ::Yosys::IdString &is_imported();
202202
static const ::Yosys::IdString &is_simplified_wire();
203203
static const ::Yosys::IdString &low_high_bound();
204+
static const ::Yosys::IdString &is_elaborated_module();
204205
};
205206

206207
// Utility for building AstNode trees.

0 commit comments

Comments
 (0)