Reputation: 668
I have a code that has a constraint
((((a == b) == c) == d) == e)
I can understand the values taken by c,d and e. But since a == b
is a constraint here, why doesn't the solver solve for a == b
? At least a and b should have same values.
module tb;
class packet;
rand bit [4:0] a,b,c,d,e;
endclass
initial
begin
packet pkt;
pkt = new();
if(pkt.randomize() with {pkt.a == pkt.b == pkt.c == pkt.d == pkt.e;})
$display("a is %h, b is %h, c is %h,d is %h, e is %d \n", pkt.a, pkt.b, pkt.c, pkt.d, pkt.e);
if(pkt.randomize() with {pkt.a == pkt.b == pkt.c;})
$display("a is %h, b is %h, c is %h,d is %h \n", pkt.a, pkt.b, pkt.c, pkt.d);
end
endmodule
I get the output as
a is 00, b is 08, c is 1c,d is 00, e is 1
a is 0d, b is 1d, c is 00,d is 09
I can relate the values taken by c,d and e. But, the values a and b I don't understand.
Upvotes: 1
Views: 464
Reputation: 115
You should refer Verilog and SystemVerilog Gotchas: 101 Common Coding Errors by Stuart Sutherland and Don Mills. The listed book has covered the above gotcha and previous question Gotcha of fork-join_none.
Upvotes: 1
Reputation: 1244
You have found a typical gotcha of SystemVerilog constraints let me explain,
"==" is a binary operator which evaluates from left to right
eg: pkt.a==pkt.b - Here if pkt.a has same value of pkt.b then the result of evaluation is 1, otherwise result is 0
(pkt.a==pkt.b)==pkt.c - to make whole expression "true" pkt.c will have to be equal to result of pkt.a==pkt.b evaluation, meaning that if pkt.a is different from pkt.b, pkt.c will have the value 0, otherwise it will have the value 1.
This means that pkt.c will always be either 0 or 1, such that the only set of values that satisfy pkt.a==pkt.b==pkt.c is all 1's. A similar issue is found at link
Solution for this is, split the constraints separately as mentioned below to get the desired result.
if(pkt.randomize() with {pkt.a == pkt.b; pkt.b == pkt.c; pkt.c == pkt.d; pkt.d == pkt.e;})
if(pkt.randomize() with {pkt.a == pkt.b; pkt.b == pkt.c;})
For easier understanding and to avoid confusion maintain same print formats throughout, I have found that there is a mix of hex and decimal formats in your example
$display("a is %h, b is %h, c is %h,d is %h, e is %d \n", pkt.a, pkt.b, pkt.c, pkt.d, pkt.e);
Upvotes: 5