Lec10 Threads
Transcript of Lec10 Threads
7/25/2019 Lec10 Threads
http://slidepdf.com/reader/full/lec10-threads 1/25
ASIC Verification
Threads
7/25/2019 Lec10 Threads
http://slidepdf.com/reader/full/lec10-threads 2/25
Topics
• Threads
• fork..join, fork…join_any, fork…join_none
• Creating dynamic threads
• Using automatic variables
• Process control
7/25/2019 Lec10 Threads
http://slidepdf.com/reader/full/lec10-threads 3/25
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
7/25/2019 Lec10 Threads
http://slidepdf.com/reader/full/lec10-threads 4/25
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
join
fork fork
join_any join_none
7/25/2019 Lec10 Threads
http://slidepdf.com/reader/full/lec10-threads 5/25
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
$display( "First Block\n" );
# 20ns;
end begin
$display( "Second Block\n" );
@eventA;
end join
Process 1
Process 2
7/25/2019 Lec10 Threads
http://slidepdf.com/reader/full/lec10-threads 6/25
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
join
begin $display("First Block \n”);
# 20ns;
end
begin $display(”Second Block \n”);
@eventA;
end
7/25/2019 Lec10 Threads
http://slidepdf.com/reader/full/lec10-threads 7/25
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
$display( "First Block\n" );
# 20ns;
end begin
$display( "Second Block\n" );
@eventA;
end join_any
Process 1
Process 2
7/25/2019 Lec10 Threads
http://slidepdf.com/reader/full/lec10-threads 8/25
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
join_any
begin
$display("First Block \n”);# 20ns;
end
begin
$display(”Second Block \n”);@eventA;
end
7/25/2019 Lec10 Threads
http://slidepdf.com/reader/full/lec10-threads 9/25
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
$display( "First Block\n" );
# 20ns;
end begin
$display( "Second Block\n" );
@eventA;
end join_none
Process 1
Process 2
7/25/2019 Lec10 Threads
http://slidepdf.com/reader/full/lec10-threads 10/25
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
join_none
begin $display("First Block \n”);
# 20ns;
end
begin $display(”Second Block \n”);
@eventA;
end
7/25/2019 Lec10 Threads
http://slidepdf.com/reader/full/lec10-threads 11/25
Working with Threads
•
fork…join and begin…end example
initial begin $display(“@%0d: starts fork…join example”,$time);
#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);
begin #30 $display(“@%0d: sequential after #30”,$time);
#10 $display(“@%0d: sequential after #10”,$time);
end join $display(“@%0d: after join”,$time);
#80 $display(“@%0d: final after #80”,$time);
end
Parent
Parent
Child Threads
7/25/2019 Lec10 Threads
http://slidepdf.com/reader/full/lec10-threads 12/25
Working with Threads
• fork…join and begin…end example
Parent
Child Threads
@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
$display(“@%0d: starts fork…join example”,$time);#10 $display(“@%0d: sequential after #10”,$time);
$display(“@%0d: parallel start”,$time);
#50 $display(“@%0d: parallel after #50”,$time);
#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
7/25/2019 Lec10 Threads
http://slidepdf.com/reader/full/lec10-threads 13/25
Working with Threads
•
fork…join_any and begin…end example
initial begin $display(“@%0d: starts fork…join_any example”,$time);
#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);
begin #30 $display(“@%0d: sequential after #30”,$time);
#10 $display(“@%0d: sequential after #10”,$time);
end join_any $display(“@%0d: after join”,$time);
#80 $display(“@%0d: final after #80”,$time);
end
Parent
Parent
Child Threads
7/25/2019 Lec10 Threads
http://slidepdf.com/reader/full/lec10-threads 14/25
Working with Threads
• fork…join_any and begin…end example
Parent
Child Threads
@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
$display(“@%0d: starts fork…join_any example”,$time);#10 $display(“@%0d: sequential after #10”,$time);
$display(“@%0d: parallel start”,$time);
#50 $display(“@%0d: parallel after #50”,$time);
#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
7/25/2019 Lec10 Threads
http://slidepdf.com/reader/full/lec10-threads 15/25
Working with Threads
•
fork…join_none and begin…end example
initial begin $display(“@%0d: starts fork…join_none example”,$time);
#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);
begin #30 $display(“@%0d: sequential after #30”,$time);
#10 $display(“@%0d: sequential after #10”,$time);
end join_none $display(“@%0d: after join”,$time);
#80 $display(“@%0d: final after #80”,$time);
end
Parent
Parent
Child Threads
7/25/2019 Lec10 Threads
http://slidepdf.com/reader/full/lec10-threads 16/25
Working with Threads
• fork…join_none and begin…end example
Parent
Child Threads
@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
$display(“@%0d: starts fork…join_none example”,$time);#10 $display(“@%0d: sequential after #10”,$time);
$display(“@%0d: parallel start”,$time);
#50 $display(“@%0d: parallel after #50”,$time);
#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
7/25/2019 Lec10 Threads
http://slidepdf.com/reader/full/lec10-threads 17/25
Automatic Variables in Threads
• Avoiding Bugs
program no_auto;
intial begin
for(int j=0; j<3; j++)
fork
$write(j);
join_none
#0 $display (“\n”); end
endprogram
j statement
0 for (j=0; …
0 Spawn $write j [thread 0]
1 j++ j=1
1 Spawn $write j [thread 1]
2 j++ j=2
2 Spawn $write j [thread 2]
3 j++ j=3
3 join_none
3 #0
3 $write(j) [thread 0: j=3]
3 $write(j) [thread 0: j=3]
3 $write(j) [thread 0: j=3]
3 $display()
7/25/2019 Lec10 Threads
http://slidepdf.com/reader/full/lec10-threads 18/25
Automatic Variables in Threads
• Avoiding Bugs
Program auto;intial begin
for(int j=0; j<3; j++)
fork
automatic int k=j;$write(k);
join_none
#0 $display (“\n”); end
endprogram
j k0 k1 k2 statement
0 for (j=0; …
0 0 Create k0, Spawn $write k
[thread 0]
1 0 j++
1 0 1 Create k1, Spawn $write k
[thread1]
2 0 1 j++
2 0 1 2 Create k2, Spawn $write k
[thread 2]
3 0 1 2 j<3
3 0 1 2 join_none
3 0 1 2 #0
3 0 1 2 $write(k0) [thread 0]
3 0 1 2 $write(k1) [thread 1]
3 0 1 2 $write(k2) [thread 2]
3 0 1 2 $display()
7/25/2019 Lec10 Threads
http://slidepdf.com/reader/full/lec10-threads 19/25
Dynamic Thread Creation
• Creating dynamic threads
program test(busif.TB bus);task check_trans(Transaction tr);
fork
begin
wait (bus.cb.addr != tr.addr);
$display("@%0d: Addr match %d", $time, tr.addr);
end
join_none
endtask
Transaction tr;
initial begin
repeat (10)
begin
tr = new();assert(tr.randomize);
transmit(tr);
check_trans(tr);
end
#100
end
endprogram
Create a random transaction
Send it into the DUT
Wait for reply from DUT
7/25/2019 Lec10 Threads
http://slidepdf.com/reader/full/lec10-threads 20/25
Dynamic Thread Creation
• Creating dynamic threads
program automatic test(busif.TB bus);task check_trans(Transaction tr);
fork
begin
wait (bus.cb.addr != tr.addr);
$display("@%0d: Addr match %d", $time, tr.addr);
end
join_none
endtask
Transaction tr;
initial begin
repeat (10)
begin
tr = new();assert(tr.randomize);
transmit(tr);
check_trans(tr);
end
#100
end
endprogram
Create a random transaction
Send it into the DUT
Wait for reply from DUT
7/25/2019 Lec10 Threads
http://slidepdf.com/reader/full/lec10-threads 21/25
Threads: Process Control
• wait…fork
SystemVerilog provides a construct wait fork that waits for thecompletion of other processes
The wait fork is used to ensure that all child processes (processes
created by the calling process) have completed their execution
Specifying a wait fork causes the calling process to block until all its
sub-processes have completed
task run_threads;fork check_trans(tr1);
check_trans(tr2);
check_trans(tr3);
join_none wait fork;
endtask
wait fork statement shall ensure
that the task run_threads waits for all
spawned processes to complete
before returning to its caller
Block until
check_trans(tr1),
check_trans(tr2),
check_trans(tr3) complete
7/25/2019 Lec10 Threads
http://slidepdf.com/reader/full/lec10-threads 22/25
Threads: Process Control
• disable…fork
SystemVerilog provides a construct disable fork that stops theexecution of processes
The disable fork statement terminates all descendants of the calling
process, as well as the descendants of the process descendants, that is, ifany child process has descendants of their own, the disable fork
statement terminates them as well
task get_first( output int addr );fork wait_device( 1, addr );
wait_device( 7, addr );
wait_device( 13, addr );
join_any disable fork;
endtask
In the example get_first spawns three
versions of a task that wait for a particulardevice (1,7 or 13). The task wait_device
waits for a particular device to become
ready and then returns the device’s
address. When the first device becomesavailable, the get_first task shall
resume execution and proceed to kill theoutstanding wait_device request
Disable ends all processes whereas disable fork only ends the process spawned by the calling thread
7/25/2019 Lec10 Threads
http://slidepdf.com/reader/full/lec10-threads 23/25
Threads: Process Control
program test(busif.TB bus);
task check_trans(Transaction tr);fork
begin
wait (bus.cb.addr != tr.addr);
end
join_none
endtask
Transaction tr;
initial begin
check_trans(tr0);
fork
begin
check_trans(tr1);
forkcheck_trans(tr2);
join
#(TIME_OUT) disable fork;
end
join
end
endprogram
initial begin
check_trans(tr0);
fork
…
join
end
Thread 0
Thread 1
check_trans(tr1);
fork
…
joinend
#TIME_OUT/2
disable fork
Thread 2
Thread 3check_trans(tr2);
Thread 4
• disable…fork
7/25/2019 Lec10 Threads
http://slidepdf.com/reader/full/lec10-threads 24/25
Threads: Process Control
initial begin
check_trans(tr0);
fork
begin : threads_innercheck_trans(tr1);
check_trans(tr2);
end
#(TIME_OUT/2) disable threads_inner;
join
end
endprogram
• disable…fork: with explicit labels
7/25/2019 Lec10 Threads
http://slidepdf.com/reader/full/lec10-threads 25/25
Thank You