Signed Arithmetic in Constraints

Having recently referred Verilog Basics for SystemVerilog Constrained Random Verification , I have been tempted to try out signed Arithmetic in Constraints .

[I] CODE 1


  rand bit [3:0] b[3]; // Unsigned by default !!
  
constraint NEG_ELEMENTS {    foreach(b[i])
                          signed'(b[i]) == -1 ; // Sign Cast !!
                        }
 

Here are my thoughts on the working for the above code ( Feel free to correct me ) ::

(i) -1 is by default 32-bit signed , hence the expression is Evaluated as Signed.

 Due to unequal size , b[i] would be extended to 32-bits . However due to signed'() Cast , we would perform Sign-Extension based on MSb !!

 **[Q1] Shouldn't each element of Array b , be Constrained to be 4'b1111  ??** 

  [  I observe different Output on Licensed Simulators , hence the Confusion ] 

[I] CODE 2


  class SIGN_ADD ;

 typedef bit signed [2:0] bitsign ;
 
 rand bitsign  a , b , c , d ;
 rand bit signed [3:0] sum ;

 constraint SIGN_ADDITION { sum == ( c < d ) + a + b ; }  // c and d Unconstrained , right ??
 
endclass 

SIGN_ADD obj ;

initial begin
  
   obj = new() ;

  if ( obj.randomize() )
    $display("Success with %p",obj); 
  else
    $display("Fails"); 
 

Each Operand would be made 4-bit due to Unequal Size of the Operands ( Table 11-21 LRM )
So Sign-Extension for a , b , c and d

The Output is Interesting

Success with '{a:7, b:6, c:2, d:5, sum:-2}
Success with '{a:3, b:6, c:6, d:0, sum:-7}

a , b , c and d are 3-bit Signed .
Hence the Max Negative Value for them would be -4 , Max Positive Value would be 3 ( But look at the Output !! )

LRM 11.8.1 ::
(1) Reduction Operator results are unsigned, regardless of the operands

So result of ( c < d ) is 1’b0 / 1’b1 making the entire expression Unsigned !! [ Verilog Basics !! ]

 Which might be the reason I see values greater than 3 for a and b .

 **Any additions to my understanding would be appreciated .** 

[Q2] But shouldn’t a and b have values defined by Digital Basics ( b/w -4 and 3 ) ??

[Q3] An in-line constraint using ::


         if ( obj.randomize() with { a < 0 ; b < 0 ; )
         
  **Gives Constraint Failure !! , Not Sure why ??**

Thanks

In reply to TC_2017:
You might have run into a few different tool issues. You’ll need to contact your tool vendor for support.
[A1] The result should be 4’b1111.
[A2] Try using %d formats instead of %p.
[A3] I’m not able to reproduce your constrained failure. It would help to provide a complete example.

c and d are part of the constraint expression; they are are constrained in some sense. But their context is independent of the rest of the expression, so it will be a signed comparison. But its result is 1-bit unsigned as you mention.

In reply to dave_59:

Hi Dave ,

[2] Using %0d instead of %p gives me Same results ::


      class SIGN_ADD ;
 
 typedef bit signed [2:0] bitsign ;
 
 rand bitsign  a , b , c , d ;
 rand bit signed [3:0] sum ;
 
 constraint SIGN_ADDITION { sum == ( c < d ) + a + b ; }  // c and d Unconstrained , right ??
 
  function void post_randomize();
    $display("a is %0d , b is %0d",a,b);
    $display("c is %0d , d is %0d",c,d); 
  endfunction

endclass 
 
SIGN_ADD obj ;
 
initial begin
 
   obj = new() ;
 
  if ( obj.randomize() )
    $display("Success with %p",obj); 
  else
    $display("Fails");
end
     

I see Similar Output ::

a is 7 , b is 7
c is 6 , d is 5
Success with {a:'h7, b:'h7, c:'h6, d:'h5, sum:-2} // [X]
a is 6 , b is 3
c is 0 , d is 0
Success with {a:'h6, b:'h3, c:'h0, d:'h0, sum:-7} // [Y]

If I were to do binary Addition ::
With , a + b + ( c < d ) is 4’b1110 i.e -2 since MSb is 1
With [Y] , a + b + ( c < d ) is 4’b1001 i.e -7 since MSb is 1

Since the 1st step would be to have Operands Sized to 4-bits ,
maybe a , b , c , d are 0-Padded instead os Sign Extension ??
[ 0-Padded since result of Relational Operator makes the expression Unsigned !! ]

[3] With in-line Constraint I have following Code for which I observe Failure !!


      class SIGN_ADD ;
 
 typedef bit signed [2:0] bitsign ;
 
 rand bitsign  a , b , c , d ;
 rand bit signed [3:0] sum ;
 
 constraint SIGN_ADDITION { sum == ( c < d ) + a + b ; }  // c and d Unconstrained , right ??
 
  function void post_randomize();
    $display("a is %0d , b is %0d",a,b);
    $display("c is %0d , d is %0d",c,d); 
  endfunction

endclass 
 
SIGN_ADD obj ;
 
initial begin
 
   obj = new() ;
 
  if ( obj.randomize() with { a < 0 ; b < 0 ; } ) // Constraint Failure !!
    $display("Success with %p",obj); 
  else
    $display("Fails");
end
     

This Failure I believe is due to the Expression being treated as Unsigned ( again due to result of relational Operator being Unsigned )

LRM 11.8.1 :: Comparison and reduction operator results are unsigned, regardless of the operands.

In reply to TC_2017:

It’s not failing for me with any simulator on EDAplayground.