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”)。
审核编辑:汤梓红。
全部0条评论
快来发表一下你的评论吧 !