From a8e06874bd1b98989b59d7cf9a9ac0d5a019a7d2 Mon Sep 17 00:00:00 2001 From: Ryszard Rozak Date: Fri, 13 Dec 2024 15:32:47 +0100 Subject: [PATCH] Fix `randomize..with` of parameterized classes (#5676) Broke in 7a04a5b --- src/V3LinkDot.cpp | 9 ++++- test_regress/t/t_randomize_param_with.py | 21 +++++++++++ test_regress/t/t_randomize_param_with.v | 48 ++++++++++++++++++++++++ 3 files changed, 76 insertions(+), 2 deletions(-) create mode 100755 test_regress/t/t_randomize_param_with.py create mode 100644 test_regress/t/t_randomize_param_with.v diff --git a/src/V3LinkDot.cpp b/src/V3LinkDot.cpp index d0cdc3903..539a83d74 100644 --- a/src/V3LinkDot.cpp +++ b/src/V3LinkDot.cpp @@ -3916,9 +3916,14 @@ class LinkDotResolveVisitor final : public VNVisitor { LINKDOT_VISIT_START(); UINFO(5, indent() << "visit " << nodep << endl); checkNoDot(nodep); + VL_RESTORER(m_curSymp); VL_RESTORER(m_inWith); - m_inWith = true; - symIterateChildren(nodep, m_statep->getNodeSym(nodep)); + { + m_ds.m_dotSymp = m_curSymp = m_statep->getNodeSym(nodep); + m_inWith = true; + iterateChildren(nodep); + } + m_ds.m_dotSymp = VL_RESTORER_PREV(m_curSymp); } void visit(AstLambdaArgRef* nodep) override { LINKDOT_VISIT_START(); diff --git a/test_regress/t/t_randomize_param_with.py b/test_regress/t/t_randomize_param_with.py new file mode 100755 index 000000000..a2b131082 --- /dev/null +++ b/test_regress/t/t_randomize_param_with.py @@ -0,0 +1,21 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2024 by Wilson Snyder. 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-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() + +test.execute() + +test.passes() diff --git a/test_regress/t/t_randomize_param_with.v b/test_regress/t/t_randomize_param_with.v new file mode 100644 index 000000000..3b7039436 --- /dev/null +++ b/test_regress/t/t_randomize_param_with.v @@ -0,0 +1,48 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2024 by Antmicro Ltd. +// SPDX-License-Identifier: CC0-1.0 + +`define check_rand(cl, field, constr, cond) \ +begin \ + longint prev_result; \ + int ok = 0; \ + if (!bit'(cl.randomize() with { constr; })) $stop; \ + prev_result = longint'(field); \ + if (!(cond)) $stop; \ + repeat(9) begin \ + longint result; \ + if (!bit'(cl.randomize() with { constr; })) $stop; \ + result = longint'(field); \ + if (!(cond)) $stop; \ + if (result != prev_result) ok = 1; \ + prev_result = result; \ + end \ + if (ok != 1) $stop; \ +end + +class Cls #(int LIMIT = 3); + rand int x; + int y = -100; + constraint x_limit { x <= LIMIT; }; +endclass + +module t; + initial begin + Cls#() cd = new; + Cls#(5) c5 = new; + + `check_rand(cd, cd.x, x > 0, cd.x > 0 && cd.x <= 3); + `check_rand(cd, cd.x, x > y, cd.x > -100 && cd.x <= 3); + if (cd.randomize() with {x > 3;} == 1) $stop; + + `check_rand(c5, c5.x, x > 0, c5.x > 0 && c5.x <= 5); + `check_rand(c5, c5.x, x > y, c5.x > -100 && c5.x <= 5); + if (c5.randomize() with {x >= 5;} == 0) $stop; + if (c5.x != 5) $stop; + + $write("*-* All Finished *-*\n"); + $finish; + end +endmodule