SV_10_面向对象编程(OOP)的类

目录

1. 对象

2. 对象成员

3. 对象方法

4. 构造函数

5. 静态类成员

6. 常量类成员

7. 赋值

8. 继承和子类

9. super关键字调用

10. 数据隐藏和封装(encapsulation)

11. 虚拟类

12. 多模块分写(Out-of-block)


摘要:SV引入了面向对象的类数据;类允许通过对象句柄动态地创建、删除、赋值和访问对象,类提供了继承和抽象类建模,从而为对象带来了多态性。

  • Objects
  • Object members
  • Constructors
  • Static class members
  • Assignments
  • Inheritance and subclasses
  • this and super
  • Data hiding and encapsulation
  • Constant class properties
  • Abstract classes and virtual methods
  • Class scope resolution operator ::
  • Parameterized classes

1. 对象

  一个类定义了一个数据类型,对象是该类的一个实例,使用对象时,首先声明该类类型的变量(包含对象句柄),然后创建该类的对象(使用new函数),并将其赋值给句柄;

1 class A;
2 A a;
3 a = new();

2. 对象成员

  对象的数据字段可以用实例名来限定类属性名。因此,对象内的任何数据字段都称为对象成员

3. 对象方法

  对象方法是对对象成员进行操作以完成一些有意义的完整功能的函数和任务。他们是对对象成员的访问。

 1 program class_t;
 2   class packet;
 3      // members in class
 4      integer size;
 5      integer payload [];
 6      integer i;
 7      // Constructor
 8      function new (integer size);
 9        begin
10          this.size = size;
11          payload = new[size];
12          for (i=0; i < this.size; i ++) begin
13            payload[i] = $random;
14          end
15        end
16      endfunction
17      // Task in class (object method)
18      task print ();
19        begin
20          $write("Payload : ");
21          for (i=0; i < size; i ++) begin
22            $write("%x ",payload[i]);
23          end
24          $write("\n");
25        end
26      endtask
27      // Function in class (object method)
28      function integer get_size();
29        begin
30          get_size = this.size;
31        end
32      endfunction
33    endclass
34 
35    packet pkt;
36 
37    initial begin
38      pkt = new(5);
39      pkt.print();
40      $display ("Size of packet %0d",pkt.get_size());
41    end
42 
43 endprogram
44 
45 //compile result
46  Payload : 12153524 c0895e81 8484d609 b1f05663 06b97b0d
47  Size of packet 5
View Code

4. 构造函数

  • 构造函数使用关键字new实现;
  • 构造函数不返回值;
  • 构造函数可以接收参数;
  • 每个类只允许有一个构造函数。
 1 `define PRINT task print (); \
 2           begin \
 3             $write("Size is %0d\n",this.size); \
 4           end \
 5        endtask
 6 
 7 program class_t;
 8   // Class with constructor, with no parameter
 9   class A;
10      integer size;
11      // Constructor
12      function new ();
13        begin
14          this.size = 0;
15        end
16      endfunction
17      // Task in class (object method)
18      `PRINT
19    endclass
20   // Class with constructor, with parameter
21   class B;
22      integer size;
23      // Constructor
24      function new (integer size);
25        begin
26          this.size = size;
27        end
28      endfunction
29      // Task in class (object method)
30      `PRINT
31    endclass
32 
33    // Class without constructor
34    class C;
35      integer size;
36      task set_size(integer size);
37        begin
38          this.size = size;
39        end
40      endtask
41      // Task in class (object method)
42      `PRINT
43    endclass
44 
45    A a;
46    B b;
47    C c;
48 
49    initial begin
50      a = new();
51      b = new(5);
52      c = new();
53      a.print();
54      b.print();
55      c.print();
56    end
57 
58 endprogram
59 
60 //compile result
61  Size is 0
62  Size is 5
63  Size is x
View Code

5. 静态类成员

静态类的成员在所有实例中享有相同的值,对改变的反应也是相同的.

 1 `define PRINT task print (); \
 2   begin \
 3     $write("%s -> Size is %0d\n",this.name, this.size); \
 4  end \
 5 endtask
 6 
 7 program class_static;
 8   // Class with constructor, with no parameter
 9   class A;
10      // Make size as static
11      static integer size;
12      string name;
13      // Constructor
14      function new (string name);
15        begin
16          this.name = name;
17          this.size = 0;
18        end
19      endfunction
20      // Increment size task
21      task inc_size();
22        begin
23          this.size ++;
24          $write("%s -> size is incremented\n",this.name);
25        end
26      endtask
27      // Task in class (object method)
28      `PRINT
29    endclass
30 
31    A a,b,c;
32 
33    initial begin
34      a = new("A");
35      b = new("B");
36      c = new("C");
37      a.inc_size();
38      a.print();
39      b.print();
40      c.print();
41      c.inc_size();
42      a.print();
43      b.print();
44      c.print();
45    end
46 
47 endprogram
48 
49 //compile result
50 
51  A -> size is incremented
52  A -> Size is 1
53  B -> Size is 1
54  C -> Size is 1
55  C -> size is incremented
56  A -> Size is 2
57  B -> Size is 2
58  C -> Size is 2
View Code

