SystemVerilog中$cast的应用

描述

SystemVerilog casting意味着将一种数据类型转换为另一种数据类型。在将一个变量赋值给另一个变量时,SystemVerilog要求这两个变量具有相同的数据类型。

SystemVerilog可以使用(')符号进行强制(静态)类型转换。另外,在SystemVerilog中还存在动态cast的概念。

SystemVerilog提供了$cast系统任务/函数,能够在两个不同的数据类型变量之间赋值,因为如果直接赋值的话会报编译错误。

在SystemVerilog中最常用的动态cast应用场景就是类的继承特性中对类句柄的赋值。基类句柄可以用来获取派生类的对象,反之则不行。

在实际仿真执行的过程中,动态cast会执行相应的检查,是否能够真正地进行赋值。

需要特别注意的是,cast既可以作为fucntion调用,也可以作为task调用。区别就是cast作为函数调用时,如果没有成功会返回0,然后可以决定是否采取相应的操作,而$cast作为任务调用失败后,会直接停止仿真。

下面SystemVerilog $cast系统函数/任务的源码声明

 

function int $cast (target_var, source_exp);

task $cast (target_var, source_exp);

 

下面的例子展示了SystemVerilog中$cast的应用:

 

module tb;
 typedef enum { soccer=2, cricket=4, football=10 } sports;
 sports mS;
 int i;
 initial begin
     i = 10;
 
     mS = i; //Synopsys-VCS - WARNING - incompatible types
     //Mentor Questa/Aldec-Riviera - run time ERROR
     $cast(mS, i); //$cast as a task - match types
     $display ("Sports=%s", mS.name( ));
     i = mS; //No Warning or Error
     $display("i=%0d",i);
     i=50;
     //$cast (mS, i); //ERROR - 50 is not a valid value for enum
     if ($cast (mS, i)) //$cast as a function
         $display ("Cast passed");
     else
         $display ("Cast failed");
     end
 endmodule

 

仿真log:

 

Sports=football
i=10
Cast failed
 V C S S i m u l a t i o n R e p o r t

 

在“tb” module中,我们定义了“int i”,并定义了一个enum“sports”并声明了一个sports类型的变量“mS”。

将一个int赋值给enum类型(sports)的变量

 

mS = i;

 

由于" i "不是enum类型,存在类型不兼容,所以会得到Synopsys - VCS的warnning(不是ERROR哦):

 

Warning-[ENUMASSIGN] Illegal assignment to enum variable
testbench.sv, 11
tb, "mS = i;"
Only expressions of the enum type can be assigned to an enum variable.
The type int is incompatible with the enum 'sports'

 

对于相同的代码,Mentor’s Questa可能会报ERROR:

 

** Error (suppressible): testbench.sv(9): (vlog-8386) An enum variable 'mS' of type 
'sports' may only be assigned the same enum typed variable or one of its values. 
Variable i requires an explicit cast.

 

大家可能有点奇怪,这个不兼容类型的赋值到底是warning还是Error,结论就是这个这个enum 值有实际的分配,其实对代码功能没有影响,当作warning也是没有问题的。

为了纠正这种类型不兼容的赋值错误/警告,我们使用$cast将“i”强制转换为enum“mS”:

 

$cast(mS, i);

 

在这个上下文下,$cast就是作为task调用的。这种动态cast将使int类型" i "和枚举类型" mS "兼容,仿真会PASS。因为i = 10, mS得到的值是10,也就是enum中的“football”。所以,仿真log显示

 

“sports = football。”

 

注意下面的枚举赋值给int类型完全是可以的,反之则不行:

 

i = mS;

 

在动态cast中分配不正确的枚举值(50)。

 

i=50;
$cast(mS, i);

 

因为50不包含在枚举“sports”的范围内,所以会得到一个ERROR:

 

Error-[STASKE_DCF] Dynamic cast failed
testbench.sv, 22
Dynamic cast using '$cast' failed. The source expression is not yielding a
valid value for the destination variable.

 

最后,我们使用$cast作为函数调用,它将返回“0”(因为cast失败),将得到fail打印(“Cast failed”)。

  审核编辑:汤梓红。

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分