SystemVerilog allows to call functions inside constraints, although, as I found out, it is a sensitive topic.
Here is an example:
class constraint_container;
rand int unsigned a, b, c;
function int unsigned get_a();
return a;
endfunction
function int unsigned value_of(int unsigned value);
return value;
endfunction
constraint a_constraint {
a == 5;
// I expect "b" to be equal to "a", but, surprise, surprise...
b == get_a();
// I expect "c" will be equal to "a"
c == value_of(a);
}
endclass
module top;
initial begin
automatic constraint_container cc_inst = new();
void'(cc_inst.randomize());
$display($sformatf("a: %0d, b: %0d, c: %0d", cc_inst.a, cc_inst.b, cc_inst.c));
end
endmodule
At first glance one would guess that all three fields will be 5, but one will get instead:
OUTPUT:
a: 5, b: 0, c: 5
Gotcha: regardless of the seed, b will always be equal to 0!
It looks like get_a() is evaluated before the generation, when a is 0.
The closest thing I could find as an explanation for this behavior was in SystemVerilog IEEE 1800-2012 standard, chapter “18.5.12 Functions in constraints”:
Functions shall be called before constraints are solved, and their return values shall be treated as state variables.
Function calls in active constraints are executed an unspecified number of times (at least once) in an unspecified order.
The conclusion is that functions used by constraints should compute the result based ONLY on function’s arguments and NOT on class members.
3 Responses
It’s the same for e as well. Cadence has a note saying that functions used in constraints shouldn’t use any class members/global variables.
Hi Tudor,
I could not find such a note. Can you please point me to a specific chapter?
I just gave it a try in ‘e’ language using this code:
The output is this:
It might be the case with old version of simulator. I tried this on vcs 2020 version and got error msg as below:
Error-[CSTR-UMC] Constraint: unsupported method call
testbench.sv, 17
$unit, “this.get_a()”
Method constraint_container::get_a contains a construct not supported in
constraint functions: reference to a rand variable ‘a’ at line 7 of
testbench.sv.
Rewrite the method to avoid unsupported constructs.
1 error