ch3-Event

2019-10-24

SystemVerilog Event

An event is a static object handle to synchronize between two or more concurrently active processes. One process will trigger the event, and another process waits for the event.

  • Can be assigned or compared to other event variables

    • Can be assigned to null
    • When assigned to another event, both variables point to same synchronization object
  • Can be passed to queues, functions and tasks

1
2
3
4
event  over;                     // a new event is created called over
event over_again = over; // over_again becomes an alias to over
event empty = null; // event variable with no synchronization object

How to trigger and wait for an event?

  • Named events can be triggered using -> or ->> operator
  • Processes can wait for an event using @ operator or .triggered

Example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
module tb;

// Create an event variable that processes can use to trigger and wait
event event_a;

// Thread1: Triggers the event using "->" operator
initial begin
#20 ->event_a;
$display ("[%0t] Thread1: triggered event_a", $time);
end

// Thread2: Waits for the event using "@" operator
initial begin
$display ("[%0t] Thread2: waiting for trigger ", $time);
@(event_a);
$display ("[%0t] Thread2: received event_a trigger ", $time);
end

// Thread3: Waits for the event using ".triggered"
initial begin
$display ("[%0t] Thread3: waiting for trigger ", $time);
wait(event_a.triggered);
$display ("[%0t] Thread3: received event_a trigger", $time);
end
endmodule

Simulation Log

1
2
3
4
5
6
7
ncsim> run
[0] Thread2: waiting for trigger
[0] Thread3: waiting for trigger
[20] Thread1: triggered event_a
[20] Thread2: received event_a trigger
[20] Thread3: received event_a trigger
ncsim: *W,RNQUIE: Simulation is complete.

Click to try this example in a simulator! img

What is the difference between @ and .triggered ?

An event’s triggered state persists throughout the time step(triggered状态在时间片内都敏感), until simulation advances. Hence if both wait for the event and trigger of the event happens at the same time there will be a race condition and the triggered property helps to avoid that.

A process that waits on the triggered state always unblocks, regardless of the order of wait and trigger.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
module tb;

// Create an event variable that processes can use to trigger and wait
event event_a;

// Thread1: Triggers the event using "->" operator at 20ns
initial begin
#20 ->event_a;
$display ("[%0t] Thread1: triggered event_a", $time);
end

// Thread2: Starts waiting for the event using "@" operator at 20ns
initial begin
$display ("[%0t] Thread2: waiting for trigger ", $time);
#20 @(event_a);
$display ("[%0t] Thread2: received event_a trigger ", $time);
end

// Thread3: Starts waiting for the event using ".triggered" at 20ns
initial begin
$display ("[%0t] Thread3: waiting for trigger ", $time);
#20 wait(event_a.triggered);
$display ("[%0t] Thread3: received event_a trigger", $time);
end
endmodule

Note that Thread2 never received a trigger, because of the race condition between @ and -> operations.(但是triggered状态能够采样到->操作)

Simulation Log

1
2
3
4
5
6
ncsim> run
[0] Thread2: waiting for trigger
[0] Thread3: waiting for trigger
[20] Thread1: triggered event_a
[20] Thread3: received event_a trigger
ncsim: *W,RNQUIE: Simulation is complete.

Click to try this example in a simulator! img

wait_order(顺序触发)

Waits for events to be triggered in the given order, and issues an error if any event executes out of order.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
module tb;
// Declare three events that can be triggered separately
event a, b, c;

// This block triggers each event one by one
initial begin
#10 -> a;
#10 -> b;
#10 -> c;
end

// This block waits until each event is triggered in the given order
initial begin

wait_order (a,b,c)
$display ("Events were executed in the correct order");
else
$display ("Events were NOT executed in the correct order !");
end
endmodule

Simulation Log

1
2
3
Compiler version J-2014.12-SP1-1; Runtime version J-2014.12-SP1-1;
Events were executed in the correct order
V C S S i m u l a t i o n R e p o r t

Click to try this example in a simulator! img

Merging Events

When one event variable is assigned to another, all processes waiting for the first event to trigger will wait until the second variable is triggered.(这句话不知道是什么鸟语,看下面程序的执行结果和自己的理解,就是事件赋值而已)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
module tb;

// Create event variables
event event_a, event_b;

initial begin
fork
// Thread1: waits for event_a to be triggered
begin
wait(event_a.triggered);
$display ("[%0t] Thread1: Wait for event_a is over", $time);
end
// Thread2: waits for event_b to be triggered
begin
wait(event_b.triggered);
$display ("[%0t] Thread2: Wait for event_b is over", $time);
end

// Thread3: triggers event_a at 20ns
#20 ->event_a;

// Thread4: triggers event_b at 30ns
#30 ->event_b;

// Thread5: Assigns event_b to event_a at 10ns
begin
// Comment code below and try again to see Thread2 finish later
#10 event_b = event_a;
end
join
end
endmodule

Simulation Log

1
2
3
4
ncsim> run
[20] Thread1: Wait for event_a is over
[20] Thread2: Wait for event_b is over
ncsim: *W,RNQUIE: Simulation is complete.

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!