parent
b90865a08a
commit
41937ecbe4
|
|
@ -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");
|
||||
AstMemberSel* randModeSel
|
||||
= new AstMemberSel{varp->fileline(), parentAccess, effectiveRandModeVarp};
|
||||
randModeSel->dtypep(effectiveRandModeVarp->dtypep());
|
||||
randModeAccess = randModeSel;
|
||||
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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in New Issue