1. 类的继承
1.1 实例1 子类没有定义new函数,会调用父类new函数
**仿真结果**: >p.i = 2; >lp.i = 2;1.2 实例2
**仿真结果**: >lp.i = 3; ## 1.3 实例3 如果子类定义function new,仍会默认调用父类的new函数 **仿真结果**: >p.i = 2; >lp.i = 2;1.4 实例4
子类和父类出现同名函数function,如果子类没有使用supper.(functionname),不会调用父类的此函数。如果子类里使用supper.(functionname),即调用父类的此函数。 ## 1.5 实例5- 子类带参数,父类不带参数,仍会调用父类new函数。
- 只要父类new没有参数,就可以默认调用
- 子类必须调动父类的new函数,否则编译无法通过。
- 如果父类new函数没有参数,直接调用;如果父类new函数有参数,子类里面需要严格用supper.new
1.6 实例6
仿真结果
p.i = 4;
lp.i = 3;
after shift p.i = 8;
after shift lp.i = 12;
设置断点分析:
**注意**: 1. 子类和父类出现同名的函数或者同名的函数或者任务(同名方法),子类想要继承,需要方法名一致参数一致,调用一定写supper 2. 子类的方法名称可以与父类同名,但子类的变量最好不要跟父类的变量同名1.7 实例7 子类的句柄能够赋值给父类的句柄,父类的句柄不能赋值给子类的句柄
- 子类的句柄能够赋值给父类的句柄( ==能够访问区域缩小==),父类的句柄不能直接赋值给子类的句柄。(注意这里是不能直接赋值,在编译时父类句柄赋值给子类句柄会报错,但是在仿真运行时,若一个父类句柄指向子类对象,此时就可以将其赋值给子类句柄,采用系统函数$cast)
- lp.i只能指向子类中的i,无法指向父类的i(子类的变量跟父类的变量同名,i被覆盖);tmp.i可以指向父类的i
- lp能访问子类的i、k、m,无法访问父类的i;tmp能访问父类的i、m,但找不到子类的i、k
2. 包的使用
2.1 包的概念
为了使得可以在多个模块(硬件)或者类(软件)之间共享用户定义的类型,SV添加了包(package) 。包的概念参考于VHDL,用户自定义的类型譬如==类、方法、变量、结构体、枚举类==(==偏软件类,Module、inteface偏硬件就不能定义在包里面==)等都可以在package…endpackage中定义。
2.2 包的使用方法
module、interface、class等可以使用包中定义或者声明的内容。
导出:可以通过域的==索引符::号==直接引用。
可以==指定索引==一些需要的包中定义的类型到指定的容器中(module/class/…) 。
通过通配符$*$来将包中==所有类别导入==到指定容器中。
2.3 实例1
3. 问答题
1.在packet和linkedpacket有关类的继承的例子中(如图),tb中的句柄p是否可以访问父类的成员i?lp是否可以访问父类的成员i?句柄tmp是否可以访问子类的成员i?
代码:
/*Problem1
在packet和linkedpacket有关类的继承的例子中(如图),
tb中的句柄p是否可以访问父类的成员i?
lp是否可以访问父类的成员i?
句柄tmp是否可以访问子类的成员i?
*/
class packet;
integer i = 1;
integer m = 2;
function new(int val);
i = val + 1;
endfunction
function shift();
i = i << 1;
endfunction
endclass
class linkedpacket extends packet;
integer i = 3;
integer k = 5;
function new (val);
super.new(val);
if (val >= 2)
i = val;
endfunction
function shift();
super.shift();
i = i << 2;
endfunction
endclass
module tb;
initial begin
packet p = new(3);
linkedpacket lp = new(1);
packet tmp;
tmp = lp;
//tb中的句柄p是否可以访问父类的成员i?
$display("p.i = %0d",p.i);
//lp是否可以访问父类的成员i?
$display("lp.i = %0d",lp.i);//lp.i只能指向子类中的i,无法指向父类的i(子类的变量跟父类的变量同名,i被覆盖)
$display("lp.m = %0d",lp.m);//但lp可以访问父类的其他成员
//句柄tmp是否可以访问子类的成员i?
$display("tmp.i = %0d",tmp.i);
//$display("tmp.k = %0d",tmp.k); //ERROR:Could not find member 'k' in class 'packet', at "class_test.sv", 7.
end
endmodule
仿真结果:
p.i = 4 tb中的句柄p是否可以访问父类的成员i
lp.i = 3 lp.i只能指向子类中的i,无法指向父类的i(子类的变量跟父类的变量同名,i被覆盖)
lp.m = 2 但lp可以访问父类的其他成员
tmp.i = 2 tmp能访问父类的i、m,但找不到子类的i、k
2.试着在对应的位置填入代码,即如何导入pkg_a中的类型packet_a,从pkg_b中导入packet_b,以及从pkg_b中导入静态变量shared?
代码:
package pkt_a;
class packet_a;
int pkg_a;
endclass
typedef struct{
int data;
int command;
}struct_a;
int va = 1;
int shared = 10;
endpackage
package pkt_b;
class packet_b;
int pkg_b;
endclass
typedef struct{
int data;
int command;
}struct_b;
int vb = 2;
int shared = 20;
endpackage
module tb;
class packet_tb;
endclass
typedef struct{
int data;
int command;
}struct_tb;
class packet_a;
int tb_a;
endclass
class packet_b;
int tb_b;
endclass
//how to import type from packages can be seen as follows
//精确导出
import pkt_a::va;
import pkt_b::vb;
//import pkt_a::shared;//从pkt_a取出shared
import pkg_b::shared;//从pkt_b取出shared
////全部导出
//import pkt_a::*;
//import pkt_b::*;
initial begin
packet_a pa = new();
packet_b pb = new();
packet_tb ptb = new();
$display("pkg_a::va = %0d,pkg_b:: = %0d",va ,vb);
$display("shared = %0d", shared);
//$display("shared = %0d", pkt_b::shared);
end
endmodule
仿真结果:
pkg_a::va = 1,pkg_b:: = 2
shared = 20