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