Calling subroutines on match of a sequence

Hi All,
Curious to know how subroutine execute on sequence match, I have been referring to section 16.11 of the LRM.
I have been trying out various examples to understand their working in terms of SV region.

Having established a decent knowledge of it, I am trying to confirm whether my understanding is correct


 bit clk , a , b , c ;
 bit [3:0] length , len ;

 always #5 clk = !clk;

 // 'Length1' could  be  declared  as  Non-blocking  task  as  well
 function void Length1( input bit [3:0] L ); //  Executes in Reactive region
    length = L ;
    $display("Assigned length == %0d",L);
 endfunction

 function bit[3:0] Length2();                //  Executes in Observed region prior to 'Length1'  !!
    $display("Length is %0d",length);
    return length ;
 endfunction

 sequence seq;
   bit [3:0] data , data2 ;
   @(posedge clk) (1, data = len , Length1(data) , data2 = Length2() , $display("data2 is %0d",data2) );
 endsequence

 assert property( seq ) $display("Assertion Pass"); // Action block executes in Reactive region

 initial begin
   #04 ; len = 10 ;
    #2 ; $finish();
 end

Here is what the LRM mentions

[1] LRM 16.10 Local variables

  1. Initialization assignments shall be performed in the Observed region in the order that they appear in the sequence or property declaration

[2] LRM 16.11

  1. Tasks, task methods, void functions, void function methods, and system tasks can be called at the end of a successful nonempty match of a sequence.
  2. All subroutine calls attached to a sequence are executed at every end point of the sequence.
    For each endpoint, the attached calls are executed in the order they appear in the list.
  3. Assertion evaluation does not wait on or receive data back from any attached subroutine.
  4. The subroutines are scheduled in the Reactive region, like an action block.

Here is my interpretation of the LRM w.r.t above code ::

(a) Local variables ‘data’ , ‘data2’ are assigned in Observed region.
The assignment occurs in the order of declaration i.e data is assigned first followed by data2
At T:5, data is assigned value of 10 ( len )

(b) Void function / task / system task ( eg: $display() ) execute in Reactive region similar to action block.
The LRM doesn’t define the order of execution between $display within ‘Length1’ and $display within action block
However as per 2 , LRM does define the order of execution between function ‘Length1’ and system task: $display(“data2 is %0d”,data2)
As ‘Length1’ appears first, it executes before system task: $display(“data2 is %0d”,data2)

Function ‘Length1’ executes in Reactive region where it assigns length = 10.

(c) As function ‘Length2’ has a return value which is used for local variable initialization, function ‘Length2’ executes in Observed region ( due to 1 )

Based on above points here is my expected output :


    Length is 0                //  Executes in Observed region as 'Length2' executes in Observed region
    Assertion Pass             //  Executes in Reactive region
    Assigned length == 10      //  Void function 'Length1' executes in Reactive region
    data2 is 0                 //  System task  executes in Reactive region AFTER 'Length1'
   
Local variable **'data2' is assigned 0 as void function 'Length1' is yet to execute later in Reactive region whereas 'data2' is assigned in Observed region.**
The "Assertion Pass" report can execute last as well as the LRM doesn't define the exact order of execution ( Refer (b) above )

So the following output is legal as well

    Length is 0                  
    Assigned length == 10  
    data2 is 0               
    Assertion Pass             // May execute last as well
   

In reply to MICRO_91:
Why are you so concerned about regions? A user should not be concerned about that.
For verification, Void functions or tasks issued in a sequence_match_item should be used for support logic, typically used for the next attempt at the assertion.
Tasks with delays should be issued in an action block for compatibility with tools.

As a general rule in SV, KISS!
Ben

In reply to ben@SystemVerilog.us:

Why are you so concerned about regions? A user should not be concerned about that.

I am just testing my understanding of the LRM.
The above code has different output across different tools, since we don’t discuss tool issues here I was curious to know on how the code executes based on SV region

In reply to MICRO_91:

As you’ve found, there is NO oversight on the LRM. A tool can strive to verify the precise 1800 details, but it falls to the users of those tools to request modifications if necessary.
Ben

In reply to ben@SystemVerilog.us:

Thanks Ben,
My intention was simply to confirm with the forum moderators that my interpretation matches the LRM and also to point out and confirm a few things which the LRM doesn’t specify.

In reply to ben@SystemVerilog.us:

Hi Ben,
I was trying a variation of the code


 initial forever #10 clk = ~clk;

 bit [3:0] a ;
 always@( posedge clk) a <= a + 1;

 property p1;
  @(posedge clk) (1,$display("a is %d",a));
 endproperty

 assert property( p1 ) $display("pass");

Considering that $display() executes in reactive region, why do we observe “a is 0” instead of “a is 1” ?( at 1st posedge of clk )
By reactive region wouldn’t the NBA update ( to 1 ) would have been done ?

If I were to re-write to


 function void disp();
   $display("a is %d",a);
 endfunction
 
 property p2;
  @(posedge clk) (1,disp() );
 endproperty

 assert property( p2 ) $display("pass");

Now I do observe “a is 1” i.e NBA updated value is observed

In reply to Have_A_Doubt:

In reply to ben@SystemVerilog.us:
Hi Ben,
I was trying a variation of the code


initial forever #10 clk = ~clk;
bit [3:0] a ;
always@( posedge clk) a <= a + 1;
property p1;
@(posedge clk) (1,$display("a is %d",a));
endproperty
assert property( p1 ) $display("pass");

Considering that $display() executes in reactive region, why do we observe “a is 0” instead of “a is 1” ?( at 1st posedge of clk )
By reactive region wouldn’t the NBA update ( to 1 ) would have been done ?

[Ben] “a is 0” because “a” is within the property in the sequence_match_item (1,$display(“a is %d”,a)); Therefore, “a” is its sampled value.

If I were to re-write to


function void disp();
$display("a is %d",a);
endfunction
property p2;
@(posedge clk) (1,disp() );
endproperty
assert property( p2 ) $display("pass");

Now I do observe “a is 1” i.e NBA updated value is observed

[Ben] @(posedge clk) (1,disp() ); does not reference the “a”, thus, the function that executes in the Observed or maybe Reactive region (tool dependent per my observation) sees the updated value of “a”; updated as you know in the NBA region.

In reply to ben@SystemVerilog.us:

because “a” is within the property in the sequence_match_item (1,$display(“a is %d”,a)); Therefore, “a” is its sampled value.

Thank you Ben.