Shankhadeep Mukerji
Shankhadeep Mukerji

Reputation: 668

Why atleast a==b constraint not solved for the constraint solvers

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

Answers (2)

Rottenengg
Rottenengg

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

Emman
Emman

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

Related Questions