Skip to content

Commit 8edc027

Browse files
authored
Merge pull request chipsalliance#523 from antmicro/kr/fix_anonymous_enum
systemverilog-plugin: fix anonymous enum when declared in submodules
2 parents 56f957c + cb6c855 commit 8edc027

File tree

2 files changed

+26
-12
lines changed

2 files changed

+26
-12
lines changed

systemverilog-plugin/UhdmAst.cc

Lines changed: 25 additions & 12 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,9 @@ 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; }
73+
74+
#define MAKE_INTERNAL_ID(X) IdString("$systemverilog_plugin$" #X)
7175

7276
void attr_id_init()
7377
{
@@ -80,14 +84,15 @@ void attr_id_init()
8084

8185
// Register IdStrings. Can't be done statically, as the IdString class uses resources created during Yosys initialization which happens after
8286
// static initialization of the plugin when everything is statically linked.
83-
attr_id::partial = IdString("$systemverilog_plugin$partial");
84-
attr_id::packed_ranges = IdString("$systemverilog_plugin$packed_ranges");
85-
attr_id::unpacked_ranges = IdString("$systemverilog_plugin$unpacked_ranges");
86-
attr_id::force_convert = IdString("$systemverilog_plugin$force_convert");
87-
attr_id::is_imported = IdString("$systemverilog_plugin$is_imported");
88-
attr_id::is_simplified_wire = IdString("$systemverilog_plugin$is_simplified_wire");
89-
attr_id::low_high_bound = IdString("$systemverilog_plugin$low_high_bound");
90-
attr_id::is_type_parameter = IdString("$systemverilog_plugin$is_type_parameter");
87+
attr_id::partial = MAKE_INTERNAL_ID(partial);
88+
attr_id::packed_ranges = MAKE_INTERNAL_ID(packed_ranges);
89+
attr_id::unpacked_ranges = MAKE_INTERNAL_ID(unpacked_ranges);
90+
attr_id::force_convert = MAKE_INTERNAL_ID(force_convert);
91+
attr_id::is_imported = MAKE_INTERNAL_ID(is_imported);
92+
attr_id::is_simplified_wire = MAKE_INTERNAL_ID(is_simplified_wire);
93+
attr_id::low_high_bound = MAKE_INTERNAL_ID(low_high_bound);
94+
attr_id::is_type_parameter = MAKE_INTERNAL_ID(is_type_parameter);
95+
attr_id::is_elaborated_module = MAKE_INTERNAL_ID(is_elaborated_module);
9196
}
9297

9398
void attr_id_cleanup()
@@ -101,6 +106,7 @@ void attr_id_cleanup()
101106
attr_id::packed_ranges = IdString();
102107
attr_id::partial = IdString();
103108
attr_id::is_type_parameter = IdString();
109+
attr_id::is_elaborated_module = IdString();
104110
attr_id::already_initialized = false;
105111
}
106112

@@ -143,7 +149,7 @@ static void delete_internal_attributes(AST::AstNode *node)
143149
return;
144150

145151
for (auto &attr : {UhdmAst::partial(), UhdmAst::packed_ranges(), UhdmAst::unpacked_ranges(), UhdmAst::force_convert(), UhdmAst::is_imported(),
146-
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}) {
147153
delete_attribute(node, attr);
148154
}
149155
}
@@ -2185,6 +2191,8 @@ void UhdmAst::process_module()
21852191
[](auto node) { return node->type == AST::AST_INITIAL || node->type == AST::AST_ALWAYS; });
21862192
auto children_after_process = std::vector<AST::AstNode *>(process_it, current_node->children.end());
21872193
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;
21882196
visit_one_to_many({vpiModule, vpiInterface, vpiParameter, vpiParamAssign, vpiPort, vpiNet, vpiArrayNet, vpiTaskFunc, vpiGenScopeArray,
21892197
vpiContAssign, vpiVariables},
21902198
obj_h, [&](AST::AstNode *node) {
@@ -2203,6 +2211,7 @@ void UhdmAst::process_module()
22032211
current_node->children.push_back(node);
22042212
}
22052213
});
2214+
shared.current_top_node = old_top;
22062215
current_node->children.insert(current_node->children.end(), children_after_process.begin(), children_after_process.end());
22072216

22082217
delete_attribute(current_node, UhdmAst::partial());
@@ -2308,6 +2317,10 @@ void UhdmAst::process_module()
23082317
module_node = module_node->clone();
23092318
module_node->str = module_name;
23102319
}
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;
23112324
}
23122325
shared.top_nodes[module_node->str] = module_node;
23132326
visit_one_to_many({vpiParamAssign}, obj_h, [&](AST::AstNode *node) {
@@ -2350,6 +2363,7 @@ void UhdmAst::process_module()
23502363
});
23512364
make_cell(obj_h, current_node, module_node);
23522365
shared.current_top_node = old_top;
2366+
set_attribute(module_node, attr_id::is_elaborated_module, AST::AstNode::mkconst_int(1, true));
23532367
}
23542368
}
23552369

@@ -2675,9 +2689,8 @@ void UhdmAst::process_enum_typespec()
26752689
// anonymous typespec
26762690
std::string typedef_name = "$systemverilog_plugin$anonymous_enum" + std::to_string(shared.next_anonymous_enum_typedef_id());
26772691
current_node->str = typedef_name;
2678-
auto current_scope = find_ancestor({AST::AST_PACKAGE, AST::AST_MODULE, AST::AST_BLOCK, AST::AST_GENBLOCK});
2679-
uhdmast_assert(current_scope != nullptr);
2680-
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);
26812694
current_node = make_node(AST::AST_WIRETYPE);
26822695
current_node->str = typedef_name;
26832696
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)