Thursday, 23 March 2017

Simulation timeout in UVM using set_timeout and +UVM_TIMEOUT

Default timeout for simulation or you can say timeout for run_phase (as rest all phases are non-time consuming) is `UVM_DEFAULT_TIMEOUT, if not overridden by uvm_root::set_timeout or uvm_cmdline_processor::+UVM_TIMEOUT.

Default value of `UVM_DEFAULT_TIMEOUT is 9200 second.
-------------------------------------------------
uvm-1.2/src/base/uvm_objection.svh
Line 57: `define UVM_DEFAULT_TIMEOUT 9200s
-------------------------------------------------

Example 1 (Timeout at default time which is 9200 second):
-------------------------------------------------
`timescale 1ns/1ns
import uvm_pkg::*;
class test extends uvm_test;
`uvm_component_utils(test)
function new(string name, uvm_component parent = null);
super.new(name, parent);
endfunction : new
function void start_of_simulation_phase(uvm_phase phase);
super.start_of_simulation_phase(phase);
endfunction : start_of_simulation_phase
task pre_main_phase(uvm_phase phase);
phase.raise_objection(this);
#100;
phase.drop_objection(this);
endtask : pre_main_phase
task main_phase(uvm_phase phase);
phase.raise_objection(this);
// Will cause a time-out
// because we forgot to drop the objection
endtask : main_phase
task shutdown_phase(uvm_phase phase);
phase.raise_objection(this);
#100;
phase.drop_objection(this);
endtask : shutdown_phase
endclass : test
module top();
initial begin
run_test("test");
end
endmodule : top
//Output (with +UVM_OBJECTION_TRACE simulation switch):
// UVM_INFO @ 0: reporter [RNTST] Running test test...
// UVM_FATAL uvm-1.2/src/base/uvm_phase.svh(1491) @ 9200000000000: reporter [PH_TIMEOUT] Default timeout of 9200000000000 hit, indicating a probable testbench issue
// UVM_INFO uvm-1.2/src/base/uvm_report_server.svh(847) @ 9200000000000: reporter [UVM/REPORT/SERVER]
-------------------------------------------------

1) Overridden by uvm_root::set_timeout

-------------------------------------------------
uvm-1.2/src/base/uvm_root.svh
Line 213: // Variable- phase_timeout
// Specifies the timeout for the run phase. Default is `UVM_DEFAULT_TIMEOUT
time phase_timeout = `UVM_DEFAULT_TIMEOUT;
Line 139: // Function: set_timeout
// Specifies the timeout for the simulation. Default is <`UVM_DEFAULT_TIMEOUT>
// The timeout is simply the maximum absolute simulation time allowed before a
// ~FATAL~ occurs. If the timeout is set to 20ns, then the simulation must end
// before 20ns, or a ~FATAL~ timeout will occur.
// This is provided so that the user can prevent the simulation from potentially
// consuming too many resources (Disk, Memory, CPU, etc) when the testbench is
// essentially hung.
function void uvm_root::set_timeout(time timeout, bit overridable=1);
static bit m_uvm_timeout_overridable = 1;
if (m_uvm_timeout_overridable == 0) begin
uvm_report_info("NOTIMOUTOVR",
$sformatf("The global timeout setting of %0d is not overridable to %0d due to a previous setting.",
phase_timeout, timeout), UVM_NONE);
return;
end
m_uvm_timeout_overridable = overridable;
phase_timeout = timeout;
endfunction
-------------------------------------------------
-------------------------------------------------
uvm-1.2/src/base/uvm_phase.svh
Line 1297: task uvm_phase::execute_phase();
uvm_task_phase task_phase;
uvm_root top;
uvm_phase_state_change state_chg;
uvm_coreservice_t cs;
cs = uvm_coreservice_t::get();
top = cs.get_root();
...........
// TIMEOUT
begin
if (this.get_name() == "run") begin
if (top.phase_timeout == 0)
wait(top.phase_timeout != 0);
if (m_phase_trace)
`UVM_PH_TRACE("PH/TRC/TO_WAIT", $sformatf("STARTING PHASE TIMEOUT WATCHDOG (timeout == %t)", top.phase_timeout), this, UVM_HIGH)
`uvm_delay(top.phase_timeout)
if ($time == `UVM_DEFAULT_TIMEOUT) begin
if (m_phase_trace)
`UVM_PH_TRACE("PH/TRC/TIMEOUT", "PHASE TIMEOUT WATCHDOG EXPIRED", this, UVM_LOW)
foreach (m_executing_phases[p]) begin
if ((p.phase_done != null) && (p.phase_done.get_objection_total() > 0)) begin
if (m_phase_trace)
`UVM_PH_TRACE("PH/TRC/TIMEOUT/OBJCTN",
$sformatf("Phase '%s' has outstanding objections:\n%s", p.get_full_name(), p.phase_done.convert2string()),
this,
UVM_LOW)
end
end
`uvm_fatal("PH_TIMEOUT",
$sformatf("Default timeout of %0t hit, indicating a probable testbench issue",
`UVM_DEFAULT_TIMEOUT))
end
else begin
if (m_phase_trace)
`UVM_PH_TRACE("PH/TRC/TIMEOUT", "PHASE TIMEOUT WATCHDOG EXPIRED", this, UVM_LOW)
foreach (m_executing_phases[p]) begin
if ((p.phase_done != null) && (p.phase_done.get_objection_total() > 0)) begin
if (m_phase_trace)
`UVM_PH_TRACE("PH/TRC/TIMEOUT/OBJCTN",
$sformatf("Phase '%s' has outstanding objections:\n%s", p.get_full_name(), p.phase_done.convert2string()),
this,
UVM_LOW)
end
end
`uvm_fatal("PH_TIMEOUT",
$sformatf("Explicit timeout of %0t hit, indicating a probable testbench issue",
top.phase_timeout))
end
if (m_phase_trace)
`UVM_PH_TRACE("PH/TRC/EXE/3","PHASE EXIT TIMEOUT",this,UVM_DEBUG)
end // if (this.get_name() == "run")
else begin
wait (0); // never unblock for non-run phase
end
end // if (m_phase_trace)
-------------------------------------------------

Example 2 (Timeout at specified time which is specified using set_timeout):
-------------------------------------------------
`timescale 1ns/1ns
import uvm_pkg::*;
class test extends uvm_test;
`uvm_component_utils(test)
function new(string name, uvm_component parent = null);
super.new(name, parent);
endfunction : new
function void start_of_simulation_phase(uvm_phase phase);
super.start_of_simulation_phase(phase);
// uvm_top is a constant handle of uvm_root declared in uvm_root.svh file
uvm_top.set_timeout(100s, 1); // Override default timeout to 1oo second
// or you can use below syntax as well
// uvm_root::get().set_timeout(100s, 1);
endfunction : start_of_simulation_phase
task pre_main_phase(uvm_phase phase);
phase.raise_objection(this);
#100;
phase.drop_objection(this);
endtask : pre_main_phase
task main_phase(uvm_phase phase);
phase.raise_objection(this);
// Will cause a time-out
// because we forgot to drop the objection
endtask : main_phase
task shutdown_phase(uvm_phase phase);
phase.raise_objection(this);
#100;
phase.drop_objection(this);
endtask : shutdown_phase
endclass : test
module top();
initial begin
run_test("test");
end
endmodule : top
//Output:
// UVM_INFO @ 0: reporter [RNTST] Running test test...
// UVM_FATAL uvm-1.2/src/base/uvm_phase.svh(1508) @ 100000000000: reporter [PH_TIMEOUT] Explicit timeout of 100000000000 hit, indicating a probable testbench issue
// UVM_INFO uvm-1.2/src/base/uvm_report_server.svh(847) @ 100000000000: reporter [UVM/REPORT/SERVER]
-------------------------------------------------


2) Overridden by uvm_cmdline_processor::+UVM_TIMEOUT

+UVM_TIMEOUT=, allows users to change the global timeout of the UVM framework.  The argument (‘YES’ or ‘NO’) specifies whether user code can subsequently change this value.  If set to ‘NO’ and the user code tries to change the global timeout value, a warning message will be generated.

Example 3 (Timeout at 100s using simulation switch +UVM_TIMEOUT=100000000000):
Note: Here you need to give simulation time in format of timescale defined in simulation
-------------------------------------------------
`timescale 1ns/1ns
import uvm_pkg::*;
class test extends uvm_test;
`uvm_component_utils(test)
function new(string name, uvm_component parent = null);
super.new(name, parent);
endfunction : new
function void start_of_simulation_phase(uvm_phase phase);
super.start_of_simulation_phase(phase);
endfunction : start_of_simulation_phase
task pre_main_phase(uvm_phase phase);
phase.raise_objection(this);
#100;
phase.drop_objection(this);
endtask : pre_main_phase
task main_phase(uvm_phase phase);
phase.raise_objection(this);
// Will cause a time-out
// because we forgot to drop the objection
endtask : main_phase
task shutdown_phase(uvm_phase phase);
phase.raise_objection(this);
#100;
phase.drop_objection(this);
endtask : shutdown_phase
endclass : test
module top();
initial begin
run_test("test");
end
endmodule : top
//Output:
// UVM_INFO @ 0: reporter [RNTST] Running test test...
// UVM_INFO @ 0: reporter [TIMOUTSET] '+UVM_TIMEOUT=100000000000' provided on the command line is being applied.
// UVM_FATAL uvm-1.2/src/base/uvm_phase.svh(1508) @ 100000000000: reporter [PH_TIMEOUT] Explicit timeout of 100000000000 hit, indicating a probable testbench issue
// UVM_INFO uvm-1.2/src/base/uvm_report_server.svh(847) @ 100000000000: reporter [UVM/REPORT/SERVER]
-------------------------------------------------

5 comments:

  1. If i call uvm_top::set_timeout() and at the same time used the plusarg +UVM_TIMEOUT which one will take effect?

    ReplyDelete
    Replies
    1. It depends on when you call set_timeout.
      +UVM_TIMEOUT is evaluated in build_phase of uvm_root class.
      And here I have called set_timeout() in start_of_simulation_phase so set_timeout() will override timeout set by +UVM_TIMEOUT.

      Delete
  2. is +UVM_TIMEOUT is alternative to $finish?

    ReplyDelete
    Replies
    1. No. If it does timeout, it will be a UVM_FATAL failure.

      Delete
  3. Hi Sagar, in my testbench environment there is no raise/drop objection any where, so my simulation ended at @0ns, but i want to control the simulation without ending @0ns ,any solution for that, could you please help on this

    ReplyDelete