sv类型转换

目录

一、概述

二、静态转换

三、动态转换

3.1 数据类型转换

3.2 句柄类型转换

3.2.1 向上类型转换

3.2.2 向下类型的转换


一、概述

  • 类型转换可以分为显式转换和隐式转换
  • 显式转换即静态转换以及动态转换,静态转换为在代转换值前面加单引号,并且不对转换结果做检查,例如int'(42+1.1);动态转换使用$cast(target,source),成功返回1,失败返回0。
  • 隐式转换即位数扩展,例如[3:0]a = [1:0]b或者[31:0]a = [1:0]b + 32'b0

二、静态转换

program test;
    initial begin
        $display("int'(42+1.1) is",int'(42+1.1));//将43.1强制转换为整型,四舍五入
        $display("(42+1.1) is",(42+1.1));//SV默认为浮点型
        $display("real'(42+1.1) is",real'(42+1.1));
    end
endprogram

++++++++++++++++++++++++++++++++++++++++++++++++++++++
run result
++++++++++++++++++++++++++++++++++++++++++++++++++++++
int'(42+1.1) is 43
(42+1.1) is 43.1
real'(42+1.1) is 43.1

可以看出静态转换可以将浮点型数据强制转换为整形数据

三、动态转换

动态转换可以用到数据类型转换也可以用到句柄转换

3.1 数据类型转换

数据类型的动态转换与上文中静态转换结果一样

program example;
    typedef enum{RED,BLUE,GREEN}COLOR_E;//0,1,2
    COLOR_E color,c2;
    int c;
    
    initial begin
        color=BLUE;
        c=color;//可以将枚举类型的变量赋值给int类型的变量
        $display("c=%0d",c);        
        c++;
        $cast(color,c);//int类型转换成枚举类型
        $display("color is %0s",color.name);
        c2=COLOR_E'(c);
         $display("c2 is %0d/%0s",c2,color.name);
    end
endprogram    

——————————————————————————————————————————————————————————
run result
——————————————————————————————————————————————————————————
c=1
color is GREEN
c2 is 2/GREEN

3.2 句柄类型转换

分为两种转换,一种为子类向父类的向上类型转换,一种为父类向子类的向下类型转换

3.2.1 向上类型转换

即fanther f = child c1,父类句柄指向子类句柄

class father;
    string m_name;
 
    function new (string name);//有参数的new函数
        m_name = name;
    endfunction
 
    function void print ();
        $display("Hello %s", m_name);
    endfunction
endclass
 
class child0 extends father;
    string car = "car";
 
    function new (string name);
        super.new(name);//因为父类new有参数,这里必须用super new
    endfunction
endclass
 
class child1 extends father;
    string plane = "plane";
 
    function new (string name);
        super.new(name);//因为父类new有参数,这里必须用super new
    endfunction
endclass
 
module top;
    father f;
    child0 c0;
    child1 c1;
 
    initial begin
        f = new("father");//为父类的
        f.print();//调用父类的方法,father
 
        c0 = new("child0");
        f = c0;//使父类句柄指向子类c0
        f.print();//调用的还是父类方法,但是被子类传参,child0
 
        c1 = new("child1");
        f = c1;//使父类句柄指向子类c1
        f.print();//调用的还是父类方法,但是被子类传参,child1
    end
endmodule
————————————————————————————————————————————————————————————
run result
————————————————————————————————————————————————————————————
hello father
hello child0
hello child1

此时第二个以及第三个print函数中,父类对象中的print函数不为虚函数且子类未重写该函数,因此未构成override以及overwrite,但此时print函数的参数由子类更新后传入,实现了子类向父类传参。

3.2.2 向下类型的转换

父类向子类的转换,即fanther a;child b1,b2; a = b1;$cast(b2,f);

class father;
    string m_name;
 
    function new (string name);//有参数的new函数
        m_name = name;
    endfunction
 
    function void print ();
        $display("Hello %s", m_name);
    endfunction
endclass
 
class child0 extends father;
    string car = "car";
 
    function new (string name);
        super.new(name);//因为父类new有参数,这里必须用super new
    endfunction
endclass
 
class child1 extends father;
    string plane = "plane";
 
    function new (string name);
        super.new(name);//因为父类new有参数,这里必须用super new
    endfunction
endclass
 
module top;
    father f;
    child0 c0;
    child1 c1;
    child1 c2;
 
    initial begin
       f = new("father");
       f.print();
 
       c0 = new("child0");
       f = c0;
       f.print();
 
       c1 = new("child1");
       f = c1;
       f.print();//以上和2.2.1没差别
 
       c1.plane="big_plane";//更改c1对象的变量
       $cast(c2,f);//强制c2->f,而f->c1,所以导致c2->c1,这就是向下类型的转换
       f.print();//此时f->c1,所以打印的还是c1传的参数
       $write(", has %s",c2.plane)//由于c2->f->c1,所以c2->c1,所以c2.plane是c1的plane名字
    end
endmodule
________________________________________________________________________________________
run result
________________________________________________________________________________________
hello father
hello child0
hello child1
, has big_plane

需要注意最后一种情况,此时f的句柄被转换成了c2完成了父类句柄向子类转换,切记此时需要先将父类句柄f指向与c2类型一致的c1子类,不然转换会报错,此时c2->f->c1,由于此时未构成override,因此f.print依然调用父类的print函数,而c2指向了c1,此时指向c1中的变量

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值