Allow reals as constant function parameters
authorZachary Snow <zach@zachjs.com>
Mon, 20 Jul 2020 02:27:09 +0000 (20:27 -0600)
committerZachary Snow <zach@zachjs.com>
Mon, 20 Jul 2020 02:27:09 +0000 (20:27 -0600)
frontends/ast/simplify.cc
tests/various/const_func.v

index 00f8c8df67cd336814993436369df50110aea2de..fda064237e62bb521359a28daaa07a1a7b38b301 100644 (file)
@@ -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;
index 76cdc385dfb38ec31d30879b3a85d9816885f633..541e63b1924e187bcbb32d051ae6ad13ebd342ed 100644 (file)
@@ -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