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