6. 常量类成员

const声明的变量具有只读属性,不可写入;

  • 全局常量(global):只能在声明中进行赋值;
  • 实例常量(instance):声明中不赋值,但后续的赋值只能在类构造函数中执行一次
 1 `define PRINT task print (); \
 2    begin \
 3       $write("%s -> Size is %0d\n",this.name, this.Lsize); \
 4       $write("%s -> Size is %0d\n",this.name, this.Gsize); \
 5    end \
 6 endtask
 7 
 8 program class_constant;
 9   class A;
10      const integer Gsize = 64; // constant value
11      const integer Lsize;
12      string name;
13      // Constructor
14      function new (string name);
15        begin
16          this.name = name;
17          this.Lsize = 100; // only one assignment in new
18        end
19      endfunction
20      // This is not allowed
21      task modify();
22        begin
23          // This is wrong
24          //this.Lsize ++;
25          // This is wrong
26          //this.Gsize ++;
27        end
28      endtask
29 
30      `PRINT
31    endclass
32 
33    A a;
34 
35    initial begin
36      a = new("A");
37      a.print();
38    end
39 
40 endprogram
41 
42 //compile result
43 
44  A -> Size is 100
45  A -> Size is 64
View Code

7. 赋值

  • 对象之间的赋值与变量之间的赋值相同,且该种赋值是浅复制,不复制任何嵌套对象;
  • 为了进行完全的深赋值,需要构建copy任务;
 1 program class_copy;
 2 
 3   class A ;
 4     integer j = 5;
 5     task print();
 6       begin
 7         $display("j is %0d",j);
 8       end
 9     endtask
10   endclass
11 
12   class B ;
13     integer i = 1;
14     A a = new;
15     task print();
16       begin
17         $display("i is %0d",i);
18         a.print();
19       end
20     endtask
21     // custom deep copy task
22     task copy(ref B bb);
23       begin
24         bb = new this;
25         bb.a = new this.a;
26       end
27     endtask
28   endclass
29 
30   initial begin
31     B b1,b2,b3;
32     $display("Testing shallow copy");
33     b1 = new; // Create an object of class B
34     b1.print();
35     b2 = new b1; // Create an object that is a copy of b1
36     b2.print();
37     b2.i = 10; // i is changed in b2, but not in b1
38     b2.a.j = 50; // change a.j, shared by both b1 and b2
39     b2.print();
40     b1.print(); // Updated due to shallow copy
41     // Now do a deep copy
42     $display("Testing deep copy");
43     b1.copy(b3) ; // Create an object that is a deep copy of b1
44     b3.print();
45     b3.i = 100; // i is changed in b3, but not in b1
46     b3.a.j = 500;// j is changes in b3, but not in b1
47     b3.print();
48     // i and J should not change due to deep copy
49     b1.print();
50   end
51 
52 endprogram
53 
54 //compile result
55  Testing shallow copy
56  i is 1
57  j is 5
58  i is 1
59  j is 5
60  i is 10
61  j is 50
62  i is 1
63  j is 50
64  Testing deep copy
65  i is 1
66  j is 50
67  i is 100
68  j is 500
69  i is 1
70  j is 50
View Code

8. 继承和子类

  • 继承:SV的OOP可以实现从基类中继承并在子类中扩展其功能的能力;
  • 类的继承不会改变类定义,但新的子类可以包含基类的所有属性和方法;
  • 继承实现的类可以选择性地添加额外的属性和方法。
  • 基类被继承的方法可以在子类中被重写;
 1 program class_inherit;
 2 
 3   class A ;
 4     integer j = 5;
 5     task print();
 6       begin
 7         $display("j is %0d",j);
 8       end
 9     endtask
10   endclass
11 
12   class B extends A;
13     integer i = 1;
14     // Override the parent class print
15     task print();
16       begin
17         $display("i is %0d",i);
18         $display("j is %0d",j);
19       end
20     endtask
21   endclass
22 
23   initial begin
24     B b1;
25     b1 = new;
26     b1.print();
27   end
28 
29 endprogram
30 
31 //compile result
32 
33  i is 1
34  j is 5
View Code

9. super关键字调用

  • super关键字可以用来在派生类调用父类的属性;
  • 当父类的属性已被重写,且不能直接访问时,有必要使用super。
 1 program class_super;
 2 
 3   class A ;
 4     integer j;
 5     function new();
 6       begin
 7         j = 10;
 8       end
 9     endfunction
