该文主要是笔者梳理绿皮书对应章节的内容

System Verilog面向对象编程OPP基础——类(class)的基本使用

  • 面向对象编程
    • 概述
    • 考虑名词而非动词
    • 编写第一个类class
    • OOP术语
    • 创建新的对象
      • 构造函数new()
    • 为对象创建一个句柄
    • 对象的解除分配
    • 使用对象
    • 静态变量static
      • 简单的静态变量
      • 通过类名访问静态变量
      • 静态变量的初始化
    • 类的方法
    • 在类之外定义方法extern
    • 作用域规则
    • this
    • 在类中可以使用另外一个类

面向对象编程


概述

面向对象编程(OOP)使得用户可以创建更加复杂的数据类型,并将该数据类型与使用这些数据类型
的程序紧密结合在一起。用户可以在更加抽象的层次建立测试平台和系统模型。通过调用函数来是
实现电平的改变。使用事务来替代信号的翻转。使得测试平台与细节分开,增加系统的可维护性。

考虑名词而非动词

测试平台的目的是给设计施加激励。然后检查其结果是否正确。我们区分传统的测试平台构建的操作:创建一个事务,发送,接收,检查结果,产生报告。

但是在OOP中,我们需要重新考虑测试平台的构建以及每一个部分的功能。

  • 发生器(generator):创建事务并将他们传送给下一级
  • 驱动器(driver):与设计进行会话
  • 监视器(monitor):设计返回的事务将被监视器捕获
  • 计分板(scoreboard):将捕获的数据与预期数据进行比对。
    因此测试平台被分为多个块(block),然后定义其互相之间的通信。

编写第一个类class

我们前面学习的是定义一个更加复杂的数据类型,类封装了数据,操作这些数的子程序.实例如下:

class Transaction;bit [31: 0] addr,crc, data(8];function void display;$display("Transaction:%h", addr);endfunction : displayfunction void calc_crccrc=addr^data.xor;endfunction : calc_crc
endclass: Transaction

补充:为了更加方便的取分对齐一个块的开始与结束部分,可以在块结束的最后放一个标记(label)。在很多时候,这些标记可以方便的区分结束。例如:endtask、endfunction、endcalss

OOP术语

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

创建新的对象

System Verilog的类,是在程序执行过程中需要的时候在被创建。所有的类在使用之前都应该被例化。例化后就会开辟一定的内存空间。

Transaction tr;// 声明一个句柄
tr = new();    //一个Transaction对象分配空间,同时初始化变量

构造函数new()

在声明句柄的时候,他被初始化为了特殊格式null。接下来调用new()来创Transaction对象的时候,nwe函数为其分配空间,并变量初始化为默认值。其中二值变量初始化为0,四值变量初始化为X。我们称作new为构造函数。没有返回值。使用new对类进行例化时,可以对变量指定初始值。方式如下:

class Transaction;logic [31: 0] addr,crc, data[8];function new(logic [31:0] a=3,d=5);addr = 1;foreach(data[i])data[i]=d;endfunction : new
endclass: Transaction
initial beginTransaction tr;tr=new(10)//data默认为5,

为对象创建一个句柄

首先要对于对象与句柄进行区分。一个句柄可以指向很多个对象。

Transaction t1,t2;//声明两个句柄
t1=new();//为第一个Transaction对象分配地址
t2=t1;//两个句柄指向一个对象,可以理解两个指针指向同一个内存空间
t1=new();//为第二个Transaction对象分配地址,因为这个时候t2还是指向的第一个对象,所以t1指向一个新的对象

具体映射关系见下图

通过以上例子对与句柄与对象进行区分。对象可以理解为向系统申请的一个内存空间,申请的方式就是通过句柄来保证的。这里句柄相当于一个对象的寻找、使用方式。一旦一个对象没有句柄指向,则这个对象的空间就会被释放掉。

对象的解除分配

实例如下。当对象不在被引用,即为没有指向他的句柄。

Transaction t;//声明一个句柄
t=new();//为第一个Transaction对象分配地址
t=new();//这是对第一个空间进行回收,同时开辟一个新的地址空间
t=null;//解除第二个分配,释放空间

使用对象

假设已经分配了一个对象,接下来就是如何使用对象。可以使用.来引用子变量和子程序。

