• 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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

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

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

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

    paraent_class = child_class;  // allowed
    
    • 1

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

    child_class = parent_class;  //not allowed
    
    • 1

    据如下例子:

    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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

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

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

    data hiding and encapsulation

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

    local integer x;
    
    • 1

    如下的例子所示:
    在这里插入图片描述
    从而会导致编译器报错:
    在这里插入图片描述
    确实需要修改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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

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

  • 相关阅读:
    Boost升压电路调试
    C++ :变量声明、定义【一个变量“声明”必须满足两个条件, 否则就是定义:①必须使用 extern;②不能为变量赋予初始值;】
    gitlab Blocking and unblocking users
    基于.Net开发的ChatGPT客户端,兼容Windows、IOS、安卓、MacOS、Linux
    A. Marathon
    git 本地分支基础操作
    【数据结构与算法】之“堆”介绍
    Linux 目录结构介绍
    console对象与控制台
    【漏洞复现】WordPress插件wp-file-manager任意文件上传漏洞(CVE-2020-25213)
  • 原文地址:https://blog.csdn.net/weixin_45614076/article/details/126292375