How is this both constraint working same?

Hi, team.

constraint en_c { solve en before val; 
                   if(en == 1) { val inside {[0:100]} } ;}
  constraint en_c1 { solve en before val1;
               !(en == 1) || { val1 inside {[0:100]} } ;}

I found that these two constraints working same, can anyone explain me how’s it working.

Thank you

All constraints get broken down into a set of Boolean equations that must evaluate to a non-zero result (that’s how SystemVerilog defines true). Although the if constraint seems like a procedural construct, it actually gets converted into the boolean equation you see in en_c1

Thanks Dave, Explanation indeed helped me to understand the logic how constraints work.

but, i have this doubt. Please check with this.

case1:
constraint en_c { solve en before val;
if(en == 1) { val inside {[0:100]} } ;}
but in this case only if my en==1, constraint is applied to the val, if en==0 it will not work.

case2:
constraint en_c1 { solve en before val1;
!(en == 1) || { val1 inside {[0:100]} } ;}
here
1)if en==1
!(en==1), which it evaluates to 0, which means constraint shouldn’t work right?
2) if en==0
!(en==1) evaluates to 1, which means now constraint should be applicable right?

Is it like this || { val1 inside {[0:100]} } ;} part of the constraint always be True ?

Thank you

It might help if you built a truth table for each constraint, and shorten val to 2-bits and the range to [0:1]. Then you will see that the valid solutions (marked with a T) are the same for both constraints.

en_c { if(en == 1)  { val inside {[0:1]} } ;}
en_c1 { !(en == 1) || val inside {[0:1]} } ;}
en val en_c en_c1
0 0 T T
0 1 T T
0 2 T T
0 3 T T
1 0 T T
1 1 T T
1 2 F F
1 3 F F

Thank you Dave. Truth table made it simple.