I have the following code.
According to my understanding the fork-join should wat for all the child processes to be completed.
Inside process B, I am waiting for an event which never happened. Shouldn’t this code end up in timeout ?
module top();
event e1;
bit clk;
task process_A();
$display("@%0t: Before triggering event e1", $time);
->e1;
$display("@%0t: After triggering event e1", $time);
endtask
task process_B();
#10;
$display("@%0t: waiting for the event e1", $time);
//@e1;
@(posedge clk);
$display("@%0t: event e1 is triggered", $time);
endtask
initial begin
fork
process_A();
process_B();
join
#10;
end
endmodule
Simulation result says
@0: Before triggering event e1
@0: After triggering event e1
@10: waiting for the event e1
Time: 10 ns
I thought the end time will be minimum 20ns as I have a 10ns delay at the end
Your code can never reach the #10 because the join never happens. The simulation ends at 10 because it has deadlocked - there is nothing left to simulate.
No, that’s not how SystemVerilog events work. When an event (like e1) is triggered, it does not remain “active” indefinitely. Events in SystemVerilog are transient, meaning they are active only at the exact simulation time when they are triggered. If no process is waiting for the event (@e1) at that specific moment, the event is essentially lost.
For this scenario, you can use a semaphore instead of an event.
module top();
semaphore e1 = new();
task process_A();
#5
$display("@%0t: Before put e1", $time);
e1.put();
$display("@%0t: After put e1", $time);
endtask
task process_B();
#10;
$display("@%0t: waiting for the get e1", $time);
e1.get();
$display("@%0t: put e1 is got", $time);
endtask
initial begin
fork
process_A();
process_B();
join
#10;
$display("@%0t: joined", $time);
end
endmodule