Fix mis-randomizing an unpacked struct member when not rand/randc (#8277) (#8278)

This commit is contained in:
Aditya Shevade
2026-09-03 20:08:44 -04:00
committed by GitHub
parent c917f04c65
commit 228635918e
4 changed files with 62 additions and 4 deletions
+3 -1
View File
@@ -4073,7 +4073,9 @@ class RandomizeVisitor final : public VNVisitor {
if (structDtp->packed()) {
randp = newRandStmtsp(fl, stmtsp ? exprp->cloneTree(false) : exprp, nullptr,
outputVarp, offset, smemberp);
} else {
} else if (smemberp->rand().isRandomizable()) {
// IEEE 1800-2023 18.4: an unpacked struct member is only
// randomized if its own declaration carries rand/randc.
AstStructSel* structSelp
= new AstStructSel{fl, exprp->cloneTree(false), smemberp->name()};
structSelp->dtypep(smemberp->childDTypep());
+5 -3
View File
@@ -41,9 +41,9 @@ typedef struct packed {
} StructOuter;
typedef struct {
int i;
StructOuter j;
Enum k;
rand int i;
rand StructOuter j;
rand Enum k;
longint z;
} StructUnpacked;
@@ -117,6 +117,7 @@ class OtherCls;
str.i = 0;
str.j = '{x: 1'b0, y: ONE, z: 64'd0, s: '{a: 32'd0, b: 1'b0, c: ONE}};
str.k = ONE;
str.z = 0;
endfunction
endclass
@@ -189,6 +190,7 @@ module t;
if (derived1.i.e != 0) $stop;
if (derived1.k != 0) $stop;
if (other.v != 0) $stop;
if (other.str.z != 0) $stop;
if (cont.b != null) $stop;
if (der_int.b != 0) $stop;
if (der_contain.cls2.a != 0) $stop;
@@ -0,0 +1,18 @@
#!/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')
test.compile()
test.execute()
test.passes()
@@ -0,0 +1,36 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed under the Creative Commons Public Domain.
// SPDX-FileCopyrightText: 2026 Aditya Shevade
// SPDX-License-Identifier: CC0-1.0
// IEEE 1800-2023 18.4: a member of an unpacked struct is random only if
// its own declaration carries rand/randc; the containing struct being
// rand does not imply that. Here no member does, so randomize() on obj
// must leave the whole struct untouched.
typedef struct {
int a;
bit [7:0] b;
} AllUnmarked;
class C;
rand AllUnmarked s;
function new();
s.a = 42;
s.b = 8'ha5;
endfunction
endclass
module t;
initial begin
C obj;
obj = new;
repeat (10) begin
if (obj.randomize() == 0) $stop;
if (obj.s.a != 42) $stop;
if (obj.s.b != 8'ha5) $stop;
end
$write("*-* All Finished *-*\n");
$finish;
end
endmodule