本文已参与「新人创作礼」活动,一起开启掘金创作之路!
1、构造函数
System Verilog不需要复杂的内存分配和C++的分配。构造对象很简单,隐式和自动地收集垃圾。
SystemVerilog可以在创建对象时初始化实例。例如,创建对象时,
Packet p = new;
系统执行与class关联的新函数:
class Packet;
integer command;
function new();
command = IDLE;
endfunction
endclass
new 被用在两个语义截然不同的环境中。变量声明创建一个类 Packet的对象。在实例的过程中,会调用new 函数,在这个函数中可以完成初始化,new 函数也称为类构造函数(class constructor)。
new 操作被定义为无返回类型的函数,与任何其他函数一样,是非阻塞的;即使new没有指定返回类型,赋值的左侧也会确定返回类型。
如果一个类没有提供用户定义的显式 new方法,则应自动提供隐式 new方法;派生类的 new方法应首先调用其基类构造函数[super.new()]。基类构造函数(base class constructor)调用完成后,类中定义的每个属性都应初始化为其显式默认值,如未提供默认值,则初始化为其未初始化值。属性初始化后,应评估用户定义构造函数中的剩余代码,默认构造函数在属性初始化后没有额外的效应,属性在初始化前的值应未定义。
class C;
int c1 = 1;
int c2 = 1;
int c3 = 1;
function new(int a);
c2 = 2;
c3 = a;
endfunction
endclass
class D extends C;
int d1 = 4;
int d2 = c2;
int d3 = 6;
function new;
super.new(d3);
endfunction
endclass
D类对象构造完成后,其特性如下:
- c1的值为1
- c2的值为2,构造函数赋值发生在属性初始化之后
- c3有一个未定义的值,因为来自D的构造函数调用传递了d3的值,当调用super.new(d3)时,d3的值未定义。
- d1的值为4
- d2的值为2,因为super.new 的调用在d2初始化时完成。
- d3的值为6
还可以将参数传递给构造函数,允许对对象运行时自定义:
Packet p = new(STARTUP, $random, $time);
Packet 中的new 初始化任务可能如下所示:
function new(int cmd = IDLE, bit[12:0] adrs = 0, int cmd_time );
command = cmd;
address = adrs;
time_requested = cmd_time;
endfunction
参数的约定与子例程调用的约定相同,构造函数可以声明为local或protected的方法,构造函数不得声明为静态方法或虚拟方法。