Welcome ! This website will help YOU (recent graduates/professionals) learn verification languages like SystemVerilog and UVM. Register for free and access more content !

When values need to be assigned between two different data type variables, ordinary assignment might not be valid and instead a system task called $cast should be used.

$cast can be called as either a task or a function, the difference being that when used as a function, it returns a 1 if the cast is legal. It becomes useful in handling invalid assignments.

Click here for an example !

Syntax

 
  function int $cast (targ_var, source_exp);
 
  task $cast (targ_var, source_exp);
 

Here, targ_var is the target variable and source_exp is the source expression that should be evaluated and assigned to the target variable.

Calling as a task/function

When $cast is called as a task, it will attempt to assign the source expression to the target variable and if it's invalid, a runtime error will occur and the target variable will remain unchanged.

When $cast is called as a function, it will attempt to assign the source expression to the target variable and return 1 if it succeeds. It does not make the assignment if it fails and returns 0. Note that in this case there will be no runtime error, and the simulation will proceed with the unchanged value of the destination variable.

Example

Using $cast

Let's take an enumerated variable and assign an integer value to it using $cast.

 
typedef enum { PENNY=1, FIVECENTS=5, DIME=10, QUARTER=25, DOLLAR=100 } Cents;
 
module tb;
  Cents   myCent;
 
  initial begin
    $cast (myCent, 10 + 5 + 10);
    $display ("Money=%s", myCent.name());
  end
endmodule
 

The source expression (10 + 5 + 10) was first evaluated to 25 and then assigned to the enumerated variable myCent.

Simulation Log
ncsim> run
Money=QUARTER
ncsim: *W,RNQUIE: Simulation is complete.

Click to try this example in a simulator!   

Without $cast

Now, let's see what happens if $cast is not used and a simple assignment is made as shown below.

 
  initial begin
    myCent = 10 + 5 + 10;
    ...
  end
 

Some simulators allow the simulation to run but gives a compilation warning because of data-type mismatch. But some others give a compilation error. The value being assigned is an integer while the target data type is an enumerated variable.

Simulation Log

This is the output from Aldec Riviera Pro

ERROR VCP2694 "Assignment to enum variable from expression of different type." "testbench.sv" 7  1
FAILURE "Compile failure 1 Errors 0 Warnings  Analysis time: 0[s]."

This is the output from Cadence ncsim

		myCent = 10 + 5 + 10;
		                |
ncelab: *W,ENUMERR (./testbench.sv,7|18): This assignment is a violation of SystemVerilog strong typing rules for enumeration datatypes.

ncsim> run
Money=QUARTER
ncsim: *W,RNQUIE: Simulation is complete.
ncsim> exit

Click to try this example in a simulator!   

Casting invalid values

Now, let's assign a value that does not fall inside the enumerated range and see what happens.

 
  initial begin
    $cast (myCent, 75);
    ...
  end
 

Note that $cast was called as a task (returned value is ignored), and hence it results in a runtime error when the cast failed.

Simulation Log
ncsim> run
		$cast (myCent, 75);
		    |
ncsim: *E,INVCST (./testbench.sv,7|6): Invalid cast: the source expression can not be cast to the type of the destination variable.
Money=
ncsim: *W,RNQUIE: Simulation is complete.

Click to try this example in a simulator!   

$cast as a function

Let's do the same out of range example with $cast called as a function.

 
  initial begin
    if ($cast (myCent, 75))
      $display ("Cast passed");
    else
      $display ("Cast failed");
    ...
  end
 

Note that the simulation completed without any runtime errors, and the target variable was left unchanged.

Simulation Log
ncsim> run
Cast failed
Money=
ncsim: *W,RNQUIE: Simulation is complete.

Click to try this example in a simulator!   

Casting is also done on class objects to allow a base class handle pointing to a child object be assigned to another child variable as discussed in Polymorphism.

Was this article helpful ?

We use cookies to personalize content and ads, to provide social media features and to analyze our traffic. You consent to our cookies if you continue to use our website. To find out more about the cookies we use and how to delete them, see our privacy policy.

  I accept cookies from this site.
Agree
EU Cookie Directive plugin by www.channeldigital.co.uk