`ifdef FORK_1
program test;
initial
begin
for(int i=0;i<16;i++) size="+0">send(i);
end
task send(int i);
fork
begin
$write("Driving port %d\n",i);
#1;
end
join_none
endtask:send
endprogram:test
`endif
/*
observation : In the above example,for loop creates 15 processes which in turn each have their own child threads(send(i)) which are queued but not executed since it is join none,once the parent thread completes it's execution(i.e initial begin for loop end,i.e the main parent thread completes its execution or once for_loop completes) All the queued threads are shifted to execution state which now share the same memory stack i.e i=15. Hence it generates the output 15.
*/
`ifdef FORK_2
program test;
initial
begin
for(int i=0;i<16;i++) size="+0">send(i);
end
task send(int i);
automatic int j;
j=i;
fork
begin
$write("Driving port %d\n",j);
#1;
end
join_none
endtask:send
endprogram:test
`endif
/* observation :
STATIC : storage allocated on instantiation,never deallocated.
AUTOMATIC : storage allocated once it entered to the stack,such as task,function or block and deallocated on exist. It gives the expected outputs : 0,1,2....15
*/
`ifdef FORK_3
program automatic test;
initial
begin
for(int i=0;i<16;i++) size="+0">send(i);
end
task send(int i);
fork
begin
$write("Driving port %d\n",i);
#1;
end
join_none
//wait fork; //to understand the simulation time.
endtask:send
endprogram:test
`endif
/*
observation :
In this example all send(i) threads will try to access the same resource i that is passed to the task send(), but since the program is itself made automatic the tasks also are executed automatic , in the sense a task once called with a value ,performs it's operation for the called value and hence the threads execute for their respective value.Here program automatic helps in avoiding the race condition where in a same task can be called with n number of values but it should perform it's operation w.r.t the value for which it is called.But here the simulation time completes at 0 irrespective of the delay element #1.
wait fork helps in preventing improper early termination of the jobs
In the above example,if we use wait fork system task the simulation time will be 16,since it waits
for the threads to execute completely (here each thread will completes it's execution only after #1 unit,hence 16)
else simulation time will be 0.
output : Generates the expected output : 0,1,2.....15
*/
`ifdef FORK_4
program automatic test;
initial
begin
for(int i=0;i<16;i++) size="+0">fork
send(i);
join_none
end
task send(int i);
begin
$write("Driving port %d\n",i);
#1;
end
//wait fork; //to understand the simulation time.
endtask:send
endprogram:test
`endif
/* observation :In this example the send(i) is spawned with a same shared resource variable i , hence the final updated values is printed by all the threads.
generates the output as 16. last value of i.
*/
`ifdef FORK_5
program automatic test;
initial
begin
for(int i=0;i<16;i++) size="+0">automatic int index = i;
fork
send(index);
join_none end
end
task send(int i);
begin
$write("Driving port %d\n",i);
#1;
end
//wait fork; //to understand the simulation time.
endtask:send
endprogram:test
`endif
/* observation : In this example the shared resource variable is dragged specific for each thread by automatic key word , hence each thread has it's own local copy of it's own value
generates the desired output i.e 0,1,2,...15
*/
`ifdef FORK_6
program test; // automatic test
initial
begin
for(int i=0;i<16;i++) size="+0">fork
send(i);
join
end
task send(int i);
begin
$write("Driving port %d\n",i);
#1;
end
//wait fork; //to understand the simulation time.
endtask:send
endprogram:test
`endif
/* observation :In this example though all the threads share the same resource value,i is not incremented until the present thread completes it's execution irrespective of the automatic keyword. It generates the expected output i.e 0,1,2,...15
*/
`ifdef FORK_7
program automatic fork_join_8;
initial
begin
for(int i =0 ; i<16;i++)begin size="+0">fork
send(i);
join_none
end
end
task send(int i);
$display("Driving port %0d",i);
endtask
endprogram
`endif
/* observation : In this example though the program block is made automatic , we find no effect as the thread is being spawned and now send(i) is treated as a thread and not a special task , so as in any other case all the threads share the same resource and hence get only the final updated value.while when the send(i) was treated as a task, the send(i) task was itself getting automatic with separate value for each of it's call.
REF : FORK_3 example
*/
`ifdef JOIN_NONE
program test;
initial
begin
int thread1 = 1 ;
string thread2 = "2" ;
reg [7:0] thread3 = 3 ;
fork
begin
$write (" First thread = %d\n",thread1); //
#(100);
end
join_none
$write (" Thread execution completed\n"); //
end
endprogram : test
`endif
/* observation : In this example it indicates that threads in join_none are queued but not executed until the parent thread encounters a wait statement or completes. (whereas it's not the same in VERA).
*/
Tuesday, June 3, 2008
Few examples on Fork and Join
Here we are adding few examples to understand the fork and join concept of system verilog.
Subscribe to:
Post Comments (Atom)
About Me
- raghu/aravinda
- It's better we can say it's about us,since I and aravinda together joined CDAC -HYDERABAD to do our PG Diploma in VLSI Design and We are working in VLSI industry since more than 5 years
No comments:
Post a Comment