• 数字验证学习笔记——SystemVerilog芯片验证9 ——类和对象


    一、类和对象的概述

    对象编程语言更符合人对自然的理解。这个世界是由无数的类(class)和对象(object)构成的。类是将相同的个体抽象出来的描述方式,对象是实体,其具备有独立行为的能力,一个对象是万千世界中的“一粒沙”。具有相同属性和功能的对象属于同一类,而不同的类之间可能有联系或者没有联系。

    面向对象编写三要素:封装、继承和多态。
    类的定义核心即是属性声明和方法定义,所以类是数据和方法的自洽体,既可以保存数据也可以处理数据。struct只是 单纯的数据保存,没有数据处理的能力。

    验证为什么需要面向对象的编程。
    验证环境的不同组件功能和所需要处理的数据内容是不相同的。
    不同环境的同一类组件所具备的功能和数据内容是相似的。

    第一个transaction事务类
    //类是方法和数据的自洽体
    class Transaction;
    bit [31:0] addr,crc,data[8]; //类定义变量,是动态变量,是软件里面的变量
    function void display;
    $dispaly(“Transaction: %h”,addr);
    endfuction : dispaly
    function void clac_crc;
    crc=addr^data.xor;
    endfuction : clac_crc
    endclass:Transaction

    面向对象编程的概念要素

    • class 类: 基本模块包含成员变量和方法。在Verilog中module也可以包含变量和方法,只不过它是硬件的盒子,而class是软件的盒子。
    • object对象:类的实例。Verilog中module也可以例化,这是硬件的例化,在SV中可以使用class来例化,这是软件的例化。
    • handle句柄(指针):用来指向对象的指针。在verilog中,可以通过层次化的索引来找到结构中的设计实例(例如 A.B.sigX),而在SV的对象索引时,需要通过句柄来索引对象的变量和方法。
    • Property属性(变量):在类中声明存储数据的变量。在verilog中它可以时wire和reg类型。
    • Method方法:类中可以使用task或者function来定义方法以便处理或者外部传入的数据。在verilog中可以在module定义task/function,也可以使用initial/always处理数据。

    创建对象
    Transaction tr; //声明句柄
    tr = new(); // 创建对象 类的实例 也可以 Transaction tr = new();

    创建对象?它创建了什么呢?
    开辟了新的内存空间,用来存放新的成员变量和方法

    创建对象时,可以通过自定义构建函数new()来完成变量的初始化和其他操作。
    class Transaction;
    bit [31:0] addr,crc,data[8];
    function new();
    addr=3;
    foreach(data(i))
    data(i) =5 ;
    endfuction
    endclass

    构建函数new()时系统预定义函数,不需要指定返回值,函数会隐约地返回例化后的对象指针。

    句柄的传递
    Transaction t1,t2;//声明句柄t1、t2 悬空的句柄是空的
    t1=new(); //例化对象,将其句柄赋予t1
    t2=t1; // 将t1值赋予t2,即t1和t2指向同一个对象
    t1=new(); //例化第二对象,将其句柄赋予t1

    对象的销毁
    当一个对象,在整个程序中没有一个地方再“需要”它时,它便会销毁。这里的需要指的是句柄指向该对象。

    class word;
    byte nb[];
    function new( int i)
    nb=new[i]; //动态数组的赋值是new[]
    endfuction
    endclass

    initial begin
    word wd;
    for(int i=1; i<=4 ; i++)
    wd=new(i); //前3个对象没有句柄
    end
    为对象的例化开辟需要4byte

    可以通过句柄来使用对象中的成员变量或者成员方法
    Transaction t;// 声明句柄
    t=new(); //例化对象
    t.addr=32’h42; //对象的成员变量赋初值
    t.display();//调用对象成员的方法

    静态变量
    在class中声明的变量默认为动态变量,其生命周期始于对象创建终于对象销毁
    使用static来声明class的变量,则为静态变量。静态变量的生命周期始于编译阶段,贯穿整个仿真阶段
    如果在类中声明了静态变量,那么可以直接引用该变量class::var。类中的静态变量声明之后,无论例化多少个对象,
    只可以共享一个同名的静态变量,因此静态变量在使用时需要注意共享资源的保护
    class Transaction;
    static int count=0;
    int id;
    function new();
    id=count++;
    endfuction
    endclass

    Transaction t1,t2;
    initial begin
    t1=new();// id=0 count=1
    t2=new();// id=1 count=2
    $dispaly(" Second id=%d ,count=%d “, t2.id, Transaction :: count); // id=1 count=2
    end
    静态方法
    class 定义的方法默认为是动态方法,可以通过添加关键词static变为静态方法。
    静态方法禁止使用类的动态变量。
    class Transaction;
    static Config cfg;
    static int count = 0 ;
    int id;
    //通过静态方法调用静态变量
    static function void display_statics();
    $dispaly(” Transaction Cfg.mode =%s,count=%d ",cfg.mode.name(),count);
    endfunction
    endclass

  • 相关阅读:
    AndroidT(13) -- C plus plus 语言格式的LOG输出(二)
    028 - STM32学习笔记 - ADC结构体学习(二)
    带有ttl的Lru在Rust中的实现及源码解析
    Qt:多语言支持,构建全面应用程序“
    【C语言刷LeetCode】1371. 每个元音包含偶数次的最长子字符串(M)
    网络编程基础(一):OSI 、TCP/IP协议与hello socket:用java实现第一个TCP连接
    LCD DRM驱动框架分析一
    若依集成钉钉扫码登录
    Linux系统——Session ID(负载均衡如何保持会话)
    Node.js知识点
  • 原文地址:https://blog.csdn.net/qq_32100199/article/details/128052859