sv面向对象:类

写在前面:开始修炼

类是通过代码怎么体现?

实例1:定义一个类

//systemverilog绿皮书
//例5.1简单的 Transaction类
class Transaction;
    bit [31: 0] addr, crc, data[8];//class properities

    function void display;         //class method
        $display("Transaction: %h", addr) ;
    endfunction: display

    function void calc_crc:
        crc=addr^data. xor;
    endfunction: calc_crc
endclass: Transaction
  • 类封装了数据和对数据的操作(定义一个类就体现了类的封装性
  • 类中的数据称为属性( properties)
  • 类中对数据的操作子程序称为方法( methods) 

实例2:创建新的对象

Transaction b;// 声明一个句柄b
b=new();       //调用new()函数创建一个对象
  •  声明一个句柄b。

该句柄描指向一个 Transaction 类型的对象。当声明一个句柄时,它的初始值为null

  • 调用new()函数创建一个对象。new()函数就是构造函数,创建对象空间

调用new函数时,系统会分配一块内存空间,用于存储对对象中得变量。

  1. new函数分配内存空间,存放Transaction的实例
  2. 将实例中的变量值初始化,默认情况下,二值逻辑变量初始值为0,四值逻辑变量的初始值位x
  3. 返回存放实例的地址(指针pointer)

 实例总结:

实例1和实例2组合起来就满足了类的基本特征

因此,使用一个类就包括三步:定义一个类、声明一个句柄、创建一个对象

而实例中包括一些基本概念,看下面描述。

面向对象的基本概念

  • 类 class

◆编码元素,包含所有的属性和功能

◆将数据和对数据的操作封装在起 Encapsulates

◆提供建立对象的模板

◆可以看做一种数据结构

  • 对象 Object

◆对象 object是类class的实体

  • 句柄 Handle

◆类型安全的指向对象( object)的指针( pointer)

  • 属性 Properties

◆类( class)的实体( object)中包含的各种变量( variables)

  • 方法 Methods

◆操作变量的任务(task)和函数( function)

面向对象编程的基本术语

面向对象编程的优势

  • 传统的编程:分开处理数据结构和算法
  • 面向对象编程:通过封装的方式对数据进行组织和管理

◆类( class)封装了数据和对数据的处理算法

◆对象( object)是一个类的实例

◆类( class)是有成员( members)组成的

◆成员( members)可以是属性( properties)(数据或者变量)或者方法( methods)(任务task或函数 function)

  • OOP具有继承的特性-允许对已经存在的类的成员进行扩展
  • OOP具有多态的特性一在运行时将数据和函数进行绑定 

类中的一些常识:

  • 释放句柄指向的对象的内存空间

◆如果没有句柄指向个对象, Systemverilog将释放该对象的内存空间

◆当句柄指向一个对象时, SystemVerilog不会释放该对象的内存空间

◆将句柄设置为null,将手动释放所有的句柄

  • 重新new()一下,就会重新开辟内存空间

  • 在一个类中可以使用另外一个类(多层嵌套)

  • 使用层次化语法hierarchical

句柄的使用

shallow copy浅复制(指向同一个内存空间 )

获得对象的句柄

◆类的属性和实例化对象可以在类声明时直接被初始化
浅复制不会复制嵌套的对象(只是复制了句柄)
◆可以通过点号“.”操作符对对象中的变量进行操作,比如b1.aj
◆可以通过手动编写代码实现对所有变量的全复制,包括嵌套的对象

Transaction b1,b2;//声明两个句柄b1,b2
b1=new;            //给b1分配内存空间
b2=new;            //给b2分配内存空间
b2.copy(b1);       //深复制,其中一个改变,不会影响另外一个

好,我们讲这个句柄讲的挺多的了,我给大家看一个例子。(这就是E课网中的原话,就喜欢听这句话,路桑的全是蓝字,小白很0.0)

实例:class_t.sv

//class_t.sv
//E课网
program class_t;
	//Class with constructor,with no parameter
	class  A;
	integer j;
	//Constructor
	//Task in class(object method)
	endclass
	//Class with constructor,with no parameter
	class  B;
		integer i;
		A a=new;
		//Constructor
		//Task in class(object method)
		function copy(B in);
			this.i=in.i;    //父类B中的i
			this.a.j=in.a.j;//父类B中父类A中的j
		endfunction
	endclass
	
	initial begin
		B b1 = new;
		B b2 = new;
		b2 = b1;//shallow copy
		//b2.copy(b1);//deep copy
		b2.a.j=50;
		$display("b2.a.j=%0d\nb1.a.j=%0d",b2.a.j,b1.a.j);
	end
endprogram
运行shallow copy的仿真结果:b2.a.j=50,b1.a.j=50

运行deep copy的仿真结果:   b2.a.j=50, b1.a.j=x

静态变量

Systemverilog中允许在类中声明一个静态变量

  • 静态变量跟类的定义相关,跟实例对象无关
  • 静态变量用于存储可变数据,如创建的实例的数量
  • 静态变量被类的所有对象共享

oop:继承inheritance

  • 在原有的类的基础上增加新功能
  • 单一继承:修改一个类的当前功能

◆在派生类中使用关键字" super"可以引用基类中的成员

◆如果在派生类中修改了基类中的成员,这必须使用关键字" 'super'获取基类的相关成员

实例:class_extend_example. sv

//systemverilog与功能验证(钟文枫)
//Chapter7 class_extend_example. sv
class Packet;
	//属性
	integer status;
	
	//方法
	task rst();
		status =0
	endtask
endcalass

Class DerivedPacket extends Packet;
	//属性
	integer a,b, c;
	/方法
	task showstatus ();
		$display(status);
	endtask
endclass

数据保护:本地变量 local


派生类不能操作基类中的本地变量(local)

 

 

抽象类和虚方法

oop:多态与虚方法直接关系

多态总结:实方法看句柄 ;虚方法看对象

实例:virtual_method.sv

//virtual_method.sv
//E课网
class A;
	virtual task disp();
		$display("This is class A");
	endtask
endclass

class EA extends A;
	task disp();
		$display("This is Extended class A");
	endtask
endclass

program main;
	EA my_ea;//声明一个EA句柄my_ea;
	A my_a;  //声明一个A 句柄my_a;

	initial begin
		my_a = new;//给my_a创建一个对象
		my_a.disp();//调用my_a的task
		
		my_ea = new;//给my_ea创建一个对象
		my_a=my_ea;//浅复制,句柄改变
		my_a.disp();//调用my_ea的task
	end
endprogram

仿真结果如下: 

This is class A
This is Extended class A
这是虚方法,因此只看对象

实例:basic_method.sv 

//basic_method.sv
//E课网
class A;
	task disp();
		$display("This is class A");
	endtask
endclass

class EA extends A;
	task disp();
		$display("This is Extended class A");
	endtask
endclass

program main;
	EA my_ea;//声明一个EA句柄my_ea;
	A my_a;  //声明一个A 句柄my_a;

	initial begin
		my_a = new;//给my_a创建一个对象
		my_a.disp();//调用my_a的task
		
		my_ea = new;//给my_ea创建一个对象
		my_a=my_ea;//浅复制,句柄改变
		my_a.disp();//调用my_ea的task
	end
endprogram

仿真结果如下: 

This is class A
This is class A

实例:class_extern_methods.sv(这些宏?)

//class_extern_methods.sv
//E课网
`ifndef CLASS_EXTERN_SV
`define CLASS_EXTERN_SV

`include "class_extern.sv"

function class_extern::new();
	this.address=$random;
	this.data ={$random, $random};
	this.crc =$random;
endfunction

task class_extern::print();
	$display("Address : %x", address);
	$display("Data    : %x", data);
	$display("CRC     : %x", crc);
endtask
`endif

//class_extern.sv
//E课网
`ifndef CLASS_EXTERN_SVI
`define CLASS_EXTERN_SVI
class class_extern;
	int address;
	bit [63:0] data;
	shortint crc;
	
	extern function new();
	extern task print();
endclass
`endif
仿真结果:b2.a.j=50,b1.a.j=x
 

参数化类​  

通用的类是很有用的,特别是在例化的时候可以修改数组的大小和数据类型。为了避免为每个特定的类编写类似的代码, SystemVerilog也支持参数化类,就如C++中的模板。

写到最后:好好修炼

  • 4
    点赞
  • 69
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

杰之行

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值