diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 5a9707976..6ab369817 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -4370,35 +4370,9 @@ AstNode *AstNode::eval_const_function(AstNode *fcall) size_t argidx = 0; for (auto child : children) { - if (child->type == AST_WIRE) - { - while (child->simplify(true, false, false, 1, -1, false, true)) { } - if (!child->range_valid) - log_file_error(child->filename, child->location.first_line, "Can't determine size of variable %s\n%s:%d.%d-%d.%d: ... called from here.\n", - child->str.c_str(), fcall->filename.c_str(), fcall->location.first_line, fcall->location.first_column, fcall->location.last_line, fcall->location.last_column); - variables[child->str].val = RTLIL::Const(RTLIL::State::Sx, abs(child->range_left - child->range_right)+1); - variables[child->str].offset = min(child->range_left, child->range_right); - variables[child->str].is_signed = child->is_signed; - if (child->is_input && argidx < fcall->children.size()) { - int width = variables[child->str].val.bits.size(); - auto* arg_node = fcall->children.at(argidx++); - if (arg_node->type == AST_CONSTANT) { - variables[child->str].val = arg_node->bitsAsConst(width); - } else { - log_assert(arg_node->type == AST_REALVALUE); - variables[child->str].val = arg_node->realAsConst(width); - } - } - backup_scope[child->str] = current_scope[child->str]; - current_scope[child->str] = child; - continue; - } - block->children.push_back(child->clone()); } - log_assert(variables.count(str) != 0); - while (!block->children.empty()) { AstNode *stmt = block->children.front(); @@ -4410,6 +4384,35 @@ AstNode *AstNode::eval_const_function(AstNode *fcall) stmt->dumpAst(NULL, "stmt> "); #endif + if (stmt->type == AST_WIRE) + { + while (stmt->simplify(true, false, false, 1, -1, false, true)) { } + if (!stmt->range_valid) + 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; + 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); + } else { + log_assert(arg_node->type == AST_REALVALUE); + variables[stmt->str].val = arg_node->realAsConst(width); + } + } + if (!backup_scope.count(stmt->str)) + backup_scope[stmt->str] = current_scope[stmt->str]; + current_scope[stmt->str] = stmt; + + block->children.erase(block->children.begin()); + continue; + } + + log_assert(variables.count(str) != 0); + if (stmt->type == AST_ASSIGN_EQ) { if (stmt->children.at(0)->type == AST_IDENTIFIER && stmt->children.at(0)->children.size() != 0 && diff --git a/tests/various/const_func_block_var.v b/tests/various/const_func_block_var.v new file mode 100644 index 000000000..98e83aa5b --- /dev/null +++ b/tests/various/const_func_block_var.v @@ -0,0 +1,23 @@ +module top(out); + function integer operation; + input integer num; + begin + operation = 0; + begin : op_i + integer i; + for (i = 0; i < 2; i = i + 1) + begin : op_j + integer j; + for (j = i; j < i * 2; j = j + 1) + num = num + 1; + end + num = num * 2; + end + operation = num; + end + endfunction + + localparam res = operation(4); + output wire [31:0] out; + assign out = res; +endmodule diff --git a/tests/various/const_func_block_var.ys b/tests/various/const_func_block_var.ys new file mode 100644 index 000000000..7c2e85c64 --- /dev/null +++ b/tests/various/const_func_block_var.ys @@ -0,0 +1 @@ +read_verilog const_func_block_var.v