systemVerilog基础9——类的继承

news2024/11/25 7:12:43

1、 描述子类继承父类的关键词:extends

        之前定义过的类Packet,可以进一步扩展构成一个它的子类LinkedPacket。类Packet的定义如下:

class Packet ;//class定义类 类名 packet
    //类 packet的成员
    //数据或类属性
    bit [3:0] command; bit [40:0] address; bit [4:0] master_id;
    integer time_requested ;
    integer time_ issued;
    integer status;
    typedef enum { ERR_OVERFLOW= 10,ERR_UNDERFLOW = 1123} PCKT_TYPE;
    const integer buffer_size = 100;
    const integer header_size;
    //类 packet的成员方法new ();clean() ;issue_request; current_status
    //初始化
    function new ();
        command = 4' d0; address = 41'b0; master_id = 5'bx;   header_size = 10;
    endfunction
     //方法
    //公共通道入口
    task clean() ;
        command = 0; address = 0; master_id = 5'bx ;
    endtask
    task issue_request( int delay ) ;
        //向总线发送请求
    endtask
    function integer current_status ( ;
        current_status = status;
    endfunction
endclass

通过extends,子类LinkedPacket继承于其父类Packet,包括继承其所有的成员(变量/方法)。

class LinkedPacket extends Packet;//父类名Packet,子类名LinkedPacket
//在子类继承父类的成员变量和方法基础上,定义新的成员next和成员函数get_next()
    LinkedPacket next ;
    function LinkedPacket get_next();
        get_next = next;
    endfunction
endclass

2、成员覆盖

         子类可以继承父类的成员,所以LinkedPacket对象中也包含Packet类的成员。由此,父类句柄可以指向子类的对象

LinkedPacket lp = new ;
Packet p = lp;

        注意: 父类句柄如果指向子类对象 ,那么将无法访问子类的成员变量(这是由于父类句柄可访问范围所限制的)

        注意: 虽然在子类中可以新定义子类成员 ,但是如果子类中声明了与父类同名的成员(变量/方法),那么子类对其同名成员的访问都将指向子类,而父类的成员将被隐藏

        示例: 下面的代码经过简化,父类和子类只保留了各自同名成员变量i和成员变量get 

//创建父类Packet
class Packet;
    integer i = 1;
    function integer get() ;
        get = i ;
    endfunction
endclass
//创建子类LinkedPacket
class LinkedPacket extends Packet;
    integer i = 2;
    function integer get() ;
        get = -i ;
    endfunction
endclass

tb.sv文件内容:


`include "class_test.sv"
module tb;

initial begin

LinkedPacket lp = new;
Packet p = lp; //将子类句柄lp赋值给父类句柄p
//虽然子类句柄和父类句柄此时都指向同一个子类,但是
//由于句柄类型,限制了其访问范围
//所以通过父类句柄p,可以访问的成员变量和成员方法都是父类范围的
integer i,j;
j = p.i; // j = 1,不是2
$display("j is %d\n",j);

i = p.get() ; //i = 1,不是-1或者-2
$display("i is %d\n",i);

end
endmodule

运行结果如下:

        虽然子类句柄和父类句柄此时都指向同一个子类,但是由于句柄类型,限制了其访问范围
,所以通过父类句柄p,可以访问的成员变量和成员方法都是父类范围的 ,而不是子类范围。 如果使用子类句柄lp,去访问同名成员,访问的都是子类范围的

3、子类继承父类成员方法——super

        由于继承的关系,如果子类成员方法想要继承父类成员方法,那么可以在子类代码中通过super关键词来访问当前对象的父类成员。 

        super是用来访问当前对象其父类的成员尤其当子类的成员如果与父类的成员同名,那么需要使用super来指定访问其父类成员,而非默认的子类成员

class Packet; //父类
    integer value;
    function integer delay () ;
        delay = value * value;
    endfunction
endclass
 
class LinkedPacket extends Packet; //子类integer value;
    function integer delay () ;
        delay = super.delay ()+ value * super.value;
//子类通过super,访问与父类同名的delay函数,和同名成员变量value
    endfunction
endclass

super对于类的继承和对域作用范围的指定都有帮助 。

 4、验证环境中的案例

这个验证环境已经有了generator和driver的两个组件:

        generator(激励产生器):是单纯产生激励数据,
        driver(驱动器):是单纯使用激励数据来发送时序激励。
     这种单一职责的划分,使得各个组件的任务十分明确,那么一个简单环境构建就有了。

        在验证环境中,描述测试环境的部分由test来实现。按照test要求来生成激励,并且传递给driver组件由generator实现。在最后,通过激励的数据内容,将其按照时钟周期,将数据驱动到硬件接口上的是driver。最后激励数据通过信号的方式,抵达了DUT边界端口。

        如果要将数据发送到DUT,那么需要有以下的基本元素和数据处理方法,我们将它们封装到Transaction类中。

        从generator产生的激励中,包括source、dst、data和crc等变量,将它们和有关的处理函数calc_crc()和display()封装在 Transaction类中。  driver获取这个类之后,将从中提取变量值,再将其驱动到DUT端口上面。

class Transaction;
    rand bit [31:0] src, dst, data[8] ;//随机成员变量
    bit [31 :0] crc; //二次处理后的成员数据
    virtual function void calc_crc () ;
        crc = src ^ dst ^ data.xor;
    endfunction
    virtual function void display(input string prefix="");
        $display("%sTr: src=%h, dst=%h, crc=%h",prefix,src, dst,crc);
    endfunction
endclass
 

5、测试DUT的稳定性 

         如果我们为了测试DUT的稳定性,需要加入一些错误的数据来测试DUT的反馈,但我们又想尽量复用原有的验证环境(也包括已经定义好的类),那么我们就可以考虑使用继承的方式来新创建一个类BadTr。

// BadTr是Transaction的子类,Transaction是BadTr的父类。
class BadTr extends Transaction;
    rand bit bad_crc;
// BadTr重新定义了函数calc_crc()和display(),
//而在其内部通过super来索引父类的同名函数。
    virtual function void calc_crc;
        super.calc_crc() ; // 计算crc
        if (bad_crc) crc = ~crc; //破坏crc
    endfunction
 
    virtual function void display(input string prefi x="");
        $write("%sBadTr: bad_crc=%b, ", prefix, bad_crc);
        super.display () ;
    endfunction
 
endclass : BadTr

        在定义了这两个激励类型以后,它们将可以被激励发生器产生,并送往驱动器。

观察以下继承关系图,可以看到:

        BadTr是Transaction的子类,Transaction是BadTr的父类。

        BadTr重新定义了函数calc_crc()和display(),而在其内部通过super来索引父类的同名函数。

        如果创建一个子类对象,那么该对象的空间可以划分为父类成员的空间和子类成员的空间。即便父类和子类有同名的成员变量和成员方法,但是它们的空间都是独立的。

        需要注意的是,如果是父类的句柄指向了子类的对象,那么它访问的空间将会受到父类句柄可访问范围的影响,只能访问父类成员 
 


 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/819840.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【css】背景图片附着

属性&#xff1a;background-attachment 属性指定背景图像是应该滚动还是固定的&#xff08;不会随页面的其余部分一起滚动&#xff09;。 background-attachment: fixed&#xff1a;为固定&#xff1b; background-attachment: scroll为滚动 代码&#xff1a; <!DOCTYPE h…

TypeScript基础学习

目录 一、安装 1、下载国内镜像 2、安装 3、查看安装情况 4、使用例子 二、变量声明 1、规则 2、声明的四种方式 3、注意 4、类型断言 5、类型推断 6、变量作用域 三、基础类型&#xff08;共11种&#xff09; 1、Any 类型 2、Null 和 Undefined 3、never 类型…

医药化工企业洁净厂房改造消防防爆安全的重要性

设计 【摘要】&#xff1a;近年来&#xff0c;我国医药化工企业规模不断扩大。医药化工企业的情况复杂&#xff0c;稍有不慎将发生火灾或者爆炸&#xff0c;对人员生命以及财产安全造成巨大的损害&#xff0c;酿成悲剧。所以&#xff0c;“三同时”原则的落实&#xff0c;如何…

伊语IM即时通讯源码/im商城系统/纯源码IM通讯系统安卓+IOS前端纯原生源码

伊语IM即时通讯源码/im商城系统/纯源码IM通讯系统安卓IOS前端纯原生源码&#xff0c; 后端是java源码。

tinkerCAD案例:30. 冰球挑战赛

tinkerCAD案例&#xff1a;30. 冰球挑战赛 这些简单易学、循序渐进的 Tinkercad 课程将指导你设计出属于自己的超棒曲棍球冰球&#xff1b;这些设计将性能和风格推向了极限&#xff01; 本课有两个目标利用科学方法提高曲棍球球的性能。通过在冰球上添加图案&#xff0c;发挥设…

rust怎么搞的,这么简单的代码也报“borrow of moved value“?

奇了怪了&#xff0c;这么简单的代码也编译不过&#xff1f; let hello String::from("hello");let world hello;hello.push_str("world"); // error[E0382]: borrow of moved value: hello看下完整报错 error[E0382]: borrow of moved value: hello--&…

picgo 图床 七牛云的设置

网站 PicGo github Molunerfinn/PicGo: &#x1f680;A simple & beautiful tool for pictures uploading built by vue-cli-electron-builder PicGo/Awesome-PicGo: A collection of awesome projects using PicGo. 设置 AcccessKey (AK) SecretKey(SK) 在个人中心&…

HarmonyOS学习路之方舟开发框架—学习ArkTS语言(状态管理 三)

Link装饰器&#xff1a;父子双向同步 子组件中被Link装饰的变量与其父组件中对应的数据源建立双向数据绑定。 概述 Link装饰的变量与其父组件中的数据源共享相同的值。 装饰器使用规则说明 Link变量装饰器 说明 装饰器参数 无 同步类型 双向同步。 父组件中State, Stor…

无法访问Microsoft Store

可以先试试把代理工具关了 如果不行 winr, 输入inetcpl.cpl 勾上TLS 1.1,TSL1.2 重启&#xff0c;再试试

react学习笔记——1. hello react

包含的包一共有4个&#xff0c;分别的作用如下&#xff1a; babel.min.js&#xff1a;可以进行ES6到ES5的语法转换&#xff1b;可以用于import&#xff1b;可以用于将jsx转换为js。注意&#xff0c;在开发的时候&#xff0c;这个转换&#xff08;jsx转换js&#xff09;不在线上…

杨辉三角,给定一个非负整数 numRows,生成「杨辉三角」的前 numRows 行。

题记&#xff1a; 给定一个非负整数 numRows&#xff0c;生成「杨辉三角」的前 numRows 行。 在「杨辉三角」中&#xff0c;每个数是它左上方和右上方的数的和。 示例 1: 输入: numRows 5 输出: [[1],[1,1],[1,2,1],[1,3,3,1],[1,4,6,4,1]] 示例 2: 输入: numRows 1 输出: …

千元内初学者吉他买什么好?SAGA萨伽SF700和VEAZEN费森VZ200评测对比,哪一款更出众适合新手入门选购!

大部分了解过相关吉他知识或者有点音乐意识的初学者&#xff0c;都会摒弃烧火棍去选择买一把千元单板&#xff0c;亦或者少数资金充足的琴友会选择更贵的吉他。所以翻阅很多有关吉他推荐的帖子&#xff0c;我们可以看到在千元的价位里&#xff0c; **VEAZEN费森VZ200和 SAGA萨伽…

ZeRO Memory Optimizations Toward Training Trillion Parameter Models

1总述 Zero Redundancy Optimizer: 提高了可以被有效训练的模型的大小&#xff0c;极大提高了模型训练的速度。 保持了较小的通信量保持较高的计算粒度 数据并行DP 并没有减少每个device上的内存占用当模型有1.4B 参数时&#xff0c;就会超过GPU的32GB显存通过PP, MP&#…

P4D编程遇到乱码?别急,这里有解决方案!

P4D简介&#xff1a; P4D&#xff08;Python for Delphi&#xff09;是一种用于在Delphi开发环境中嵌入Python的技术&#xff0c;它允许开发人员使用Python语言编写脚本和模块&#xff0c;然后将其集成到Delphi应用程序中。这使得开发人员可以利用Python的强大功能来扩展和增强…

JavaWeb(7)——前端综合案例1(面向对象)

一、需求 JS进阶-day3-184-综合案例-模态框构造函数写法 二、 实现 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta http-equiv"X-UA-Compatible" content"IEedge" /><meta…

Meta AI研究团队新AI模型:Segment Anything图像分割任务

Segment Anything是Meta AI研究团队开发的一种新的AI模型&#xff0c;用于图像分割任务。该模型可以对任何图像中的任何对象进行分割&#xff0c;即将对象从图像中"剪切"出来。Segment Anything模型&#xff08;SAM&#xff09;是一个可提示的模型&#xff0c;可以根…

Linux常用命令——dpkg-preconfigure命令

在线Linux命令查询工具 dpkg-preconfigure Debian Linux中软件包安装之前询问问题 补充说明 dpkg-preconfigure命令用于在Debian Linux中软件包安装之前询问问题。 语法 dpkg-preconfigure(选项)(参数)选项 -f&#xff1a;选择使用的前端&#xff1b; -p&#xff1a;感兴…

我国科学家揭秘河蚌铰链耐疲劳的秘密

《科学》杂志发表了中国科学技术大学俞书宏院士团队联合吴恒安教授团队的研究成果。他们揭示了河蚌铰链耐疲劳的奥秘&#xff0c;并提出了一种耐疲劳材料设计的新思路。 在此次研究中&#xff0c;研究人员探明了河蚌铰链中折扇形组织的设计原理&#xff0c;发现这种生物组织在河…

【Redis】内存数据库 Redis 基础

目录 内存数据库Redis概念Redis 安装Redis的启动方式Redis命令行客户端 Redis通用命令Redis key结构Redis value数据类型String 和基础操作Hash 和基础操作List 和基础操作Set 和基础操作Sorted_set 和基础操作 Redis的Java客户端Jedis客户端SpringDataRedis客户端自定义RedisT…

Linux下 Docker容器引擎基础(1)

简述&#xff1a; Docker的容器技术可以在一台主机上轻松为任何应用创建一个轻量级的、可移植的、自给自足的容器。通过这种容器打包应用程序&#xff0c;意味着简化了重新部署、调试这些琐碎的重复工作&#xff0c;极大的提高了工作效率。例如&#xff1a;项目从腾讯云迁移阿…