Fix anonymous enums Signed-off-by: Kamil Rakoczy <krakoczy@antmicro.com>
diff --git a/systemverilog-plugin/UhdmAst.cc b/systemverilog-plugin/UhdmAst.cc index 0d9d1f4..1b6fdf0 100644 --- a/systemverilog-plugin/UhdmAst.cc +++ b/systemverilog-plugin/UhdmAst.cc
@@ -2611,11 +2611,36 @@ if (current_node->str.empty()) { // anonymous typespec, check if not already created - if (const auto enum_iter = shared.anonymous_enums.find(enum_object); enum_iter != shared.anonymous_enums.end()) { - // we already created typedef for this. - delete current_node; - current_node = make_node(AST::AST_WIRETYPE); - current_node->str = enum_iter->second; + log_assert(shared.current_top_node); + auto check_created_anonymous_enums = [enum_object, this](std::string top_module_name) -> bool { + for (auto pair : shared.anonymous_enums[top_module_name]) { + UHDM::AnySet visited; + if (pair.first->Compare(enum_object, visited) == 0) { + // we already created typedef for this. + delete current_node; + current_node = make_node(AST::AST_WIRETYPE); + current_node->str = pair.second; + return true; + } + } + return false; + }; + std::string top_module_name = shared.current_top_node->str; + if (check_created_anonymous_enums(top_module_name)) { + return; + } + // in case of parametrized module, also check unparametrized top module + // as we could add this enum there and then copy it to parametrized + // version + if (top_module_name.find("$paramod") != std::string::npos) { + // possible names: + // $paramod\module_name\PARAM=VAL + // $paramod$81af6bf473845aee480c993b90a1ed0117ae9091\module_name + top_module_name = top_module_name.substr(top_module_name.find("\\")); + if (auto params = top_module_name.find("\\", 1 /* skip first \ */) != std::string::npos) + top_module_name = top_module_name.substr(0, params); + } + if (check_created_anonymous_enums(top_module_name)) { return; } } @@ -2716,7 +2741,7 @@ move_type_to_new_typedef(shared.current_top_node, current_node); current_node = make_node(AST::AST_WIRETYPE); current_node->str = typedef_name; - shared.anonymous_enums[enum_object] = std::move(typedef_name); + shared.anonymous_enums[shared.current_top_node->str][enum_object] = std::move(typedef_name); } }
diff --git a/systemverilog-plugin/uhdmastshared.h b/systemverilog-plugin/uhdmastshared.h index a25acf3..bfa23d9 100644 --- a/systemverilog-plugin/uhdmastshared.h +++ b/systemverilog-plugin/uhdmastshared.h
@@ -92,7 +92,7 @@ std::set<const UHDM::BaseClass *> nonSynthesizableObjects; // Map of anonymous enum types to generated typedefs - std::unordered_map<const UHDM::enum_typespec *, std::string> anonymous_enums; + std::unordered_map<std::string, std::unordered_map<const UHDM::enum_typespec *, std::string>> anonymous_enums; }; } // namespace systemverilog_plugin