Order of displays inside Function Calls

Hi all ,

I have the following Code ::



module Main ;

class A ;
 
 
rand bit [3:0] q[];
 
 
 
constraint Q_SIZE { q.size() == 6 ; }   
 
 
 
 
constraint Q_VAL {  
                        foreach( q[Index] ) 
                     {
 
                           q[Index] == FUNC(Index) ;
 
		      }
 
		 }    
  
 
function int FUNC ( input int Ind );
static int Count ; 
$display(" Function Called for %0d Time with Ind == %0d ",Count,Ind);

   
   Count++;
   return Ind;
 
 
endfunction
 
endclass
 
A a1 ;
 
initial begin
 
a1 = new();
 
  
if ( a1.randomize() )
 begin 
  $display("Success with %p ",a1);
 end
else
  $display("Fails with %p",a1);
 
 end
 

endmodule


I have the following Output on 2 different Simulators ::

(1) SIMULATOR 1 ::
Function Called for 0 Time with Ind == 5
Function Called for 1 Time with Ind == 4
Function Called for 2 Time with Ind == 3
Function Called for 3 Time with Ind == 2
Function Called for 4 Time with Ind == 1
Function Called for 5 Time with Ind == 0
Function Called for 6 Time with Ind == 5
Function Called for 7 Time with Ind == 4
Function Called for 8 Time with Ind == 3
Function Called for 9 Time with Ind == 2
Function Called for 10 Time with Ind == 1
Function Called for 11 Time with Ind == 0
Function Called for 12 Time with Ind == 5
Function Called for 13 Time with Ind == 4
Function Called for 14 Time with Ind == 3
Function Called for 15 Time with Ind == 2
Function Called for 16 Time with Ind == 1
Function Called for 17 Time with Ind == 0
Success with ‘{q:’{'h0, 'h1, 'h2, 'h3, 'h4, 'h5}}

(2) SIMULATOR 2 ::
Function Called for 0 Time with Ind == 0
Function Called for 1 Time with Ind == 1
Function Called for 2 Time with Ind == 2
Function Called for 3 Time with Ind == 3
Function Called for 4 Time with Ind == 4
Function Called for 5 Time with Ind == 5
Success with ‘{q:’{0, 1, 2, 3, 4, 5}}

Although the contents of queue is as expected ,
I have a question regarding the Order of $display in Output

(Q1) Since the Index of q inside constraint iterates from 0 to 5 , I expect the Ind ( in Output ) to be from 0 to 5 as well .

Is it possible for the display to be something else ?? 
Does the LRM guarantee that the Output would be in FIFO Ordering ( i.e Ind is displayed from 0 ( First ) to 5 ( Last )  ) ? 

(Q2) Shouldn’t I get only 5 displays per randomization call ?

Thanks ,
HV

In reply to himanshu valecha:

  • Functions that appear in constraint expressions should be automatic (or preserve no state information) and have no side effects.
  • Function calls in active constraints are executed an unspecified number of times (at least once) in an unspecified order.

In reply to dave_59:

Thanks Dave .

I have one more question . If I have the following Codes ::


[ Sample 1 ]

for ( int i = 0 ; i < 10 ; i ++ ) // Inside any procedural block like initial begin
   $display(i) ;

[ Sample 2 ]

for ( int i = 0 ; i < 10 ; i ++ ) // Inside any procedural block like initial begin
    FUNC(i) 

...

function automatic void FUNC ( input int a ) ; // Could be static OR automatic
 $display(a);
endfunction


In these cases can I say that there is always a guarantee that the displays would always
be 0 to 9 ? [ i.e 0 displayed first and 9 displayed last in ascending order ]
Is there a possibility of the output being in any other order ?

For eg : the for loop getting unrolled in parallel ( Like in a generate ) and hence the display statements could be executed in any order OR
Would it be unrolled sequentially and execute display statement from i == 0 to i == 9 ?

Thanks in advance ,
Himanshu

In reply to himanshu valecha:

In both the samples the incremental display is always guaranteed. It executed $display statement (displays i) in each iteration before moving to the next value of i.

In reply to ManjunathBhat:

Hi ,

If its not too much to ask could you please point to which section of LRM describes the atomic guarantee ( Incremental display ) ?

Thanks in advance ,
HV

In reply to himanshu valecha:

Ordering and atomic execution are two separate principles. Within a single procedural begin/end thread, order is guaranteed, but not relative to multiple threads. This is explained in sections 4.6-4.8 of the IEEE 1800-2017 LRM.

A procedural-for-loop might get unrolled, but the behavior must be maintained as if it were not.
A generate=for usually creates concurrent threads, and the relative execution order of those threads is indeterminate.