Fix pre/post_randomize on extended classes (#6467).

This commit is contained in:
Wilson Snyder 2025-12-07 14:14:48 -05:00
parent 0e3dffa5d1
commit 8130fed777
5 changed files with 79 additions and 2 deletions

View File

@ -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]

View File

@ -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);

View File

@ -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

View File

@ -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()

View File

@ -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