• systemverilog学习 --- 代码重用


    参数化类 (parameterized class)

    systemverilog也支持参数化的类。看下面的实例:

    //---- class ----
    class packet #(parameter int ADDR_WIDTH = 32,DATA_WIDTH = 32);
      bit [ADDR_WIDTH-1:0] address;
      bit [DATA_WIDTH-1:0] data   ;
     
      function new();
        address = 10;
        data    = 20;
      endfunction
    endclass
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    packet pkt;此时声明了一个pkt句柄,其中参数为默认值,即ADDR_WIDTH = 32, DATA_WIDTH= 32。我们可以在这个类被实例化的时候修改默认的参数值。如:packet #(32,64) pkt.

    systemVerilog还支持将变量类型进行参数化,在下面的例子中,使用type表示参数化。

    class packet #(parameter type T = int);
      T address;
      T data   ;
     
      function new();
        address = 10;
        data    = 20;
      endfunction
    endclass
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    packet pkt.表明address 和 data的类型都是Int类型。packet #(bit [31:0] )pkt.表明address 和 data的类型都是bit [31:0]。

    继承

    继承是一个oop概念,它允许基于一个已经存在的类来创建类。这个新的类有新的特性和方法,但是同时它也可以访问原本类的特性和方法。继承就是继承基类成员衍生到新类中,
    在这里插入图片描述
    既然是继承,谁继承谁,要做区分。被继承者叫基类base,或者父类parent,继承者叫拓展类extended,或者子类subclass。拓展类基于存在的类创建,会继承基类所有的属性和方法,即基类有的,拓展类都有,但拓展类可能会有基类没有的新成员。

    class  parent_class;
    
    bit     [31:0]  addr;
    
    endclass
    
    class child_class extends parent_class;
    bit     [31:0]  data;
    endclass
    
    module inheritence;
        initial begin
            child_class c = new();
            c.addr = 10;
            c.data = 20;
            $display("Value of addr = %0d data = %0d", c.addr, c.data);
        end
    endmodule
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    其输出结果是:
    在这里插入图片描述

    多态

    多态意味着多种形式,在systemverilog中的多态意味一个对象可以展现多种形式。
    在这里插入图片描述
    基类中有方法display,每个子类都定义了自己的display方法。一般,我们父类并不会用它的display方法,更多的是设置为接口,提供api方便调用,具体的实现由子类自己决定。见下面的代码,父类display方法设为虚方法virtual,表示子类可以覆盖掉父类的方法,读写可以尝试删除virtual关键词,体会virtual的效果。然后分别创建了三个子类对象,并把子类对象赋值给父类,然后用父类句柄访问display。如下面的例子所示:

    // base class
    class base_class;
        virtual function void display();
            $display("Inside base class");
        endfunction
    endclass
    
    //extended class 1
    class ext_class_1 extends base_class;
        function void display();
            $display("Inside extended class 1");
        endfunction
    endclass
    
    //extended class 2
    class ext_class_2 extends base_class;
        function void display();
            $display("Inside extended class 2");
        endfunction
    endclass
    
    //extended class 3
    class ext_class_3 extends base_class;
        function void display();
            $display("Inside extended class 3");
        endfunction
    endclass
    
    module class_polymorphism;
        initial begin
            //declare and create extended class
            ext_class_1 ec_1 = new();
            ext_class_2 ec_2 = new();
            ext_class_3 ec_3 = new();
    
            //base class handle
            base_class b_c[3];
    
            //assigning extended class to base class
            b_c[0] = ec_1;
            b_c[1] = ec_2;
            b_c[2] = ec_3;
    
            //accessing extended class methods using base class handle
            b_c[0].display();
            b_c[1].display();
            b_c[2].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
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49

    其输出结果是:
    在这里插入图片描述

    Overrinding class members

    基类或者父类中的性质和方法可能会在子类或者拓展类中被重写,因此此时就存在以谁为准的问题。具体见下面的一个实例:

    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();
            $display("Data = %0d", data);
        endfunction
    endclass
    
    module inheritence;
        initial begin
            child_class c = new();
            c.addr = 10;
            c.data = 20;
            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

    其输出结果是:
    在这里插入图片描述
    当子类对象调用display方法时,会调用自己定义的方法,即打印data。可以理解为,调用方法遵循就近原则,当成员自己没有的时候,才会去父类寻找。

    super

    super主要用来是子类访问父类中的成员。如果在子类中一些成员被重写,那么就需要使用super来访问父类中的成员。super关键词,和this一样,内建句柄用于访问父类成员,但仅仅是上一级父类的成员。还是4的代码示例,在子类display方法增加语句。
    在这里插入图片描述
    在上一个例子中添加如下语句:
    在这里插入图片描述
    其输出结果是:
    在这里插入图片描述

  • 相关阅读:
    如何通过GDB分析Native Crash
    运放电压跟随器为什么要加电阻
    可视化—gojs 超多超实用经验分享(一)
    Bootstrap Blazor Table 组件(二)手动刷新组件数据
    【微信小程序入门到精通】— AppID和个性配置你学会了么?
    每天一个数据分析题(三百九十二)- 多元线性回归
    基于SSM的旅游网站系统
    es如何聚合查询同一字段文档数大于1的文档
    推荐5个神仙软件,个个让你爱不释手
    使用位运算实现加减乘除(+、-、*、/)及比较器的用法
  • 原文地址:https://blog.csdn.net/weixin_45614076/article/details/126278998