Merge pull request #439 from antmicro/rszc/bump-surelog

systemverilog: Keep enums compatible with UHDM changes
diff --git a/systemverilog-plugin/UhdmAst.cc b/systemverilog-plugin/UhdmAst.cc
index 6b72d48..6c4dabf 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;
         }
     }
 
@@ -1409,7 +1426,7 @@
                 if (child->type == AST::AST_MEMORY)
                     child->type = AST::AST_WIRE;
             }
-            child->is_signed = (*it)->is_signed;
+            child->is_signed = child->is_signed || (*it)->is_signed;
             if (!(*it)->children.empty() && child->children.empty()) {
                 // This is a bit ugly, but if the child we're replacing has children and
                 // our node doesn't, we copy its children to not lose any information
@@ -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);
 }
@@ -3993,7 +4014,7 @@
                     current_node->children = std::move(node->children);
                 }
             }
-            current_node->is_signed = node->is_signed;
+            current_node->is_signed = current_node->is_signed || node->is_signed;
             delete node;
         }
     });
diff --git a/systemverilog-plugin/UhdmAstUpstream.cc b/systemverilog-plugin/UhdmAstUpstream.cc
deleted file mode 100644
index 79da255..0000000
--- a/systemverilog-plugin/UhdmAstUpstream.cc
+++ /dev/null
@@ -1,221 +0,0 @@
-#include <algorithm>
-#include <string>
-#include <vector>
-
-#include "UhdmAstUpstream.h"
-#include "frontends/ast/ast.h"
-
-YOSYS_NAMESPACE_BEGIN
-
-AST::AstNode *mkconst_real(double d)
-{
-    AST::AstNode *node = new AST::AstNode(AST::AST_REALVALUE);
-    node->realvalue = d;
-    return node;
-}
-
-namespace VERILOG_FRONTEND
-{
-
-using namespace AST;
-
-// divide an arbitrary length decimal number by two and return the rest
-static int my_decimal_div_by_two(std::vector<uint8_t> &digits)
-{
-    int carry = 0;
-    for (size_t i = 0; i < digits.size(); i++) {
-        if (digits[i] >= 10)
-            log_file_error(current_filename, get_line_num(), "Invalid use of [a-fxz?] in decimal constant.\n");
-        digits[i] += carry * 10;
-        carry = digits[i] % 2;
-        digits[i] /= 2;
-    }
-    while (!digits.empty() && !digits.front())
-        digits.erase(digits.begin());
-    return carry;
-}
-
-// find the number of significant bits in a binary number (not including the sign bit)
-static int my_ilog2(int x)
-{
-    int ret = 0;
-    while (x != 0 && x != -1) {
-        x = x >> 1;
-        ret++;
-    }
-    return ret;
-}
-
-// parse a binary, decimal, hexadecimal or octal number with support for special bits ('x', 'z' and '?')
-static void my_strtobin(std::vector<RTLIL::State> &data, const char *str, int len_in_bits, int base, char case_type, bool is_unsized)
-{
-    // all digits in string (MSB at index 0)
-    std::vector<uint8_t> digits;
-
-    while (*str) {
-        if ('0' <= *str && *str <= '9')
-            digits.push_back(*str - '0');
-        else if ('a' <= *str && *str <= 'f')
-            digits.push_back(10 + *str - 'a');
-        else if ('A' <= *str && *str <= 'F')
-            digits.push_back(10 + *str - 'A');
-        else if (*str == 'x' || *str == 'X')
-            digits.push_back(0xf0);
-        else if (*str == 'z' || *str == 'Z' || *str == '?')
-            digits.push_back(0xf1);
-        str++;
-    }
-
-    if (base == 10 && GetSize(digits) == 1 && digits.front() >= 0xf0)
-        base = 2;
-
-    data.clear();
-
-    if (base == 10) {
-        while (!digits.empty())
-            data.push_back(my_decimal_div_by_two(digits) ? State::S1 : State::S0);
-    } else {
-        int bits_per_digit = my_ilog2(base - 1);
-        for (auto it = digits.rbegin(), e = digits.rend(); it != e; it++) {
-            if (*it > (base - 1) && *it < 0xf0)
-                log_file_error(current_filename, get_line_num(), "Digit larger than %d used in in base-%d constant.\n", base - 1, base);
-            for (int i = 0; i < bits_per_digit; i++) {
-                int bitmask = 1 << i;
-                if (*it == 0xf0)
-                    data.push_back(case_type == 'x' ? RTLIL::Sa : RTLIL::Sx);
-                else if (*it == 0xf1)
-                    data.push_back(case_type == 'x' || case_type == 'z' ? RTLIL::Sa : RTLIL::Sz);
-                else
-                    data.push_back((*it & bitmask) ? State::S1 : State::S0);
-            }
-        }
-    }
-
-    int len = GetSize(data);
-    RTLIL::State msb = data.empty() ? State::S0 : data.back();
-
-    if (len_in_bits < 0) {
-        if (len < 32)
-            data.resize(32, msb == State::S0 || msb == State::S1 ? RTLIL::S0 : msb);
-        return;
-    }
-
-    if (is_unsized && (len > len_in_bits))
-        log_file_error(current_filename, get_line_num(), "Unsized constant must have width of 1 bit, but have %d bits!\n", len);
-
-    for (len = len - 1; len >= 0; len--)
-        if (data[len] == State::S1)
-            break;
-    if (msb == State::S0 || msb == State::S1) {
-        len += 1;
-        data.resize(len_in_bits, State::S0);
-    } else {
-        len += 2;
-        data.resize(len_in_bits, msb);
-    }
-
-    if (len_in_bits == 0)
-        log_file_error(current_filename, get_line_num(), "Illegal integer constant size of zero (IEEE 1800-2012, 5.7).\n");
-
-    if (len > len_in_bits)
-        log_warning("Literal has a width of %d bit, but value requires %d bit. (%s:%d)\n", len_in_bits, len, current_filename.c_str(),
-                    get_line_num());
-}
-
-// convert the Verilog code for a constant to an AST node
-AST::AstNode *const2ast(std::string code, char case_type, bool warn_z)
-{
-    if (warn_z) {
-        AST::AstNode *ret = const2ast(code, case_type, false);
-        if (ret != nullptr && std::find(ret->bits.begin(), ret->bits.end(), RTLIL::State::Sz) != ret->bits.end())
-            log_warning("Yosys has only limited support for tri-state logic at the moment. (%s:%d)\n", current_filename.c_str(), get_line_num());
-        return ret;
-    }
-
-    const char *str = code.c_str();
-
-    // Strings
-    if (*str == '"') {
-        int len = strlen(str) - 2;
-        std::vector<RTLIL::State> data;
-        data.reserve(len * 8);
-        for (int i = 0; i < len; i++) {
-            unsigned char ch = str[len - i];
-            for (int j = 0; j < 8; j++) {
-                data.push_back((ch & 1) ? State::S1 : State::S0);
-                ch = ch >> 1;
-            }
-        }
-        AST::AstNode *ast = AST::AstNode::mkconst_bits(data, false);
-        ast->str = code;
-        return ast;
-    }
-
-    for (size_t i = 0; i < code.size(); i++)
-        if (code[i] == '_' || code[i] == ' ' || code[i] == '\t' || code[i] == '\r' || code[i] == '\n')
-            code.erase(code.begin() + (i--));
-    str = code.c_str();
-
-    char *endptr;
-    long len_in_bits = strtol(str, &endptr, 10);
-
-    // Simple base-10 integer
-    if (*endptr == 0) {
-        std::vector<RTLIL::State> data;
-        my_strtobin(data, str, -1, 10, case_type, false);
-        if (data.back() == State::S1)
-            data.push_back(State::S0);
-        return AST::AstNode::mkconst_bits(data, true);
-    }
-
-    // unsized constant
-    if (str == endptr)
-        len_in_bits = -1;
-
-    // The "<bits>'[sS]?[bodhBODH]<digits>" syntax
-    if (*endptr == '\'') {
-        std::vector<RTLIL::State> data;
-        bool is_signed = false;
-        bool is_unsized = len_in_bits < 0;
-        if (*(endptr + 1) == 's' || *(endptr + 1) == 'S') {
-            is_signed = true;
-            endptr++;
-        }
-        switch (*(endptr + 1)) {
-        case 'b':
-        case 'B':
-            my_strtobin(data, endptr + 2, len_in_bits, 2, case_type, is_unsized);
-            break;
-        case 'o':
-        case 'O':
-            my_strtobin(data, endptr + 2, len_in_bits, 8, case_type, is_unsized);
-            break;
-        case 'd':
-        case 'D':
-            my_strtobin(data, endptr + 2, len_in_bits, 10, case_type, is_unsized);
-            break;
-        case 'h':
-        case 'H':
-            my_strtobin(data, endptr + 2, len_in_bits, 16, case_type, is_unsized);
-            break;
-        default:
-            char next_char = char(tolower(*(endptr + 1)));
-            if (next_char == '0' || next_char == '1' || next_char == 'x' || next_char == 'z') {
-                is_unsized = true;
-                my_strtobin(data, endptr + 1, 1, 2, case_type, is_unsized);
-            } else {
-                return NULL;
-            }
-        }
-        if (len_in_bits < 0) {
-            if (is_signed && data.back() == State::S1)
-                data.push_back(State::S0);
-        }
-        return AST::AstNode::mkconst_bits(data, is_signed, is_unsized);
-    }
-
-    return NULL;
-}
-} // namespace VERILOG_FRONTEND
-
-YOSYS_NAMESPACE_END
diff --git a/systemverilog-plugin/UhdmAstUpstream.h b/systemverilog-plugin/UhdmAstUpstream.h
deleted file mode 100644
index 5fe8f14..0000000
--- a/systemverilog-plugin/UhdmAstUpstream.h
+++ /dev/null
@@ -1,33 +0,0 @@
-#ifndef YOSYS_SYSTEMVERILOG_PLUGIN_UHDM_AST_UPSTREAM_H_
-#define YOSYS_SYSTEMVERILOG_PLUGIN_UHDM_AST_UPSTREAM_H_
-
-#include <algorithm>
-#include <string>
-#include <vector>
-
-#include "frontends/ast/ast.h"
-
-YOSYS_NAMESPACE_BEGIN
-
-namespace AST
-{
-enum AstNodeTypeExtended {
-    AST_DOT = AST::AST_BIND + 1, // here we always want to point to the last element of yosys' AstNodeType
-    AST_BREAK,
-    AST_CONTINUE
-};
-}
-
-AST::AstNode *mkconst_real(double d);
-
-namespace VERILOG_FRONTEND
-{
-
-// convert the Verilog code for a constant to an AST node
-AST::AstNode *const2ast(std::string code, char case_type, bool warn_z);
-
-} // namespace VERILOG_FRONTEND
-
-YOSYS_NAMESPACE_END
-
-#endif // YOSYS_SYSTEMVERILOG_PLUGIN_UHDM_AST_UPSTREAM_H_