I am looking for way to disable assert in side uvm component for certain test. Below simple code represent my env, with comment for requirement. I thought I can use $assertoff. I can modify uvm component if required additional instrumentation to achieve this.
import uvm_pkg::*;
`include "uvm_macros.svh"
class tb_env extends uvm_component;
`uvm_component_utils(tb_env)
int exp_val = 0;
int act_val = 0;
function new(string name = "tb_env", uvm_component parent = null);
super.new(name, parent);
endfunction
virtual task run_phase (uvm_phase phase);
super.run_phase(phase);
phase.raise_objection(this);
#10us;
ASRT: assert ( exp_val == act_val) else
`uvm_error(get_name(), "Error");
#10us;
`uvm_info(get_name(), "Done env", UVM_LOW);
phase.drop_objection(this);
endtask : run_phase
endclass
program tb_run;
initial
begin
tb_env env = new("env");
// Requirement: Disable assertion env.ASRT with system call $assertoff(...)
fork
run_test();
begin
#5us;
env.exp_val = 1;
end
join
end
endprogram
I would like to make things simple to understand. So, prefer to use some glue logic for suppressing the assertion.
For some simulators, $assertoff
works only on modules and not on classes, you can use some guarding flag indicating the enable/disable of assertion. The assertion will be checked only when the flag is set. You can declare this flag anywhere in the base classes and use the same flag in enabling/disabling assertions from different extended classes.
One can also develop a generalized macro for this guarding flag. The following code disables the assertions by the use of a guard. If the guard is a static variable, then it can be accessed via scope resolution (::) also.
import uvm_pkg::*;
`include "uvm_macros.svh"
`define ASSERT(VAL,ERR) \
assert(!assert_guard || (VAL)) else begin // If assert_guard=0, then assertion passes without checking other condition \
`uvm_error(get_name(),ERR); \
end \
class tb_env extends uvm_component;
`uvm_component_utils(tb_env)
bit assert_guard;
int exp_val = 0;
int act_val = 0;
function new(string name = "tb_env", uvm_component parent = null);
super.new(name, parent);
assert_guard = 1; // by default assertions are on
endfunction
virtual task run_phase (uvm_phase phase);
super.run_phase(phase);
phase.raise_objection(this);
#10us;
ASRT: `ASSERT( exp_val == act_val, "Error");
#10us;
`uvm_info(get_name(), "Done env", UVM_LOW);
phase.drop_objection(this);
endtask : run_phase
endclass
module tb_run;
initial begin
tb_env env = new("env");
env.assert_guard = 0;
//tb_env::assert_guard = ; // If assert_guard was static
//$assertoff(0,env.run_phase.ASRT); // Works only for VCS
fork
run_test();
begin
#5us;
env.exp_val = 1;
end
join
end
endmodule
// Output:
UVM_INFO @ 0: reporter [RNTST] Running test ...
UVM_INFO testbench.sv(31) @ 20000: env [env] Done env
As an alternative approach, one can also make use of disable
statement of disabling deffered assertion. But in this case, one needs to know exact time when the assertion is to be fired. Refer to IEEE 1800-2012 Section 16.4.4 for more information about this approach.