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.

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.

This is the output from Aldec Riviera Pro

 Simulation Log
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

 Simulation Log
		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

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.

$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.

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.