Fixes #7473.
This commit is contained in:
parent
3149f43372
commit
ae642facf5
|
|
@ -2560,12 +2560,23 @@ class ConstraintExprVisitor final : public VNVisitor {
|
|||
const V3TaskConnects tconnects
|
||||
= V3Task::taskConnects(nodep, funcp->stmtsp(), nullptr, false);
|
||||
|
||||
// Clone return expression, substitute params with args
|
||||
AstNodeExpr* const inlinedp = retExprp->cloneTreePure(false);
|
||||
// Clone return expression, substitute params with args.
|
||||
// Track the root via a local pointer: when the root itself is a VarRef to a port
|
||||
// (e.g. body `F = d;`), the cloned root has no back pointer, so foreach's
|
||||
// replaceWith would trip the "no back" assertion -- substitute the root pointer
|
||||
// directly instead.
|
||||
AstNodeExpr* inlinedp = retExprp->cloneTreePure(false);
|
||||
for (const auto& tconnect : tconnects) {
|
||||
const AstVar* const portp = tconnect.first;
|
||||
AstArg* const argp = tconnect.second;
|
||||
if (!argp || !argp->exprp()) continue;
|
||||
if (AstVarRef* const rootRefp = VN_CAST(inlinedp, VarRef)) {
|
||||
if (rootRefp->varp() == portp) {
|
||||
inlinedp = argp->exprp()->cloneTreePure(false);
|
||||
VL_DO_DANGLING(rootRefp->deleteTree(), rootRefp);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
inlinedp->foreach([&](AstVarRef* refp) {
|
||||
if (refp->varp() == portp) {
|
||||
refp->replaceWith(argp->exprp()->cloneTreePure(false));
|
||||
|
|
|
|||
|
|
@ -0,0 +1,21 @@
|
|||
#!/usr/bin/env python3
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# 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-FileCopyrightText: 2026 Wilson Snyder
|
||||
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
import vltest_bootstrap
|
||||
|
||||
test.scenarios('simulator')
|
||||
|
||||
if not test.have_solver:
|
||||
test.skip("No constraint solver installed")
|
||||
|
||||
test.compile()
|
||||
|
||||
test.execute()
|
||||
|
||||
test.passes()
|
||||
|
|
@ -0,0 +1,88 @@
|
|||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed under the Creative Commons Public Domain.
|
||||
// SPDX-FileCopyrightText: 2026 PlanV GmbH
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
// verilog_format: off
|
||||
`define stop $stop
|
||||
`define checkd(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got=%0d exp=%0d\n", `__FILE__,`__LINE__, (gotv), (expv)); `stop; end while(0);
|
||||
// verilog_format: on
|
||||
|
||||
class FassignBody;
|
||||
rand int b1;
|
||||
rand int b2;
|
||||
function int F(input int d);
|
||||
F = d;
|
||||
endfunction
|
||||
constraint c1 {b1 inside {[4'd1 : 4'd9]};}
|
||||
constraint c2 {b2 == F(b1);}
|
||||
endclass
|
||||
|
||||
class Freturn;
|
||||
rand int b1;
|
||||
rand int b2;
|
||||
function int F(input int d);
|
||||
return d;
|
||||
endfunction
|
||||
constraint c1 {b1 inside {[4'd1 : 4'd9]};}
|
||||
constraint c2 {b2 == F(b1);}
|
||||
endclass
|
||||
|
||||
class Fmultiarg;
|
||||
rand int b1;
|
||||
rand int b2;
|
||||
rand int b3;
|
||||
function int F(input int x, input int y);
|
||||
F = y;
|
||||
endfunction
|
||||
constraint c1 {b1 inside {[4'd1 : 4'd9]};}
|
||||
constraint c2 {b2 inside {[8'd20 : 8'd40]};}
|
||||
constraint c3 {b3 == F(b1, b2);}
|
||||
endclass
|
||||
|
||||
class Fnonrand;
|
||||
rand int b2;
|
||||
int k;
|
||||
function int F(input int d);
|
||||
F = d;
|
||||
endfunction
|
||||
constraint c {b2 == F(k);}
|
||||
endclass
|
||||
|
||||
module t;
|
||||
FassignBody o1;
|
||||
Freturn o2;
|
||||
Fmultiarg o3;
|
||||
Fnonrand o4;
|
||||
int rand_ok;
|
||||
|
||||
initial begin
|
||||
o1 = new;
|
||||
o2 = new;
|
||||
o3 = new;
|
||||
o4 = new;
|
||||
|
||||
repeat (20) begin
|
||||
rand_ok = o1.randomize();
|
||||
`checkd(rand_ok, 1)
|
||||
`checkd(o1.b2, o1.b1)
|
||||
|
||||
rand_ok = o2.randomize();
|
||||
`checkd(rand_ok, 1)
|
||||
`checkd(o2.b2, o2.b1)
|
||||
|
||||
rand_ok = o3.randomize();
|
||||
`checkd(rand_ok, 1)
|
||||
`checkd(o3.b3, o3.b2)
|
||||
|
||||
o4.k = $urandom_range(32'd100, 32'd1);
|
||||
rand_ok = o4.randomize();
|
||||
`checkd(rand_ok, 1)
|
||||
`checkd(o4.b2, o4.k)
|
||||
end
|
||||
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
endmodule
|
||||
Loading…
Reference in New Issue