Merge pull request #464 from antmicro/kr/negative_range

systemverilog-plugin: set range before range_valid
diff --git a/systemverilog-plugin/UhdmAst.cc b/systemverilog-plugin/UhdmAst.cc
index 5b059ef..20959a8 100644
--- a/systemverilog-plugin/UhdmAst.cc
+++ b/systemverilog-plugin/UhdmAst.cc
@@ -496,6 +496,16 @@
     check_memories(node, "", memories);
 }
 
+static void warn_start_range(const std::vector<AST::AstNode *> ranges)
+{
+    for (size_t i = 0; i < ranges.size(); i++) {
+        auto start_elem = min(ranges[i]->children[0]->integer, ranges[i]->children[1]->integer);
+        if (start_elem != 0) {
+            log_file_warning(ranges[i]->filename, ranges[i]->location.first_line, "Limited support for multirange wires that don't start from 0\n");
+        }
+    }
+}
+
 // This function is workaround missing support for multirange (with n-ranges) packed/unpacked nodes
 // It converts multirange node to single-range node and translates access to this node
 // to correct range
@@ -516,9 +526,6 @@
         wire_node->range_valid = true;
         return;
     }
-    size_t size = 1;
-    size_t packed_size = 1;
-    size_t unpacked_size = 1;
     std::vector<AST::AstNode *> ranges;
 
     // Convert only when node is not a memory and at least 1 of the ranges has more than 1 range
@@ -542,11 +549,23 @@
         return false;
     }();
     if (convert_node) {
+        // if not already converted
         if (wire_node->multirange_dimensions.empty()) {
-            packed_size = add_multirange_attribute(wire_node, packed_ranges);
-            unpacked_size = add_multirange_attribute(wire_node, unpacked_ranges);
-            size = packed_size * unpacked_size;
-            ranges.push_back(make_range(size - 1, 0));
+            const size_t packed_size = add_multirange_attribute(wire_node, packed_ranges);
+            const size_t unpacked_size = add_multirange_attribute(wire_node, unpacked_ranges);
+            if (packed_ranges.size() == 1 && unpacked_ranges.empty()) {
+                ranges.push_back(packed_ranges[0]->clone());
+            } else if (unpacked_ranges.size() == 1 && packed_ranges.empty()) {
+                ranges.push_back(unpacked_ranges[0]->clone());
+            } else {
+                // currently we have limited support
+                // for multirange wires that doesn't start from 0
+                warn_start_range(packed_ranges);
+                warn_start_range(unpacked_ranges);
+                const size_t size = packed_size * unpacked_size;
+                log_assert(size >= 1);
+                ranges.push_back(make_range(size - 1, 0));
+            }
         }
     } else {
         for (auto r : packed_ranges) {