Fix non-member identifiers used inside constraints (#7033)

This commit is contained in:
Pawel Kojma 2026-02-11 14:18:24 +01:00 committed by GitHub
parent 22dc437dbb
commit 5d12ae3a2f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 60 additions and 8 deletions

View File

@ -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

View File

@ -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()

View File

@ -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