Why do we use $cast() for checking at run time?

Dear All,

I’m trying to understand about “runtime checks with the cast method” in Runtime checks with the $cast() method - Verification Horizons

There’s a simple snippet code as the below,

traffic_t light;
bit [2:0] v3 = 3'b010; // One-hot value, not traffic_t type
initial
  light = v3;          // Gets compile error
You need a way to check that the value of v3 is one of the legal values for light, ‘b001 for GREEN, ‘b010 for YELLOW, and ‘b100 for RED. The SystemVerilog $cast() method performs this check for you. Here you are calling it like a task.

initial
  $cast(light, v3); // Check value of v3 at run time: compatible with traffic_t?

Here, to avoid to get compile error, $cast() was used for check value of v3 at run time to check compatibility with traffic_t.
But I’m wondering that why does check value of v3 at run time not compile time?
Usually, we get the order “ELABORATE” → “COMPILE” → “SIMULATION”, so if we can check v3 value at COMPILE not SIMULATION(run time), it would be better to save the time.

So why does the value of v3 check at run time ?

In reply to UVM_LOVE:

What is the value of v3 at compile time? In this simple example, you can see it is 3’b010, but that is only at time 0. What about the following code?

enum {RED=3'b001, YELLOW=3'b010, GREEN=3'100} light;
initial begin
  v3 = 3'b010;      // 2 is equivalent to YELLOW
  $cast(light, v3); // Success, light gets YELLOW

  v3++;             // 3 does not match any enum value
  $cast(light, v3); // Error as the value 3 is not a legal enum value
end

The two calls to $cast() are identical, yet one succeeds at run time, and one gets an error. It would be hard for the compiler to predict this. Replace the v3++ with a call to a function that increments v3, and it is almost impossible for the compiler to decide if the $cast call succeeds. That decision can only be done at run time.

In reply to chrisspear:

In reply to UVM_LOVE:
What is the value of v3 at compile time? In this simple example, you can see it is 3’b010, but that is only at time 0. What about the following code?

enum {RED=3'b001, YELLOW=3'b010, GREEN=3'100} light;
initial begin
v3 = 3'b010;      // 2 is equivalent to YELLOW
$cast(light, v3); // Success, light gets YELLOW
v3++;             // 3 does not match any enum value
$cast(light, v3); // Error as the value 3 is not a legal enum value
end

The two calls to $cast() are identical, yet one succeeds at run time, and one gets an error. It would be hard for the compiler to predict this. Replace the v3++ with a call to a function that increments v3, and it is almost impossible for the compiler to decide if the $cast call succeeds. That decision can only be done at run time.

Dear chrisspear, Thanks for replay.
I got the answer from Application of $cast() in UVM - UVM - Verification Academy.

You need $cast to downcast the function argument from uvm_object variable to a derived class variable. Otherwise you will not be able to access the derived class members from the uvm_object variable.

Is this the same idea $cast() used for compatibility check(downcast) at run time?

In reply to UVM_LOVE:
Yes. In both cases, $cast(L,R) is checking the value of R to see if it compatible with the type of L. With an enum, the value of R is checked to see if it is one of the legal constant values.

With a class variable, look at type of the object that R points to, and see if L can point to it.


class Base;
  int ib;
endclass

class Extend extends Base;
  int ie;
endclass

Base b;
Extends e1, e2;

initial begin
  e1 = new();
  b = e1;  // Legal as an Extends object is-a Base object
// e2 = b; // Won't compile as compiler just looks at handle type
  $cast(e2, b); // Success as b points to an Extend object
end