Is $cast as Constraint Guard Valid?

Based on type of object I constraint a Variable


class Base ;
 ...
endclass

class Ext1 extends Base ;
 ...
endclass

class Ext2 extends Ext1 ;
 ...
endclass

class RAND ;

rand bit [1:0] val ;

Base b ; // Will hold Object @ run-time based on which I want to constraint val ;

local Ext1 e1 ;
local Ext2 e2 ;

constraint VALUE {  if ( $cast(e1,b) ) // Error !!
                    { val == 1 ; }
                   else if ( $cast(e2,b) ) // Error !!
                    { val == 2 ; }
                  else 
                    { val == 3 ; }
                 }

endclass 

Rand r ;
Base b;
Ext1 e1 ;
Ext2 e2 ;

initial begin

r = new() ;
b = new();
e1 = new();
e2 = new();

 r.b = b ;
 void'( r.randomize() ) ; // Yes , I know not recommended

  r.b = e1 ;
 void'( r.randomize() ) ; // Yes , I know not recommended
  
  r.b = e2 ;
 void'( r.randomize() ) ; // Yes , I know not recommended

end

[Q1] Is there a restriction in using $cast() as a Constraint Guard ?

I then use a function call in Constraint Guard


// Inside Class RAND 
typedef bit [1:0] BB;

function BB CAST();

if ( $cast(e1,b) ) 
  return 1 ; 
else if ( $cast(e2,b) )
  return 2 ; }
else 
  return 3 ; 

endfunction

constraint VALUE {  if ( CAST() == 1 ) 
                    { val == 1 ; }
                   else if ( CAST() == 2 ) 
                    { val == 2 ; }
                  else if ( CAST() == 3 )
                    { val == 3 ; }
                 }

function void post_randomize() ;

                    if ( $cast(e1,b) )
                    $display(" val == 1 ") ; 
                   else if ( $cast(e2,b) ) 
                    $display("val == 2") ; 
                  else 
                    $display("val == 3") ; 

endfunction

Rand r ;
Base b;
Ext1 e1 ;
Ext2 e2 ;

initial begin

r = new() ;
b = new();
e1 = new();
e2 = new();

 r.b = b ;
 void'( r.randomize() ) ; 

  r.b = e1 ;
 void'( r.randomize() ) ; 
  
  r.b = e2 ;
 void'( r.randomize() ) ; 

end

I get Output as ::

val == 1
val == 1

[Q2] Shouldn’t it display 3 times ( Since I call randomize thrice ) ?

[Q3] I expected it to display all 3 values , where do I go wrong ?

Thanks ,

In reply to MICRO_91:

$cast is not a valid function to use in a constraint, nor is using $cast in a function called in a constraint. You are not allow call functions that modify some external value. A functions value must be solely determined by its inputs.

What you could do something like

class Base ;
 int code =1;
endclass
 
class Ext1 extends Base ;
  function new;
    super.new;
    code = 2;
  endfunction
 ...
endclass
 
class Ext2 extends Ext1 ;
function new;
    super.new;
    code = 3;
  endfunction
 ...
endclass

In reply to dave_59:

In reply to MICRO_91:
(a) $cast is not a valid function to use in a constraint, nor
(b) is using $cast in a function called in a constraint.
You are not allow call functions that modify some external value.
(c) A functions value must be solely determined by its inputs.

Didn’t get why $cast() doesn’t work in (a) and (b) above .
So after going the LRM I found the following ::

[a] LRM 18.4 :: “Randomization shall not modify the actual object handle”

 Using $cast() we point to another object thereby a possibility to modify it .

(Q1) Is this the reason $cast() isn’t valid in a Constraint ?

**Similarly

[b]LRM 18.5.12 :: “Functions that appear in constraints cannot modify the constraints”**
(Q2) Similar to (a) there’s a possibility that user could modify the object passed as input

Is this the reason $cast() isn’t valid in a function called in a Constraint ?

[3] I had posted a query some time ago and your suggestion was to use a function
without input argument .

Similar to the link below , shouldn't the CAST() solution work ? 

 [LINK...](https://verificationacademy.com/forums/systemverilog/using-4-state-constraint-guard)

In reply to Have_A_Doubt:

You can’t use $cast directly in a constraint because the first of its two arguments is an output argument.
You can’t use $cast directly or indirectly through a user function call because you’re not allowed to change the actual object handle of a random class variable.

In reply to dave_59:

Hi Dave ,

Please correct me if wrong ::

(1) Constraints can ‘ONLY’ be an expression .
$cast() is an assignment ( i.e It uses ‘=’ internally ) .

 Hence it's Illegal to use them in constraints .
(  Even Constraint Guards since these are written within Constraints )

(2) I tried the code with CAST function as a Constraint Guard , it works fine .

 Since there is no random class variable in the Class RAND
 ( b , e1 and e2 are State variables ) , shouldn't $cast() work in this case ?

 [ It could be a Simulator Issue too , hence I am confused  ]