Fix member select of variable without randmode (#6800) (#6833)

This commit is contained in:
Yilou Wang 2025-12-18 12:49:04 +01:00 committed by GitHub
parent b90865a08a
commit 41937ecbe4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 69 additions and 11 deletions

View File

@ -892,18 +892,25 @@ class ConstraintExprVisitor final : public VNVisitor {
AstNodeExpr* constFormatp AstNodeExpr* constFormatp
= membersel ? getConstFormat(membersel->cloneTree(false)) : getConstFormat(nodep); = membersel ? getConstFormat(membersel->cloneTree(false)) : getConstFormat(nodep);
// Build randmode access: for membersel, access parent object's __Vrandmode // Build randmode access: for membersel, use member's class randmode if available
AstNodeExpr* randModeAccess; AstNodeExpr* randModeAccess;
if (membersel) { if (membersel) {
AstNodeExpr* parentAccess = membersel->fromp()->cloneTree(false);
AstNodeModule* const varClassp = VN_AS(varp->user2p(), NodeModule); AstNodeModule* const varClassp = VN_AS(varp->user2p(), NodeModule);
AstVar* const effectiveRandModeVarp = VN_AS(varClassp->user2p(), Var); AstVar* const effectiveRandModeVarp = VN_AS(varClassp->user2p(), Var);
UASSERT_OBJ(effectiveRandModeVarp, nodep, if (effectiveRandModeVarp) {
"Member-selected variable must have randmode in its class"); // Member's class has randmode, use it
AstMemberSel* randModeSel AstNodeExpr* parentAccess = membersel->fromp()->cloneTree(false);
= new AstMemberSel{varp->fileline(), parentAccess, effectiveRandModeVarp}; AstMemberSel* randModeSel
randModeSel->dtypep(effectiveRandModeVarp->dtypep()); = new AstMemberSel{varp->fileline(), parentAccess, effectiveRandModeVarp};
randModeAccess = randModeSel; randModeSel->dtypep(effectiveRandModeVarp->dtypep());
randModeAccess = randModeSel;
} else {
// Member's class has no randmode, use current scope's randmode
UASSERT_OBJ(m_randModeVarp, nodep, "No m_randModeVarp");
randModeAccess = new AstVarRef{varp->fileline(),
VN_AS(m_randModeVarp->user2p(), NodeModule),
m_randModeVarp, VAccess::READ};
}
} else { } else {
UASSERT_OBJ(m_randModeVarp, nodep, "No m_randModeVarp"); UASSERT_OBJ(m_randModeVarp, nodep, "No m_randModeVarp");
randModeAccess randModeAccess

View File

@ -21,14 +21,65 @@ endclass
class Foo extends Base; class Foo extends Base;
endclass endclass
module t; package uvm_pkg;
virtual class uvm_object;
endclass
class uvm_sequence_item;
endclass
virtual class uvm_sequencer_param_base;
function void send_request(uvm_sequence_item t);
uvm_sequence_item par;
if (0 == par.randomize()) begin
end
endfunction
endclass
class uvm_reg_item extends uvm_sequence_item;
rand uvm_object extension;
endclass
class uvm_reg_field extends uvm_object;
rand int value;
virtual function bit get_rand_mode();
return bit'(value.rand_mode());
endfunction
endclass
endpackage
module t_constraint_global_randMode;
import uvm_pkg::*;
class reg_r extends uvm_object;
rand int value;
local rand uvm_reg_field _dummy;
constraint _dummy_is_reg {_dummy.value == value;}
function new();
_dummy = new;
endfunction
endclass
initial begin initial begin
Foo d = new; Foo d;
Base b = d; Base b;
reg_r r;
// Test 1: Member class with randmode
d = new;
b = d;
b.v.disable_val(); b.v.disable_val();
b.v.value = 11; b.v.value = 11;
/* verilator lint_off WIDTHTRUNC */
if (bit'(b.randomize())) $stop; if (bit'(b.randomize())) $stop;
if (b.v.value != 11) $stop; if (b.v.value != 11) $stop;
// Test 2: Member class without randmode
r = new;
if (!r.randomize()) $stop;
/* verilator lint_on WIDTHTRUNC */
$write("*-* All Finished *-*\n"); $write("*-* All Finished *-*\n");
$finish; $finish;
end end