How does constraint solver randomize


I am not able to understand how a constraint solver works

a == b == c I can see that it starts from left and equals a and b and does not equal c (reason not known).
But a == b == c == d gives different result.

module tb;
  class packet;
    rand bit [4:0] a,b,c,d;
          
  endclass
  
  initial
  begin
    packet pkt;
    pkt = new();
    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);
    if(pkt.randomize() with {pkt.a == pkt.b == pkt.c == pkt.d;})
      $display("a is %h, b is %h, c is %h,d is %h \n", pkt.a, pkt.b, pkt.c, pkt.d);
    
  end  
 
endmodule

Output is

a is 0f, b is 0f, c is 01,d is 1b

a is 15, b is 0f, c is 17,d is 00

In reply to smukerji:

The expression in the constraints can take only one operator at a time.

for example, if you want pkt.a==pkt.b==pkt.c==pkt.d then I hope the following solution works.

module tb;
class packet;
rand bit [4:0] a,b,c,d;

endclass

initial
begin
packet pkt;
pkt = new();
if(pkt.randomize() with {pkt.a == pkt.b, 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);
if(pkt.randomize() with {pkt.a == pkt.b, pkt.b == pkt.c, pkt.c == pkt.d;})
$display(“a is %h, b is %h, c is %h,d is %h \n”, pkt.a, pkt.b, pkt.c, pkt.d);

end

endmodule

Please correct me if I am wrong.

In reply to smukerji:
Your problem is with the expression you are using in your constraint. It’s not the constraint solver. A constraint expression evaluates true or false following the same Boolean/arithmetic rules found elsewhere in SystemVerilog (like the condition of an if statement)… Those rules (from table 11-2) say that the operators associate from left to right. So your constraint expression evaluates the same as

(a == b) == c
((a == b) == c ) == d

The first randomize call produces

(5’h0f == 5’h05) == 5’b01, which reduces to
(1’b1) == 5’h01, which is true. So those values meet the constraint.

The second randomize call produces
((5’h15 == 5’h0f) == 5’h17) == 5’h00
((1’b0) == 5’h17) == 5’h00
(1’b0) == 5’h00, which is true. So those values meet the constraint.

What I think you are looking to write is

{a == b && b == c;}
{a == b && b == c && c == d;}

You can also write is as a series of constraints

{a == b; b == c;}
{a == b; b == c; c ==d;}