Reputation: 10240
I ran across the following constraint in a testbench. It's behavior seems to vary depending on the simulator used.
constraint wr_c {
if (!one_beat) { addr[5:0] == 0, len == 15 };
}
What is it actually supposed to do, as written?
An example:
import uvm_pkg::*;
class pkt extends uvm_object;
rand bit one_beat;
rand int len;
rand bit [31:0] addr;
`uvm_object_utils_begin(pkt)
`uvm_field_int(one_beat, UVM_DEFAULT)
`uvm_field_int(len, UVM_DEFAULT)
`uvm_field_int(addr, UVM_DEFAULT)
`uvm_object_utils_end
constraint wr_c {
if (!one_beat) { addr[5:0] == 0, len == 15 };
}
endclass
module test;
initial begin
for (int i = 0; i < 10; i++) begin
automatic pkt p = new();
p.randomize();
p.print();
end
end
endmodule
Upvotes: 2
Views: 271
Reputation: 19112
The reason the different simulator give different results likely has to do with what it constitutes as true
for the solver. Using the following example:
rand bit [1:0] example;
rand bit one_beat;
constraint example_c { if(!one_beat) example; }
In this case example
has the same randomization width as { addr[5:0] == 0, len == 15 }
. Depending on the simulator the above constraint may infer example==2'b1
or example!=2'b0
or example>2'b0
(different results with signed and unsigned) . If one_beat
wasn't an one-bit value, the same issue would be true for want counts as true for the if()
statement.
If the OR option is intended, a better way to write the constraint would be:
if (!one_beat) ( addr[5:0] == 0 || len == 15 );
or
if (!one_beat) { addr[5:0] == 0, len == 15 } != 0; // or '>0', '>=1', etc
There is a good change the creator of the constraint intended both constraints to be true when if(!one_beat)
. In this case the follow would be better constraint options:
if (!one_beat) { addr[5:0] == 0; len == 15; } // note the semicolon positions
or
if (!one_beat) ( addr[5:0] == 0 && len == 15 );
Also note that with the given SSCCE, one_beat
has a very low probability of being 1'b0
because the solver is trying to find a legal condition for one_beat
, addr
and len
in parallel with equal priority.
addr[5:0]==0 || len==15
its probability is 1/(1+2**6) + 1/(1+2**32)
addr[5:0]==0 && len==15
its probability is 1/(1+2**(6+32))
If this is not intend, then add another constraint such as one_beat dist { ... };
or sovle one_beat before addr,len;
constraints
IEEE Std 1800-2012 § 18.5 Constrained random value generationdist {...}
IEEE Std 1800-2012 § 18.5.4 Distributionsolve ... before ...
IEEE Std 1800-2012 § 18.5.10 Variable orderingUpvotes: 4
Reputation: 10240
This is how the constraint behaves on different simulators. The constraint behaves differently because the simulators treat the concatenation constraint {a, b};
in different ways.
The code below is pseudo code for purposes of demonstrating how the constraint from the question works.
On VCS 2013.06:
if (!one_beat) {
{ addr[5:0] == 0, len == 15 } == 2'b01 || { addr[5:0] == 0, len == 15 } == 2'b10;
// distribution highly favors 2'b01
}
On Questa SIM 10.1d:
if (!one_beat) {
{ addr[5:0] == 0, len == 15 } == 2'b10;
}
On INCISIV 13.10.001:
if (!one_beat) {
{ addr[5:0] == 0, len == 15 } == 2'b01 || { addr[5:0] == 0, len == 15 } == 2'b10;
// distribution favors 2'b10
}
Upvotes: 1