Transaction t;//声明一个句柄
t=new();//为第一个Transaction对象分配地址,创建一个对象
t.addr=32'h32;//设置变量的值
t.display();//调用一个子程序

静态变量static

每个对象都有自己的局部变量,这些变量不与其他任何对象共享。但若是需要存在一个某种类型的变量需要被所有变量共享,就需要创建一个全局变量。

简单的静态变量

在System Verilog中,可以在类中创建一个静态变量,该变量将被这个类所有的实例共享。但是它使用的范围仅仅限制与则个类。如下实例中静态变量count用来保护目前所创建的对象的数目。他在声明的时候被初始化为0。之后每构建一个新的对象,相当于调用一次new()函数,他就被标记为一个唯一的值。同时count的值加1。

class Transaction;static int count=0;//已创建的对象的数目int id://实例的唯一标志function new()id= count++;//设置标志, count递增endfunction
endclass : Transaction
Transaction t1,t2;
initial begintl=new();//第一个实例,id=0,count=1t2=new();//第二个实例id=1, count=2
end

一个类应该事尽可能自己自足的,当打算创建一个全局变量的时候。首先需要考虑创建一个类的静态变量能否解决问题,对于一个类,应用的外部变量越少越好。

通过类名访问静态变量

这里引入一个新的访问静态变量的方法。该方法不需要使用句柄,而是使用class_name ::即类作用域操作符。

class Transaction; static int count=0;//创建的对象数...
endclass
Transaction t;
initial beginTransaction t;$display("%d transaction were created",t.count);//使用句柄引用静态句柄$display("%d transaction were created",Transaction:: count);//引用静态句柄
end

静态变量的初始化

通常是在声明的时候初始化。静态变量通常在声明时初始化。你不能简单地在类的构造函数中初始化静态变量因为每一个新的对象都会调用构造函数new()。你可能需要另一个静态变量来作为标志,以标识原始变量是否已被初始化。如果需要做一个更加详细的初始化,你可以使用初始化块但是要保证在创建第一个对象前,就已经初始化了静态变量。

类的方法

类中的程序也称为方法。也就是在类的作用域定义的task或者function。

class Transaction;function void display ();$display ("...");endfunction
endclass
Transaction t;
initial begintt=new();//创建一个 Transaction对象t.display();//调用 Transaction的方法
end

在类之外定义方法extern

SV允许在一个块外声明例子。使用关键词extern。实例如下

class Transaction;extern function void display ();
endclassfunction void Transaction::display ();$display ("...");
endfunction

作用域规则

作用域是一个代码块。例如一个模块,一个程序、任务、函数、类或者begin-end块。每个作用域都使用其作用域下定义的变量。

this

当你使用一个变量名的时候, Systemverilog将先在当前作用域内寻找,接着在上一级作用域内寻找,直到找到该变量为止。这也是 Verilog所采用的算法。但是如果你在类的很深的底层作用域,却想明确地引用类一级的对象呢?这种风格的代码在构造函数里最常见,因为这时候程序员使用相同的类变量名和参数名。关键词this可以实现该功能。

class Scoping;string oname;function new ( string oname ) ;this.oname = oname // 类变量oname=局部变量onameendfunction
endclass

在类中可以使用另外一个类

class Transact⊥on;bit [31: 0] addr, crc, data[8];Statistics stats;// Statistics句柄function new();stats=new();//创建 stats实例endfunctiontask create packet();//填充包数据stats.start()//传送数据包endtask
endclass

一定要记得例化对象,否则句柄stats是null,调用start会失败。这最好在上层即 Transaction类的构造函数中完成。这其中涉及到了编译的顺序问题。有时候你需要编译一个类。而这个类包含一个尚未定义的类。这个被包含的类的句柄就会引起错误。这时候需要使用typedef来声明一个类名。

typedef class Statistics;
class Transaction;Statistics stats;...
endclass
class Statistics; ...
endclass

