In these examples, the automatic variable is declared before the fork. In most other examples I have seen it inside the Fork. Are both equivalent? Before forking feels as if the variable isn’t really belonging to the forked thread?
In reply to NiLu:
You are correct. There needs to be a separate idx variable for each invocation of the fork/join_none. I overlooked this since it was not the main point of the original question. I have edited the example.
Is it possible to do something similar, but accomplish join_any behavior instead of join_all? All examples that I have seen on this topic always use the “wait fork” statement.
I am interested in starting multiple threads in parallel and joining them when just one completes. In particular, I want to wait for just one of any events to occur. I have tried a few variations of the following example, but without success.
Any help would be greatly appreciated. Thanks!
JH
fork
begin
foreach(my_cbs[i]) begin // loop through an array of callbacks
fork
automatic int var_i = i;
begin
@(my_cbs[var_i].change_event); // wait for an event triggered within the callback
end
join_none
end
end
join_any
In reply to jhardy:
begin
event just_one_of any;
foreach(my_cbs[i]) // loop through an array of callbacks
fork
int var_i = i;
begin
@(my_cbs[var_i].change_event); // wait for an event triggered within the callback
-> just_one_of_any;
end
join_none
@just_one_of_any;
end
Thanks Dave! I appreciate the quick reply. Your suggestion solved my problem.
I assume that we still should declare the variable as automatic. Please correct correct me if I am wrong.
In reply to theketi:
i < 8 has to fail in order to end the loop. So i will be 8 after exiting the loop.
In reply to dave_59:
Hello Dave,
I am trying to run below code :
my_seq = new[2];
fork
begin : isolating_thread
for(int index=0;index<2;index++) begin : for_loop
automatic int idx=index;
automatic int local_qd=$urandom_range(1,4);
fork
`uvm_do_with(my_seq[idx],
{
qd == local_qd;
})
join_none;
end : for_loop
wait fork;
end : isolating_thread
join
I am getting below Error :
=======================================================
Solver failed when solving following set of constraints
integer qd = 0;
integer local_qd = 4;
constraint WITH_CONSTRAINT // (from this) (constraint_mode = ON) (<File_path>:233)
{
(qd == local_qd);
}
=======================================================
Can you please help me with this ?? Thanks a lot in advance.
- Biren
In reply to birenkumar:
This likely has nothing to do with a fork statement. Maybe you did not declare qd as rand.
In reply to dave_59:
Hi Dave,
If I have two for-loop, how to handle it ? Is below code correct ?
fork
begin : isolating_thread
for(int index=0;index<14;index++)begin : for_loop
fork
automatic int idx=index;
for(int j=0;j<14;j++)begin
automatic int jdx=j;
begin
`ovm_do_on(sequence_inst,p_sequencer.my_sqr[idx][jdx]);
end
join_none;
end : for_loop
wait fork;
end
end : isolating_thread
join
In reply to zz8318:
In reply to dave_59:
Hi Dave,
If I have two for-loop, how to handle it ? Is below code correct ?
fork
begin : isolating_thread
for(int index=0;index<14;index++)begin : for_loop
fork
automatic int idx=index;
for(int j=0;j<14;j++)begin
automatic int jdx=j;
begin
`ovm_do_on(sequence_inst,p_sequencer.my_sqr[idx][jdx]);
end
join_none;
end : for_loop
wait fork;
end
end : isolating_thread
join
That should work, not sure you need that second automatic variable assignment for j, but it shouldn’t hurt.
I just ran into this problem yesterday… great thread… I totally missed the part about the automatic variable for the fork.
In reply to dave_59:
With respect to the fork and join ALL inside for loop, I have a very basic question regarding the same.
for (i = 0; i<3;i++) begin
automatic int j = i;
fork
$display(j);
join
end
Will the output for the above code will be :
0
1
2
???
In reply to SanjanaDhiran:
A fork/join with one statement behaves just like a begin/end block as far as your example is concerned.
In reply to dave_59:
Hie Dave,
Thank you for responding. However, I am still a little confused. Will my output be :
0
1
2
??
In reply to dave_59:
Hi Dave,
I have a question here.
Is there any different between below two snippet of code ? (The different code is pointed out with comment)
I have thread_A() which is an isolated thread, and thread_B(i) which is parameterized with forloop variable, and another thread_C() in my code. I want all thread_B(i) are spawned in parallel and start the thread_C() when all of them finished. and above process is regarded as a whole thread, and run with thread_A in parallel. One of them finished then disable all others.
fork
thread_A();
begin
fork // here is difference
for (int i = 0; i < 8; i++) begin
fork
automatic int j = i;
thread_B(j);
join_none
end
wait fork;
join // here is difference
thread_C();
end
join_any
disable fork;
fork
thread_A();
begin
for (int i = 0; i < 8; i++) begin
fork
automatic int j = i;
thread_B(j);
join_none
end
wait fork;
thread_C();
end
join_any
disable fork;
In reply to zz8318:
The wait fork waits for all child processes of the current thread to terminate. In your first example, any process created by thread_A are cousins, not children of the current thread. In your second example, any process created by thread_A are children of the current thread.
In reply to dave_59:
Hi Dave,
How to determine which thread is current thread ?
and which one is correct to meet the requirement I mentioned in my last post ?
In reply to zz8318:
By current thread I mean from the perspective of the thread executing the wait fork statement. You should have enough information to make the correct decision.
module abc;
task thread_A();
#100;
endtask
task thread_B(int j);
#2;
endtask
task thread_C();
#30;
endtask
initial begin
fork
thread_A();
begin
fork // here is difference
for (int i = 0; i < 8; i++) begin
fork
automatic int j = i;
thread_B(j);
join_none
end
wait fork;
join // here is difference
thread_C();
end
join_any
$display($time);
disable fork;
end
initial begin
fork
thread_A();
begin
for (int i = 0; i < 8; i++) begin
fork
automatic int j = i;
thread_B(j);
join_none
end
wait fork;
thread_C();
end
join_any
$display($time);
disable fork;
end
endmodule
Dave, can you help me with understanding the above example.
the first initial block is printing #30, expecting it to be 32 (thread_B + thread_C).
the second initial block is printing #32, expecting it to be 102 (thread_A + thread_B + thread_C) bcz of the “wait fork” inside the begin-end.