System Verilog笔记总结(5)

2020-02-21 22:21

背景:基类句柄可以指向扩展类对象,不需要额外的代码; 扩展类句柄指向基类对象,一般情况下会出错,但有时候是可以的,前提是基类句柄指向了它的一个扩展类对象。 作用:扩展类句柄指向基类对象时,使用$cast()函数。在非法的情况下,不会编译报错,会返回了一个0.

$cast做任务使用时,systemverilog会在运行时,检查源对象类型和目的对象类型不匹配,会报错;

$cast 做函数使用时,运行时,仍做类型检查,在不匹配时,不会报错,$函数返回0. 前面所述:基类句柄可以指向任何它的扩展类的对象、

1) 基类句柄指向扩展类对象——出现情况:修改蓝图,不改过多代码,增加功能 Transaction tr; //基类句柄 BadTr bad; //扩展类句柄 Bad = new();

Tr = bad; // 基类句柄指向扩展类对象 tr.display; //掉用的是扩展类的方法

2) 扩展类句柄指向基类对象——出现情况:基类virtual 方法copy函数,它的继承类中copy函数

将基类句柄赋值给扩展类句柄,使扩展类句柄指向基类对象,一般编译器会出错,不能运行,所以非常小心;只有基类句柄指向扩展类对象时,再将扩展类句柄指向基类对象时,不出错。为了检测基类句柄是否指向了扩展对象,并且不让编译器报错,可以使用$cast()函数检测。

当把扩展类句柄指向基类对象时,发生什么? Tr= new();

Bad = tr; //扩展类句柄指向基类句柄

上述会发生错误,编译不会被通过。因为有些属性在基类中不存在;但是扩展类句柄指向基类句柄不总是非法的(见下面代码,是可以的),当基类句柄指向一个扩展类对象时是允许的。

Transcation tr; BadTr bad,bad2;

Bad= new();

Tr = bad; //基类句柄指向扩展类对象 $cast(bad2,tr); //扩展类句柄指向基类对象 if(!$cast(bad2,tr);

$display(―cannot assign tr to bad2‖);

$display(bad2.bad_crc);

l 句柄类型和对象类型差异(书中翻译的不准,type of handdle 和 object) 个人理解:

Transaction tr; 句柄tr类型是transaction 句柄类型:关键字

对象类型:类中成员的类型差异

l 虚方法和多态

多态:多个程序使用一个共同的名字的现象。

多态解决问题:计算机建构面临的一个问题。让物理内存很小的情况下,让处理器能够对很大的地址空间寻址。针对这个问题引入了虚拟内存。

虚拟方法继承劣势:

基类使用了虚拟方法,扩展类也必须使用相同的―签名‖,扩展类中虚拟子程序不能增加或删除参数,这意味着必须提前做好规划。

l 对象复制

1) 因为是virtual 函数,扩展类中copy方法也必须是transaction型的, 但是要copy的是badtr类型的,所以要new一个bad 带有copy 的事物基类。 Class transaction ;

Rand bit[31:0] src,dst,data[8]; Bit[31:0] crc;

Virtual function transaction copy (); Copy = new(); Copy.src = s rc; Copy.dst = dst; Copy.data = data; Copy.crc = crc; Endfunction

Endclass

带有copy的扩展类 Calss badtr extends transaction Rand bit bad_crc;

Virtual function badtr copy(); //错误 Virtual function transaction copy(); Badtr bad; Bad = new(); Bad.src = src; bad.dst = dst; bad.data = data; bad.crc = crc; Bad.bad_crc = bad_crc; Return bad; Rendfunction endclass

2)优化途径一,创建一个独立的函数copy_data,这样每个类只负责copy其局部变量,即扩展类中的copy函数用super.copy_data(tr),代替了基类中变量的复制。代码的重用性提高。P8.22

$cast(bad,tr); //扩展类句柄指向基类句柄

使用的情况: 因为virtual 函数,在继承中,虚拟函数必须和基类中名称和参数也一致。这样扩展类中copy_data函数参数仍然是transaction类型的tr,这样出现了参数是基类句柄,但是copy_data函数内要作的确实扩展类的成员,就要将基类句柄参数赋值给扩展类句柄,

要将扩展类badtr类型的数据返回,所以必须用$cast(bad,tr)。

2) 优化途径二,最好的。前面的copy子程序都会创建一个新对象,改进的一种方法就是指定复制对象的存放地址。

Virtual function transaction copy(transaction to =null);

if(to == null) copy = new(); else copy = to; copy_data(copy); endfunction

l 抽象类和纯虚方法

背景:验证的目标之一是创建多个项目共享的代码。

目的:systemverilog 有两种方法创建共享的基类:抽象类和纯虚方法 Virtual class (抽象类):可以被扩展但是不能被直接例化。

Pure virtual function(纯虚方法):没有实体的方法原型,相当于一个声明。 1) 由抽象类扩展而来的类,只有在所以的虚拟方法都有实体的时候才能被例化, 2) 纯虚方法只能在抽象类中定义。

3)抽象类中,纯虚方法是没实体的,非纯虚方法最好也不写实体。 l 回调

背景:测试平台目的:创建一个不做任何修改就能在所有测试中使用的验证环境。要做到这点的关键是测试平台使用钩子,(什么是钩子?)钩子作用,在不修改原始类的情况下注入新的代码。采用virtual 方法,也可以在扩展类中覆盖基类方法,但是需要重复原方法的所有代码,并且它的修改将传播到它的所有扩展类中。

作用:回调就是一个钩子,在不修改原始类的情况下注入新的代码。

实现:回调任务在顶层中创建,在最低级即驱动器中调用。这样驱动器不需要知道测试的任何信息,它只需要使用一个可以在测试中扩展的通用类。

1) 使用回调注入干扰

回调的一个常见用法就是注入干扰,例如引入一个错误或者延迟。下面测试平台使用回调对象,随机地丢弃数据包。

扩展类是如何作用的?在扩展的回调类中注入错误,如何在驱动器中作用的? 关键是数据队列的作用,驱动器中使用了,回调基类的数据队列

回调基类是抽象类,在扩展的回调类中加入错误注入,而drive驱动类中,是回调基类的数据队列,在环境中将扩展类句柄让入驱动器类,回调基类的数据队列中。

begin // Create error injection callback Driver_cbs_drop dcd = new();

env.drv.cbs.push_back(dcd); // Put into driver

end

与前面扩展类作用的差异?

前面代码,要使扩展类中增加代码,需要使基类句柄指向扩展类句柄。

l 驱动器类: 下面的代码如何解释

2)回调也可以想scoreboard 发送数据或收集功能覆盖率。

优点:你可能想过将scoreboard和功能覆盖数据组置于一个事物处理器中,通过邮箱连接到测试平台中,这是一种笨拙的方法,原因如下:测试平台组件几乎都是被动和异步的,组件只有在测试平台给他数据的时候才被唤醒,而且不会主动地向下游事物处理器传递信息。麻烦:1)这样一个需要同时监视多个邮箱的事物处理器复杂了;2)你可能在多个地方采集数据,但是事物处理器设计用来处理单个数据源回调


System Verilog笔记总结(5).doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:关于成立信访稳定工作领导小组的通知

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: