Hi,
I was trying a sequence as an event control: edalink
Tasks and void function get called in Reactive region whereas the event control ’ @(seq) ’ unblocks in loopback/feedback from Observed to Active region.
So when @(seq) unblocks what should the value of length be ? Should we observe the value assigned from subroutine ? Is there a pre-defined order of execution between the assignment within the subroutine and unblocking of event control @(seq) ?
I checked **LRM Figure 4-1—Event scheduling regions:
There is a loopback from Observed region to Active region and another loopback from Re-NBA to Active region.
Note: There is no direct loopback from Reactive to Active region.**
In reply to MICRO_91:
I modified your code slightly and added varivle f that toggles.
code: Sequence as Event control(1) - EDA Playground
wave: EPWave Waveform Viewer
SIM: T:35 Length == 0 f=0
All signals change at the clock edge in the Active region
At t35, $sampled(c)==1 and $sampled(len)==0
Thus, at t35 ##0 (1, data = len , Length( data )
Also, at t35, in the Observed region, the end point of seq is true.
Thus, always@( seq )
$display(“T:%0t Length == %0d f=%d”,$time,length, f);
Length==0 (as explained above)
$sampled(f) at the posedge clk is 1, but it changed in the Active region to 0
The $display of f is the value of f in the Observed Region, which is a 0
(this is what is sees with $display what you see NOW) NOTE: If I change the code to
always@( seq )
$display(“T:%0t Length == %0d f=%d”,$time,length, $sampled(f)); Sequence as Event control(2) - EDA Playground
I get T:35 Length == 0 f=1
module top;
bit clk , a , b , c, f ;
bit [3:0] length , len ;
always #5 clk = !clk;
function void Length( input bit [3:0] L );
length = L;
endfunction
sequence seq;
bit [3:0] data;
@(posedge clk) a ##1 b ##1 c ##0 (1, data = len , Length( data ) );
endsequence
always@( seq )
$display("T:%0t Length == %0d f=%d",$time,length, f);
always @(posedge clk) f<=!f;
initial begin
$dumpfile("dump.vcd"); $dumpvars;
#5 ; a = 1 ;
#10 ; a = 0 ; b = 1 ;
#10 ; b = 0 ; c = 1 ;
#10 len = 10 ;
#10 ;
#2; $finish();
end
endmodule
Ben Cohen Ben@systemverilog.us
Link to the list of papers and books that I wrote, many are now donated.
In your code the variable ‘f’ is updated in NBA region whereas the endpoint of sequence ‘seq’ occurs in Observed region.
At T:35 by Observed region the value of ‘f’ would be updated to 0.
Event control @(seq) unblocks in loopback from Observed to Active region and the $display() within it executes in Active region.
Hence we observe updated value of 0 for ‘f’.
In your code variable ‘length’ is assigned preponed value of 0 ( which is same as default value ) so there is no discrepancy here
i.e whether the assignment occurs before or after @(seq) unblocks.
In both cases the value (0) is the same
In my code the void function ‘Length’ is assigned value of 10 in Reactive region whereas @(seq) unblocks in loopback from Observed to Active region.
So some tools show updated value for Length whereas some show the non-updated value of Length.
**As the void function is called in Reactive region the assignment also occurs in Reactive region whereas the seq. endpoint occurs in Observed region.
When do we say that the sequence has ended ? i.e after the assignment is done for ‘Length’ OR before the assignment as soon as ‘c’ is true
**
In reply to ben@SystemVerilog.us:
In my code the void function ‘Length’ is assigned value of 10 in Reactive region whereas @(seq) unblocks in loopback from Observed to Active region.
Your code " … ##0 (1, data = len , Length( data )
The Reactive region is for Action block.
See my paper on immediate assertions (link in the list of papers)
[/quote][b]As the void function is called in Reactive region …
[/quote[
Again, the function is called in a sequence matched item in the Observed region.
Again, the function is called in a sequence matched item in the Observed region.
As per our discussion a few months ago, we both concluded that a void function/task called as part of sequence_match_item executes in Reactive region similar to action block.
I am currently referring to your 2nd reply in this thread
LRM Section 16.11 says
All subroutine calls attached to a sequence are executed at every end point of the sequence. For each end point, the attached calls are executed in the order they appear in the list. Assertion evaluation does not wait on or receive data back from any attached subroutine.
The subroutines are scheduled in the Reactive region,like an action block.
As the 1st line of the above LRM quote says: “All subroutine calls attached to a sequence are executed at every end point of the sequence.”
So now we have @(seq) which unblocks at every endpoint of sequence as well as the subroutine call which too executes at every endpoint of sequence
Possibly a race condition ? OR
If I go by Figure 4-1 of the LRM the loopback from Observed region to Active region occurs before loopback from Re-NBA to Active.
So should @(seq) unblock before the subroutine gets called in Reactive region ?
In reply to ben@SystemVerilog.us:
Ben,
As per our discussion a few months ago, we both concluded that a void function/task called as part of sequence_match_item executes in Reactive region similar to action block.
NO, that is only true for action blocks.
LRM Section 16.11 says All subroutine calls attached to a sequence are executed at every end point of the sequence. For each end point, the attached calls are executed in the order they appear in the list.
[Ben] Moving into another topic Assertion evaluation does not wait on or receive data back from any attached subroutine.
The subroutines are scheduled in theReactive region,like an action block.
[Ben] thus, " … ##0 (1, data = len , Length( data ), which causes the variable length to be modified, does not affect the assertion evaluation. length is modified in the Observed region.
A side comment, module variables modified in an assertion should be used only for support logic. A user should be concerned with these timing regions/
Ben
Ben,
Unfortunately I am still not clear on the following
(1)
LRM Section 16.11 says
All subroutine calls attached to a sequence are executed at every end point of the sequence. For each end point, the attached calls are executed in the order they appear in the list.
This tells me that local_variable 'data' is assigned before calling function 'Length'
In cases where there are multiple sequence_match_items, they would execute in left to right order.
(2)
Assertion evaluation does not wait on or receive data back from any attached subroutine.
We discussed this LRM quote in [this](https://verificationacademy.com/forums/systemverilog/achieving-dynamic-delays-sva-using-subroutine). So when a time consuming task gets called as part of sequence_match_item, the assertion doesn't wait for the task to complete
(3)
The subroutines are scheduled in the Reactive region,like an action block
So doesn't this mean that void function 'Length' gets called in Reactive region ?
As void function/task don't return any value , they execute in Reactive region.
As the void function 'Length' gets called in Reactive region the assignment within it would also execute in Reactive region right ?
(4)
A side comment, module variables modified in an assertion should be used only for support logic. A user should be concerned with these timing regions
I do agree but consider a code where the sequence event control is used as triggering event to a covergroup,
And the coverpoint is sampling the value of variable assigned in subroutine.
The same scenario would exist i.e would the value prior to assignment would be sampled OR will the updated value be sampled ?
The way I think it works is that functions called in a sequence_matchedItem
are scheduled in the Observed region. If the function returns a value, it is executed immediately. Thus,
function bit f(bit i) return !i; endfunction
property p;
bit x;
(a, x=f(c)) ## d==x ..; // x is updated in the Observed region
// Otherwise you could not complete the sequence
..
function void Length( input bit [3:0] L ); length = L; endfunction
task t(bit [3:0] L ); length = L; endtask
assert property( @(ce) (a, Length(data), t(data1)) );
// The function and the task are scheduled to be processed in the Observed region.
// When are they executed? Probably after all executions of queued up
// assertions are completed, thus probably in the Reactive region.
// But it really doesn't make a difference to the user.
// Any updated module variables is not seen by any ongoing assertions
// being executed in that time step since signals are sampled.
The way I think it works is that functions called in a sequence_matchedItem
are scheduled in the Observed region. If the function returns a value, it is executed immediately. Thus,
function bit f(bit i) return !i; endfunction
property p;
bit x;
(a, x=f(c)) ## d==x …; // x is updated in the Observed region
// Otherwise you could not complete the sequence
I agree. The same is confirmed in LRM.
LRM 16.10 Local variables :
Initialization assignments shall be performed in the Observed region in the order that they appear in the sequence or property declaration.
The sequence or property shall assign a value to the local variable prior to the point at which the reference is made.
As ‘x’ will be assigned in observed region, function ‘f’ executes in Observed region as well. ( Hence I believe functions with return type (i.e non-void functions) called as part of sequence_match_item execute in Observed region )
Regarding the order of execution between the assignment within the subroutine and execution of action block,
(a) LRM 16.11 Calling subroutines on match of a sequence :
All subroutine calls attached to a sequence are executed at every end point of the sequence. For each end point, the attached calls are executed in the order they appear in the list. Assertion evaluation does not wait on or receive data back from any attached subroutine.The subroutines are scheduled in the Reactive region,like an action block.
Hence can I state the following ?
Since both void function/task as well as action blocks execute in Reactive region, there is no pre-defined order of execution between the two
In the code, assignment to ‘length’ within void function ‘Length’ as well as $display within action block execute in Reactive region.
As a result there is no pre-defined order of execution between the function ‘Length’ and action block.
As a result there is no pre-defined order of execution between the function ‘Length’ and action block.
Probably correct. However, since the void function length was put into q queue to be executed at a later point, anything to be queued in the action block may be executed next.
A tool vendor can do what he wants.
As @(seq) unblocks in loopback from Observed to Active region, the $display() within always@(seq) executes before $display() in action block ( which executes in Reactive region )
So this essentially tells us that loopback from Observed to Active occurs before Reactive region.
Now consider the code at the top of this thread: edalink2
The void function executes in Reactive region similar to action block ( as we discussed in the last 2 replies ).
Hence the $display() within always@(seq) executes before void function ‘Length’ executes.
Therefore I believe ‘length’ would be unassigned when $display() executes within always@(seq).
In reply to MICRO_91: Q: In which region a void function or task is executed if that function/task is called from a sequence_match_item?
My previous answer may be incorrect as it may be tool-dependent.
**Previous answer:**The void functions and tasks are scheduled to be processed in the Observed region. When are they executed? Probably after all executions of queued-up
assertions are completed, thus probably in the Reactive region.
However, when I tested this model, it appeared that some tools(not all) execute the void functions and tasks when they are called in the Observed region. Thus, if the task has Delays or wait statements that would not work in completing an on-going assertion. The tool may then set a warning about the non-support of Delays or wait statements in match item task calls.
Previous answer:The void functions and tasks are scheduled to be processed in the Observed region. When are they executed? Probably after all executions of queued-up
assertions are completed, thus probably in the Reactive region.
However, when I tested this model, it appeared that some tools(not all) execute the void functions and tasks when they are called in the Observed region. Thus, if the task has Delays or wait statements that would not work in completing an on-going assertion.
I have a similar understanding on this.
LRM 16.11 : "Assertion evaluation does not wait on or receive data back from any attached subroutine"