Merge pull request #509 from antmicro/kr/add_anonymous_enum_vars
systemverilog-plugin: add support for multiple variables declared in anonymous enum var
diff --git a/systemverilog-plugin/UhdmAst.cc b/systemverilog-plugin/UhdmAst.cc
index e32be89..aa511b4 100644
--- a/systemverilog-plugin/UhdmAst.cc
+++ b/systemverilog-plugin/UhdmAst.cc
@@ -2474,6 +2474,17 @@
const auto *enum_object = (const UHDM::enum_typespec *)handle->object;
const auto *typespec = enum_object->Base_typespec();
+ 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;
+ return;
+ }
+ }
+
if (typespec && typespec->UhdmType() == UHDM::uhdmlogic_typespec) {
// If it's a logic_typespec, try to reduce expressions inside of it.
// The `reduceExpr` function needs the whole context of the enum typespec
@@ -2562,6 +2573,17 @@
if (range) {
delete range;
}
+ if (current_node->str.empty()) {
+ // anonymous typespec
+ std::string typedef_name = "$systemverilog_plugin$anonymous_enum" + std::to_string(shared.next_anonymous_enum_typedef_id());
+ current_node->str = typedef_name;
+ auto current_scope = find_ancestor({AST::AST_PACKAGE, AST::AST_MODULE, AST::AST_BLOCK, AST::AST_GENBLOCK});
+ uhdmast_assert(current_scope != nullptr);
+ move_type_to_new_typedef(current_scope, current_node);
+ current_node = make_node(AST::AST_WIRETYPE);
+ current_node->str = typedef_name;
+ shared.anonymous_enums[enum_object] = std::move(typedef_name);
+ }
}
void UhdmAst::process_enum_const()
diff --git a/systemverilog-plugin/uhdmastshared.h b/systemverilog-plugin/uhdmastshared.h
index 4bbc447..a25acf3 100644
--- a/systemverilog-plugin/uhdmastshared.h
+++ b/systemverilog-plugin/uhdmastshared.h
@@ -25,6 +25,9 @@
// Used for generating unique names for anonymous types used as parameters.
unsigned anonymous_type_count = 0;
+ // Used to generate unique names for anonymous enum typedefs
+ unsigned anonymous_enum_typedef_count = 0;
+
public:
~UhdmAstShared()
{
@@ -45,6 +48,9 @@
// Generate the next anonymous type ID (starting with 0).
unsigned next_anonymous_type_id() { return anonymous_type_count++; }
+ // Generate the next anonymous enum typedef ID (starting with 0).
+ unsigned next_anonymous_enum_typedef_id() { return anonymous_enum_typedef_count++; }
+
// Flag that determines whether debug info should be printed
bool debug_flag = false;
@@ -81,8 +87,12 @@
std::unordered_map<std::string, ::Yosys::AST::AstNode *> param_types;
::Yosys::AST::AstNode *current_top_node = nullptr;
+
// Set of non-synthesizable objects to skip in current design;
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;
};
} // namespace systemverilog_plugin