Merge pull request #418 from antmicro/rszc/fix-memory-inference

systemverilog: Fix memory inference
diff --git a/systemverilog-plugin/UhdmAst.cc b/systemverilog-plugin/UhdmAst.cc
index ee19809..3936d03 100644
--- a/systemverilog-plugin/UhdmAst.cc
+++ b/systemverilog-plugin/UhdmAst.cc
@@ -340,7 +340,7 @@
     log_assert(AST_INTERNAL::current_scope.count(wiretype_node->str));
     wiretype_ast = AST_INTERNAL::current_scope[wiretype_node->str];
     // we need to setup current top ast as this simplify
-    // needs to have access to all already definied ids
+    // needs to have access to all already defined ids
     while (wire_node->simplify(true, false, false, 1, -1, false, false)) {
     }
     if (wiretype_ast->children[0]->type == AST::AST_STRUCT && wire_node->type == AST::AST_WIRE) {
@@ -450,11 +450,27 @@
     size_t packed_size = 1;
     size_t unpacked_size = 1;
     std::vector<AST::AstNode *> ranges;
-    bool convert_node = packed_ranges.size() > 1 || unpacked_ranges.size() > 1 || wire_node->attributes.count(ID::wiretype) ||
-                        wire_node->type == AST::AST_PARAMETER || wire_node->type == AST::AST_LOCALPARAM ||
-                        ((wire_node->is_input || wire_node->is_output) && ((packed_ranges.size() > 0 || unpacked_ranges.size() > 0))) ||
-                        (wire_node->attributes.count(UhdmAst::force_convert()) && wire_node->attributes[UhdmAst::force_convert()]->integer == 1);
-    // Convert only when atleast 1 of the ranges has more then 1 range
+
+    // Convert only when node is not a memory and at least 1 of the ranges has more than 1 range
+    const bool convert_node = [&]() {
+        if (wire_node->type == AST::AST_MEMORY)
+            return false;
+        if (packed_ranges.size() > 1)
+            return true;
+        if (unpacked_ranges.size() > 1)
+            return true;
+        if (wire_node->attributes.count(ID::wiretype))
+            return true;
+        if (wire_node->type == AST::AST_PARAMETER)
+            return true;
+        if (wire_node->type == AST::AST_LOCALPARAM)
+            return true;
+        if ((wire_node->is_input || wire_node->is_output) && (packed_ranges.size() > 0 || unpacked_ranges.size() > 0))
+            return true;
+        if (wire_node->attributes.count(UhdmAst::force_convert()) && wire_node->attributes[UhdmAst::force_convert()]->integer == 1)
+            return true;
+        return false;
+    }();
     if (convert_node) {
         if (wire_node->multirange_dimensions.empty()) {
             packed_size = add_multirange_attribute(wire_node, packed_ranges);
@@ -474,6 +490,7 @@
         if (wire_node->type == AST::AST_WIRE && packed_ranges.size() == 1 && unpacked_ranges.size() == 1 && !wire_node->is_input &&
             !wire_node->is_output) {
             wire_node->type = AST::AST_MEMORY;
+            wire_node->is_logic = true;
         }
     }
 
@@ -1919,6 +1936,10 @@
             delete node;
         }
     });
+    if (auto elemtypespec_h = vpi_handle(vpiElemTypespec, obj_h)) {
+        visit_one_to_many({vpiRange}, elemtypespec_h, [&](AST::AstNode *node) { packed_ranges.push_back(node); });
+        vpi_release_handle(elemtypespec_h);
+    }
     visit_one_to_many({vpiRange}, obj_h, [&](AST::AstNode *node) { unpacked_ranges.push_back(node); });
     add_multirange_wire(current_node, packed_ranges, unpacked_ranges);
 }