10     task print();
11       begin
12         $display("j is %0d",j);
13       end
14     endtask
15   endclass
16 
17   class B extends A;
18     integer i = 1;
19     function new();
20       begin
21         // call the parent new
22         super.new(); // constructor chaining
23         $display("Done calling the parent new");
24         i = 100;
25       end
26     endfunction
27     // Override the parent class print
28     task print();
29       begin
30         $display("i is %0d",i);
31         $display("Call the parent print");
32         super.print();
33       end
34     endtask
35   endclass
36 
37   initial begin
38     B b1;
39     b1 = new;
40     b1.print();
41   end
42 
43 endprogram
44 
45 //compile result
46 
47  Done calling the parent new
48  i is 100
49  Call the parent print
50  j is 10
View Code

10. 数据隐藏和封装(encapsulation)

  • 默认情况下,类的所有方法和成员都可以用句柄从类外访问;
  • 如果想限制访问,可以将变量声明为local,protected;

local:父类可见,子类和外部不可见;

protected:父类,子类可见,外部不可见;

static:父类,子类,外部可见。

 1 program class_data_hiding;
 2   class A;
 3     integer data;
 4     local   integer addr;
 5     protected integer cmd;
 6     static integer credits;
 7     function new();
 8       begin
 9         data = 100;
10         addr = 200;
11         cmd  = 1;
12         credits = 10;
13       end
14     endfunction
15     task printA();
16       begin
17         $write ("value of data %0d in A\n", data);
18         $write ("value of addr %0d in A\n", addr);
19         $write ("value of cmd  %0d in A\n", cmd);
20       end
21     endtask
22   endclass
23 
24   class B extends A;
25     task printB();
26       begin
27         $write ("value of data %0d in B\n", data);
28         // Below line will give compile error
29         //$write ("value of addr %0d in B\n", addr);
30         $write ("value of cmd  %0d in B\n", cmd);
31       end
32     endtask
33   endclass
34 
35   class C;
36     A a;
37     B b;
38     function new();
39       begin
40         a = new();
41         b = new();
42         b.data = 2;
43       end
44     endfunction
45     task printC();
46       begin
47         $write ("value of data %0d in C\n", a.data);
48         $write ("value of data %0d in C\n", b.data);
49         // Below line will give compile error
50         //$write ("value of addr %0d in C\n", a.addr);
51         //$write ("value of cmd  %0d in C\n", a.cmd);
52         //$write ("value of addr %0d in C\n", b.addr);
53         //$write ("value of cmd  %0d in C\n", b.cmd);
54       end
55     endtask
56   endclass
57 
58   initial begin
59     C c = new();
60     c.a.printA();
61     c.b.printB();
62     c.printC();
63     $write("value of credits is %0d\n",c.a.credits);
64     $write("value of credits is %0d\n",c.b.credits);
65     c.a.credits ++;
66     $write("value of credits is %0d\n",c.a.credits);
67     $write("value of credits is %0d\n",c.b.credits);
68     c.b.credits ++;
69     $write("value of credits is %0d\n",c.a.credits);
70     $write("value of credits is %0d\n",c.b.credits);
71   end
72 
73 endprogram
74 
75 //compile result
76 
77  value of data 100 in A
78  value of addr 200 in A
79  value of cmd  1 in A
80  value of data 2 in B
81  value of cmd  1 in B
82  value of data 100 in C
83  value of data 2 in C
84  value of credits is 10
85  value of credits is 10
86  value of credits is 11
87  value of credits is 11
88  value of credits is 12
89  value of credits is 12
View Code

