Fixes #7409.
This commit is contained in:
parent
14e2f834e9
commit
83b2061a35
|
|
@ -5148,8 +5148,10 @@ class LinkDotResolveVisitor final : public VNVisitor {
|
|||
return;
|
||||
}
|
||||
}
|
||||
if (first && nodep->name() == "randomize" && VN_IS(m_modp, Class)) {
|
||||
if (first && nodep->name() == "randomize" && VN_IS(m_modp, Class)
|
||||
&& !VN_IS(nodep->classOrPackagep(), Package)) {
|
||||
// need special handling to avoid falling back to std::randomize
|
||||
// Skip if classOrPackagep is a Package (i.e. std::randomize resolved earlier)
|
||||
VMemberMap memberMap;
|
||||
AstFunc* const randFuncp = V3Randomize::newRandomizeFunc(
|
||||
memberMap, VN_AS(m_modp, Class), nodep->name(), true, true);
|
||||
|
|
@ -5231,7 +5233,9 @@ class LinkDotResolveVisitor final : public VNVisitor {
|
|||
|| nodep->name() == "get_randstate" || nodep->name() == "set_randstate"
|
||||
|| nodep->name() == "rand_mode" || nodep->name() == "constraint_mode") {
|
||||
if (AstClass* const classp = VN_CAST(m_modp, Class)) {
|
||||
nodep->classOrPackagep(classp);
|
||||
// Don't overwrite if already resolved to a package (e.g. std::randomize)
|
||||
if (!VN_IS(nodep->classOrPackagep(), Package))
|
||||
nodep->classOrPackagep(classp);
|
||||
} else if (nodep->name() == "randomize") {
|
||||
// A std::randomize resolved in V3Width
|
||||
nodep->classOrPackagep(v3Global.rootp()->stdPackagep());
|
||||
|
|
|
|||
|
|
@ -0,0 +1,21 @@
|
|||
#!/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('simulator')
|
||||
|
||||
if not test.have_solver:
|
||||
test.skip("No constraint solver installed")
|
||||
|
||||
test.compile()
|
||||
|
||||
test.execute()
|
||||
|
||||
test.passes()
|
||||
|
|
@ -0,0 +1,102 @@
|
|||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed under the Creative Commons Public Domain.
|
||||
// SPDX-FileCopyrightText: 2026 PlanV GmbH
|
||||
// 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\n", `__FILE__,`__LINE__, (gotv), (expv)); `stop; end while(0);
|
||||
// verilog_format: on
|
||||
|
||||
// Test std::randomize() inside classes extending parameterized base classes.
|
||||
// Derived from issue #7409 (wsnyder's minimized reproduction).
|
||||
|
||||
package my_pkg;
|
||||
|
||||
class uvm_sequence_item;
|
||||
endclass
|
||||
|
||||
class uvm_sequence #(
|
||||
parameter type T = int
|
||||
);
|
||||
endclass
|
||||
|
||||
// std::randomize in class extending parameterized base (the bug)
|
||||
class foo_t extends uvm_sequence #(uvm_sequence_item);
|
||||
task test_std_rand();
|
||||
int unsigned my_var;
|
||||
int ok;
|
||||
ok = std::randomize(my_var);
|
||||
`checkd(ok, 1);
|
||||
endtask
|
||||
endclass
|
||||
|
||||
// std::randomize with 'with' clause
|
||||
class bar_t extends uvm_sequence #(uvm_sequence_item);
|
||||
task test_std_rand_with();
|
||||
int unsigned v;
|
||||
int ok;
|
||||
ok = std::randomize(v) with { v inside {[1:100]}; };
|
||||
`checkd(ok, 1);
|
||||
if (v < 1 || v > 100) begin
|
||||
$write("%%Error: constraint violated: v=%0d\n", v);
|
||||
`stop;
|
||||
end
|
||||
endtask
|
||||
endclass
|
||||
|
||||
// this.randomize() regression for parameterized-derived class
|
||||
class rand_t extends uvm_sequence #(uvm_sequence_item);
|
||||
rand int unsigned x;
|
||||
constraint c_x { x inside {[1:50]}; }
|
||||
endclass
|
||||
|
||||
endpackage
|
||||
|
||||
// std::randomize outside package, multi-level parameterized inheritance
|
||||
class base_c #(type T = int);
|
||||
T item;
|
||||
endclass
|
||||
|
||||
class mid_c extends base_c #(int);
|
||||
endclass
|
||||
|
||||
class leaf_c extends mid_c;
|
||||
task test_std_rand();
|
||||
int unsigned v;
|
||||
int ok;
|
||||
ok = std::randomize(v);
|
||||
`checkd(ok, 1);
|
||||
endtask
|
||||
endclass
|
||||
|
||||
module t;
|
||||
initial begin
|
||||
automatic my_pkg::foo_t foo = new;
|
||||
automatic my_pkg::bar_t bar = new;
|
||||
automatic my_pkg::rand_t rt = new;
|
||||
automatic leaf_c lc = new;
|
||||
int ok;
|
||||
|
||||
// Issue #7409 exact scenario: std::randomize in package class
|
||||
foo.test_std_rand();
|
||||
|
||||
// std::randomize with 'with' clause
|
||||
bar.test_std_rand_with();
|
||||
|
||||
// this.randomize() regression
|
||||
ok = rt.randomize();
|
||||
`checkd(ok, 1);
|
||||
if (rt.x < 1 || rt.x > 50) begin
|
||||
$write("%%Error: constraint violated: x=%0d\n", rt.x);
|
||||
`stop;
|
||||
end
|
||||
|
||||
// Multi-level parameterized inheritance outside package
|
||||
lc.test_std_rand();
|
||||
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
endmodule
|
||||
Loading…
Reference in New Issue