Hi
Please let me know how i can disable all the threads inside a fork join
for(int i =0 ; i < total; i = i + 1)begin
fork
automatic int j = i;
create_commands(j);
join_none
end
How do i disable all the threads at the same time after a particular wait statement?
You can use a disable fork statement to disable all threads forked by the current thread. You may need to wrap your code with another fork/join to isolate any other fork/join_none threads you may have spawned before the one inside this loop.
...
fork
begin
for(int i =0 ; i < total; i = i + 1)
fork
automatic int j = i;
create_commands(j);
join_none
wait(for_something_particular);
disable fork;
end
join
...
Another option is to use the fine-grain process control described in section 9.7 of the 1800-2012 LRM. You can create a list of process you want to disable with the process::kill() method.
In reply to dave_59:
Thanks Dave. The solution works !
In reply to meenu2k11:
Hi Dave,
I had a question on this. If we disable a fork. Is there anyway to reenable it later ? I thought once we disable a fork and next time the same task is called again the fork gets enabled again…
But it does not work like that. In the code snippet below it looks like once the disable fork() in task monitor_sb_transaction gets activated. It does not execute the threads once this task is called again.
And because of this my test is stuck here in this task: check_transaction() on this message foreover: Actual transaction seen in interface: SRC_ID: %0h, DEST_ID:%0h, OPCODE: %0h … Waiting for Expected Transaction …
How to fix this problem. WHat I want here is when the task monitor_transaction() is called again the threads should not be disabled from last invocation of the task.
task monitor_transaction();
fork
begin
wait ((vif.p || vif.np) == 1);
end
begin: timeout
#1us;
`ovm_fatal(get_name(), $psprintf("Timeout ..." ))
end
join_any
disable fork;
endtask
task check_transaction(input logic[7:0]src_id, [7:0] dest_id, [7:0] opcode);
if((vif.src_id == src_id) && (vif.dst_id == dest_id) && (vif.opcode == opcode)) begin
`ovm_info(get_name(), $sformatf("Detected Expected transaction: SRC_ID: %0h, DEST_ID:%0h, OPCODE: %0h", src_id, dest_id, opcode), OVM_MEDIUM);
end else begin
`ovm_info(get_name(), $sformatf("Actual transaction seen in interface: SRC_ID: %0h, DEST_ID:%0h, OPCODE: %0h .. Waiting for Expected Transaction: SRC_ID: %0h, DEST_ID:%0h, OPCODE: %0h", vif.src_id, vif.dst_id, vif.opcode,src_id,dest_id,opcode), OVM_MEDIUM);
monitor_and_check_transaction(src_id,dest_id,opcode);
end
endtask
task monitor_and_check_transaction(input logic[7:0]src_id, [7:0] dest_id, [7:0] opc);
monitor_transaction();
check_transaction(src_id, dest_id, opc);
endtask
In reply to sriram.seshagiri:
Please use code tags making your code easier to read. I have added them for you.
I do not understand your situation. When task monitor_sb_transaction gets called again, the fork/join/any starts again. Are you missing other fork/joins in the code you show. How does monitor_sb_transaction gets called again?
In reply to dave_59:
Hi Dave,
This task : Check_transaction () calls the task below in else part of the code
monitor_and_check_transaction(src_id,dest_id,opcode)
which in turn calls the task monitor_transaction() again.;
In reply to sriram.seshagiri:
You have a recursive calling thread. Perhaps you need to explain the sequence of events without SystemVerilog code
In reply to dave_59:
Hi Dave,
Yes I found out that later. I do a have a recursive calling thread there but, not sure why it is stuck the way it was. In my understanding the monitor_transaction() should have waited for the next transaction. And then should have called the task check_transcation(). So once a fork gets disabled inside a task and if we call that the task later the fork does get reenabled again right.
Anyways I have simplified the code and got rid of this recursion happening. Trying a rerun now…
task monitor_and_check_transaction(input logic[7:0]src_id, [7:0] dest_id, [7:0] opc);
while (txn_hit ! = 1) begin
monitor_transaction();
check_transaction(src_id, dest_id, opc);
end
endtask
In reply to sriram.seshagiri:
You have a recursive calling thread. Perhaps you need to explain the sequence of events without SystemVerilog code
In reply to sriram.seshagiri:
Hi Dave,
There was nothing wrong with the old code with recursive calling thread. The issue was both the disable fork and next call to this task to make it respawn occurs at the same zero time causing a zero time simulation hang and an infinite loop.
Added a small delay after disable fork and that fixed my issue
disable fork ;
#1 ns;