aboutsummaryrefslogtreecommitdiffstats
path: root/frontends
diff options
context:
space:
mode:
authorwhitequark <whitequark@whitequark.org>2021-02-23 21:46:16 +0000
committerGitHub <noreply@github.com>2021-02-23 21:46:16 +0000
commitad2960adb7ae66d524e4ac5f8f5c16cbca3730e2 (patch)
tree7da8cbbf621850924cee90e94d8ad95597f2fa5c /frontends
parent4b31223e60f8854d50c1d1bbddca528fbf37d261 (diff)
parentb6af90fe20bc92631061c48c328f3c6e4760e4df (diff)
downloadyosys-ad2960adb7ae66d524e4ac5f8f5c16cbca3730e2.tar.gz
yosys-ad2960adb7ae66d524e4ac5f8f5c16cbca3730e2.tar.bz2
yosys-ad2960adb7ae66d524e4ac5f8f5c16cbca3730e2.zip
Merge pull request #2594 from zachjs/func-arg-width
verilog: fix sizing of constant args for tasks/functions
Diffstat (limited to 'frontends')
-rw-r--r--frontends/ast/ast.h8
-rw-r--r--frontends/ast/simplify.cc32
2 files changed, 30 insertions, 10 deletions
diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h
index 8cc7b474f..df2700831 100644
--- a/frontends/ast/ast.h
+++ b/frontends/ast/ast.h
@@ -263,7 +263,13 @@ namespace AST
bool detect_latch(const std::string &var);
// additional functionality for evaluating constant functions
- struct varinfo_t { RTLIL::Const val; int offset; bool is_signed; };
+ struct varinfo_t {
+ RTLIL::Const val;
+ int offset;
+ bool is_signed;
+ AstNode *arg = nullptr;
+ bool explicitly_sized;
+ };
bool has_const_only_constructs();
bool replace_variables(std::map<std::string, varinfo_t> &variables, AstNode *fcall, bool must_succeed);
AstNode *eval_const_function(AstNode *fcall, bool must_succeed);
diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc
index 3c315f7ff..ae42d7ec6 100644
--- a/frontends/ast/simplify.cc
+++ b/frontends/ast/simplify.cc
@@ -3403,6 +3403,8 @@ skip_dynamic_range_lvalue_expansion:;
range->children.push_back(mkconst_int(0, true));
}
}
+ // updates the sizing
+ while (wire->simplify(true, false, false, 1, -1, false, false)) { }
continue;
}
AstNode *wire_id = new AstNode(AST_IDENTIFIER);
@@ -4603,17 +4605,29 @@ AstNode *AstNode::eval_const_function(AstNode *fcall, bool must_succeed)
log_file_error(stmt->filename, stmt->location.first_line, "Can't determine size of variable %s\n%s:%d.%d-%d.%d: ... called from here.\n",
stmt->str.c_str(), fcall->filename.c_str(), fcall->location.first_line, fcall->location.first_column, fcall->location.last_line, fcall->location.last_column);
}
- variables[stmt->str].val = RTLIL::Const(RTLIL::State::Sx, abs(stmt->range_left - stmt->range_right)+1);
- variables[stmt->str].offset = min(stmt->range_left, stmt->range_right);
- variables[stmt->str].is_signed = stmt->is_signed;
+ AstNode::varinfo_t &variable = variables[stmt->str];
+ int width = abs(stmt->range_left - stmt->range_right) + 1;
+ // if this variable has already been declared as an input, check the
+ // sizes match if it already had an explicit size
+ if (variable.arg && variable.explicitly_sized && variable.val.size() != width) {
+ log_file_error(filename, location.first_line, "Incompatible re-declaration of constant function wire %s.\n", stmt->str.c_str());
+ }
+ variable.val = RTLIL::Const(RTLIL::State::Sx, width);
+ variable.offset = min(stmt->range_left, stmt->range_right);
+ variable.is_signed = stmt->is_signed;
+ variable.explicitly_sized = stmt->children.size() &&
+ stmt->children.back()->type == AST_RANGE;
+ // identify the argument corresponding to this wire, if applicable
if (stmt->is_input && argidx < fcall->children.size()) {
- int width = variables[stmt->str].val.bits.size();
- auto* arg_node = fcall->children.at(argidx++);
- if (arg_node->type == AST_CONSTANT) {
- variables[stmt->str].val = arg_node->bitsAsConst(width);
+ variable.arg = fcall->children.at(argidx++);
+ }
+ // load the constant arg's value into this variable
+ if (variable.arg) {
+ if (variable.arg->type == AST_CONSTANT) {
+ variable.val = variable.arg->bitsAsConst(width);
} else {
- log_assert(arg_node->type == AST_REALVALUE);
- variables[stmt->str].val = arg_node->realAsConst(width);
+ log_assert(variable.arg->type == AST_REALVALUE);
+ variable.val = variable.arg->realAsConst(width);
}
}
current_scope[stmt->str] = stmt;