SystemVerilog Classes 类的基础知识(2)

608 阅读2分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路!

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

参数的约定与子例程调用的约定相同,构造函数可以声明为localprotected的方法,构造函数不得声明为静态方法或虚拟方法