System Verilog面向对象编程(OPP)基础——类(class)的基本使用相关推荐

  1. java零基础Ⅰ-- 6.面向对象编程(基础部分)

    java零基础Ⅰ-- 面向对象编程(基础部分) 类与对象 类与对象引出 类与对象概述 快速入门 类与对象的区别和联系 对象在内存中存在形式 属性/成员变量/字段 注意事项和细节说明 如何创建对象 如何 ...

  2. java学习笔记-第七章:面向对象编程(基础部分)

    第七章:面向对象编程(基础部分) 总体内容 类与对象 引出类与对象 类与对象概述 类与对象的关系示意图 属性概念及其细节 类与对象快速入门案例 对象内存布局 类与对象内存分配机制 引申:java内存的 ...

  3. 【面向对象编程】(4) 类的继承,重构父类中的方法

    各位同学好,今天和大家分享一下面向对象编程中,类的三大特征之继承.主要介绍:子类继承父类的基本方法:重写父类的类方法:重构父类的初始化方法:super() 方法.本节主要是单继承,多继承在下一节中介绍 ...

  4. c语言面向对象编程中的类_C ++中的面向对象编程

    c语言面向对象编程中的类 Object oriented programming, OOP for short, aims to implement real world entities like ...

  5. Java面向对象编程篇1——类与对象

    Java面向对象编程篇1--类与对象 1.面向过程 1.1.概念 面向过程就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候一个一个依次调用就可以了 1.2.优缺点 优点:性 ...

  6. 【面向对象编程】(3) 类之间的交互,依赖关系,关联关系

    各位同学好,今天和大家分享一下面向对象编程中,类之间的交互,类之间的依赖关系和关联关系.有不明白的可见前一章节:https://blog.csdn.net/dgvv4/article/details/ ...

  7. 面向对象编程(OPP)

    作者:狐狸家的鱼 本文链接:面向对象编程 GitHub:sueRimn 面向对象编程(OPP) 具有灵活.代码可复用.高度模块化等特点,易维护和开发 实例对象与new命令 1.对象 对象是单个实物的抽 ...

  8. 了解使用JavaScript进行面向对象编程的基础(并增强您的编码…

    by Kris Baillargeon 通过克里斯·拜伦 学习使用JavaScript进行面向对象编程的基础知识(并增强您的编码能力!) (Learn the basics of object-ori ...

  9. C语言面向对象编程的类是指,c语言面向对象编程中的类_C ++中的面向对象编程...

    c语言面向对象编程中的类 Object Oriented programming is a programming style that is associated with the concept ...

最新文章

  1. Visual C++ 2012/2013的内存溢出检測工具
  2. SIFT 特征检测及匹配
  3. 用Java实现输入一个英语文本输出第1000个字节后的第一个完整单词
  4. 贝叶斯定理的实际应用
  5. 纯Shading Language绘制飞机火焰效果
  6. 操作无法完成_注意!城里人开始羡慕农村户口啦!4种情况却无法完成分户操作!...
  7. java forEach使用
  8. C# 系统应用之TreeView控件 (一).显示树状磁盘文件目录及加载图标
  9. SAP CRM Fiori应用My Note的OData调用设计
  10. mysql 设计两个主键都不可重复_18个MySQL面试题剖析(答案解析),听说身为程序员的你还没掌握...
  11. 前端学习(2197):__WEBPACK_IMPORTED_MODULE_1_vuex__.a.store is not a constructor
  12. Java还有发展前景吗?现在该怎么去学习?
  13. 原生微信小程序添加背景音乐
  14. NTC功率型热敏电阻
  15. java图片蒙版,在javafx中创建图像叠加蒙版
  16. 微信分享代码,朋友圈分享代码
  17. 达索SOLIDWORKS PDM让你的团队协作更紧密
  18. 年末去字节跳动面试,居然被面试官问的哑口无言,原因竟然是这个!!!
  19. 我的梦想就是不工作,有什么错?
  20. docker搭建redis集群

热门文章

  1. Cannot create container for service peer1.org2.example.com: Conflict. 解决方案
  2. error: Microsoft Visual C++ 14.0 is required. Get it with “Microsoft Visual C++ Build Tools“:解决方案
  3. JS动态修改页面EasyUI datebox不生效、EasyUI动态添加Class、EasyUI动态渲染解析解决方案
  4. Android ADB设备离线,无法发出命令
  5. 如何使用JavaScript从字符串中删除空格?
  6. 在C#中将字符串转换为字节数组
  7. 找不到元数据文件“ .dll”
  8. 计算机模块的概念,用户定义类模块概念-计算机二级-Access
  9. win11更新黑屏无法进入系统怎么办 windows11黑屏更新无法进入系统的解决方法
  10. 分辨率win11英文版怎么调整