From 8130fed77769459afa1c14c08b2079391bd0ca5d Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Sun, 7 Dec 2025 14:14:48 -0500 Subject: [PATCH] Fix pre/post_randomize on extended classes (#6467). --- Changes | 3 ++- src/V3LinkDot.cpp | 18 +++++++++++++++- test_regress/t/t_randomize_prepost.v | 19 +++++++++++++++++ test_regress/t/t_randomize_prepost_super.py | 18 ++++++++++++++++ test_regress/t/t_randomize_prepost_super.v | 23 +++++++++++++++++++++ 5 files changed, 79 insertions(+), 2 deletions(-) create mode 100755 test_regress/t/t_randomize_prepost_super.py create mode 100644 test_regress/t/t_randomize_prepost_super.v diff --git a/Changes b/Changes index 760e361b9..fe0ce08dd 100644 --- a/Changes +++ b/Changes @@ -45,6 +45,7 @@ Verilator 5.043 devel * Optimize trace initialization code size (#6749). [Geza Lore] * Fix extern function that returns parameterized class (#4924). * Fix randomize called within func/task (#6144) (#6753). [Yilou Wang] +* Fix pre/post_randomize on extended classes (#6467). [Alex Solomatnikov] * Fix expression short circuiting (#6483). [Todd Strader] * Fix expression coverage of system calls (#6592). [Todd Strader] * Fix `--timing` with `--x-initial-edge` (#6603) (#6631). [Krzysztof Bieganski, Antmicro Ltd.] @@ -64,7 +65,7 @@ Verilator 5.043 devel * Fix splitting of Syms constructor/destructor bodies (#6662). [Geza Lore, Fractile Ltd.] * Fix long C++ compilation due to VerilatedScope constructors (#6664). [Geza Lore, Fractile Ltd.] * Fix large array initialization (#6669). [Artur Bieniek, Antmicro Ltd.] -* Fix --expand-limit not respected for expressions (#6670). [Geza Lore, Fractile Ltd.] +* Fix `--expand-limit` not respected for expressions (#6670). [Geza Lore, Fractile Ltd.] * Fix `free` name collision (#6675). [Todd Strader] * Fix bounds checking in non-inlined function (#6677). [Geza Lore, Fractile Ltd.] * Fix stream operator widening (#6693) (#6697). [Jean-Nicolas Strauss] diff --git a/src/V3LinkDot.cpp b/src/V3LinkDot.cpp index 257807fd8..71497a01f 100644 --- a/src/V3LinkDot.cpp +++ b/src/V3LinkDot.cpp @@ -4622,9 +4622,25 @@ class LinkDotResolveVisitor final : public VNVisitor { } } else if (VN_IS(nodep, New) && m_statep->forPrearray()) { // Resolved in V3Width + } else if ((nodep->name() == "pre_randomize" || nodep->name() == "post_randomize") + && VN_IS(dotSymp->nodep(), Class)) { + AstClass* const classp = VN_AS(dotSymp->nodep(), Class); + // Functions that might be defined by user, but if not, they get empty + // definitions within referenced class. + // TODO perhaps cleaner to add to symbol table up-front with + // a lambda to construct them on a reference. + AstFunc* const funcp + = new AstFunc{nodep->fileline(), nodep->name(), nullptr, nullptr}; + funcp->classMethod(true); + funcp->dtypep(funcp->findVoidDType()); + classp->addMembersp(funcp); + m_statep->insertBlock(dotSymp, nodep->name(), funcp, classp); + nodep->taskp(funcp); + nodep->classOrPackagep(classp); + UINFO(9, indent() << " Auto-made " << funcp); + return; } else if (nodep->name() == "randomize" || nodep->name() == "srandom" || nodep->name() == "get_randstate" || nodep->name() == "set_randstate" - || nodep->name() == "pre_randomize" || nodep->name() == "post_randomize" || nodep->name() == "rand_mode" || nodep->name() == "constraint_mode") { if (AstClass* const classp = VN_CAST(m_modp, Class)) { nodep->classOrPackagep(classp); diff --git a/test_regress/t/t_randomize_prepost.v b/test_regress/t/t_randomize_prepost.v index 85cee7ad5..af65d780e 100644 --- a/test_regress/t/t_randomize_prepost.v +++ b/test_regress/t/t_randomize_prepost.v @@ -45,6 +45,25 @@ class Cls extends Base; endfunction endclass +package emp_pkg; + virtual class emp_sequence #( + type REQ = int + ); + endclass + class emp_txn; + endclass + class emp_base_sequence extends emp_sequence #(emp_txn); + endclass + class emp_base_port_seq extends emp_base_sequence; + function void pre_randomize(); + super.pre_randomize(); + endfunction + function void post_randomize(); + super.post_randomize(); + endfunction + endclass +endpackage + module t; initial begin diff --git a/test_regress/t/t_randomize_prepost_super.py b/test_regress/t/t_randomize_prepost_super.py new file mode 100755 index 000000000..f989a35fb --- /dev/null +++ b/test_regress/t/t_randomize_prepost_super.py @@ -0,0 +1,18 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2025 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') + +test.compile() + +test.execute() + +test.passes() diff --git a/test_regress/t/t_randomize_prepost_super.v b/test_regress/t/t_randomize_prepost_super.v new file mode 100644 index 000000000..6327e05b7 --- /dev/null +++ b/test_regress/t/t_randomize_prepost_super.v @@ -0,0 +1,23 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2025 by Wilson Snyder. +// SPDX-License-Identifier: CC0-1.0 + +module t; + + virtual class uvm_object; + endclass + + class config_obj extends uvm_object; + function void pre_randomize(); + super.pre_randomize(); + endfunction + function void post_randomize(); + super.post_randomize(); + endfunction + endclass + + initial $finish; + +endmodule