From f285f7b76916420b5d55a83d53a371ebe257cfb2 Mon Sep 17 00:00:00 2001 From: Zachary Snow Date: Sun, 19 Jul 2020 20:27:09 -0600 Subject: [PATCH] Allow reals as constant function parameters --- frontends/ast/simplify.cc | 14 +++++++++++--- tests/various/const_func.v | 12 ++++++++++++ 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 00f8c8df6..fda064237 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -3029,7 +3029,7 @@ skip_dynamic_range_lvalue_expansion:; bool all_args_const = true; for (auto child : children) { while (child->simplify(true, false, false, 1, -1, false, true)) { } - if (child->type != AST_CONSTANT) + if (child->type != AST_CONSTANT && child->type != AST_REALVALUE) all_args_const = false; } @@ -4349,8 +4349,16 @@ AstNode *AstNode::eval_const_function(AstNode *fcall) 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()) - variables[child->str].val = fcall->children.at(argidx++)->bitsAsConst(variables[child->str].val.bits.size()); + 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; diff --git a/tests/various/const_func.v b/tests/various/const_func.v index 76cdc385d..541e63b19 100644 --- a/tests/various/const_func.v +++ b/tests/various/const_func.v @@ -53,6 +53,15 @@ module top(out); c1, c2, c3, c4, d1, d2, d3, d4}; + function signed [31:0] negate; + input integer inp; + negate = ~inp; + endfunction + parameter W = 10; + parameter X = 3; + localparam signed Y = $floor(W / X); + localparam signed Z = negate($floor(W / X)); + // `define VERIFY `ifdef VERIFY assert property (a1 == 0); @@ -71,5 +80,8 @@ module top(out); assert property (d2 == 0); assert property (d3 == 1); assert property (d4 == 1); + + assert property (Y == 3); + assert property (Z == ~3); `endif endmodule