学习目标:
SV绿皮书第八章:面向对象编程的高级技巧指南
学习内容:
1.继承允许从一个现存的类得到一个新的类,并共享其变量和子程序。原始类被称为基类或者超类,而新类因为它扩展了基类的功能,被称为扩展类。
2.扩展类调用基类函数—super.函数(注意:不能多层调用)
3.应该将类中的子程序定义为虚拟的(virtual),这样就能在扩展类中重定义,这一点适用于所有任务和函数(除了new函数,SV始终基于句柄类型来调用new函数)
4.如果你的基类构造函数带有参数,那么扩展类必须有一个构造函数而且必须在其构造函数的第一行调用基类的构造函数。
class Basel;
int var;
function new(input int var); //带有参数的构造函数
this.var=var;
endfunction
endclass
class Extended extends Basel;
function new(input int var); //需要参数
super.new(var); //必须是new函数的第一行
//构造函数的其他行为
endfunction
endclass
5.使用蓝图模式的发生器类
class Generator;
mailbox gen2drv;
Transaction blueprint;
function new(input mailbox gen2drv);
this.gen2drv=gen2drv;
blueprint=new();
endfunction
task run;
Transaction tr;
forever begin
assert(blueprint.randomize);
tr=blueprint.copy();
gen2drv.put(tr);
end
endtask
endclass
6.使用$cast作类型向下转换(类型向下转换或者类型变换是指一个指向基类的指针转换成一个指向派生类的指针)
7.基类句柄指向扩展对象是允许的,扩展句柄指向基类对象并不总是非法的(可以使用$cast(bad2,tr);来检查源对象和目的对象是否为同一类型)--------------基类中有的扩展类也有,扩展类有的基类不一定有
8.当需要决定调用哪个虚方法的时候,SV根据对象的类型,而非句柄的类型来决定调用什么方法。
如果没有使用virtual修饰符,SV会根据句柄的类型,而不是对象的类型。
9.对象复制的方法:copy函数、copy_data方法、指定复制的目标
//带copy虚函数的事务基类
class Transaction;
rand bit[31:0]src,dst,data[8];
bit[31:0]crc;
virtual function Transaction copy();
copy=new();
copy.src=src;
copy.dst=dst;
copy.data=data;
copy.crc=crc;
ednfunction
endclass
//带有copy虚函数的扩展事务类
class BadTr extends Transaction;
rand bit crc;
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;
ednfunction
endclass
//使用copy_data函数的事务基类
class Transaction;
rand bit[31:0]src,dst,data[8];
bit[31:0]crc;
virtual function void copy_data(input Transaction tr);
copy.src=src;
copy.dst=dst;
copy.data=data;
copy.crc=crc;
ednfunction
virtual function Transaction copy();
copy=new();
copy_data(copy);
endfunction
endclass
//使用copy_data函数的扩展事务类
class BadTr extends Transaction;
rand bit crc;
virtual function void copy_data(input Transaction tr);
BadTr bad;
super.copy_data(tr);
$cast(bad,tr);
bad.bad_crc=bad_crc;
ednfunction
virtual function Transaction copy();
BadTr bad;
bad=new();
copy_data(bad);
return bad;
endfunction
endclass
//指定复制的目标,copy函数的一种改进方法就是指定复制对象的存放地址
class Transaction;
virtual function Transaction copy(Transaction to=null);
if(to==null)
copy=new();
else
copy=to;
copy_data(copy);
endfunction
//使用上面copy_data方法
endclass
//含有新copy函数的扩展事务类
class BadTr;
virtual function Transaction copy(Transaction to=null);
BadTr badd;
if(to==null)
bad=new(); //创建一个新对象
else
assert($cast(bad,to);); //重用已有对象
copy_data(bad);
return bad;
endfunction
endclassBadTr
10.SV允许你使用两种构造方法来创建一个可以共享的基类:抽象类(可以扩展但不能被直接实例化)、纯虚方法(没有实体的方法原型—空壳)
11.一个抽象类扩展而得来的类只有在所有虚方法都有实体的时候才能被例化
12.关键词“pure”表明一个方法是原型定义,而不仅仅是空的虚方法
13.纯虚方法只能在抽象类中定义,但是抽象类中也可以定义非纯方法
14.一个回调任务应该在顶层测试中创建,在环境中的最低级即驱动器中调用
15.驱动器使用一个队列来保存回调对象,这样就可以增加多个对象。回调基类是一个抽象类,使用前必须先进行扩展。
问题:
P237-P241 回调和记分板
学习时间:
早:9.30-11.30
中:15-17