I was using inline constraints in my sequence with the uvm_do_with
macro and I came across something I don't quite understand. Hoping someone can shed some insight into this:
Assume my my_seq_item
has 2 rand variables - data
and addr
my_sequence.sv
class my_sequence extends uvm_sequence;
// Constructor, .... etc etc
virtual task body();
my_sequence_item tx;
bit [31:0] addr = 'h0101_0101;
bit [31:0] data = 'hDEAD_BEEF;
`uvm_do_with(tx , { tx.addr == addr;
tx.data == data;
});
endtask: body
This doesn’t play nice. Instead:
`uvm_do_with(tx , { tx.addr == local::addr;
tx.data == local::data;
}
Works fine.
The other solution is naming my local
variables something other than addr
and data
.
The expansion of the uvm_do_with
macro says that it calls item.randomize()
, so I assume in this case, the call would be
item.randomize(addr, data) with {addr == local::addr;
data == local::data;
}
Does this mean that if the scope of the variables within the constraint block is that of item rather than the current object? If this is the case, then I should be able to call:
`uvm_do_with(tx , { addr == local::addr;
data == local::data;
}
If this also true, then why does naming the variables to something else work?
In-line constraints have complex identifier search semantics. It first searches the object that
randomize()
is called on (item
in this case). If no identifiers are found, the search proceeds normally from the point where the call torandomize()
occurs (from thebody()
task).So when you have the same identifier names in both the item and the body, the constraint finds the
item
identifiers first. You don't have this problem when the names are not the same. Usinglocal::
is the way to show your intent that you do not want the item to be search. I suggest usinglocal::
whenever you just want the local scope search, regardless of when or not there are identifiers with the same names in the item.