首页|资源下载
登录|注册

您现在的位置是:首页 > 技术阅读 >  ​SystemVerilog中的动态 Cast

​SystemVerilog中的动态 Cast

时间:2024-07-16

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”)。