Systemverilog(5)

2020-02-20 23:21

function new(input int var); super.new(var); endfunction endclass

3)OPP规则指出:基类的句柄,也可以指向扩展类的对象。(好好体会)

l 蓝图模式

1)背景:一个简单的发生器,通过信箱将数据传递给驱动器。 class generator mailbox gen2drv; transaction tr;

function new(input mailbox gen2drv) this.gen2drv = gen2drv; endfunction task run; forever begin tr = new(); assert(tr.randmize);

gen2drv.put(tr); //mail.put(x) end endtask endclass

存在问题:这个例子在循环内部创建事务对象,而不是在循环外部,避免了测试平台常见的错误。New()放在循环外部,错误原因是,mailbox中放入的是句柄,而不能是对象,所有的句柄都指向同一个对象。(1)任务Run创建了一个事物并立即随机化,意味着事务使用了默认的所有约束。要修改,必须要修改transaction类。(2)无法使用扩展

解决办法:将tr的创建和初始化分开,使用蓝图模式。

另一个问题:如果简单的把创建和初始化分开,而放在循环外部,而避免测试平台错误(P200),如何解决?蓝图模式如何解决

2)蓝图模式概念:

首先构建一个对象蓝图(金属模),然后修改它的约束,甚至可以用扩展对象替换它,随机化这个蓝图时,就得到想赋予的随机值;然后复制这个对象,将copy发给下游。

蓝图:是一个钩子,允许你改变发生器类的行为而无需修改其类代码。蓝图对象在一个地方构建(new()),在另一个地方(任务run)使用

3)P200与P221相对比分析:重要

蓝图模式,也就比new()在循环外地generator多了一个copy函数。问题(1)蓝图模式,new()在循环外,也只有一个对象,而mailbox中放入的只能是句柄,如何解决常见的平台错误?

因为copy,是对象的复制,而不是句柄的复制。这样蓝图模式只有一个句柄,但是随机化后,copy,相当于再循环中创建了许多对象。而测试平台常见错误的本质是,只创建了一个对象。这样就避免了问题。

(2)蓝图模式下,因为只有一个ID号,那么任务run循环中,下发了许多数据,这些只有一个ID号了?

因为copy是对象的复制,所以在copy中ID号也会增加。下发的每个数据,都有各自的ID号。

l 使用扩展的transaction

为了注入错误,需要将蓝图对象transaction变成Badtransaction(改变蓝图)。必须在环境的创建和运行阶段之间完成这个操作。注意:所有的badTr引用都在这一个文件中,这样就不需要改变environment类或generator类。

Env.build(); Begin

Badtr bad = new(); Env.gen.blueprint = bad; End Env.run

目的是:将一个对象取代另一个对象。New()后都是对象了,将对象赋值给对象,这是什么写法?不是复制呀?复制本质是将一个句柄指向一个对象。

解释:上述是句柄的复制,将扩展类句柄bad赋值给基类句柄blueprint,这样基类句柄指向扩展类对象,后面的代码调用的时候,就直接指向扩展类bad了,改变了蓝图。

l Env.new()和nev.build()区别 Env.new()仅仅new()函数

nev.build()是将各个模块new(),并传达一些参数,通过这些参数将环境的各个模块,连接起来。P213

l $cast 作类型向下转换

背景:基类句柄可以指向扩展类对象,不需要额外的代码; 扩展类句柄指向基类对象,一般情况下会出错,但有时候是可以的,前提是基类句柄指向了它的一个扩展类对象。

作用:扩展类句柄指向基类对象时,使用$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;


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

下一篇:塑料模复习资料9

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

马上注册会员

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