I have a sequence . Inside the body -
task body
fork
…
… 10 threads
join_none
fork
join
disable fork;
endtask
What will be the scope of this disable fork . I ran this sequence in main phase (controlled through uvm_object_wrapper as default sequence in main phase). Is it the top initial block which runs the test case, or the main phase (it will disable all threads that are invoked in main phase of different components)
However, when you call the start() method of a sequence, the code inside start task looks like
task start();
...
fork
begin
...
pre_body();
...
body();
...
post_body();
...
end
join
...
endtask
So executing a disable fork inside the body() task will potentially kill the processes created by the pre_body() and body() tasks. It cannot affect any process created outside the fork within the start method.
The same is true for all the run_phase() tasks. There are all fork’ed into independent processes.
Thanks for clarification Dave.
As going by last line , all the main_phase tasks in different components of testbench are forked independently of each other ? So, disable fork in main_phase od scoreboard will not affect main_phase threads of monitor
is this syntax valid? the intention is to kill task3 and task4 only, while keeping task1 and task2 alive.
i know i can swap the order of the forks and put the disable in between, this is just a theoretical question
my real issue is that i have several watchdog tasks in my ref_model, of course watchdog tasks should be kill once the expected event occurs, my concern is that if i use ‘disable fork’ in one watchdog task, it will kill all the other ref model watchdog tasks as well.
with that said, i would expect that the scope of the the ‘disable fork’ would be the scope of the task calling it. but from what i read above (and in other answers you gave), i understand that the scope of the ‘disable fork’ is the process in which it is called…
Yes, what you wrote works under one condition—there is only one invocation of my_task. If there are multiple invocations, disable sec_fork kills all of them.
There are a couple better ways of coding this. You can put a fork/join as a process guard.
In reply to yakirye:
Yes, what you wrote works under one condition—there is only one invocation of my_task. If there are multiple invocations, disable sec_fork kills all of them.
Hello Dave,
I have one question for ‘multiple invocations’ you mentioned.
If this task belongs to one component and we have multiple objects of this components, like below:
Does this mean ‘multiple invocations’ in your case? how can we just kill those threads(task3/4)inside c2 instead of all rests even in C0 and C1, if so.
Correct, ‘ disable blockname;’ does not provide a mechanism for specifying a particular object. I already gave better ways of killing a particular process.
Hello Dave,
May I have one more question here. As for the first solution above, ‘disable fork’ means to disable the fork/join without label outside of begin/end instead of the ‘fork: sec_fork’. Am I correct?
disable fork only kills the processes that are children of the process that executes the disable fork statement. It might help to describe the process tree rather than scopes.
process1 calls my_task. The first statement is a fork/join_any. That suspends process1 until any one of the forked processes it creates ends. It it has two statements and creates two child processes, process2 and process3. One of those processes must end before continuing beyond the join_any. Let’s assume process3 ends, so process2 remains.
The next statement is a fork/join. That suspends process1 again until all the processes it creates ends. It contains one statement, so it creates one process4. Now process1 has two children, process2/4. Process4 contains a fork/join_any with two statements. It creates tow child processes, process5/6. One of those processes must end before continuing beyond the join_any. Let’s assume process5 ends, so process6 remains. Now process4 continues executing the disable fork statement. Only process6 is a child of process4, so only that process gets disabled. That is also the last statement in process4, so that process ends and the join can continue process1. When we get to the end of the task, process2 is still a child of process1
In reply to tongwang: disable fork only kills the processes that are children of the process that executes the disable fork statement. It might help to describe the process tree rather than scopes. process1 calls my_task. The first statement is a fork/join_any. That suspends process1 until any one of the forked processes it creates ends. It it has two statements and creates two child processes, process2 and process3. One of those processes must end before continuing beyond the join_any. Let’s assume process3 ends, so process2 remains.
The next statement is a fork/join. That suspends process1 again until all the processes it creates ends. It contains one statement, so it creates one process4. Now process1 has two children, process2/4. Process4 contains a fork/join_any with two statements. It creates tow child processes, process5/6. One of those processes must end before continuing beyond the join_any. Let’s assume process5 ends, so process6 remains. Now process4 continues executing the disable fork statement. Only process6 is a child of process4, so only that process gets disabled. That is also the last statement in process4, so that process ends and the join can continue process1. When we get to the end of the task, process2 is still a child of process1
Then if i use ‘disable sec_fork’ instead of ‘disable fork’, can i get a same result since task3 and task4 are children processes of sec_fork_guard which executes ‘disable sec_fork’ statement