[systemverilog]3_类_对象_句柄_静态变量和方法

1.类和对象简述
(1)类是将相同的个体抽象出来的描述方式,对象是实体。具有相同属性和功能的对象属于同一类,而不同的类之间肯有继承关系或没有联系。
(2)Verilog的module+method的方式与SV的class定义有本质上的差别,class是面向对象编程,即面向对象编程的三要素:封装(Encapsulation)、继承(Inheritance)和多态(Polymorphism) 。
(3)类的定义核心即是属性声明(property declaration)和方法定义(method definition) ,所以类是数据和方法的自治体(self-compatible) ,即可以保存数据和处理数据。这是与struct结构体在数据保存方面的重要区别,因为结构体只是单纯的数据集合,而类则可以对数据做出符合需要的处理。
(4)验证为什么需要OOP

2.OOP概念要素
(1)
(2)补充
  • 句柄不同于C语言中的指针区别在于,C语言中允许指针指向标量,而句柄只能指向对象。
  • 变量只能是logic和bit,不允许是reg wire等硬件中的类型。

3.class 例化与module 例化的区别
(1)两者的共同点在于使用相同的模板来创建内存实例
(2)不同点在于Verilog的例化是静态的,即在编译链接时完成,而SV class的例化是动态的,可以在任意时间点发生,这也使得类的例化方式更加灵活和节省空间。
(3)Verilog中没有句柄的概念,即只能通过层次化的索引方式A.B.sigx,而SV class通过句柄可以将对象的指针赋予其它句柄,使得操作更加灵活。
(4)class中不能出现过程块(initial always),module中方法的调用可以在过程块中,class中方法的调用则是用方法嵌套调用。

4.声明句柄、创建对象(例化)
(1)语法
Transaction tr;//声明句柄
tr = new(); //创建对象
(Transaction tr = new();)
(2)new()三步骤:开空间;初始化;返回句柄。
(3)new()可以指定参数,但是这是默认参数,即没有传参时,默认值。
(4)对应第(3)
初始化并赋值了16,等调用new后,重新复制了10。

5.对象的销毁
(1)sv自动收回空间
(2)例1-理解对象的销毁
class word
    byte nb[];
    function new(int n);
        nb=new[n];
    endfunction
endclass
initial begin : initial_1
    word wd;
    for(int i=1; i<= 4; i++)    wd = new(i) ;
end
initial begin: initial_2
    #1ps
    $display("How many Bytes are allocated for word instances?");
end
initial里面的变量是静态的,虽然循环了四次,例化了四个对象,但最终只有一个句柄wd指向,故答案是4。
(3)例2-理解对象的销毁
class word
    byte nb[];
    function new(int n);
        nb=new[n];
    endfunction
endclass
initial begin : initial_1
    automatic word wd;
    for(int i=1; i<= 4; i++)    wd = new(i) ;
end
initial begin: initial_2
    #1ps
    $display("How many Bytes are allocated for word instances?");
end
0时刻后,initial_1完了后,wd句柄都释放了,对象自然也没分配空间。

6.句柄的使用
(1)句柄的传递
区分对象(存储空间)和句柄(空间指针)。也就是说,在创建了对象,之后,该对象的空间位置不会更改,而指向该空间的句柄可以有多个。
(2)

7.静态变量与静态方法
(1)静态变量
  • 与硬件域例如module,interface不同的是,在class中声明的变量其默认类型为动态变量,即其生命周期在仿真开始后的某时间点开始到某时间点结束。具体来讲,其声明周期始于对象创建,终于对象销毁
  • 那么如果使用关键字 static来声明class内的变量时,则其为静态变量。根据之前课程对变量声明周期的描述,静态变量的生命开始于编译阶段,贯穿于整个仿真阶段。
  • 如果在类中声明了静态变量,那么可以直接引用该变量 class::var,或者通过例化对象引用 object.var。
  • 类中的静态变量声明以后,无论例化多少个对象(0..N) ,只可以 共享一个同名的静态变量,因此类的静态变量在使用时需要注意共享资源的保护。
(2)静态变量-例子
(3)静态方法
  • 类似于静态变量,在class中定义的方法默认类型是动态方法,而我们也可以通过关键词static修改其类型为静态方法。
  • 静态方法内可以声明并使用动态变量, 但是不能使用类的动态成员变量。原因是因为在调用静态方法时,可能并没有创建具体的对象,也因此没有为动态成员变量开辟空间,因此在静态方法中使用类的动态成员变量是禁止的,可能会造成内存泄漏,但是静态方法可以使用类的静态变量,因为静态方法同静态变量一样在编译阶段就已经为其分配好了内存空间。
(4)静态方法-例子

8.类的成员
(1)SRP和OCP
(2)protected\local
  • 如果没有指明访问类型,那么成员的默认类型是public(不是关键字),子类和外部均可以访问成员。
  • 如果指明了访问类型是protected,那么只有该类或者子类可以访问成员,而外部无法访问。
  • 如果指明了访问类型是local,那么只有该类可以访问成员,子 类和外部均无法访问。
  • 访问类型的设定是为了更好地封装类,尤其是要发布供他人使用的软件包(商业软件) ,但对于初学者以及应用范围较窄的验证环境,可以使用默认的访问类型,以便于在类的内部或者外部更方便地修改成员变量或者调用成员方法。
(3)local的例子
class clock
    local bit is_summer = 0;
    Lacal int nclock = 6;
    function int get_clock();
        if(!is_summer) return this.nclock;
        else return this.nclack+1;
    endfunction
    function bit set_summer (bit s); 
        this.is_summer = s; 
    endfunction
endclass
...
clock ck;
initial begin 
    ck = new();
    $display ("now time is 80d", ck.get_clock());
    ck. set_summer (1);
    $display ("now time is 0d", ck.nclock);
end
如果将ck.nclock改为ck.get_clock()答案即是7.
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值