SV语法 / 数据类型 / 类型转换
资料来源:
(1)sv绿皮书;
(2)公众号-芯片学堂;
(3)硅芯思见:【113】SystemVerilog中不同句柄之间的动态类型转换 (qq.com)
1. 隐式转换
(1)隐式和显示类型转换的区分通常在于有没有使用到系统函数或者操作符。
(2)隐式类型转换在SystemVerilog编程中经常遇到,比如源类型和目的类型不一致的情况下,在赋值完成之前默认会有类型转换的动作。
2. 显式转换
(1)显式类型转换则是使用类型转换操作符type'(expression)或者系统函数$cast。
(2)使用类型转换操作符属于静态类型转换,这种方式的目的类型是固定的,并且只会在编译阶段(compile-time)进行类型检查和编译报错。
(3)动态类型转换的”动态“,具体指的是仿真程序只会在运行的过程(run-time)中对类型兼容性做检查和报错。
2.1 静态转换
不对转换值进行检查.转换时,指定目标类型,并在需要转换的表达式前加上单引号即可.
int’(10.0-0.1);
2.2 动态转换
动态转换函数$cast允许对越界的数值进行检查.
2.2.1 使用$cast作类型向下转换(对类操作)
(1) 类型向下转换或类型变换是指将一个指向基类的指针转换成一个指向派生类的指针.
(2) 可以将一个派生类句柄赋给一个基类句柄,并且不需要任何特殊代码(属于静态转换).
注:子类句柄指向创建对象之后,访问的属性和方法都是子类的(也可以访问基类的);在没有使用多态机制的情况下,当把子类句柄赋值给父类句柄后,可以通过父类句柄访问父类句柄类型的所有属性和方法,但是不能访问子类句柄指向的子类对象中的属性和方法;
(3) 如果将一个基类对象拷贝到一个扩展类的句柄中,会失败(会报编译错误).
(4) 但将基类句柄赋值给一个派生类句柄并不总是非法的(当基类句柄确实指向一个派生类对象时,是允许的).
(5) $cast子程序会检查句柄所指向的对象类型,而不仅仅检查句柄本身. 一旦源对象与目的对象是同一类型,或者是目的类的派生类,就可以使用$cast进行转换.
注意: $cast(dest, src),当dest与src为class时,src需要例化,而dest则不需要.
注:虽然将c_ahb0赋给了f_amba,但是通过f_amba访问disp时,其访问的是指向空间中父类部分的disp(如果采用虚函数和多态则有所不同);
2.2.2. $cast任务与$cast函数
(1) $cast任务: 如果检查到源对象类型与目的对象类型不匹配,则给错误报告.
(2) $cast函数: system verilog仍会做类型检查,但在失配时,不会输出错误信息.如果类型不兼容, $cast函数返回0,且不会改变目标变量原来的值,仿真程序还可以继续正常往下走,如果类型兼容,则返回非零值.