Conditional assertion inside a module scope

I am trying to add a “conditional assertion” inside modular scope that check my shiftData from DUT is not high until done signal is high.

Ex:

module MyModule (
    input wire shiftData,
    input wire done
);

property shiftData_until_done;
    @(posedge clk) disable iff (!reset) // Disable during reset
        (shiftData === 0) until (done === 1);
endproperty

if ($test$plusargs("ENABLE_ASSERTION")) begin
  assert property (shiftData_until_done)
  else $display("Assertion failed: shiftData is high before done signal is high");
end

endmodule

But this syntactically incorrect. Wrote the code to convey my aim.

Is there a way to add conditional processing for assertion?

NB: I don’t want to use `ifdef since the arg should be passed during simulation.

In reply to bachan21:

There are a number of different ways of handling this.

  1. You can add a signal to the disable iff expression set by $test$plusargs.
  2. Use $assertcontrol system tasks to turn the assertion on and off.
  3. Use simulator specific command line options to turn off assertions. Check your tool’s user manual.

In reply to bachan21:

Have you tried using vunit?
vunit is alternative of bind except you don’t need to probe/connect the design signals.
Moreover, you can keep the Assertions and Covergroup out of the design code for readability.
vunit supports the SVA and covergroup to be within and it’s kind of extending the design where you have access to all the design signals.

here is the example I made it for the code you provided.
I added the missing clk and reset signals.
Command to run:
xrun -sv -clean assert_in_mod.sv -propfile_vlog vunit_assert.vunit +ENABLE_ASSERTION

module MyModule (
    input wire shiftData,
    input wire done,
    input clk,
    input reset
);
 
endmodule : MyModule

vunit mod_assert(MyModule) {
    
property shiftData_until_done;
    @(posedge clk) disable iff (!reset & **!$test$plusargs("ENABLE_ASSERTION")**) // Disable during reset
        (shiftData === 0) until (done === 1);
endproperty
 
//if ($test$plusargs("ENABLE_ASSERTION")) begin
  assert property (shiftData_until_done)
  else $display("Assertion failed: shiftData is high before done signal is high");
//end
 
}

In reply to bachan21:
I guess the missing code was always@ or initial.

module MyModule (
    input wire shiftData,
    input wire done,
    input clk,
    input reset
);
 
property shiftData_until_done;
    @(posedge clk) disable iff (!reset) // &!$test$plusargs("ENABLE_ASSERTION")) // Disable during reset
        (shiftData === 0) until (done === 1);
endproperty

always@(posedge clk) begin
    if ($test$plusargs("ENABLE_ASSERTION")) begin
      assert property (shiftData_until_done)
      else $display("Assertion failed: shiftData is high before done signal is high");
    end
end
endmodule : MyModul

In reply to nhp:

Having to call $test$plusargs every clock cycle will result in very poor performance.

In reply to dave_59:

I agree with you. Just gave a working but won’t recommend doing it.

I would prefer the vunit where I separate the actual design and Assertion, coverage to be explicit.

thanks!

In reply to dave_59:

Thanks Dave. This will pretty much work for me.

In reply to nhp:

Thanks. Will try this.

In reply to dave_59:

In reply to bachan21:
[*] Use $assertcontrol system tasks to turn the assertion on and off.
[/list]

Hi Dave, Isn’t it sufficient to use $asserton and $assertoff instead of $assertcontrol?
Also whats the syntax to use it for module level Top?