Fix varRef scope in unique on dynamic array (#7981)

Signed-off-by: Kornel Uriasz <kuriasz@antmicro.com>
This commit is contained in:
Kornel Uriasz 2026-07-23 21:56:51 +02:00 committed by GitHub
parent e0e0fadacc
commit 7d3021c34d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 54 additions and 7 deletions

View File

@ -2397,12 +2397,14 @@ class ConstraintExprVisitor final : public VNVisitor {
return;
}
AstNodeModule* const modp = VN_AS(genVarp->user2p(), NodeModule);
UASSERT_OBJ(modp, nodep, "genVarp has no NodeModule set");
AstNodeModule* const genModp = VN_AS(genVarp->user2p(), NodeModule);
UASSERT_OBJ(genModp, nodep, "genVarp has no NodeModule set");
for (AstNode* itemp = nodep->rangesp(); itemp; itemp = itemp->nextp()) {
if (AstVarRef* const varRefp = VN_CAST(itemp, VarRef)) {
AstVar* const varp = varRefp->varp();
AstNodeModule* const varModp = VN_AS(varp->user2p(), NodeModule);
UASSERT_OBJ(varModp, nodep, "varp has no NodeModule set");
AstNodeDType* const dtypep = varp->dtypep()->skipRefp();
AstConst* dtypeWidthp = nullptr;
@ -2444,9 +2446,9 @@ class ConstraintExprVisitor final : public VNVisitor {
fl, AstCExpr::Pure{}, "\"" + varp->name() + "\"", varp->width()};
AstCMethodHard* const writeVarCallp
= new AstCMethodHard{fl, new AstVarRef{fl, modp, genVarp, VAccess::READ},
= new AstCMethodHard{fl, new AstVarRef{fl, genModp, genVarp, VAccess::READ},
VCMethod::RANDOMIZER_WRITE_VAR};
writeVarCallp->addPinsp(new AstVarRef{fl, varp, VAccess::READ});
writeVarCallp->addPinsp(new AstVarRef{fl, varModp, varp, VAccess::READ});
writeVarCallp->addPinsp(dtypeWidthp);
writeVarCallp->addPinsp(varnamep);
writeVarCallp->addPinsp(new AstConst{fl, 1}); // Dimension
@ -2473,7 +2475,7 @@ class ConstraintExprVisitor final : public VNVisitor {
? VCMethod::ASSOC_SIZE
: VCMethod::DYN_SIZE;
AstCMethodHard* const dynSizep = new AstCMethodHard{
fl, new AstVarRef{fl, modp, varp, VAccess::READ}, sizeMethod};
fl, new AstVarRef{fl, varModp, varp, VAccess::READ}, sizeMethod};
dynSizep->dtypeSetUInt32();
// unable to check dynamic array size during verilation
randUniquePinsp->addNext(dynSizep);
@ -2484,7 +2486,7 @@ class ConstraintExprVisitor final : public VNVisitor {
}
AstCMethodHard* const randUniqueCallp
= new AstCMethodHard{fl, new AstVarRef{fl, modp, genVarp, VAccess::READ},
= new AstCMethodHard{fl, new AstVarRef{fl, genModp, genVarp, VAccess::READ},
VCMethod::RANDOMIZER_UNIQUE, randUniquePinsp};
randUniqueCallp->dtypep(nodep->findVoidDType());
initTaskp->addStmtsp(new AstStmtExpr{fl, randUniqueCallp});

View File

@ -8,6 +8,46 @@
// We only check uniqueness for small # of elements on a large range
// as Z3 does not actually give unique elements (bug?) as of Jul 2026.
class Subclass;
rand int sub_arr[];
endclass
class C extends Subclass;
rand int arr[];
function new ();
arr = new[10];
sub_arr = new[10];
endfunction
function bit check_unique();
// dynamic array inside class
for (int i = 0; i < $size(arr); i++) begin
for (int j = i + 1; j < $size(arr); j++) begin
if (arr[i] == arr[j]) begin
$error("UNIQUENESS VIOLATION: arr[%0d] == arr[%0d] == 0x%h", i, j, arr[i]);
return 0;
end
end
end
// dynamic array inside base class
for (int i = 0; i < $size(sub_arr); i++) begin
for (int j = i + 1; j < $size(sub_arr); j++) begin
if (sub_arr[i] == sub_arr[j]) begin
$error("UNIQUENESS VIOLATION: arr[%0d] == arr[%0d] == 0x%h", i, j, arr[i]);
return 0;
end
end
end
return 1;
endfunction
constraint c {
unique {arr};
unique {sub_arr};
}
endclass
module t;
class UniqueMultipleArray;
rand bit [15:0] arr[4];
@ -86,9 +126,14 @@ module t;
endclass : UniqueMultipleArray
initial begin
automatic C cc = new();
automatic UniqueMultipleArray a = new();
cc.randomize();
a.randomize();
assert (a.check_unique());
assert(cc.check_unique());
assert(a.check_unique());
$write("*-* All Finished *-*\n");
$finish;