Working with Threads
¥! Grouping Statements
!! Classic Verilog has two ways of grouping statements
!! Using beginÉend : Statements run sequentially
!! Using forkÉjoin : Statements run in parallel
¥! forkÉjoin
!! forkÉjoin construct enables the creation of concurrent processes from
each of its parallel statements
© Engineering Design Institute 3
Working with Threads
¥! join, join_any, join_none
!! SystemVerilog uses three ways for specifying when the parent process
resumes execution
!! forkÉjoin
!! forkÉjoin_any
!! forkÉjoin_none
fork fork fork
join join_any join_none
© Engineering Design Institute 4
2
Working with Threads
¥! forkÉjoin
!! The parent process blocks until all the processes spawned by this fork
complete
!! When defining a forkÉjoin block, encapsulating the entire fork within a
beginÉend block causes the entire block to execute as a single process,
with each statement executing sequentially
¥! forkÉjoin example
fork
begin Process 1
$display( "First Block\n" );
# 20ns;
end
begin Process 2
$display( "Second Block\n" );
@eventA;
end
join
© Engineering Design Institute 5
Working with Threads
¥! forkÉjoin example (cont.)
!! In the example two processes are forked
!! The first process waits for 20 ns
!! The second process waits for the named event eventA to be triggered
!! Because the join keyword is specified, the parent process shall block until
the two processes complete; that is, until 20ns have elapsed and eventA
has been triggered fork
begin begin
$display("First Block \n); $display(Second Block \n);
# 20ns; @eventA;
end end
join
© Engineering Design Institute 6
3
Working with Threads
¥! forkÉjoin_any
!! The parent process blocks until any one of the processes spawned by this
fork complete
¥! forkÉjoin_any example
fork
begin Process 1
$display( "First Block\n" );
# 20ns;
end
begin Process 2
$display( "Second Block\n" );
@eventA;
end
join_any
© Engineering Design Institute 7
Working with Threads
¥! forkÉjoin_any example (cont.)
!! In the example two processes are forked
!! The first process waits for 20 ns
!! The second process waits for the named event eventA to be triggered
!! Because the join_any keyword is specified, the parent process shall block
until any one of the two processes complete; that is, until 20ns have elapsed
or eventA has been triggered
fork
begin begin
$display("First Block \n); $display(Second Block \n);
# 20ns; @eventA;
end end
join_any
© Engineering Design Institute 8
4
Working with Threads
¥! forkÉjoin_none
!! The parent process continues to execute concurrently with all the processes
spawned by the fork. The spawned processes do not start executing until
the parent thread executes a blocking statement
¥! forkÉjoin_none example
fork
begin Process 1
$display( "First Block\n" );
# 20ns;
end
begin Process 2
$display( "Second Block\n" );
@eventA;
end
join_none
© Engineering Design Institute 9
Working with Threads
¥! forkÉjoin_none example (cont.)
!! In the example two processes are forked
!! The first process waits for 20 ns
!! The second process waits for the named event eventA to be triggered
!! Because the join_none keyword is specified, the parent process shall
continue to execute with the other two processes.
fork
begin begin
$display("First Block \n); $display(Second Block \n);
# 20ns; @eventA;
end end
join_none
© Engineering Design Institute 10
5
Working with Threads
¥! forkÉjoin and beginÉend example
initial begin
$display(@%0d: starts forkÉjoin example,$time);
Parent
#10 $display(@%0d: sequential after #10,$time);
fork
$display(@%0d: parallel start,$time);
#50 $display(@%0d: parallel after #50,$time);
#10 $display(@%0d: parallel after #10,$time); Child Threads
begin
#30 $display(@%0d: sequential after #30,$time);
#10 $display(@%0d: sequential after #10,$time);
end
join
$display(@%0d: after join,$time);
Parent
#80 $display(@%0d: final after #80,$time);
end
© Engineering Design Institute 11
Working with Threads
¥! forkÉjoin and beginÉend example
$display(@%0d: starts forkÉjoin example,$time);
#10 $display(@%0d: sequential after #10,$time);
Parent
$display(@%0d: parallel start,$time);
#50 $display(@%0d: parallel after #50,$time);
Child Threads
#10 $display(@%0d: parallel after #10,$time);
#30 $display(@%0d: sequential after #30,$time);
#10 $display(@%0d: sequential after #10,$time);
$display(@%0d: after join,$time);
#80 $display(@%0d: final after #80,$time); Parent
@0: starts forkÉjoin example
@10: sequential after #10
@10: parallel start
@20: parallel after #10
@40: sequential after #30
@50: sequential after #10
@60: parallel after #50
@60: after join
@140: final after #80
© Engineering Design Institute 12
6
Working with Threads
¥! forkÉjoin_any and beginÉend example
initial begin
$display(@%0d: starts forkÉjoin_any example,$time); Parent
#10 $display(@%0d: sequential after #10,$time);
fork
$display(@%0d: parallel start,$time);
#50 $display(@%0d: parallel after #50,$time);
#10 $display(@%0d: parallel after #10,$time); Child Threads
begin
#30 $display(@%0d: sequential after #30,$time);
#10 $display(@%0d: sequential after #10,$time);
end
join_any
$display(@%0d: after join,$time);
Parent
#80 $display(@%0d: final after #80,$time);
end
© Engineering Design Institute 13
Working with Threads
¥! forkÉjoin_any and beginÉend example
$display(@%0d: starts forkÉjoin_any example,$time);
#10 $display(@%0d: sequential after #10,$time); Parent
$display(@%0d: parallel start,$time);
#50 $display(@%0d: parallel after #50,$time);
Child Threads
#10 $display(@%0d: parallel after #10,$time);
#30 $display(@%0d: sequential after #30,$time);
#10 $display(@%0d: sequential after #10,$time);
$display(@%0d: after join,$time);
#80 $display(@%0d: final after #80,$time); Parent
@0: starts forkÉjoin_any example
@10: sequential after #10
@10: parallel start
@10: after join
@20: parallel after #10
@40: sequential after #30
@50: sequential after #10
@60: parallel after #50
@90: final after #80
© Engineering Design Institute 14
7
Working with Threads
¥! forkÉjoin_none and beginÉend example
initial begin
$display(@%0d: starts forkÉjoin_none example,$time); Parent
#10 $display(@%0d: sequential after #10,$time);
fork
$display(@%0d: parallel start,$time);
#50 $display(@%0d: parallel after #50,$time);
#10 $display(@%0d: parallel after #10,$time); Child Threads
begin
#30 $display(@%0d: sequential after #30,$time);
#10 $display(@%0d: sequential after #10,$time);
end
join_none
$display(@%0d: after join,$time);
Parent
#80 $display(@%0d: final after #80,$time);
end
© Engineering Design Institute 15
Working with Threads
¥! forkÉjoin_none and beginÉend example
$display(@%0d: starts forkÉjoin_none example,$time);
#10 $display(@%0d: sequential after #10,$time);
Parent
$display(@%0d: parallel start,$time);
#50 $display(@%0d: parallel after #50,$time);
Child Threads
#10 $display(@%0d: parallel after #10,$time);
#30 $display(@%0d: sequential after #30,$time);
#10 $display(@%0d: sequential after #10,$time);
$display(@%0d: after join,$time);
#80 $display(@%0d: final after #80,$time); Parent
@0: starts forkÉjoin_none example
@10: sequential after #10
@10: after join
@10: parallel start
@20: parallel after #10
@40: sequential after #30
@50: sequential after #10
@60: parallel after #50
@90: final after #80
© Engineering Design Institute 16