Output difference between the following Size cast expressions


 
module  TB ;

 bit bb [2]  = '{ 1 , 0 } ;

 initial  begin

 foreach( bb[i] )
     begin
       
       $display(" bb[%0d] is %0b ",i , bb[i] ) ;
       
       $display(" int'( ( ~ bb[%0d] ) ) is %32b ",i , int'( ( ~ bb[i] ) ) ) ;                 //  [ A ]
       
       $display(" int'( ( ! bb[%0d] ) ) is %32b ",i , int'( ( ! bb[i] ) ) ) ;                 //  [ B ]
       
       $display(" int'( 1'( ~ ( bb[%0d] ) ) ) is %32b ",i,int'( 1'( ~ ( bb[i] ) ) ) ) ;       //  [ C ] 
       
       $display(" int'( ~ ( 1'( bb[%0d] ) ) ) is %32b ",i,int'( ~ (  1'( bb[i] ) ) ) ) ;      //  [ D ]
     
       $display("==============================================================") ;
       
     end  
   
 end
 

endmodule

 
The   output  I   Observe  :: 

**bb[0] is 1
int’( ( ~ bb[0] ) ) is 11111111111111111111111111111110
int’( ( ! bb[0] ) ) is 00000000000000000000000000000000
int’( 1’( ~ ( bb[0] ) ) ) is 00000000000000000000000000000000
int’( ~ ( 1’( bb[0] ) ) ) is 11111111111111111111111111111110

bb[1] is 0
int’( ( ~ bb[1] ) ) is 11111111111111111111111111111111
int’( ( ! bb[1] ) ) is 00000000000000000000000000000001
int’( 1’( ~ ( bb[1] ) ) ) is 00000000000000000000000000000001
int’( ~ ( 1’( bb[1] ) ) ) is 11111111111111111111111111111111
==============================================================**

For first two expressions , first due to the int’() Cast , the size of the expression is 32-bits and then expressions resolve to ::

( ~ 32’h0000_0001 ) and ( ! 32’h0000_0001 ) . Hence the 1st two output is as per expectation .

However I am not sure about how [C] and [D] are resolved

Why does the Output differ between [C] and [D] ?

In reply to Have_A_Doubt:

You are slightly mistaken in your understanding of [B]. The result of logical negation ! is always 1-but unsigned, and it operand has a self-determined width. That means bb[i] is not extended before applying ! operator.

For [C] and [D], you have nested a cast within another cast. Each cast creates an independent context for determining bit-widths. The expression
1’( ~ ( bb[i] ) )
means that
~ ( bb[i] )
get evaluated in the context of a 1-bit type, which means
bb[i]
does not get extended since it is already 1-bit. So [B] and [C] are essentially the same equation, as well as [A] and [D].



int'( 1'( ~ ( bb[i] ) ) )  is  equivalent  to  ::

  bit  B  ;  // Due  to  1'()  Cast

  int  E  ;  //  Due  to  int'()  Cast 

  //   Procedural  Code  :: 

       B   =   (  ~  bb[i]  )  ;

       E   =   B  ;  //  Zero  Padding  since  RHS  is  bit  (  unsigned  type  )  


In reply to dave_59:

Hi Dave ,

Consider the following expression consisting of both self-determined and context-determined operands ::



bit [2:0]  A  =  4 ; 
 
 bit [3:0]  B  =  14 ; 

     int    C  =   1 ;

 bit [3:0]  D  =  8 ; 

initial  begin
  
$display(" (  A + B  >>  C  <  D )  is %32b " ,  (  A + B  >>  C  <  D )  ) ;                  
//   Incorrect   Result
$display(" 5'(  A + B  >>  C  <  D )  is %32b " ,  5'(  A + B  >>  C  <  D )  )  ;             
//   Incorrect   Result
$display(" int'(  A + B  >>  C  <  D )  is %32b " ,  int'(  A + B  >>  C  <  D )  ) ;          
//   Incorrect   Result
   
$display(" ( 5'(  A + B  ) >>  C  <  D )  is %32b " ,  (  5'(  A + B  ) >>  C  <  D )  )  ;  //   Correct   Result  
end


Based on Operator precedence the equivalent expression is ::


 (  (  (  A + B  ) >>  C  ) <  D )  )

Why is it that intermediate cast via 5’( A + B ) gives correct result
whereas using size casting on entire expression gives a different Output ?

I believed the Operands A , B , D would be Size Extended to achieve 5-bits / 32-bits before any of the operators are applied

In reply to ABD_91:

Because the result of (x < y) is always 1-bit unsigned. x and y are in a separate context from the result. When you cast the entire expression, you are only casting the result of <.