SV cast

1、$cast 一目了然

 

图中:向下类型转换,子类类型的句柄访问的方法对于父类类型的实体对象来说,可能不存在,不安全,必须检查;

图中:向上类型转换,父类类型的句柄访问的方法对于子类类型的实体对象来说,一定是存在的,安全,不必检查;

2、$cast 的使用

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

<1> cast 作为函数时:source to targ的转换如果成功,则转换,且返回1,如果不成功则不转换,且返回0,但是不报错error

<2> cast 作为task时:source to targ的转换如不成功,则报错error

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

//Without $cast
  initial begin
    myCent = 10 + 5 + 10;
    ...
  end
//会出现编译错误或者仿真错误

//Casting invalid values
  initial begin
    $cast (myCent, 75);
    ...
  end
//上面的cast作为task使用,仿真报error

//Casting invalid values
  initial begin
    if ($cast (myCent, 75))
      $display ("Cast passed");
    else
      $display ("Cast failed");
    ...
  end
//上面的cast作为function使用,仿真不报错

3、cast的使用场所

<1、句柄:可以指向一个类或者任何它的宽展类的对象。

<2、可以直接将派生类的句柄赋值给一个基类句柄,总是合法的。但是通过基类句柄调用子类对象的方法时,是根据对象类型,而非句柄的类型来决定调用什么方法。

<3、基类句柄赋值给扩展类句柄,不总是合法的。因为通过扩展类句柄可以使用对象方法或变量时,基类对象中该变量或方法不一定存在。

<4、实际的应用过程中,验证组件之间某对象传递都是通过基类句柄进行传递的。

    C1(Bad_tr1) -----------------Tr----------------->  C2(Bad_tr)

     C1组件中的派生类对象Bad_tr1,通过基类句柄Tr,传递给C2组件中。所以在C2中需要将基类句柄 Tr 赋值给扩展类句柄Bad_tr,由于转换不一定成功,所以必须使用cast。

<5  虚方法

     通过句柄调用对象的方法时,根据对象类型,而非句柄的类型来决定调用什么方法。

 

4、$cast 到底做了什么?

$cast(ex_tr, tr) ;  检查tr句柄指向的对象的类型并拷贝句柄。(如果成功ex_tr 就指向tr 所指向的对象)

$cast(ex_tr, tr.clone()) ;  检查tr句柄指向的对象的类型并拷贝对象本身。

 

posted on 2019-03-01 10:46  hematologist  阅读(952)  评论(0编辑  收藏  举报

导航