sv学习——OOP

面向过程和面向对象的区别?

面向过程:

就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候一个一个依次调用就可以了。

把大象装进冰箱需要几步?

按照面向过程思想:
第一步:工作人员去打开冰箱门
第二步:把大象塞进冰箱
第三步:工作人员把冰箱门关上
面向过程就是把一件事按步骤一步一步来实现
用代码表示

    public void openDoor(){}  //开门
    public void putIn(){}       //装冰箱
    public void closeDoor(){}   //关门

面向对象:

对象,就是对问题中的事物的抽象,面向对象就是把现实中的事物都抽象为“对象”。每个对象是唯一的,且都可以拥有它的属性与行为。我们就可以通过调用这些对象的方法、属性去解决问题。

例如在这个事件中:
冰箱作为一个对象;
大象作为一个对象。
冰箱有这些功能:开门、装物体、关门

class fridge{
    public void open(大象){}   //开门
    public void putIn(大象){}  //放进冰箱
    public void close(大象){}  //关门
}
class elephant{
	public void eat(){}   //吃
}

每个对象是独立的,有属于它自己的功能,只需要专心实现自己的功能就好。所以在建立对象模型阶段,仅仅关注对象有什么的功能,但不考虑如何实现这些功能。

如何理解OOP——面向对象编程?

OOP使用户能够创建复杂的数据类型,并且将它们跟使用这些数据类型的程序紧密的结合在一起,用户可以在更加抽象的层次建立测试平台和系统级模型。同时会提高代码的层次结构和复用性。

OOP的三大特性:封装、继承、多态

class和module的区别? 

class

module

变量在仿真的任何时刻可以构造或销毁模块从仿真开始就确定
变量默认都是动态的变量默认都是静态的
可以封装,继承,类里的变量默认是public类型,可以添加受保护类型(protected)和私有类型(local)模块不能封装和继承,模块内的变量是对公共开放的
类可以在module,interface,program,package中定义

编写第一个类

类封装了数据和操作这些数据的子程序,

创建新的对象

  • verilog中也有例化的概念,比如verilog中的一个模块,是代码被编译时例化的,verilog的例化是静态的,就像硬件在仿真时不会变化,只有信号值在改变。
  • sv中,例化是动态的,而且是在需要的时候才会被创建。产生的对象在使用过后,占用的内存会被释放,以供新的对象使用。

sv中的句柄

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

 Transaction是声明的类,tr是指向Transaction这个类的一个句柄。在声明句柄tr的时候,它被初始化为特殊值null,调用new()函数创建Transaction的一个对象,new()函数为Transaction分配空间,将变量初始化为默认值并返回保存对象的地址。

OOP术语

  • 类(class):包含变量和子程序的基本构建块。Verilog中与之对应的是模块(module)
  • 对象(object):类的一个实例,在Verilog中,需要实例化一个module才能使用
  • 句柄(handle):指向对象的指针,一个OOP句柄就像一个地址。但是它保存在一个只能指向单一数据类型的指针中。
  • 属性(property):类中定义的变量
  • 方法(method):任务或者函数中操作变量的程序性代码

个人的理解:类就像建造一个房子前画好的图纸,是一个没有实体的抽象概念,而句柄表示房子的地址,句柄指向了要建造的房子的位置,而使用new()函数表示开始在这个地址上建造图纸对应的房子。房子中的各种物品(冰箱,洗衣机,电灯)是类中定义的各种变量,类中定义的各种方法是对这些变量的操作。

自定义new函数

new()函数除了分配内存之外,它还初始化变量。在默认情况下,它将变量设置成默认数值,二值变量为0,四值变量为X。可以通过自定义new函数将默认值设成想要的数据。但是new函数不能有返回值,因为它总是返回一个指向类对象的句柄,其类型就是类本身。

new()是class中默认自带的,也可以自定义new()函数。

class Transaction;
    logic[31:0]addr,crc,data[8];
 
    function new(logic[31:0]a=3,d=5);
        addr=a;
        foreach(data[i])
            data[i]=d;
    endfunction
endclass

带有参数的new函数

class Transaction;
        logic [31:0] addr ='h10; 
        logic [31:0] crc, data[8] ;                //开辟空间;
        function new(logic [31:0] a=3, d=5);
            addr = a; 
            foreach (data[i])
                data[i]= d; 
        endfunction
endclass

 
initial begin 
        Transaction tr;                            //声明句柄
        tr = new(10);                             // data uses default of 5

end 

sv调用哪个new函数,与这个取决于赋值操作符左边的句柄类型,这个句柄指向哪个类就是用的哪个类的new函数

 new()和new[]的区别?

  • new()函数创建一个实例化的对象
  • new[]建立了一个动态数组

对象和句柄的区别?

句柄是类的指针,通过声明一个句柄创建一个对象,在一次仿真过程中,句柄可能指向很多个对象。

 ​​​​​​

 静态变量

在sv中,可以在类中创建一个静态变量,该变量将被这个类的所有实例所共享,并且它的使用范围仅限于这个类。

 count变量在声明时加了static关键字,表示为静态变量,用来保存创建的对象的数目。t1,t2是Transaction这个类的两个句柄。不管创建了多少个对象,静态变量count只存在一个。可以认为静态变量count保存在类中而非对象中。

变量id不是静态变量,所以实例化的每个对象都有属于自己的id。

 

 使用id来区分不同的对象是很好的方法。

通过类名访问静态变量

可以使用类名加上::           这是类作用域操作符

 也可以通过句柄的方式访问静态变量,t1.count            t2.count,两个值是一样的,因为count只有一个。

  1. 静态变量和类的定义相关,与实例化对象无关
  2. 静态变量常用于存储可变数据
  3. 静态变量被类的所有对象共享

静态变量的初始化

静态变量通常在声明时初始化,而不是在new()函数中初始化。因为每一个新的对象被实例化时都会调用new()函数,静态变量不能每次都被初始化。

静态方法

sv中使用静态方法访问静态变量,不允许静态方法读写非静态变量

 类的方法

就是在类中定义的内部task或者function,类中的方法默认是自动存储,所以不必使用automatic修饰符。

虽然两个类中都有display这个function,但sv会根据句柄的类型调用所属的display方法。 

在类之外定义方法

  1. 把task和function都写在类里面,显得类特别长,不便阅读,
  2. 可以把方法的原型定义放在类的内部,然后再开始处添加关键词extern
  3. 方法的程序体(过程代码)移至类的后面定义

 如何理解this?

当使用一个变量名时,sv将先在当前作用域内寻找,接着在上一级作用域内寻找,直到找到该变量为止。但如果在类的很深的底层作用域,想引用类一级的变量,这时用this比较方便。

 this就是指代当前的这个类。


待续

类的继承,父类,子类

virtual function

shallow copy,deep copy

virtual class

pure virtual function

……

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值