diff --git a/Changes b/Changes index e19b51400..a78488cc1 100644 --- a/Changes +++ b/Changes @@ -14,6 +14,8 @@ The contributors that suggested a given feature are shown in []. Thanks! **** Fix GCC noreturn compile error, bug1209. [Mike Popoloski] +**** Fix constant function default parameters, bug1211. [Mike Popoloski] + * Verilator 3.910 2017-09-07 diff --git a/src/V3Task.cpp b/src/V3Task.cpp index 601ea1c99..1bf89e406 100644 --- a/src/V3Task.cpp +++ b/src/V3Task.cpp @@ -35,6 +35,7 @@ #include #include "V3Global.h" +#include "V3Const.h" #include "V3Task.h" #include "V3Inst.h" #include "V3Ast.h" @@ -1260,11 +1261,20 @@ V3TaskConnects V3Task::taskConnects(AstNodeFTaskRef* nodep, AstNode* taskStmtsp) <<"' in function call to "<taskp()->prettyTypeName()); newvaluep = new AstConst(nodep->fileline(), AstConst::Unsized32(), 0); } else if (!portp->valuep()->castConst()) { - // Problem otherwise is we might have a varref, task call, or something else that only - // makes sense in the domain of the function, not the callee. - nodep->v3error("Unsupported: Non-constant default value in missing argument '"<prettyName() - <<"' in function call to "<taskp()->prettyTypeName()); - newvaluep = new AstConst(nodep->fileline(), AstConst::Unsized32(), 0); + // The default value for this port might be a constant + // expression that hasn't been folded yet. Try folding it + // now; we don't have much to lose if it fails. + newvaluep = V3Const::constifyParamsEdit(portp->valuep()); + if (!newvaluep->castConst()) { + // Problem otherwise is we might have a varref, task call, or something else that only + // makes sense in the domain of the function, not the callee. + nodep->v3error("Unsupported: Non-constant default value in missing argument '"<prettyName() + <<"' in function call to "<taskp()->prettyTypeName()); + newvaluep = new AstConst(nodep->fileline(), AstConst::Unsized32(), 0); + } + else { + newvaluep = newvaluep->cloneTree(true); + } } else { newvaluep = portp->valuep()->cloneTree(true); } diff --git a/test_regress/t/t_array_type_methods.pl b/test_regress/t/t_array_type_methods.pl old mode 100644 new mode 100755 diff --git a/test_regress/t/t_func_defaults.pl b/test_regress/t/t_func_defaults.pl new file mode 100755 index 000000000..f91289753 --- /dev/null +++ b/test_regress/t/t_func_defaults.pl @@ -0,0 +1,18 @@ +#!/usr/bin/perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2003 by Wilson Snyder. This program is free software; you can +# redistribute it and/or modify it under the terms of either the GNU +# Lesser General Public License Version 3 or the Perl Artistic License +# Version 2.0. + +compile ( + ); + +execute ( + check_finished=>1, + ); + +ok(1); +1; diff --git a/test_regress/t/t_func_defaults.v b/test_regress/t/t_func_defaults.v new file mode 100644 index 000000000..daccafc92 --- /dev/null +++ b/test_regress/t/t_func_defaults.v @@ -0,0 +1,33 @@ +// DESCRIPTION: Verilator: Test for warning (not error) on improperly width'ed +// default function argument +// +// This file ONLY is placed into the Public Domain, for any use, +// without warranty, 2015 by Todd Strader. + +parameter logic Bar = 1'b1; + +function automatic logic calc_y; + return 1'b1; +endfunction + +function automatic logic [1:0] foo + ( + input logic x = Bar, + input logic y = calc_y() + ); + return x + y; +endfunction + +module t (/*AUTOARG*/); + logic [1:0] foo_val; + + initial begin + foo_val = foo(); + if (foo_val != 2'b10) $stop; + + $write("*-* All Finished *-*\n"); + $finish; + end + +endmodule +