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
= 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;
if (membersel) {
AstNodeExpr* parentAccess = membersel->fromp()->cloneTree(false);
AstNodeModule* const varClassp = VN_AS(varp->user2p(), NodeModule);
AstVar* const effectiveRandModeVarp = VN_AS(varClassp->user2p(), Var);
UASSERT_OBJ(effectiveRandModeVarp, nodep,
"Member-selected variable must have randmode in its class");
if (effectiveRandModeVarp) {
// Member's class has randmode, use it
AstNodeExpr* parentAccess = membersel->fromp()->cloneTree(false);
AstMemberSel* randModeSel
= new AstMemberSel{varp->fileline(), parentAccess, effectiveRandModeVarp};
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 {
UASSERT_OBJ(m_randModeVarp, nodep, "No m_randModeVarp");
randModeAccess

View File

@ -21,14 +21,65 @@ endclass
class Foo extends Base;
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
Foo d = new;
Base b = d;
Foo d;
Base b;
reg_r r;
// Test 1: Member class with randmode
d = new;
b = d;
b.v.disable_val();
b.v.value = 11;
/* verilator lint_off WIDTHTRUNC */
if (bit'(b.randomize())) $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");
$finish;
end