task wait_packet;
Packet packet;
event packet_received;
@packet_received;
packet = new();
endtask
function void do_print();
wait_packet();
$display("packet received");
endfunction
function中不能使用任何延时语句。上面的例子中,function调用了一个耗时的task,这是非法的。
new()时systemverilog中类的构造函数。他在类中定义,并初始化对象。
new[]用于动态数组的内存分配。
有时候,一个类有可能引用另一个尚未编译的类,这会导致编译错误。例如,如果按照下面的顺序编译Statistics和Packet,由于在编译Statistics时,Packet尚未定义,编译器将为报错。
class Statistics;
Packet p1;
endclass
class Packet; //full definition here
endclass
为了避免这个问题,类在完全定义之前,可以先进行前置声明。
typedef Packet; //forward declaration
class Statistics;
Packet p1;
endclass
class Packet; //full definition here
endclass
task gen_packet(Packet pkt);
pkt = new();
pkt.dest = 0xABCD;
endtask
Packet pkt;
initial begin
gen_packet(pkt);
$display(pkt.dest);
end
这段代码在运行时,会产生空指针错误。task传入pkt句柄,而在内部为句柄创建了一个对象。在initial块中,调用了gen_packet,并修改了pkt.dest,但是对于task来说这些都是局部的。task的默认方向是input,在内部的修改句柄的指向并不能影响外部,尽管在task内部进行了对象例化并且修改了值,而实际上外部的pkt始终是空句柄。
你答对了吗
欢迎在留言区给出你的答案,正确答案将在下一期公布,或者到下面的文章获取答案