11. 虚拟类

  • 虚拟类包含虚方法;
    • 所有的信息通常在方法声明的第一行可以找到:封装标准、参数的类型和数量,以及非必要的返回类型;
    • 虚方法的所有版本(包括重写情况)对子类都是相同的。
  • 普通类也可以声明为虚方法;
    • 这种情况下的方法必须有实体;
  1 program class_virtual;
  2   // Virtual class for body of any driver
  3   virtual class verif;
  4     // This starts all the threads
  5     virtual task startSim();
  6     endtask
  7     // This stops all the threads
  8     virtual task stopSim();
  9     endtask
 10     // This prints all the stats
 11     virtual task printStats();
 12     endtask
 13     // This check if driver is done or not
 14     virtual function bit isDone ();
 15       begin
 16         isDone = 0;
 17       end
 18     endfunction
 19     // set the driver config
 20     virtual task setConfig(integer item, integer value);
 21     endtask
 22     virtual function integer getConfig(integer item);
 23       begin
 24         getConfig = 32'hDEAD_BEAF;
 25       end
 26     endfunction
 27   endclass
 28   // ethernet inherits verif
 29   class ethernet extends verif;
 30     integer min_frame_size;
 31     integer max_frame_size;
 32     function new();
 33       begin
 34         min_frame_size = 32'h40;
 35         max_frame_size = 32'h200;
 36       end
 37     endfunction
 38     task startSim();
 39       begin
 40         $write("Starting Simulation\n");
 41       end
 42     endtask
 43     task stopSim();
 44       begin
 45         $write("Stopping Simulation\n");
 46       end
 47     endtask
 48     task printStats();
 49       begin
 50         $write("Sent normal   frames %d\n",100);
 51         $write("Sent runt     frames %d\n",1);
 52         $write("Sent oversize frames %d\n",1);
 53       end
 54     endtask
 55     function bit isDone();
 56       begin
 57         isDone = 1;
 58       end
 59     endfunction
 60     task setConfig(integer item, integer value);
 61       begin
 62         case(item)
 63            0 : min_frame_size = value;
 64            1 : max_frame_size = value;
 65         endcase
 66       end
 67     endtask
 68     function integer getConfig(integer item);
 69       begin
 70         case(item) 
 71            0 : getConfig = min_frame_size;
 72            1 : getConfig = max_frame_size;
 73            default :  begin
 74                      $write("Calling super.setConfig\n");
 75                       getConfig  = super.getConfig(item);
 76            end
 77         endcase
 78        end
 79     endfunction
 80   endclass
 81   
 82   class ethernet2 extends ethernet;
 83     integer min_ipg;
 84     function new();
 85       begin
 86         min_ipg = 32'hc;
 87       end
 88     endfunction
 89     task setConfig(integer item, integer value);
 90       begin
 91         case(item) 
 92            2 : min_ipg = value;
 93            default : begin
 94                      $write("Calling super.setConfig\n");
 95                      super.setConfig(item,value);
 96            end
 97         endcase
 98       end
 99     endtask
100     function integer getConfig(integer item);
101       begin
102         case(item) 
103            2 : getConfig = min_ipg;
104            default :  begin
105                      $write("Calling super.setConfig\n");
106                       getConfig  = super.getConfig(item);
107                     end
108         endcase
109       end
110     endfunction
111   endclass
112  
113 
114   initial begin 
115     ethernet2 eth = new();
116     eth.setConfig(0,32'h100);
117     eth.setConfig(2,32'h24);
118     $write ("Value of min_frame is %0x\n", eth.getConfig(0));
119     $write ("Value of max_frame is %0x\n", eth.getConfig(1));
120     $write ("Value of min_ipg   is %0x\n", eth.getConfig(2));
121     $write ("Value of unknown   is %0x\n", eth.getConfig(3));
122   
123     eth.startSim();
124     while (eth.isDone() == 0) begin
125      #1;
126     end
127     eth.stopSim();
128     eth.printStats();
129   end
130 
131 endprogram
132 //compile result
133  Calling super.setConfig
134  Calling super.setConfig
135  Value of min_frame is 100
136  Calling super.setConfig
137  Value of max_frame is 200
138  Value of min_ipg   is 24
139  Calling super.setConfig
140  Calling super.setConfig
141  Value of unknown   is deadbeaf
142  Starting Simulation
143  Stopping Simulation
144  Sent normal   frames         100
145  Sent runt     frames           1
146  Sent oversize frames           1
View Code

12. 多模块分写(Out-of-block)

 多次引用,防止重复编译:`ifdef-`define-`endif

Header File

 1 `ifndef CLASS_EXTERN_SVI
 2 `define CLASS_EXTERN_SVI
 3 
 4 class class_extern;
 5   int address;
 6   bit [63:0] data;
 7   shortint crc;
 8 
 9   extern function new();
10   extern task print();
11 endclass
12 
13 
14 `endif
View Code Header File

Body File

 1 `ifndef CLASS_EXTERN_SV
 2 `define CLASS_EXTERN_SV
 3 
 4 `include "class_extern.svi"
 5 
 6 function class_extern::new();
 7   this.address = $random;
 8   this.data = {$random,$random};
 9   this.crc  = $random;
10 endfunction
11 
12 task class_extern::print();
13   $display("Address : %x",address);
14   $display("Data    : %x",data);
15   $display("CRC     : %x",crc);
16 endtask
17 
18 `endif
View Code Body File

Program File

 1 program class_exterm_prg;
 2 
 3  `include "class_extern.sv"
 4 
 5 class_extern c;
 6 
 7 initial begin
 8   c = new();
 9   c.print();
10   $finish;
11 end
12 
13 endprogram
View Code Program File
1 //compile result    
2  Address : 12153524
3  Data    : c0895e818484d609
4  CRC     : 5663
  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值