Merge pull request #508 from antmicro/mglb/AddSynthArg

systemverilog-plugin: Enable non-synthesizable code removal in Surelog.
diff --git a/systemverilog-plugin/UhdmAst.cc b/systemverilog-plugin/UhdmAst.cc
index 94736fe..aa511b4 100644
--- a/systemverilog-plugin/UhdmAst.cc
+++ b/systemverilog-plugin/UhdmAst.cc
@@ -1470,19 +1470,7 @@
                 break;
             }
 
-            int size = -1;
-            // Surelog sometimes report size as part of vpiTypespec (e.g. int_typespec)
-            // if it is the case, we need to set size to the left_range of first packed range
-            visit_one_to_one({vpiTypespec}, obj_h, [&](AST::AstNode *node) {
-                if (node && node->attributes.count(UhdmAst::packed_ranges()) && node->attributes[UhdmAst::packed_ranges()]->children.size() &&
-                    node->attributes[UhdmAst::packed_ranges()]->children[0]->children.size()) {
-                    size = node->attributes[UhdmAst::packed_ranges()]->children[0]->children[0]->integer + 1;
-                }
-                delete node;
-            });
-            if (size == -1) {
-                size = vpi_get(vpiSize, obj_h);
-            }
+            auto size = vpi_get(vpiSize, obj_h);
             // Surelog by default returns 64 bit numbers and stardard says that they shall be at least 32bits
             // yosys is assuming that int/uint is 32 bit, so we are setting here correct size
             // NOTE: it *shouldn't* break on explicite 64 bit const values, as they *should* be handled
@@ -2486,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
@@ -2574,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