Achieving Dynamic delays in SVA using subroutine

In reply to MICRO_91:

In reply to ben@SystemVerilog.us:
Verilog tells us that $display executes in Active region
[1] When does the $displays within the task execute ? Is it in Reactive region OR in Active region ( via loopback from Re-NBA to Active Region )
[ NOTE : There is No loopback directly from Reactive to Active Region ]

With @( posedge clk ) a |-> ( 1, dynamic_delay2( val ) );
the task is started in the Reactive region.
then task automatic dynamic_delay2( int cnt ); // Executes in Reactive Region
$display(" Within task b == %0d",b);

b== current value in current region.
I would think that since $display is a statement, it executes when it is seen.
This is not an assertion. You would need a $sampled(b) unless the assertion passes b
as an actual argument to the task.

[2] It seems that some tools use updated value of b : edalink
Hence to avoid the tool discrepancy I feel it’s better to use $sampled( b ) instead .

I didn’t analyze that code, but it might be a good discipline to use the $sampled.

Within the task when we write : repeat( cnt ) @( posedge clk );
@(posedge clk) executes in re-entrant Active region ( via loopback from Re-NBA to Active Region )
( However I believe the NBA assignment to b would execute before the loopback to Active region )
When we write the next statement as : assert(b);
(a) Are we still in Active Region ? i.e Non-blocking update to ‘b’ hasn’t occurred yet.

Yes. You have

repeat( cnt ) @( posedge clk );
     am_b: assert( b == 4 ); 

The tool is sensitive events. When an event occurs, you have regions for that even:
Active, NBA, Observed, Reactive, etc…
Thus, at the least repeat @( posedge clk ); you are now in the Active region.
am_b: assert( b == 4 ); // executes immediately. b has not changed yet, as you stated.

(b) For some tool it seems that since the subroutine execute in Reactive region , the updated value of ‘b’ is sampled ( i.e immediate assertion executes in Reactive region ).
Although @( posedge clk ) unblocks in re-entrant Active region , the NBA update to b is already done

If I had the following


 ... @( posedge clk )  a  |->  ( 1, dynamic_delay2( val ) );
task automatic dynamic_delay2( int cnt );  // Executes in Reactive Region
    am_cb: assert( $sampled(c) ); 
// **** am_cb assertion executes in the Reactive region, since it is upon entry
// and since immediate assertions executes in the place they are seen 
    if($sampled(c) && cnt > 0 ) begin      
       repeat( cnt ) @( posedge clk );
     am_b: assert( b == 4 )  // Discrepancy  here ?
// *** am_b executes in the Active region since @( posedge clk ) is the event 
// that causes the simulator to enter the various regions, with Active being the 1st one. 

[3] In your code : edacode
As always_comb executes at T:0 we end up using the value updated at T:0 for m within the immediate assertion at the 1st clock edge.
Hence there is No discrepancy in output across tools in this case as the immediate assertion executes in 1st iteration of Active region prior to NBA update ( unlike the immediate assertion called in subroutine which executes in Reactive region post NBA region update )

Looks correct.
Ben