2017-09-06 36 views
3

如果我所说的任务,并通过引用传递的事件,它不会被里面的任务检测到事件被触发后:Systemverilog中的事件可以通过引用传递吗?

event e; 

    fork 
    test_ev(e); 
    begin 
     #1ms; 
     ->e; 
    end 
    join 

    ... 

    task ev(ref event e); 
     @(e) 
     do_something; // this will never happen 
    endtask 

与此试验台打围:http://www.edaplayground.com/x/5YS7,这似乎有些模拟器如参考事件,有些则不。没有发出编译警告,但@(..)语句永远不会传递。

这似乎是一个有效的Systemverilog用于我,有没有我失踪的警告?

回答

7

没有必要通过引用传递事件变量 - 它已经是一个引用。

这里的问题是SystemVerilog将两个构造拼凑成一个关键字。在Verilog中,event只是一个无价值的变量,您可以使用触发器->进行更改,并等待其像任何其他变量一样更改。

SystemVerilog增强了event数据类型的行为更像一个类变量。除了event不需要构造函数外,任何事件声明都会自动构造一个事件对象。这使事件向后兼容Verilog。当您将一个事件变量赋值给另一个事件变量时,您正在将一个句柄复制到一个事件对象。这与复制类变量相同 - 只是复制句柄,而不是对象。

因此,要使您的代码正常工作,请将ref替换为input

+0

哇事件的这个类行为是不直观的..所以现在我明白为什么'输入'的作品,它是有道理的使用它的方式。我仍然好奇为什么在使用'ref'时它不起作用?不应该这样在任务内创建一个引用吗? – chinocolerico

+0

我不认为LRM在这里很清楚。由于这是对引用事件的引用,所以@e可以被解释为等待引用变为另一个事件对象,而不是事件触发器本身。可能应该被定为非法构造。 –

4

传递事件为task ev(event e)也应该通过引用传递它,就像它在类对象中发生一样。按值传递事件(即复制它并给函数一个新事件)并没有意义,因为事件并不真正存储数据。我不确定这是否明确列在LRM中,但IMO只是常识。

您的块未触发的工具将事件视为基元并按值传递。我会为这些文件提供支持案例。

+0

我同意在任何通过价值传递事件的程序中都没有意义。但是,乍看之下,我预料他们被当作一个int或bit来对待。如果将事件声明为“输入”问题,问题就会消失,就像@ dave_59所建议的那样,所以工具似乎在做正确的事情。尽管如此,仍然不确定它为什么会失败 – chinocolerico