Fix R/W references to random builtin function seeds (#8112)

This commit is contained in:
Geza Lore 2026-08-14 18:29:12 +02:00 committed by GitHub
parent 75a776c516
commit 621a67e819
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 123 additions and 22 deletions

View File

@ -229,7 +229,7 @@ class LinkLValueVisitor final : public VNVisitor {
} }
void visit(AstRand* nodep) override { void visit(AstRand* nodep) override {
VL_RESTORER(m_setRefLvalue); VL_RESTORER(m_setRefLvalue);
if (!nodep->urandom()) m_setRefLvalue = VAccess::WRITE; if (!nodep->urandom()) m_setRefLvalue = VAccess::READWRITE;
iterateAndNextNull(nodep->seedp()); iterateAndNextNull(nodep->seedp());
} }
void visit(AstReadMem* nodep) override { void visit(AstReadMem* nodep) override {
@ -262,14 +262,14 @@ class LinkLValueVisitor final : public VNVisitor {
} }
void visit(AstNodeDistBiop* nodep) override { void visit(AstNodeDistBiop* nodep) override {
VL_RESTORER(m_setRefLvalue); VL_RESTORER(m_setRefLvalue);
m_setRefLvalue = VAccess::WRITE; m_setRefLvalue = VAccess::READWRITE;
iterateAndNextNull(nodep->lhsp()); iterateAndNextNull(nodep->lhsp());
m_setRefLvalue = VAccess::NOCHANGE; m_setRefLvalue = VAccess::NOCHANGE;
iterateAndNextNull(nodep->rhsp()); iterateAndNextNull(nodep->rhsp());
} }
void visit(AstNodeDistTriop* nodep) override { void visit(AstNodeDistTriop* nodep) override {
VL_RESTORER(m_setRefLvalue); VL_RESTORER(m_setRefLvalue);
m_setRefLvalue = VAccess::WRITE; m_setRefLvalue = VAccess::READWRITE;
iterateAndNextNull(nodep->lhsp()); iterateAndNextNull(nodep->lhsp());
m_setRefLvalue = VAccess::NOCHANGE; m_setRefLvalue = VAccess::NOCHANGE;
iterateAndNextNull(nodep->rhsp()); iterateAndNextNull(nodep->rhsp());

View File

@ -270,37 +270,37 @@
-000000 point: type=branch comment=else hier=top.t -000000 point: type=branch comment=else hier=top.t
~000010 if (($dist_erlang(result, 2, 3) != 0) && foo) bump <= bump + 1; ~000010 if (($dist_erlang(result, 2, 3) != 0) && foo) bump <= bump + 1;
-000000 point: type=expr comment=(($dist_erlang(result, 32'sh2, 32'sh3) != 32'sh0)==0) => 0 hier=top.t -000000 point: type=expr comment=(($dist_erlang(result, 32'sh2, 32'sh3) != 32'sh0)==0) => 0 hier=top.t
+000010 point: type=expr comment=(($dist_erlang(result, 32'sh2, 32'sh3) != 32'sh0)==1 && foo==1) => 1 hier=top.t -000009 point: type=expr comment=(($dist_erlang(result, 32'sh2, 32'sh3) != 32'sh0)==1 && foo==1) => 1 hier=top.t
-000000 point: type=expr comment=(foo==0) => 0 hier=top.t -000000 point: type=expr comment=(foo==0) => 0 hier=top.t
+000010 point: type=branch comment=if hier=top.t +000010 point: type=branch comment=if hier=top.t
-000000 point: type=branch comment=else hier=top.t -000000 point: type=branch comment=else hier=top.t
~000010 if (($dist_normal(result, 2, 3) != 0) && foo) bump <= bump + 1; ~000010 if (($dist_normal(result, 2, 3) != 0) && foo) bump <= bump + 1;
-000000 point: type=expr comment=(($dist_normal(result, 32'sh2, 32'sh3) != 32'sh0)==0) => 0 hier=top.t -000002 point: type=expr comment=(($dist_normal(result, 32'sh2, 32'sh3) != 32'sh0)==0) => 0 hier=top.t
+000010 point: type=expr comment=(($dist_normal(result, 32'sh2, 32'sh3) != 32'sh0)==1 && foo==1) => 1 hier=top.t -000009 point: type=expr comment=(($dist_normal(result, 32'sh2, 32'sh3) != 32'sh0)==1 && foo==1) => 1 hier=top.t
-000000 point: type=expr comment=(foo==0) => 0 hier=top.t -000000 point: type=expr comment=(foo==0) => 0 hier=top.t
+000010 point: type=branch comment=if hier=top.t +000010 point: type=branch comment=if hier=top.t
-000000 point: type=branch comment=else hier=top.t -000000 point: type=branch comment=else hier=top.t
~000010 if (($dist_t(result, 2) != 0) && foo) bump <= bump + 1; %000007 if (($dist_t(result, 2) != 0) && foo) bump <= bump + 1;
-000000 point: type=expr comment=(($dist_t(result, 32'sh2) != 32'sh0)==0) => 0 hier=top.t -000005 point: type=expr comment=(($dist_t(result, 32'sh2) != 32'sh0)==0) => 0 hier=top.t
-000000 point: type=expr comment=(($dist_t(result, 32'sh2) != 32'sh0)==1 && foo==1) => 1 hier=top.t -000007 point: type=expr comment=(($dist_t(result, 32'sh2) != 32'sh0)==1 && foo==1) => 1 hier=top.t
-000000 point: type=expr comment=(foo==0) => 0 hier=top.t -000000 point: type=expr comment=(foo==0) => 0 hier=top.t
-000000 point: type=branch comment=if hier=top.t -000007 point: type=branch comment=if hier=top.t
+000010 point: type=branch comment=else hier=top.t -000003 point: type=branch comment=else hier=top.t
~000010 if (($dist_chi_square(result, 2) != 0) && foo) bump <= bump + 1; %000009 if (($dist_chi_square(result, 2) != 0) && foo) bump <= bump + 1;
-000000 point: type=expr comment=(($dist_chi_square(result, 32'sh2) != 32'sh0)==0) => 0 hier=top.t -000000 point: type=expr comment=(($dist_chi_square(result, 32'sh2) != 32'sh0)==0) => 0 hier=top.t
+000010 point: type=expr comment=(($dist_chi_square(result, 32'sh2) != 32'sh0)==1 && foo==1) => 1 hier=top.t -000009 point: type=expr comment=(($dist_chi_square(result, 32'sh2) != 32'sh0)==1 && foo==1) => 1 hier=top.t
-000000 point: type=expr comment=(foo==0) => 0 hier=top.t -000000 point: type=expr comment=(foo==0) => 0 hier=top.t
+000010 point: type=branch comment=if hier=top.t -000006 point: type=branch comment=if hier=top.t
-000000 point: type=branch comment=else hier=top.t -000004 point: type=branch comment=else hier=top.t
~000010 if (($dist_exponential(result, 2) != 0) && foo) bump <= bump + 1; %000008 if (($dist_exponential(result, 2) != 0) && foo) bump <= bump + 1;
-000000 point: type=expr comment=(($dist_exponential(result, 32'sh2) != 32'sh0)==0) => 0 hier=top.t -000002 point: type=expr comment=(($dist_exponential(result, 32'sh2) != 32'sh0)==0) => 0 hier=top.t
-000000 point: type=expr comment=(($dist_exponential(result, 32'sh2) != 32'sh0)==1 && foo==1) => 1 hier=top.t -000006 point: type=expr comment=(($dist_exponential(result, 32'sh2) != 32'sh0)==1 && foo==1) => 1 hier=top.t
-000000 point: type=expr comment=(foo==0) => 0 hier=top.t -000000 point: type=expr comment=(foo==0) => 0 hier=top.t
+000010 point: type=branch comment=if hier=top.t -000008 point: type=branch comment=if hier=top.t
-000000 point: type=branch comment=else hier=top.t -000002 point: type=branch comment=else hier=top.t
~000010 if (($dist_poisson(result, 2) != 0) && foo) bump <= bump + 1; ~000010 if (($dist_poisson(result, 2) != 0) && foo) bump <= bump + 1;
+000010 point: type=expr comment=(($dist_poisson(result, 32'sh2) != 32'sh0)==0) => 0 hier=top.t -000002 point: type=expr comment=(($dist_poisson(result, 32'sh2) != 32'sh0)==0) => 0 hier=top.t
+000010 point: type=expr comment=(($dist_poisson(result, 32'sh2) != 32'sh0)==1 && foo==1) => 1 hier=top.t -000009 point: type=expr comment=(($dist_poisson(result, 32'sh2) != 32'sh0)==1 && foo==1) => 1 hier=top.t
-000000 point: type=expr comment=(foo==0) => 0 hier=top.t -000000 point: type=expr comment=(foo==0) => 0 hier=top.t
+000010 point: type=branch comment=if hier=top.t +000010 point: type=branch comment=if hier=top.t
-000000 point: type=branch comment=else hier=top.t -000000 point: type=branch comment=else hier=top.t

View File

@ -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('vlt')
test.compile(verilator_flags2=["--binary"])
test.execute()
test.passes()

View File

@ -0,0 +1,83 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed under the Creative Commons Public Domain.
// SPDX-FileCopyrightText: 2026 Wilson Snyder
// SPDX-License-Identifier: CC0-1.0
// verilog_format: off
`define stop $stop
`define checkd(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got=%0d exp=%0d (%s !== %s)\n", `__FILE__,`__LINE__, (gotv), (expv), `"gotv`", `"expv`"); `stop; end while(0);
// verilog_format: on
module t;
logic clk = 0;
always #5 clk = ~clk;
localparam CYCLES = 10;
int cyc = 0;
wire logic last = cyc == CYCLES - 1;
// Reports and returns zero if any two of the samples are the same
function automatic bit all_different(input int samples[CYCLES]);
for (int i = 0; i < CYCLES; ++i) begin
for (int j = i + 1; j < CYCLES; ++j) begin
if (samples[i] === samples[j]) begin
$write("%%Error: samples %0d and %0d are both %0d\n", i, j, samples[i]);
return 1'b0;
end
end
end
return 1'b1;
endfunction
// A seed must be referred to by the call only for this test to be effective
// 2 operand $dist_*
int dist_bi_seed;
int dist_bi_values[CYCLES];
// 3 operand $dist_*
int dist_tri_seed;
int dist_tri_values[CYCLES];
// $random
int random_seed;
int random_values[CYCLES];
// $urandom - seed or this is input, not inout
int urandom_seed = 32'h4567_89ab;
always @(posedge clk) begin
cyc <= cyc + 1;
// 2 operand $dist_*
dist_bi_values[cyc] = $dist_exponential(dist_bi_seed, 1000000);
if (last) begin
`checkd(all_different(dist_bi_values), 1'b1);
end
// 3 operand $dist_*
dist_tri_values[cyc] = $dist_normal(dist_tri_seed, 100, 1000000);
if (last) begin
`checkd(all_different(dist_tri_values), 1'b1);
end
// $random
random_values[cyc] = $random(random_seed);
if (last) begin
`checkd(all_different(random_values), 1'b1);
end
// $urandom - seed must not change
void'($urandom(urandom_seed));
`checkd(urandom_seed, 32'h4567_89ab);
if (last) begin
$write("*-* All Finished *-*\n");
$finish;
end
end
endmodule