[sv-ec] Problem with implicit production variables in randsequence

From: Ryan, Ray <Ray_Ryan_at_.....>
Date: Wed Oct 10 2007 - 16:18:01 PDT
In general, it is not possible to determine the number of instances of a
child production (production_item) in a randsequence production.  This
implies that the current LRM explanation of the associated implicit
array declaration is insufficient for general case problems.  The rest
of the discussion here provides a detailed example and explanation of
the kind of scenario that requires a change in how such situations work.

The proposed changes (at the end) are not compatible with the 2005 LRM.
It isn't clear whether the 2005 LRM is making unstated simplifying
assumptions or whether the general case was just not considered.  We are
assuming the latter and are proposing a change on that basis. 


Introduction:

Example 1:
   int i1, i2;
   string s1;
   ...
   randsequence (main)
      main   : P1 | P2;
             P1 : P3 { i1 = P3; } P4 { s1 = P4 };
             P2 : P3 { i2 = P3; };
      int    P3 : { return 99; };
      string P4 : { return "blue"; };
   endsequence

In this randsequence, the production P1 contains two production_items
(P3, P4) and contains two code blocks. The return values of the
productions referenced by the production_items are assigned to the
variables i1, s1 in the code blocks.

As per the LRM, to allow a reference to the value returned by a
production, "Within each production, a variable of the same name is
implicitly declared for each production that returns a value". The type
of the variable is derived from the return type of the referenced
production. 

In example 1, the following variables are implicitly declared in the
scope of the production P1. 
      int P3;
      string P4;
Similarly, variable 'P3' is also implicitly declared in the scope of P2;

When a production returns, its return value is assigned to the
corresponding implicit variable in the parent production. In example 1,
when P4 returns, the value "blue" is assigned to the variable P4 in the
scope of P1.

Example 2:
   int i1, i2;
   string s1, s2;
   ...
   randsequence (main)
      main   : P1 | P2;
             P1 : P3 { i1 = P3[1]; } P4 P3 P3 { i2 = P3[3] };
             P2 : P4 { s1 = P4; };
      int    P3 : { return 99; };
      string P4 : { return "blue"; };
   endsequence

In example 2, P3 occurs multiple times in the production P1. To allow
reference to the separate return values, an implicit array is declared.
The LRM states, "If the same production appears multiple times, then a
one-dimensional array that starts at 1 is implicitly declared."

In the scope of P1, the following variables are implicitly declared.
   int P3[1:3];
   int P4;

In the LRM, it is implied by example that the number of elements in the
implicit array is the number of occurances of the associated production.

The 'if-else' and 'repeat' constructs make this more complicated.

Example 3:
   int i1, i2, n;
   string s1, s2;
   ...
   randsequence (main)
           main   : P1a | P1b | P2;
           P1a    : P3 
                    { i1 = P3[1]; }
                    if (n==0) P3
                    ;
           P1b    : P4(99) 
                    { s1 = P4[1]; }
                    if (n==0) P4(5) else P4(20)
                    ;
           P2     : P3 
                    { i1 = P3[1]; }
                    repeat (n) P3
                    ;
      int  P3     : { return 99; };
      string P4 (int prm)
                  : { if (prm > 10)
                         return "red" 
                       else 
                         return "blue"; 
                    };
   endsequence

The production P1a is defined as an occurrence of P3, followed by a code
block, followed by a conditional occurrence of P3.  The production P1b
is defined as an occurrence of P4 (with input parameter value 99),
followed by a code block, followed by either an occurrence of P4(5) or
P4(20) depending on the value of 'n'. 
The production P2 is defined as an occurrence of P3 followed, by a code
block, followed by 'n' occurrences of P3.

How many times do P3 and P4 occur in the productions P1a, P1b, P2?  Is
it the number of syntactic occurrences? Is it the dynamic number of
occurrences? It would seem the most useful would be the dynamic number
of occurrences.


Issue 1:
According to 'declare-before-use', a variable should be declared before
it is used. In the example 2, the implicit variable P3 is used in the
first code block of production P1. However, the implicit declaration
cannot be (implicitly) created until the end of the production (P1).
That is, at the point of the first reference to the implicit variable
P3, it is unknown how many times P3 will occur.

Issue 2:
In some cases the number of occurrences of a production is a dynamic
value (EG when 'if-else' or 'repeat' constructs are used). In this case
it is ambiguous (problematic) to determine whether the implicit variable
has a scalar or aggregate type.

Alternative 1:
Always make the implicit variable a queue. Each dynamic occurrence of
the associated production inserts its return value at the end of the
queue. 
Problems with 1:
a) It is not backward compatible.
   - A reference to the implicit value using a simple 
     name (non-indexed) would refer to the queue as an 
     aggregate (instead of the value of a single 
     occurrence). This is a common usage today.
b) The first element of a queue is indexed by [0]. 
   Currently the first element of the implicit array 
   is indexed by [1]. Existing code where an array is 
   implicitly declared would compile, but have 
   different behavior.
c) The single instance of a non-terminal is common. 
   Requiring the indexed expression is not as 
   simple (friendly).

Alternative 2:
Always make the implicit variable a scalar. Each dynamic occurrence of
the associated non-terminal would update this variable (last occurrence
overrides).
Problems with 2:
a) This is also not backward compatible. Existing 
   references to an implicit array using an indexed 
   expression would no longer compile.
b) In order to reference other than the most recent 
   instance, the User must explicitly save the prior 
   value(s). For example:
       int vals[1:2]
       ...
       randsequence
         ...
         P1 :  P3 { vals[1] = P3; }
               P3 { vals[2] = P3; }
               P3
               { $display( vals[1], vals[2], P3 ); }
               ;
         ...


Regards,
Ray



-------------------------------------------------------------------
Ray Ryan                                        408-487-7240
Mentor Graphics Corp.                           rryan@model.com


-- 
This message has been scanned for viruses and
dangerous content by MailScanner, and is
believed to be clean.
Received on Wed Oct 10 16:18:20 2007

This archive was generated by hypermail 2.1.8 : Wed Oct 10 2007 - 16:18:30 PDT