• System Verilog OOP 学习笔记


    1、OOP术语

    a.类(class):包含变量和子程序(函数或者任务)的基本构建块。
    b.对象(object):类的一个实例。
    c.句柄(handle):指向对象的指针。
    d.属性(property):存储数据变量。
    e.方法(method):任务或者函数中操作变量的程序性代码。
    f.原型(prototype):程序的头,包括程序名、返回类型和参数列表。程序体则包含了执行代码。

    类是对象的一个模板,其内部定义了数据和方法。对象是类的一个例化和实现。

    注:《SystemVerilog验证 测试平台编写指南》中使用 变量(variable)和程序(routine),而没有使用OOP中的属性(property)和方法(method)。

    2、用户使用对象的三个步骤:
      a.定义类:

    1 class packet;
    2 ...
    3 endclass:packet
    4 
    5 class long_packet;
    6 ...
    7 endclass:long_packet

      b.在module、class、function、task等地方声明对象:

    1 packet my_packet;
    2 packet packet_array[32];
    3 long_packet my_l_packet;

    对象标识符(my_packet/packet_array/my_l_packet)是例化该对象的句柄(指向对象的指针)。当该对象被创建的时候,该句柄有效,默认情况下句柄将为空(null)。

      c.通过构造函数new创建对象的例化
    通过new这个构造函数给对象分配内存空间,并且把入口地址赋给对象的句柄:
     1 my_packet=new(168);

    2 my_l_packet=new(); 

    例5.1 简单的Transaction类

     1 class Transaction;
     2 bit [31:0] addr,crc,data[8];
     3 
     4 function void display;
     5 $display("Transaction:%h",addr);
     6 endfunction:display
     7 
     8 function void calc_crc;
     9 crc=addr^data.xor;
    10 endfunction:calc_crc
    11 
    12 endclass:Transaction

    3、在哪里定义类?
    program、module、package中。或者在这些块之外的任何地方。

    例5.2 Class in a package

    1 //File abc.svh
    2 package abc;
    3 calss Transaction;
    4 //Class body
    5 endclass
    6 endpackage

    例5.3 Importing a package in program

    1 program automatic test;
    2 import abc::*;
    3 Transaction tr;
    4 
    5 //Test code    
    6 endprogram

    sv中,激励对象不断的被创建并且用来驱动DUT,检查结果。最后这些对象所占用的内存可以被释放。以供新的对象使用。

    例5.4 声明和使用一个句柄
     1 Transaction tr;//声明一个句柄

    2 Tr=new(); //为 Transaction对象分配空间 

    注:1、调用new函数例化一个对象,即在为该对象申请一个新的内存块来保存对象的变量。
    2、new除了分配内存外,还初始化变量。default 二值为0,四值为X。
    3、new函数不能有返回值,因为构造函数是返回一个指向类的对象的句柄,其类型就是本身。

    例5.4 简单的用户定义的new()函数

    1 class Transaction;
    2 logic [31:0] addr,crc,data[8];
    3 
    4 function new;
    5 addr = 3;//固定值
    6 data= '{default:5};//crc未定义,默认值为X
    7 endfunction
    8 endclass

    例5.5 一个带有参数的new函数

     1 class Transaction;
     2 logic [31:0] addr,crc,data[8];
     3 
     4 function new(logic [31:0] a=3,d=5);
     5 addr = a;
     6 data = '{default:5};//crc未定义,默认值为X
     7 endfunction
     8 endclass
     9 
    10 initial begin
    11 Transaction tr;
    12 tr = new.(.a(10));//a=10,d uses default of 5 tr=new(10);
    13 end

    sv如何知道调用哪个new()函数,取决于赋值操作符左边的句柄类型。tr是 Transaction的句柄,索引会调用 Transaction的new函数。
    例5.6 调用正确的new函数

     1 class Transaction;
     2 logic [31:0] addr,csm,data[8];
     3 endclass:Transaction
     4 
     5 class Driver;
     6 Transaction tr;
     7 function new();//Driver's new function
     8 tr = new();//Call the Transaction new function
     9 endfunction
    10 endclass:Driver

    new()和new[]的区别
    调用new()函数仅创建了一个对象,而new[]操作则建立一个含有多个元素的数组。
    new()可以使用参数设置对象的值,而new[]只需使用一个数值来设置数组的大小。

    通过声明一个句柄来创建一个对象

    例5.7 为多个对象分配地址

    1 Transaction t1,t2;//声明两个句柄
    2 t1=new();    //为第一个 Transaction对象分配地址
    3 t2=t1;    //t1和t2都指向该对象
    4 t1=new();    //为第2个 Transaction对象分配地址

    注:最后t2指向第一次分配的对象,t1指向第二次分配的对象。

    对象的解除分配(deallocation)
    垃圾回收就是一种自动释放不在被引用的对象的过程,sv分辨对象不再被引用的办法就是记住指向它的句柄的数量。当最后一个句柄不再引用某个对象了,sv就释放该对象的空间。
    例5.8 创建多个对象

    1 Transaction t;//创建一个句柄
    2 t=new();    //分配一个新的 Transaction
    3 t=new();    //分配第二个,并且释放第一个t
    4 t=null;    //解除分配第二个

    对对象使用“.”符号来引用变量和子程。
    直接访问变量会限制以后对代码的修改,因此OOP规定只能通过对象的公有方法访问对象的变量。
    例5.9 使用对象的变量和子程序

    1 Transaction t;    //声明一个 Transaction句柄
    2 t=new();    //创建一个 Transaction对象
    3 t.addr=32'h42;    //设置变量的值
    4 t.display();    //调用一个子程序

    i++和++i区别:
    i++:先引用后增加,先在i所在的表达式中使用i的当前值,后让i加1

    ++i:先增加后引用,先让i加1,然后在i所在的表达式中使用i的新值


    静态属性与方法
    1、每一个类的例化(也就是一个对象)都拥有它自身每个变量的复制,因此OOP规定只能通过对象的公有方法访问对象的变量。

    2、 对象1:变量1,变量2...
    对象2:变量1,变量2...
    对象1 和 对象2 自身成员变量不和其他对象共享。

    3、类的静态属性是存在类中的,而不是在每个类的对象中,在类中,使用静态static方式声明的属性可以被多个对象共享。

    例5.10 含有一个静态变量的类

     1 class Transaction;
     2 static int count=0;    //已创建的对象的数目
     3 int id;    //实例的唯一标志
     4 function new();
     5 id=count++;    //设置标志,count递增
     6 endfunction
     7 endclass
     8 
     9 Transaction t1,t2;
    10 initial begin
    11 t1=new();    //第一个实例,id=0,count=1
    12 t2=new();    //第二个实例,id=1,count=2
    13 $display("Second id=%d,count=%d",t2.id,t2.count);
    14 end

    例5.11 类的作用域操作符 ::

    1 class Transaction;
    2 static int count=0;    //创建的对象数
    3 ...
    4 endclass
    5 
    6 initial begin
    7 run_test();
    8 $display("%d transaction were creat",Transaction::count);//引用静态句柄
    9 end

    静态变量的初始化
    静态变量通常在声明时初始化,不能简单的在类的构造函数中初始化静态变量,因为每一个新的对象都会调用构造函数。

    类的方法——也就是类的作用域定义的内部task或者function

    例5.13 类中的方法

     1 class Transaction;
     2 bit [31:0] addr,crc,data[8];
     3 function void display();
     4 $display("@%0t:TR addr=%h,crc=%h",$time,addr,crc);
     5 $write("	data[0-7]=");
     6 foreach(data[i]) $write(data[i]);
     7 $display();
     8 endfunction
     9 endclass
    10 
    11 class PCI_Tran;
    12 bit [31:0] addr,data;
    13 function void display();
    14 $display("@%0t:PCI:addr=%h,data=%h",$time,addr,data);
    15 endfunction
    16 endclass
    17 
    18 Transaction t;
    19 PCI_Tran pc;
    20 
    21 initial begin
    22 t=new();//创建一个 Transaction对象
    23 t.display();//调用 Transaction的方法
    24 pc=new();//创建一个PCI事务
    25 pc.display();//调用PCI事务的方法
    26 end

    块外方法声明
    //在开始处添加关键字extern,将整个方法移至类定义后面,并在方法名前面加上类名和::作用域操作符。

     1 class Transaction;
     2 bit [31:0] addr,crc,data[8];
     3 extern function void display();
     4 endclass
     5 
     6 function void Transaction::display();
     7 $display("@%0t:TR addr=%h,crc=%h",$time,addr,crc);
     8 $write("	data[0-7]=");
     9 foreach(data[i]) $write(data[i]);
    10 $display();
    11 endfunction
  • 相关阅读:
    实现用户信息的增删改-mongoose数据库操作
    gulp使用流程及常用插件
    Js面向对象动态添加标签页,Tab栏切换
    类似淘宝侧边栏jq代码编写
    jQuery选择器
    jQuery-突出显示案例
    隔行变色加高亮显示
    ajax请求到后台
    LOOK OUT THE HOLE!
    应用keyup监测输入框兼容IE处理
  • 原文地址:https://www.cnblogs.com/loves6036/p/5568036.html
Copyright © 2020-2023  润新知