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句柄指向的对象的类型并拷贝对象本身。
本文来自博客园,作者:hematologist,转载请注明原文链接:https://www.cnblogs.com/littleMa/p/10455080.html
posted on 2019-03-01 10:46 hematologist 阅读(991) 评论(0) 编辑 收藏 举报