3

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
AndresM
  • 1,293
  • 10
  • 19
albert waissman
  • 39
  • 1
  • 2
  • 6

3 Answers3

2

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.

sharvil111
  • 4,301
  • 1
  • 14
  • 29
1

The $assertoff system task can turn assertions off in specific modules, but not specific classes or objects. So, you'll have to do it manually by modifying your tb_env class.

Matthew Taylor
  • 13,365
  • 3
  • 17
  • 44
1

Yes you can use $assertoff for your purpose.

Here is your code without $assertoff.

class tb_env;
  int exp_val = 0;
  int act_val = 0;

  virtual task run_phase ();
    #10;
    ASRT: assert ( exp_val == act_val) else
      $error("Error");
  endtask : run_phase
endclass

program tb_run;
  tb_env env = new();

  initial
  begin      
     // $assertoff(0, env.run_phase.ASRT);

     fork
       env.run_phase();
       begin
         #5;
         env.exp_val = 1;
         $display("@%0t : exp_val - %0b, act_val - %0b", $time(), env.exp_val, env.act_val);
       end
     join
  end
endprogram

// Output -
@5 : exp_val - 1, act_val - 0
"a.sv", 7: $unit::\tb_env::run_phase .ASRT: started at 10s failed at 10s
        Offending '(this.exp_val == this.act_val)'
Error: "a.sv", 7: $unit.tb_env::run_phase.ASRT: at time 10
Error
$finish at simulation time                   10

And here is your code with $assertoff.

class tb_env;
  int exp_val = 0;
  int act_val = 0;

  virtual task run_phase ();
    #10;
    ASRT: assert ( exp_val == act_val) else
      $error("Error");
  endtask : run_phase
endclass

program tb_run;
  tb_env env = new();

  initial
  begin
     $assertoff(0, env.run_phase.ASRT);

     fork
       env.run_phase();
       begin
         #5;
         env.exp_val = 1;
         $display("@%0t : exp_val - %0b, act_val - %0b", $time(), env.exp_val, env.act_val);
       end
     join
  end
endprogram

// Output -
Stopping new assertion attempts at time 0s: level = 0 arg = $unit::\tb_env::run_phase .ASRT (from inst tb_run (a.sv:17))
@5 : exp_val - 1, act_val - 0
$finish at simulation time                   10
Karan Shah
  • 1,912
  • 1
  • 29
  • 42
  • Seems like the code does not work in *irun* but runs fine with *vcs*. Maybe a generalized approach that works on all simulators would be preferable. – sharvil111 Dec 23 '17 at 04:07
  • Code is working with irun as well. Hese is the link of edaplayground : https://www.edaplayground.com/x/33Pb. You can try by commenting & uncommenting the `$assertoff` line to compare the results. – Karan Shah Dec 23 '17 at 07:37
  • Not working with OP's code (UVM based). [EDAPlayground sample](https://www.edaplayground.com/x/5jHX). Irun error: `Invalid assertion or scope name argument to $assertoff assertion control task`. Runs with vcs though. – sharvil111 Dec 23 '17 at 07:47
  • I have modified my code with the given UVM code. And it is working in my case. Please check https://www.edaplayground.com/x/33Pb with Incisive simulator. – Karan Shah Dec 24 '17 at 01:40