Reputation: 119
If I call a task and pass an event by reference, it will not be detected inside the task after the event has been triggered:
event e;
fork
test_ev(e);
begin
#1ms;
->e;
end
join
...
task ev(ref event e);
@(e)
do_something; // this will never happen
endtask
Playing around with this test bench: http://www.edaplayground.com/x/5YS7, it would seem that some simulators like the ref event
and some don't. No compile warning is issued, but the @(..)
statement is never passed.
It seems a valid SystemVerilog use to me, is there a caveat that I'm missing?
Upvotes: 3
Views: 2546
Reputation: 7573
Passing the event as task ev(event e)
should also pass it by reference, as it happens with class objects. It doesn't really make sense to pass events by value (i.e. copy it and give the function a new event), since events don't really store data. I'm not sure if this is listed in the LRM explicitly, but IMO it's just common sense.
Tools where your block doesn't get triggered treat events as primitives and pass them by value. I would file support cases for these.
Upvotes: 4
Reputation: 42788
There is no need to pass an event variable by reference - it is already a reference.
The problem here is that SystemVerilog kludged two constructs into a single keyword. In Verilog, an event
was simply a valueless variable that you could change with a trigger ->
and wait for it to change like any other variable.
SystemVerilog enhanced the event
data type to behave more like a class variable. Except an event
does not need a constructor, any event declaration automatically constructs an event object. This keeps events backward compatible with Verilog. When you make an assignment from one event variable to another event variable, you are copying a handle to an event object. This is the same as copying a class variable - you are only copying the handle, not the object.
So to make your code work, replace ref
with input
.
Upvotes: 7