• SystemVerilog——class类


    2. 类的定义

            在SystemVerilog中,class也是一种类型(type),可以把类定义在program、module、package中,或者在这些块之外的任何地方定义。类可以在程序或者模块中使用。

            类可以被声明成一个参数(方向可以是input、output、inout或者ref),此时被拷贝的是这个对象的句柄,而不是这个对象的内容

    1. class Packet;
    2. //data or class properties
    3. bit [3:0] command;
    4. bit [40:0] address;
    5. bit [4:0] master_id;
    6. integer time_requested;
    7. integer time_issued;
    8. integer status;
    9. typedef enum { ERR_OVERFLOW= 10, ERR_UNDERFLOW = 1123} PCKT_TYPE;
    10. const integer buffer_size = 100;
    11. const integer header_size;
    12. // initialization
    13. function new();
    14. command = 4'd0;
    15. address = 41'b0;
    16. master_id = 5'bx;
    17. header_size = 10;
    18. endfunction
    19. // methods
    20. // public access entry points
    21. task clean();
    22. command = 0;
    23. address = 0;
    24. master_id = 5'bx;
    25. endtask
    26. task issue_request( int delay );
    27. // send request to bus
    28. endtask
    29. function integer current_status();
    30. current_status = status;
    31. endfunction
    32. endclass

    注:未初始化对象句柄的默认值为null,可以通过比较对象句柄是否等于null来判断对象是否被初始化。

    3.类作用域操作符::

            可以通过类作用域操作符::用类名去访问类中定义的属性,它的语法为:

    1. class_type::{class_type:: } identifier
    2. 其中class_type可以是以下几种类型
    3. class类型名字;
    4. package类型名字;
    5. typedef名字;
    6. covergroup类型名字;
    7. coverpoint名字;
    8. cross名字;
    9. 类型参数。
    10. 注:在SystemVerilog中,类作用域操作符::可以应用到类所有的静态(static)成员(属性和方法)、typedef、枚举、参数、local参数、约束、结构体、unions以及嵌套类上。
    1. class Base;
    2. typedef enum {bin,oct,dec,hex} radix;
    3. static task print( radix r, integer n );
    4. $display("r == %0d,n == %0d",r,n);
    5. endtask
    6. endclass
    7. Base b = new();
    8. int bin = 123;
    9. b.print(Base::bin, bin); // Base::bin and bin are different
    10. Base::print(Base::hex, 66);
    11. // 类作用域操作符::应用到嵌套类上
    12. class StringList;
    13. class Node; // Nested class for a node in a linked list.
    14. string name;
    15. Node link;
    16. endclass
    17. endclass
    18. class StringTree;
    19. class Node; // Nested class for a node in a binary tree.
    20. string name;
    21. Node left, right;
    22. endclass
    23. endclass
    24. // StringList::Node is different from StringTree::Node

    注:StringList::Node不同于StringTree::Node。
    类作用域操作符支持以下操作

    1. 从类层次结构之外访问类的静态公共成员(methods和类属性);
    2. 从派生类里面访问父类的publicprotected成员;
    3. 从次结构之外或者派类外层生类里面访问在类中声明的约束块、type声明以及枚举常量;
    4. 从类外层次结构之外或者派生类里面访问在类中声明参数或者local参数。

            嵌套类可以访问包含类中的local和protected成员。嵌套类不能隐式访问包含类中的non-static方法和属性。包含类的静态成员,嵌套类可以直接访问,也可以通过::访问

    1. class Outer;
    2. int outerProp;
    3. local int outerLocalProp;
    4. static int outerStaticProp;
    5. static local int outerLocalStaticProp;
    6. class Inner;
    7. function void innerMethod(Outer h);
    8. outerStaticProp = 0;//Legal, same as Outer::outerStaticProp
    9. outerLocalStaticProp = 0;//Legal, nested classes may access local's in outer class
    10. outerProp = 0;//Illegal, Nested class can't implicit access to non-static outer
    11. h.outerProp = 0;//Legal, qualified access.
    12. h.outerLocalProp = 0;//Legal, qualified access and locals to outer class allowed.
    13. endfunction
    14. endclass
    15. endclass

    4. 参数化类

            参数化类声明例化对象时可以设置不同的数组大小或者数据类型(type)。参数化类的参数可以是一个变量、也可以是type关键词定义的数据类型

    1. class vector #(int size = 1);//参数是一个变量
    2. bit [size-1:0] a;
    3. endclass
    4. vector #(10) vten; // object with vector of size 10
    5. vector #(.size(2)) vtwo; // object with vector of size 2
    6. typedef vector#(4) Vfour; // Class with vector of size 4
    7. class stack #(type T = int);//参数是一个数据类型
    8. local T items[];
    9. task push( T a ); ... endtask
    10. task pop( ref T a ); ... endtask
    11. endclass
    12. stack is; // default: a stack of ints
    13. stack#(bit[1:10]) bs; // a stack of 10-bit vector
    14. stack#(real) rs; // a stack of real numbers

    注:任何类型(type)都可以作为一个参数,包括user定义的class或者struct等类型(type)。

    • 一个参数化类可以被扩展成其他参数化累,例如:
       
      1. class C #(type T = bit); ... endclass // base class
      2. class D1 #(type P = real) extends C; // T is bit (the default)
      3. class D2 #(type P = real) extends C #(integer); // T is integer
      4. class D3 #(type P = real) extends C #(P); // T is P
      5. class D4 #(type P = C#(real)) extends P; // for default T is real

      4.1 参数化类中类作用域操作符的使用

    • 当缺省参数化类作为类解析操作符前缀时,应该显式的使用#()。例如
       
      1. class C #(int p = 1);
      2. parameter int q = 5; // local parameter
      3. static task t;
      4. int p;
      5. int x = C::p; // C::p disambiguates p
      6. // C::p is not p in the default specialization
      7. endtask
      8. endclass
      9. int x = C::p; // illegal; C:: is not permitted in this context
      10. int y = C#()::p; // legal; refers to parameter p in the default specialization of C
      11. typedef C T; // T is a default specialization, not an alias to the name "C"
      12. int z = T::p; // legal; T::p refers to p in the default specialization
      13. int v = C#(3)::p; // legal; parameter p in the specialization of C#(3)
      14. int w = C#()::q; // legal; refers to the local parameter
      15. T obj = new();
      16. int u = obj.q; // legal; refers to the local parameter
      17. bit arr[obj.q]; // illegal: local parameter is not a constant expression
      参数化类使用extern关键在在类外声明方法。
      1. class C #(int p = 1, type T = int);
      2. extern static function T f();
      3. endclass
      4. function C::T C::f();
      5. return p + C::p;
      6. endfunction
      7. initial $display(“%0d %0d”, C#()::f(),C#(5)::f()); // output is "2 10"

      5. Typedef class

              有时候我们需要在class自身被定义之前去声明一个这个class的变量,例如两个类彼此需要对方的对象句柄

      1. typedef class C2; // C2 is declared to be of type class
      2. class C1;
      3. C2 c;
      4. endclass
      5. class C2;
      6. C1 c;
      7. endclass

      注:typedef  class C2中class关键词可以省略,即typedef  C2。

      //forward class的声明和实际class的定义应该在同一个scope中,而且forward class的声明不用看实际class是否为参数化类。

  • 相关阅读:
    C++ 静态和运行时断言 assert, static_assert和 throw runtime_error
    文举论金:9.13黄金原油全面走势分析策略指导。
    Pytorch中DataLoader的collate_fn()参数学习笔记
    Android网络请求(4) 网络请求框架Volley
    Bootstrap学习从一个模板开始
    Python3高级特性(五)之容器(container)
    当遇到第一个不满足条件的元素后返回这个元素及之后的各元素itertools.dropwhile()
    【Java面试】为什么引入偏向锁、轻量级锁,介绍下升级流程
    Prometheus(三)node-exporter
    父域 Cookie实现sso单点登录
  • 原文地址:https://blog.csdn.net/qq_33300585/article/details/132863715