how to use assertoff from test to disable assertion in side uvm object

albert waissman picture albert waissman · Dec 21, 2017 · Viewed 10.7k times · Source

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

Answer

sharvil111 picture sharvil111 · Dec 23, 2017

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.