diff --git a/src/V3Randomize.cpp b/src/V3Randomize.cpp index bf1da3a77..75fc3ed21 100644 --- a/src/V3Randomize.cpp +++ b/src/V3Randomize.cpp @@ -291,8 +291,6 @@ class RandomizeMarkVisitor final : public VNVisitor { targetClassp->foreachMember([&](AstClass* const, AstConstraint* const existingConstrp) { if (existingConstrp->name() == newName) { // Multiple paths lead to same constraint - unsupported pattern - std::string fullPath = rootVarRefp->name(); - for (AstVar* pathVar : newPath) { fullPath += "." + pathVar->name(); } isDuplicate = true; } }); @@ -301,12 +299,14 @@ class RandomizeMarkVisitor final : public VNVisitor { AstConstraint* const cloneConstrp = constrp->cloneTree(false); cloneConstrp->name(newName); cloneConstrp->foreach([&](AstVarRef* varRefp) { - AstNodeExpr* const chainp = buildMemberSelChain(rootVarRefp, newPath); - AstMemberSel* const finalSelp - = new AstMemberSel{varRefp->fileline(), chainp, varRefp->varp()}; - finalSelp->user2p(m_classp); - varRefp->replaceWith(finalSelp); - VL_DO_DANGLING(varRefp->deleteTree(), varRefp); + if (varRefp->varp()->isClassMember()) { + AstNodeExpr* const chainp = buildMemberSelChain(rootVarRefp, newPath); + AstMemberSel* const finalSelp + = new AstMemberSel{varRefp->fileline(), chainp, varRefp->varp()}; + finalSelp->user2p(m_classp); + varRefp->replaceWith(finalSelp); + VL_DO_DANGLING(varRefp->deleteTree(), varRefp); + } }); // Add constraint directly to the target class diff --git a/test_regress/t/t_constraint_nested_class.py b/test_regress/t/t_constraint_nested_class.py new file mode 100755 index 000000000..87b346af1 --- /dev/null +++ b/test_regress/t/t_constraint_nested_class.py @@ -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: 2024 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(verilator_flags2=['-Wno-CONSTRAINTIGN']) + +test.execute() + +test.passes() diff --git a/test_regress/t/t_constraint_nested_class.v b/test_regress/t/t_constraint_nested_class.v new file mode 100644 index 000000000..9630f7711 --- /dev/null +++ b/test_regress/t/t_constraint_nested_class.v @@ -0,0 +1,31 @@ +// DESCRIPTION: Verilator: Verilog Test module for SystemVerilog +// +// This file ONLY is placed under the Creative Commons Public Domain +// SPDX-FileCopyrightText: 2026 Antmicro +// SPDX-License-Identifier: CC0-1.0 + +parameter int LEN = 32; + +class A; + rand int x; + constraint a_c { + x <= LEN; + x >= LEN; + } +endclass + +class B; + rand A a; +endclass + +module t; + B b; + initial begin + b = new; + b.a = new; + if (b.randomize() == 0) $stop; + if (b.a.x != LEN) $stop; + $write("*-* All finished *-*\n"); + $finish; + end +endmodule