Support arrayed parameter functions partial (#2846)

This commit is contained in:
Wilson Snyder 2021-03-19 18:44:26 -04:00
parent a159c41219
commit 29505ef013
7 changed files with 82 additions and 13 deletions

View File

@ -2114,7 +2114,7 @@ private:
VL_DO_DANGLING(replaceNum(nodep, num), nodep);
did = true;
}
} else if (m_params && VN_IS(valuep, InitArray) && VN_IS(nodep->backp(), Pin)) {
} else if (m_params && VN_IS(valuep, InitArray)) {
// Allow parameters to pass arrays
// Earlier recursion of InitArray made sure each array value is constant
// This exception is fairly fragile, i.e. doesn't
@ -2156,7 +2156,7 @@ private:
}
}
if (!did && m_required) {
nodep->v3error("Expecting expression to be constant, but variable isn't const: "
nodep->v3error("Expecting expression to be constant, but enum value isn't const: "
<< nodep->itemp()->prettyNameQ());
}
}

View File

@ -191,8 +191,9 @@ public:
AstVar* portp = conIt->first;
AstNode* pinp = conIt->second->exprp();
AstNodeDType* dtypep = pinp->dtypep();
if (AstConst* valp = fetchConstNull(pinp))
stack << "\n " << portp->prettyName() << " = "
<< prettyNumber(&fetchConst(pinp)->num(), dtypep);
<< prettyNumber(&valp->num(), dtypep);
}
}
m_whyNotOptimizable += stack.str();

View File

@ -0,0 +1,21 @@
#!/usr/bin/env perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2021 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.
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
scenarios(simulator => 1);
compile(
);
execute(
check_finished => 1,
);
ok(1);
1;

View File

@ -0,0 +1,54 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed under the Creative Commons Public Domain, for
// any use, without warranty, 2021 by Noam Gallmann.
// SPDX-License-Identifier: CC0-1.0
`define stop $stop
`define checkh(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='h%x exp='h%x\n", `__FILE__,`__LINE__, (gotv), (expv)); `stop; end while(0)
module t(/*AUTOARG*/);
localparam int SIZES [3:0] = '{1,2,3,4};
typedef int calc_sums_t [3:0];
localparam int SUMS_ARRAY [3:0] = calc_sums_array(SIZES, 4);
function calc_sums_t calc_sums_array(int s[3:0], int n);
int sum = 0;
for (int ii = 0; ii < n; ++ii) begin
sum = sum + s[ii];
calc_sums_array[ii] = sum;
end
endfunction
`ifndef VERILATOR
localparam int SUMS_DYN [3:0] = calc_sums_dyn(SIZES, 4);
`endif
function calc_sums_t calc_sums_dyn(int s[], int n);
int sum = 0;
for (int ii = 0; ii < n; ++ii) begin
sum = sum + s[ii];
calc_sums_dyn[ii] = sum;
end
endfunction
initial begin
`checkh(SIZES[0], 4);
`checkh(SIZES[1], 3);
`checkh(SIZES[2], 2);
`checkh(SIZES[3], 1);
`checkh(SUMS_ARRAY[0], 4);
`checkh(SUMS_ARRAY[1], 7);
`checkh(SUMS_ARRAY[2], 9);
`checkh(SUMS_ARRAY[3], 10);
`ifndef VERILATOR
`checkh(SUMS_DYN[0], 1);
`checkh(SUMS_DYN[1], 3);
`checkh(SUMS_DYN[2], 6);
`checkh(SUMS_DYN[3], 10);
`endif
$write("*-* All Finished *-*\n");
$finish;
end
endmodule

View File

@ -1,7 +1,7 @@
%Error: t/t_enum_recurse_bad.v:7:9: Recursive enum value: 'u'
7 | enum {u=u} e_t;
| ^
%Error: t/t_enum_recurse_bad.v:7:9: Expecting expression to be constant, but variable isn't const: 'u'
%Error: t/t_enum_recurse_bad.v:7:9: Expecting expression to be constant, but enum value isn't const: 'u'
7 | enum {u=u} e_t;
| ^
%Error: t/t_enum_recurse_bad.v:7:9: Enum value isn't a constant

View File

@ -1,5 +0,0 @@
%Error: t/t_param_avec.v:34:43: Expecting expression to be constant, but variable isn't const: 'array'
: ... In instance t.i0
34 | localparam elementf = get_element(IDX, array);
| ^~~~~
%Error: Exiting due to

View File

@ -11,13 +11,11 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
scenarios(simulator => 1);
compile(
fails => $Self->{vlt_all}, # Verilator unsupported, bug477
expect_filename => $Self->{golden_filename},
);
execute(
check_finished => 1,
) if !$Self->{vlt_all};
);
ok(1);
1;