yi_wang_ifb Imported from Blogger
in “desired result”, why are the values in reversed order? I guess that’s a copy/past typo
btw, another trick you can play with in this is to add “#0;” after join_none in for loop.
4 repliesin “desired result”, why are the values in reversed order? I guess that’s a copy/past typo
btw, another trick you can play with in this is to add “#0;” after join_none in for loop.
4 repliesThe order in which the spawned threads are scheduled is not defined. This particular simulator chose to switch to the last spawned thread first (the thread that prints 2). It’s actually pretty cool that it did that, because this way we can also see that we shouldn’t rely on any specific execution order when it comes to parallel threads, unless we use explicit synchronization mechanisms (such as semaphores).
Also, thanks for the tip with the extra #0 delay. This works inside tasks, where you’re allowed to consume time, but if you have a function that spawns multiple threads, then you won’t be allowed to do any delays (# statements, @ statements, etc.).
You are right about the order. It’s just that I’ve never seen reversed order with the simulators I used.
As to the #0, it’s particularly useful when fork/join_none is used and you want to get the spawned thread run without advancing time. In fact, it’s used in UVM source codes.
Good posts~
Using #0 is the wrong thing to do. It is a hack that is a short term fix that creates problems later. The #0’s in the UVM and other code create unnatural ordering issue that are fixed by adding extraneous loops of #0s. The problem using them to fix the example here is that instead of getting parallel threads, you get a series of ordered threads delayed by one delta cycle. -dave_59
How i solved same problem
module top;
initial begin
for (int i = 0; i < 3; i++) begin
fork
begin
some_task(i);
end
join_none
wait fork; //make wait all threads to finish before exiting the for loop.
end
end
task some_task(int i);
$display(“i = %d”, i);
endtask
endmodule
1 replyThis seems to just fork off some_task()
in each iteration, but wait for it to complete until moving on to the next. So in essence, it just does:
for (int i = 0; i < 3; i++) begin
some_task(i);
end