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_