The fork...join construct enables the creation of concurrent processes from each of its parallel statements.
SystemVerilog provides following version's of fork-join.
1.fork ... join //(join all)
2.fork ... join_none
3.fork ... join_any
4.disable fork ; //yes we need to use ; here , part of syntax
5.wait fork ; //yes we need to use ; here , part of syntax
//example 1
fork
p1 //suppose it takes 2ns
p2 //suppose it takes 3ns
join // p1 and p2 are parallel here
p3 // p3 will be executed only after finishing the process p1 and p2, means only after the time 3ns
//example 2
fork
begin
p1 //suppose it takes 2ns
p2 //suppose it takes 3ns
end
join // p1 and p2 are parallel here
p3 // p3 will be executed only after finishing the process p1 and p2, means only after the time 5ns, using begin end making it sequential
//example 3
fork
p1 //suppose it takes 2ns
p2 //suppose it takes 3ns
join_any // p1 and p2 are parallel here
p3 // p3 will be executed only after finishing the any of the process, whatever takes less time means only after the time 3ns(p2)
//example 4
fork
begin
p1 //suppose it takes 2ns
p2 //suppose it takes 3ns
end
join_any // p1 and p2 are parallel here
p3 // p3 will be executed only after finishing the process p1 and p2, means only after the time 5ns, using begin end making it sequential
If we want to run all the process parallel and we want to wait for the completion of all the threads before any new step to be executed
use wait fork like this
//example 5
foreach[i] //i is an 8 bit array which will give 8 values , so the loop will be executed 8 times
begin
fork
begin // this begin will make the p1 and p2 sequential otherwise p1 and p2 will execute simultaneously as soon as the foreach loop starts
p1 //process p1 or thread p1
p2 //process p2 or thread p2
end
join_none
end
wait fork ;
//example 6
fork
p1
p2
join_any
disable fork;
in join_any , if one process is complete, and it is out form fork , but the other process will be running in the background and if we dont need it, we use disable fork .
Note from : (http://stackoverflow.com/questions/14287446/proper-use-of-disable-fork-in-systemverilog)
Next interesting scenario: you have exited fork loop by join_none or join_any and after some steps, you want to kill just one thread (out of many). The solution, have named begin end block and call "disable ". (For example, in the last example if you want to kill only the 2nd thread after exiting the loop via join_any/join_none, then add "disable Second_thread;" at the point where you want to disable the second thread
General Note 1 : While learning SV or UVM, we also need to learn the appropriate term and the actual meaning of that word, so that we can co-relate it better.
SystemVerilog provides following version's of fork-join.
1.fork ... join //(join all)
2.fork ... join_none
3.fork ... join_any
4.disable fork ; //yes we need to use ; here , part of syntax
5.wait fork ; //yes we need to use ; here , part of syntax
//example 1
fork
p1 //suppose it takes 2ns
p2 //suppose it takes 3ns
join // p1 and p2 are parallel here
p3 // p3 will be executed only after finishing the process p1 and p2, means only after the time 3ns
//example 2
fork
begin
p1 //suppose it takes 2ns
p2 //suppose it takes 3ns
end
join // p1 and p2 are parallel here
p3 // p3 will be executed only after finishing the process p1 and p2, means only after the time 5ns, using begin end making it sequential
//example 3
fork
p1 //suppose it takes 2ns
p2 //suppose it takes 3ns
join_any // p1 and p2 are parallel here
p3 // p3 will be executed only after finishing the any of the process, whatever takes less time means only after the time 3ns(p2)
//example 4
fork
begin
p1 //suppose it takes 2ns
p2 //suppose it takes 3ns
end
join_any // p1 and p2 are parallel here
p3 // p3 will be executed only after finishing the process p1 and p2, means only after the time 5ns, using begin end making it sequential
If we want to run all the process parallel and we want to wait for the completion of all the threads before any new step to be executed
use wait fork like this
//example 5
foreach[i] //i is an 8 bit array which will give 8 values , so the loop will be executed 8 times
begin
fork
begin // this begin will make the p1 and p2 sequential otherwise p1 and p2 will execute simultaneously as soon as the foreach loop starts
p1 //process p1 or thread p1
p2 //process p2 or thread p2
end
join_none
end
wait fork ;
//example 6
fork
p1
p2
join_any
disable fork;
in join_any , if one process is complete, and it is out form fork , but the other process will be running in the background and if we dont need it, we use disable fork .
Note from : (http://stackoverflow.com/questions/14287446/proper-use-of-disable-fork-in-systemverilog)
disable fork" kills not only the processes launched by your fork...join_any, but also any other processes that are descendants of the same process that executes the disable-fork. If you have launched any other processes (using, for example, fork...join_none) earlier in the life of this process, then those other processes will be killed too.
You can rather easily protect against this by causing your fork...join_any, and its later disable-fork, to run in a new child process of its own. This limits the effect of your disable-fork so that it can affect only the newly launched processes that you care about, and is guaranteed to have no other unwanted effects.
Do this by enclosing the whole mess in "fork begin...end join" like this:
fork begin // isolate the following code as a single child process
fork // launch the processes you wish to manage
apply_input();
update_status();
verify_status();
join_any // kill off the *_status threads when apply_input terminates
disable fork;
end join // end of child process isolation
This is a well-known issue with fork...join_any and fork...join_none. It's been discussed recently on Verification Guild forum, and is described in sections #79 and #80 of the Sutherland and Mills book "Verilog and SystemVerilog Gotchas".
Putting "fork begin" and "end join" on single lines is unusual, but I like it as a way to make it very obvious that I'm synchronously forking exactly one child process. Normally that would be a useless thing to do, but in this situation it's essential.
Next interesting scenario: you have exited fork loop by join_none or join_any and after some steps, you want to kill just one thread (out of many). The solution, have named begin end block and call "disable
General Note 1 : While learning SV or UVM, we also need to learn the appropriate term and the actual meaning of that word, so that we can co-relate it better.