The in-line constraints in SystemVerilog are implemented by the class.randomize() with {…} syntax which basically allows you do add additional constraints over the generation of some field from some class.
I’ll show you a very common mistake which engineers are doing with this feature.
Let’s say that we have a sequence item with some integer field called size:
1 2 3 4 5 6 7 8 | class my_item extends uvm_sequence_item; rand int unsigned size; constraint default_size { size < 1000; } endclass |
In a sequence body, when we randomize this item we want to constrain the size to a particular value. For this we use a local field in our sequence:
1 2 3 4 5 6 7 8 9 10 11 12 13 | class my_sequence extends uvm_sequence; task body(); int unsigned size = 5; my_item local_item = my_item::type_id::create("local_item"); void'(local_item.randomize() with { local_item.size == size; }); `uvm_info("cfs", $sformatf("local_item.size: %0d", local_item.size), UVM_LOW) endtask endclass |
If you think that local_item.size will be 5 after randomization you will be very wrong. I simulated this code on EDA Playground and this is the strange output:
1 | UVM_INFO testbench.sv(33) @ 0: reporter@@local_sequence [cfs] local_item.size: 169 |
Did you spot the problem?
Is not that easy!
Inside the scope of randomize() with {…} local_item.size and size are the same field, the size member of local_item object. So the constraint above is the same as writing:
1 2 3 | void'(local_item.randomize() with { local_item.size == local_item.size; }); |
In order to access the local variable size from the body() task you need to use local::size
1 2 3 | void'(local_item.randomize() with { local_item.size == local::size; }); |
Hope this helps!

Awesome article
thanks
I have encountered this and spent an entire day debugging it. Great to see your article resonates with what we encounter in our day-to-day life. Keep up the good work and expecting more articles from you.
Thank you!
Cris, Is it because the the local size and the local item object member have the same name?.It looks like.When I change the name of size to something other than size ,size is constrained to 5. It appears like randomize function lookup order is object scope followed by local?
Hi,
You are right
Great Post Cris.
How is this.variable different from local::variable in this constraint? Will the code
void'(local_item.randomize() with {
local_item.size == this.size;
});
wouldn’t have worked?
Hi Lakshmi,
I don’t think it will work because this is actually that local_item so for the simulator is like doing “local_item.size == local_item.size;”. That local:: points to the “local” context of local_item – so it refers to the local variable from the body() task.
Hope this helps,
Cristi
Great article, Cristian!
Spent quite some time to solve this. It was a pain to find it, especially as a begginer!
Best regards,
Iulian