Anupama
September 30, 2020, 5:30pm
1
initial begin
$dumpfile("dump.vcd");
$dumpvars(0, top);
fork
begin : isolating_thread
for(int index=0;index<4;index++)begin : outer_for_loop
fork
automatic int idx=index;
`uvm_info(" testing ",$sformatf(" idx:%0d ",idx), UVM_LOW)
#1000 `uvm_info(" testing ",$sformatf(" idx:%0d ",idx ), UVM_LOW) <------- test ends before this msg gets printed
#10 `uvm_info(" testing ",$sformatf(" idx:%0d ",idx ), UVM_LOW)
join_none
end : outer_for_loop
`uvm_info(" testing before wait fork"," before ", UVM_LOW)
wait fork;
`uvm_info(" testing after wait fork"," after ", UVM_LOW)
end : isolating_thread
join
end
I thought wait fork will wait for all the grand children threads. Thank you for any help in advance.
dave_59
September 30, 2020, 6:27pm
2
In reply to S2011 :
I thought wait fork will wait for all the grand children threads. Thank you for any help in advance.
Where did you get that thought? Certainly not from reading the LRM
The wait fork statement blocks process execution flow until all immediate child subprocesses (processes created by the current process, excluding their descendants) have completed their execution.
Anupama
September 30, 2020, 6:37pm
3
In reply to dave_59 :
Then what can I do to keep the test alive till below statement gets printed? #1000 is a arbitrary number I am using to replicate some random delays in my real test.
#1000 `uvm_info(" testing “,$sformatf(” idx:%0d ",idx ), UVM_LOW)
dave_59
September 30, 2020, 7:11pm
4
In reply to S2011 :
The output I get is:
# UVM_INFO testbench.sv(22) @ 0: reporter [ testing before wait fork] before
# UVM_INFO testbench.sv(17) @ 0: reporter [ testing ] idx:3
# UVM_INFO testbench.sv(17) @ 0: reporter [ testing ] idx:2
# UVM_INFO testbench.sv(17) @ 0: reporter [ testing ] idx:1
# UVM_INFO testbench.sv(17) @ 0: reporter [ testing ] idx:0
# UVM_INFO testbench.sv(19) @ 10: reporter [ testing ] idx:3
# UVM_INFO testbench.sv(19) @ 10: reporter [ testing ] idx:2
# UVM_INFO testbench.sv(19) @ 10: reporter [ testing ] idx:1
# UVM_INFO testbench.sv(19) @ 10: reporter [ testing ] idx:0
# UVM_INFO testbench.sv(18) @ 1000: reporter [ testing ] idx:3
# UVM_INFO testbench.sv(18) @ 1000: reporter [ testing ] idx:2
# UVM_INFO testbench.sv(18) @ 1000: reporter [ testing ] idx:1
# UVM_INFO testbench.sv(18) @ 1000: reporter [ testing ] idx:0
# UVM_INFO testbench.sv(24) @ 1000: reporter [ testing after wait fork] after
# exit
So what is your problem
Anupama
September 30, 2020, 11:22pm
5
In reply to dave_59 :
Here is my code, I am not seeing `uvm_info msg with no delay and with #1000 delay, not sure why?
task run_phase(uvm_phase phase);
// We raise objection to keep the test from completing
phase.raise_objection(this);
#10;
`uvm_warning("", "Hello World!")
fork
begin : isolating_thread
for(int index=0;index<4;index++)begin : outer_for_loop
fork
automatic int idx=index;
for(int j=0;j<3;j++)begin : inner_for_loop
fork
automatic int jdx=j;
begin
`uvm_info(" testing ",$sformatf(" idx:%0d jdx:%0d",idx, jdx), UVM_LOW)
#1000 `uvm_info(" testing ",$sformatf(" idx:%0d jdx:%0d ",idx, jdx ), UVM_LOW)
#10 `uvm_info(" testing ",$sformatf(" idx:%0d jdx:%0d",idx, jdx ), UVM_LOW)
end
join_none
end : inner_for_loop
`uvm_info(" testing before wait fork inner loop"," before ", UVM_LOW)
wait fork;
`uvm_info(" testing after wait fork inner loop"," after ", UVM_LOW)
join_none
end : outer_for_loop
`uvm_info(" testing before wait fork outer loop "," before ", UVM_LOW)
wait fork;
`uvm_info(" testing after wait fork outer loop "," after ", UVM_LOW)
end : isolating_thread
join
// We drop objection to allow the test to complete
phase.drop_objection(this);
endtask
UVM_INFO verilog_src/questa_uvm_pkg-1.2/src/questa_uvm_pkg.sv(277) @ 0: reporter [Questa UVM] QUESTA_UVM-1.2.3
UVM_INFO verilog_src/questa_uvm_pkg-1.2/src/questa_uvm_pkg.sv(278) @ 0: reporter [Questa UVM] questa_uvm::init(+struct)
UVM_INFO @ 0: reporter [RNTST] Running test my_test…
UVM_WARNING my_testbench_pkg.svh(76) @ 10: uvm_test_top Hello World!
UVM_INFO my_testbench_pkg.svh(97) @ 10: uvm_test_top [ testing before wait fork outer loop ] before
UVM_INFO my_testbench_pkg.svh(86) @ 10: uvm_test_top [ testing ] idx:3 jdx:2
UVM_INFO my_testbench_pkg.svh(86) @ 10: uvm_test_top [ testing ] idx:3 jdx:1
UVM_INFO my_testbench_pkg.svh(86) @ 10: uvm_test_top [ testing ] idx:3 jdx:0
UVM_INFO my_testbench_pkg.svh(92) @ 10: uvm_test_top [ testing before wait fork inner loop] before
UVM_INFO my_testbench_pkg.svh(94) @ 10: uvm_test_top [ testing after wait fork inner loop] after
UVM_INFO my_testbench_pkg.svh(86) @ 10: uvm_test_top [ testing ] idx:2 jdx:2
UVM_INFO my_testbench_pkg.svh(86) @ 10: uvm_test_top [ testing ] idx:2 jdx:1
UVM_INFO my_testbench_pkg.svh(86) @ 10: uvm_test_top [ testing ] idx:2 jdx:0
UVM_INFO my_testbench_pkg.svh(92) @ 10: uvm_test_top [ testing before wait fork inner loop] before
UVM_INFO my_testbench_pkg.svh(94) @ 10: uvm_test_top [ testing after wait fork inner loop] after
UVM_INFO my_testbench_pkg.svh(86) @ 10: uvm_test_top [ testing ] idx:1 jdx:2
UVM_INFO my_testbench_pkg.svh(86) @ 10: uvm_test_top [ testing ] idx:1 jdx:1
UVM_INFO my_testbench_pkg.svh(86) @ 10: uvm_test_top [ testing ] idx:1 jdx:0
UVM_INFO my_testbench_pkg.svh(92) @ 10: uvm_test_top [ testing before wait fork inner loop] before
UVM_INFO my_testbench_pkg.svh(94) @ 10: uvm_test_top [ testing after wait fork inner loop] after
UVM_INFO my_testbench_pkg.svh(86) @ 10: uvm_test_top [ testing ] idx:0 jdx:2
UVM_INFO my_testbench_pkg.svh(86) @ 10: uvm_test_top [ testing ] idx:0 jdx:1
UVM_INFO my_testbench_pkg.svh(86) @ 10: uvm_test_top [ testing ] idx:0 jdx:0
UVM_INFO my_testbench_pkg.svh(92) @ 10: uvm_test_top [ testing before wait fork inner loop] before
UVM_INFO my_testbench_pkg.svh(94) @ 10: uvm_test_top [ testing after wait fork inner loop] after
UVM_INFO my_testbench_pkg.svh(99) @ 10: uvm_test_top [ testing after wait fork outer loop ] after
UVM_INFO design.sv(20) @ 15: reporter [DUT] Received cmd=0, addr=0xc6, data=0x08
UVM_INFO design.sv(20) @ 25: reporter [DUT] Received cmd=0, addr=0x1f, data=0xb4
UVM_INFO design.sv(20) @ 35: reporter [DUT] Received cmd=0, addr=0x95, data=0x53
UVM_INFO design.sv(20) @ 45: reporter [DUT] Received cmd=0, addr=0x18, data=0x36
UVM_INFO design.sv(20) @ 55: reporter [DUT] Received cmd=0, addr=0x93, data=0x3f
UVM_INFO design.sv(20) @ 65: reporter [DUT] Received cmd=0, addr=0x2a, data=0xf5
UVM_INFO design.sv(20) @ 75: reporter [DUT] Received cmd=0, addr=0x7d, data=0xe6
UVM_INFO design.sv(20) @ 85: reporter [DUT] Received cmd=1, addr=0x8b, data=0x77
UVM_INFO verilog_src/uvm-1.2/src/base/uvm_objection.svh(1270) @ 85: reporter [TEST_DONE] ‘run’ phase is ready to proceed to the ‘extract’ phase
UVM_INFO verilog_src/uvm-1.2/src/base/uvm_report_server.svh(847) @ 85: reporter [UVM/REPORT/SERVER]
In reply to S2011 :
Please use code tags making your code easier to read. I have added them for you.
That’s much more information than in your original example. Dropping objections is what’s causing your test to end.
There are number of ways of getting your code to do what you are looking for. For example, the middle fork/join_none in your code is unnecessary. Getting rid of it will make the wait fork work properly since all the forked threads are now immediate children. You can also have each thread raise and drop an objection to keep the phase going.
In reply to dave_59 :
Thank you! removing the inner fork fixed the issue.
task run_phase(uvm_phase phase);
// We raise objection to keep the test from completing
phase.raise_objection(this);
#10;
`uvm_warning("", "Hello World!")
fork
begin : isolating_thread
for(int index=0;index<4;index++)begin : outer_for_loop
fork
automatic int idx=index;
for(int j=0;j<3;j++)begin : inner_for_loop
`uvm_info(" testing ",$sformatf(" idx:%0d jdx:%0d",idx, j), UVM_LOW)
#1000 `uvm_info(" testing ",$sformatf(" idx:%0d jdx:%0d ",idx, j ), UVM_LOW)
#10 `uvm_info(" testing ",$sformatf(" idx:%0d jdx:%0d",idx, j ), UVM_LOW)
end
join_none
end : outer_for_loop
`uvm_info(" testing before wait fork outer loop "," before ", UVM_LOW)
wait fork;
`uvm_info(" testing after wait fork outer loop "," after ", UVM_LOW)
end : isolating_thread
join
// We drop objection to allow the test to complete
phase.drop_objection(this);
endtask