diff --git a/src/V3Randomize.cpp b/src/V3Randomize.cpp index 5b5064f5d..04e11b48a 100644 --- a/src/V3Randomize.cpp +++ b/src/V3Randomize.cpp @@ -914,7 +914,22 @@ class ConstraintExprVisitor final : public VNVisitor { if (nodep->user1()) { nodep->v3warn(CONSTRAINTIGN, "Global constraints ignored (unsupported)"); } - editFormat(nodep); + // Handle MemberSel references created by captureRefByThis() + if (VN_IS(nodep->fromp(), VarRef) + && nodep->fromp()->user1() // Depending on a randomized variable + && nodep->user2p() // Pointer to containing module + && VN_AS(nodep->user2p(), NodeModule) == nodep->varp()->user2p()) { + // Convert to VarRef + AstVarRef* const varRefp + = new AstVarRef{nodep->fileline(), nodep->varp(), VAccess::READ}; + varRefp->user1(nodep->varp()->rand().isRandomizable()); + varRefp->classOrPackagep(VN_AS(nodep->user2p(), NodeModule)); + nodep->replaceWith(varRefp); + VL_DO_DANGLING(pushDeletep(nodep), nodep); + visit(varRefp); + } else { + editFormat(nodep); + } } void visit(AstSFormatF* nodep) override {} void visit(AstStmtExpr* nodep) override {} diff --git a/test_regress/t/t_randomize_this_with.py b/test_regress/t/t_randomize_this_with.py new file mode 100755 index 000000000..c88b3d0f3 --- /dev/null +++ b/test_regress/t/t_randomize_this_with.py @@ -0,0 +1,21 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2025 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 + +import vltest_bootstrap + +if not test.have_solver: + test.skip("No constraint solver installed") + +test.scenarios('simulator') + +test.compile() + +test.execute() + +test.passes() diff --git a/test_regress/t/t_randomize_this_with.v b/test_regress/t/t_randomize_this_with.v new file mode 100644 index 000000000..cc7d3fce5 --- /dev/null +++ b/test_regress/t/t_randomize_this_with.v @@ -0,0 +1,28 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2025 by Antmicro. +// SPDX-License-Identifier: CC0-1.0 + +`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); + +class Cls; + rand int v_rand; + int v_norand; + task body; + int x; + v_norand = 42; + x = this.randomize() with {v_rand==0;}; + `checkd(v_rand, 0); + `checkd(v_norand, 42); + endtask +endclass + +module t; + initial begin + Cls c = new; + c.body(); + $finish; + end +endmodule