systemverilog学习 --- casting and local protected

casting

在systemverilog中,casting意味着把一种数据类型转化为另一种数据类型。在一个变量赋值时,需要左右两边的值是一样的数据类型。在一些情况下,我们需要为不用数据类型的变量赋值,此时就需要类型转换,否则编译器会报错。在systemverilog中有两种类型的数据转换:

  • 静态的casting

  • 动态的casting
    静态转换具有如下特点:

  • 静态转换不适合面向对象编程

  • 将一种数据类型转换为另一种数据类型(如string转化为int)

  • 静态也意味着转换的数据类型是固定的

  • 会在编译的时候检查是否可行

  • 形式上我们可以使用单引号(')表示类型转换,转换对象要用圆括号包起来。
    如下面的例子所示:

module  casting;
    real    r_a     ;
    int     i_a     ;

    initial begin
        r_a = (2.1 * 3.2);

        //real to integer conversion
        i_a = int'(2.1 * 3.2);      // or i_a = int'(r_a)

        $display("real value is %f", r_a);
        $display("int value is %d", i_a);
    end
endmodule

其输出结果是:
在这里插入图片描述
由此看出当把real类型数据转化为Int类型数据时,会进行四舍五入。
动态转换具有如下特点:

  1. 动态转换可以安全的将父类指针转化为子类指针(在一个类的体系结构中)
  2. 动态转换是在跑的时间中检查是否有错误的,当转换不成功的时候会在运行时报错。
  3. 动态转换的转换形式:$cast(destination, source)

在继承树中,我们把一个孩子类的变量赋值给父类变量是合理的。

paraent_class = child_class;  // allowed

但是若把一个父类的变量赋值给一个子类的变量是不被允许的。如下所示:

child_class = parent_class;  //not allowed

据如下例子:

class  parent_class;
    bit [31:0]  addr;
    function display();
        $display("Addr = %0d", addr);
    endfunction
endclass

class child_class extends parent_class;
    bit [31:0]  data;
    function display();
        super.display();
        $display("Data = %0d", data);
    endfunction
endclass

module inheritence;
    initial begin
        parent_class p = new();
        child_class c = new();
        c.addr = 10;
        c.data = 20;
        p = c;          // assigning child class handle to parent class handle
        c.display();
    end
endmodule

其输出结果是:
在这里插入图片描述
做如下修改,把父类的句柄赋值子类的句柄。
在这里插入图片描述
编译器会报如下的错误:
在这里插入图片描述
做如下修改,创建一个子类的句柄c1。

在这里插入图片描述
但是编译器仍然会报错:
在这里插入图片描述
做如下改动,可以实现父类的句柄转化为子类的句柄。
在这里插入图片描述
其输出结果是:
在这里插入图片描述

data hiding and encapsulation

在systemverilog中,我们想隐藏类中一些数据,这些数据只可以通过一些方法才可以被访问到。这种技术就叫做封装。因为它把一些数据隐藏一起,只可以被信得过的使用者(类中定义的方法)才可以访问。
这种实现方式就是通过对访问权限的控制。默认的情况下,任何都可以同时这个对象的句柄来访问类中的成员和方法,但是在一些情况下,这会危害类中成员的值。类中成员的权限是通过在类成员名字的前面加图两个关键字:local和protected
本地类成员不允许在类外访问成员变量,也就是要通过类的方法才可以访问到,任何的违例都会导致编译器报错。其声明形式如下:

local integer x;

如下的例子所示:
在这里插入图片描述
从而会导致编译器报错:
在这里插入图片描述
确实需要修改tmp_addr值时,new方法可以传递参数,但只在创建对象时执行一次。需要再修改,我们就需要定义新的方法用于给tmp_addr设置值。
我们再来保护类型成员,在某些用例中,只需要通过派生类访问类成员,这可以通过在类成员前面加上 protected 关键字来完成。即子类可以在类外访问protected类型变量,而其它类却是不可以的。

class parent_class;
    protected bit [31:0]    tmp_addr;

    function new(bit [31:0] r_addr);
        tmp_addr = r_addr + 10;
    endfunction

    function display();
        $display("tmp_addr = %0d", tmp_addr);
    endfunction
endclass

class child_class extends parent_class;
    function new(bit [31:0] r_addr);
        super.new(r_addr);
    endfunction

    function void incr_addr();
        tmp_addr++;
    endfunction
endclass

//module
module encapsulation;
    initial begin
        parent_class p_c = new(5);
        child_class c_c = new(10);

        //varible declared as protected cannot be accessed outside the class
        p_c.tmp_addr = 10;
        p_c.display();

        c_c.incr_addr();  // Accessing protected varible in extended class
        c_c.display();
    end

endmodule

在编译器报错如下:
在这里插入图片描述
注释掉下面这一句:
在这里插入图片描述
结果是:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值