diff --git a/src/V3LinkLValue.cpp b/src/V3LinkLValue.cpp index 825665e52..0592a8dc8 100644 --- a/src/V3LinkLValue.cpp +++ b/src/V3LinkLValue.cpp @@ -229,7 +229,7 @@ class LinkLValueVisitor final : public VNVisitor { } void visit(AstRand* nodep) override { VL_RESTORER(m_setRefLvalue); - if (!nodep->urandom()) m_setRefLvalue = VAccess::WRITE; + if (!nodep->urandom()) m_setRefLvalue = VAccess::READWRITE; iterateAndNextNull(nodep->seedp()); } void visit(AstReadMem* nodep) override { @@ -262,14 +262,14 @@ class LinkLValueVisitor final : public VNVisitor { } void visit(AstNodeDistBiop* nodep) override { VL_RESTORER(m_setRefLvalue); - m_setRefLvalue = VAccess::WRITE; + m_setRefLvalue = VAccess::READWRITE; iterateAndNextNull(nodep->lhsp()); m_setRefLvalue = VAccess::NOCHANGE; iterateAndNextNull(nodep->rhsp()); } void visit(AstNodeDistTriop* nodep) override { VL_RESTORER(m_setRefLvalue); - m_setRefLvalue = VAccess::WRITE; + m_setRefLvalue = VAccess::READWRITE; iterateAndNextNull(nodep->lhsp()); m_setRefLvalue = VAccess::NOCHANGE; iterateAndNextNull(nodep->rhsp()); diff --git a/test_regress/t/t_cover_sys_line_expr.out b/test_regress/t/t_cover_sys_line_expr.out index b6548b542..f4f44dbdf 100644 --- a/test_regress/t/t_cover_sys_line_expr.out +++ b/test_regress/t/t_cover_sys_line_expr.out @@ -270,37 +270,37 @@ -000000 point: type=branch comment=else hier=top.t ~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 -+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 +000010 point: type=branch comment=if hier=top.t -000000 point: type=branch comment=else hier=top.t ~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 -+000010 point: type=expr comment=(($dist_normal(result, 32'sh2, 32'sh3) != 32'sh0)==1 && foo==1) => 1 hier=top.t +-000002 point: type=expr comment=(($dist_normal(result, 32'sh2, 32'sh3) != 32'sh0)==0) => 0 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 +000010 point: type=branch comment=if hier=top.t -000000 point: type=branch comment=else hier=top.t -~000010 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 --000000 point: type=expr comment=(($dist_t(result, 32'sh2) != 32'sh0)==1 && foo==1) => 1 hier=top.t +%000007 if (($dist_t(result, 2) != 0) && foo) bump <= bump + 1; +-000005 point: type=expr comment=(($dist_t(result, 32'sh2) != 32'sh0)==0) => 0 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=branch comment=if hier=top.t -+000010 point: type=branch comment=else hier=top.t -~000010 if (($dist_chi_square(result, 2) != 0) && foo) bump <= bump + 1; +-000007 point: type=branch comment=if hier=top.t +-000003 point: type=branch comment=else hier=top.t +%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 -+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 -+000010 point: type=branch comment=if hier=top.t --000000 point: type=branch comment=else hier=top.t -~000010 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 --000000 point: type=expr comment=(($dist_exponential(result, 32'sh2) != 32'sh0)==1 && foo==1) => 1 hier=top.t +-000006 point: type=branch comment=if hier=top.t +-000004 point: type=branch comment=else hier=top.t +%000008 if (($dist_exponential(result, 2) != 0) && foo) bump <= bump + 1; +-000002 point: type=expr comment=(($dist_exponential(result, 32'sh2) != 32'sh0)==0) => 0 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 -+000010 point: type=branch comment=if hier=top.t --000000 point: type=branch comment=else hier=top.t +-000008 point: type=branch comment=if hier=top.t +-000002 point: type=branch comment=else hier=top.t ~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 -+000010 point: type=expr comment=(($dist_poisson(result, 32'sh2) != 32'sh0)==1 && foo==1) => 1 hier=top.t +-000002 point: type=expr comment=(($dist_poisson(result, 32'sh2) != 32'sh0)==0) => 0 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 +000010 point: type=branch comment=if hier=top.t -000000 point: type=branch comment=else hier=top.t diff --git a/test_regress/t/t_rand_dist_seed.py b/test_regress/t/t_rand_dist_seed.py new file mode 100755 index 000000000..c87a1e49f --- /dev/null +++ b/test_regress/t/t_rand_dist_seed.py @@ -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() diff --git a/test_regress/t/t_rand_dist_seed.v b/test_regress/t/t_rand_dist_seed.v new file mode 100644 index 000000000..94c63bf26 --- /dev/null +++ b/test_regress/t/t_rand_dist_seed.v @@ -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