mirror of
https://github.com/YosysHQ/yosys
synced 2025-04-25 18:15:34 +00:00
verilog: fix sizing of constant args for tasks/functions
- Simplify synthetic localparams for normal calls to update their width - This step was inadvertently removed alongside `added_mod_children` - Support redeclaration of constant function arguments - `eval_const_function` never correctly handled this, but the issue was not exposed in the existing tests until the recent change to always attempt constant function evaluation when all-const args are used - Check asserts in const_arg_loop and const_func tests - Add coverage for width mismatch error cases
This commit is contained in:
parent
127484e675
commit
b6af90fe20
10 changed files with 124 additions and 47 deletions
|
@ -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);
|
||||
|
|
|
@ -3376,6 +3376,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);
|
||||
|
@ -4591,17 +4593,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;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue