Fix `randc` on extended class (#6852).
This commit is contained in:
parent
1d7f5ed33e
commit
f6b966ed16
1
Changes
1
Changes
|
|
@ -120,6 +120,7 @@ Verilator 5.043 devel
|
||||||
* Fix randcase under fork (#6843). [Amal Araweelo Almis]
|
* Fix randcase under fork (#6843). [Amal Araweelo Almis]
|
||||||
* Fix JSON missing `signed` indication (#6845).
|
* Fix JSON missing `signed` indication (#6845).
|
||||||
* Fix class reference throwing cannot detect changes error (#6851).
|
* Fix class reference throwing cannot detect changes error (#6851).
|
||||||
|
* Fix `randc` on extended class (#6852).
|
||||||
|
|
||||||
|
|
||||||
Verilator 5.042 2025-11-02
|
Verilator 5.042 2025-11-02
|
||||||
|
|
|
||||||
|
|
@ -126,7 +126,7 @@ bool V3LinkDotIfaceCapture::replaceTypedef(const AstRefDType* refp, AstTypedef*
|
||||||
|
|
||||||
void V3LinkDotIfaceCapture::propagateClone(const AstRefDType* origRefp, AstRefDType* newRefp) {
|
void V3LinkDotIfaceCapture::propagateClone(const AstRefDType* origRefp, AstRefDType* newRefp) {
|
||||||
if (!origRefp || !newRefp) return;
|
if (!origRefp || !newRefp) return;
|
||||||
auto it = s_map.find(origRefp);
|
const auto it = s_map.find(origRefp);
|
||||||
UASSERT_OBJ(it != s_map.end(), origRefp,
|
UASSERT_OBJ(it != s_map.end(), origRefp,
|
||||||
"iface capture propagateClone missing entry for orig=" << cvtToStr(origRefp));
|
"iface capture propagateClone missing entry for orig=" << cvtToStr(origRefp));
|
||||||
CapturedIfaceTypedef& entry = it->second;
|
CapturedIfaceTypedef& entry = it->second;
|
||||||
|
|
|
||||||
|
|
@ -1979,11 +1979,14 @@ class RandomizeVisitor final : public VNVisitor {
|
||||||
return pair.first->second;
|
return pair.first->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
AstVar* newRandcVarsp(AstVar* const varp) {
|
AstVar* newRandcVarsp(AstVar* const varp, AstClass* const classp) {
|
||||||
|
// Might be called multiple times on same var, if var is referenced in class extends,
|
||||||
|
// If so, each is randomized separately, so the select lands in the extending class
|
||||||
|
|
||||||
// If a randc, make a VlRandC object to hold the state
|
// If a randc, make a VlRandC object to hold the state
|
||||||
if (!varp->isRandC()) return nullptr;
|
if (!varp->isRandC()) return nullptr;
|
||||||
uint64_t items = 0;
|
|
||||||
|
|
||||||
|
uint64_t items = 0;
|
||||||
if (AstEnumDType* const enumDtp = VN_CAST(varp->dtypep()->skipRefToEnump(), EnumDType)) {
|
if (AstEnumDType* const enumDtp = VN_CAST(varp->dtypep()->skipRefToEnump(), EnumDType)) {
|
||||||
items = static_cast<uint64_t>(enumDtp->itemCount());
|
items = static_cast<uint64_t>(enumDtp->itemCount());
|
||||||
} else if (AstBasicDType* const basicp = varp->dtypep()->skipRefp()->basicp()) {
|
} else if (AstBasicDType* const basicp = varp->dtypep()->skipRefp()->basicp()) {
|
||||||
|
|
@ -2002,11 +2005,11 @@ class RandomizeVisitor final : public VNVisitor {
|
||||||
} else {
|
} else {
|
||||||
varp->v3fatalSrc("Unexpected randc variable dtype");
|
varp->v3fatalSrc("Unexpected randc variable dtype");
|
||||||
}
|
}
|
||||||
AstCDType* newdtp = findVlRandCDType(varp->fileline(), items);
|
AstCDType* const newdtp = findVlRandCDType(varp->fileline(), items);
|
||||||
AstVar* newp
|
AstVar* const newp
|
||||||
= new AstVar{varp->fileline(), VVarType::MEMBER, varp->name() + "__Vrandc", newdtp};
|
= new AstVar{varp->fileline(), VVarType::MEMBER, varp->name() + "__Vrandc", newdtp};
|
||||||
newp->isInternal(true);
|
newp->isInternal(true);
|
||||||
varp->addNextHere(newp);
|
classp->addStmtsp(newp);
|
||||||
UINFO(9, "created " << varp);
|
UINFO(9, "created " << varp);
|
||||||
return newp;
|
return newp;
|
||||||
}
|
}
|
||||||
|
|
@ -2285,6 +2288,7 @@ class RandomizeVisitor final : public VNVisitor {
|
||||||
|
|
||||||
void addBasicRandomizeBody(AstFunc* const basicRandomizep, AstClass* const nodep,
|
void addBasicRandomizeBody(AstFunc* const basicRandomizep, AstClass* const nodep,
|
||||||
AstVar* randModeVarp) {
|
AstVar* randModeVarp) {
|
||||||
|
UINFO(9, "addBasicRTB " << nodep);
|
||||||
FileLine* const fl = nodep->fileline();
|
FileLine* const fl = nodep->fileline();
|
||||||
AstVar* const basicFvarp = VN_AS(basicRandomizep->fvarp(), Var);
|
AstVar* const basicFvarp = VN_AS(basicRandomizep->fvarp(), Var);
|
||||||
AstVarRef* const basicFvarRefp = new AstVarRef{fl, basicFvarp, VAccess::WRITE};
|
AstVarRef* const basicFvarRefp = new AstVarRef{fl, basicFvarp, VAccess::WRITE};
|
||||||
|
|
@ -2340,8 +2344,9 @@ class RandomizeVisitor final : public VNVisitor {
|
||||||
new AstAnd{fl, basicFvarRefReadp, callp}}};
|
new AstAnd{fl, basicFvarRefReadp, callp}}};
|
||||||
basicRandomizep->addStmtsp(wrapIfRandMode(nodep, memberVarp, assignIfNotNullp));
|
basicRandomizep->addStmtsp(wrapIfRandMode(nodep, memberVarp, assignIfNotNullp));
|
||||||
} else {
|
} else {
|
||||||
AstVar* const randcVarp = newRandcVarsp(memberVarp);
|
AstVar* const randcVarp = newRandcVarsp(memberVarp, nodep);
|
||||||
AstVarRef* const refp = new AstVarRef{fl, classp, memberVarp, VAccess::WRITE};
|
AstVarRef* const refp
|
||||||
|
= new AstVarRef{memberVarp->fileline(), classp, memberVarp, VAccess::WRITE};
|
||||||
AstNodeStmt* const stmtp = newRandStmtsp(fl, refp, randcVarp, basicFvarp);
|
AstNodeStmt* const stmtp = newRandStmtsp(fl, refp, randcVarp, basicFvarp);
|
||||||
if (!refp->backp()) VL_DO_DANGLING(refp->deleteTree(), refp);
|
if (!refp->backp()) VL_DO_DANGLING(refp->deleteTree(), refp);
|
||||||
basicRandomizep->addStmtsp(new AstBegin{fl, "", stmtp, false});
|
basicRandomizep->addStmtsp(new AstBegin{fl, "", stmtp, false});
|
||||||
|
|
|
||||||
|
|
@ -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()
|
||||||
|
|
@ -0,0 +1,38 @@
|
||||||
|
// 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
|
||||||
|
|
||||||
|
package uvm_pkg;
|
||||||
|
|
||||||
|
virtual class uvm_sequence #(
|
||||||
|
type REQ = int
|
||||||
|
);
|
||||||
|
endclass
|
||||||
|
|
||||||
|
class uvm_sequence_library #(
|
||||||
|
type REQ = int
|
||||||
|
) extends uvm_sequence #(REQ);
|
||||||
|
randc bit [15:0] select_randc; // Passes without randc here
|
||||||
|
task body();
|
||||||
|
if (0 == randomize(select_randc)) begin
|
||||||
|
end
|
||||||
|
endtask
|
||||||
|
endclass
|
||||||
|
endpackage
|
||||||
|
|
||||||
|
module t;
|
||||||
|
import uvm_pkg::*;
|
||||||
|
|
||||||
|
class t1 extends uvm_sequence_library;
|
||||||
|
endclass
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
t1 c;
|
||||||
|
c = new;
|
||||||
|
c.body;
|
||||||
|
$finish;
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
@ -15,12 +15,12 @@ package uvm_pkg;
|
||||||
type REQ = int
|
type REQ = int
|
||||||
) extends uvm_sequence #(REQ);
|
) extends uvm_sequence #(REQ);
|
||||||
rand bit [15:0] m_rand;
|
rand bit [15:0] m_rand;
|
||||||
// TODO: randc bit [15:0] m_randc;
|
randc bit [15:0] m_randc;
|
||||||
task body();
|
task body();
|
||||||
if (0 == randomize(m_rand)) begin
|
if (0 == randomize(m_rand)) begin
|
||||||
end
|
end
|
||||||
// TODO: if (0 == randomize(m_randc)) begin
|
if (0 == randomize(m_randc)) begin
|
||||||
// TODO: end
|
end
|
||||||
endtask
|
endtask
|
||||||
endclass
|
endclass
|
||||||
endpackage
|
endpackage
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue