I have attached the analysis. It is also available on the website. Chuck Swart -- This message has been scanned for viruses and dangerous content by MailScanner, and is believed to be clean. VHDL Issue Number: 2126 Language_Version VHDL-2002 Classification Language Definition Problem Summary Concatenation ambiguity Relevant_LRM_Sections Clause 7.2.4 Adding Operators (specifically concatenation) Clause 7.3.5 Type Conversions Related_Issues Key_Words_and_Phrases concatenation, type conversion Authors_Name Tim McBrayer Authors_Phone_Number 508-647-4229 Authors_Fax_Number Authors_Email_Address tim_mcbrayer@ieee.org Authors_Affiliation The MathWorks Authors_Address1 3 Apple Hill Dr. Authors_Address2 Natick, MA 01760 Authors_Address3 Current Status: Analyzed Superseded By: ------------------------ Date Submitted: 11 December 2007 Date Analyzed: 07 February 2008 Author of Analysis: Chuck Swart Revision Number: 1 Date Last Revised: 07 February 2008 Description of Problem ---------------------- I have encountered an issue where commercially available VHDL simulators differ as to the correctness of a certain concatenation, when the concat is contained inside a type conversion statement. Two commercial parsers reject this concatenation as ambiguous; six other commercial and research parsers consider this construct valid. My study of the LRM leads me to believe that it is valid. The vendor for one of the parsers that consider the construct ambiguous suggested I submit this to P1076 WG ISAC. Here is my specific example: LIBRARY ieee; USE ieee.std_logic_1164.all; USE ieee.numeric_std.all; ENTITY concatissue IS PORT ( in_0, in_1, in_2 : IN unsigned(1 DOWNTO 0); out1 : OUT std_logic_vector(5 DOWNTO 0)); END concatissue; ARCHITECTURE arch OF concatissue IS -- This type declaration causes some parsers to flag the concat as ambiguous TYPE bad_type IS ARRAY (0 to 99) of unsigned(1 to 1000); BEGIN out1 <: std_logic_vector(in_0 & in_1 & in_2); -- is this ambiguous or not? END arch; The primary question lies with the resolution of the first concat processed of the two that comprise the operand of the type conversion. Is the result of the concat of type unsigned, or is it of type bad_type? First, it is relevant to note that the expression inside a type conversion must be able to have its type unambiguously determined. This is stated in Clause 7.3.5, Type conversions, page 111, IEEE Std. 1076-2002. "The type of the operand of a type conversion must be determinable independent of the context (in particular, independent of the target type)." For the concatenation expression: any type (unsigned, in my specific case) has defined implicitly for it 4 different versions of the concat operator with different signatures, as expressed in the table in Clause 7.2.4, page 102. They can be summarized based on their argument and return types as: 1. &(T, T) return T 2. &(T, element_type of T) return T 3. &(element_type of T, T) return T 4. &(element_type of T, element_type of T) return T The ambiguity seen here by some parsers is between cases 1 and 4; 2 and 3 are not relevant in this case. In Clause 7.2.4, Adding operators, page 102, after the table there are three mutually exclusive cases listed. Case c) is the point on which I believe there is a difference of interpretation. "c) If both operands are of the same type and it is the element type of some one-dimensional array type, the type of the result must be known from the context and is this one-dimensional array type. In this case, each operand is treated as the one element of an implicit array, and the result of the concatenation is determined as in case a). The bounds and direction of the index subtypes of the implicit arrays are determined as in the case of the implicit array in case b)." My understanding of this language, piece by piece, is: "If both operands are of the same type and it is the element type of some one-dimensional array type,..." This is true in this case. The operands are of type unsigned and unsigned is the element type of bad_type, a 1-D array of unsigned. "...the type of the result must be known from the context and is this one-dimensional array type." I contend this statement is not true. The result cannot be known from the context, because the expression in a type conversion explicitly does not provide any context. The type of the conversion expression (in this case the concatenation) must be determined by itself. Since case c) for concats requires the type be known from the context, and since the context cannot provide type information in this case, case c) is not valid for determining the type of the concat expression in the example. Case b) in 7.2.4 is not relevant, as it concerns the concat of a 1-D array and the appropriate element_type. Thus b) is not valid for determining the return type of the concat expression in this example. This leaves a) as the only mutually exclusive choice left. Thus, the type of the concat expression is the same array type (unsigned) as both the left and right operands. This implies the example code is legal VHDL. This logic is clearly open to another interpretation, since two vendors' tools claim the concatenation is ambiguous between bad_type and unsigned. The LRM even addresses this specific possibility of ambiguity in note 2, 7.2.4, page 104. Proposed Resolution ------------------- I believe that the example code in this case is not ambiguous; neither do I believe that the LRM wording is ambiguous. My only suggestion at this time would be to explicitly reference this specific case in an example, if the construct is decided to be unambiguous. If the construct is determined to be ambiguous, I propose removing the phrase "mutually exclusive" from 7.2.4, as it is possible to have one concatenation expression that meets the requirements of both a) and c). If this is the case the text of note 2 should be given a more prominent position. VASG-ISAC Analysis & Rationale ------------------------------ The major area describing the issues raised by this IR is Clause 10.5, The context of overload resolution. This clause describes the following general procedure: A syntactic region of the design is identified, called an "innermost complete context". Certain rules are applied to potentially ambiguous names, operations, etc. to determine which interpretation is intended. After a unique interpretation is selected, further semantic checking may occur. However, in some cases not all of the rules of 10.5 are applied to the entire complete context. A good example of this can be found in rules for sequential case statements. The LRM states that "Each choice in a case statement alternative must be of the same type as the (case) expression." This rule could be used to resolve the type of the case expression, since Clause 10.5 states that we must consider "a) Any rule that requires a name or expression ... to have the same type as another name or expression." However, the original language designers decided against this. Instead they decided that the type of the case expression should be determined independently of the case choices. Once this type is determined then a semantic check is performed to make sure that the case alternatives are of the same type. The ISAC believes that the intent is that the type of the case expression be determined without examining the innermost complete context outside of the case expression but by applying the rules of 10.5 to the case expression. However, the LRM wording is: "This type (of the case expression) must be determined independently of the context in which the expression occurs, but using the fact that ...". Unfortunately, the expression "independently of the context" is not completely clear. It could be interpreted as the ISAC believes was intended, but it could also be interpreted as "There is no applicable context for the case expression." the word "context" might mean the innermost complete context or it might refer to the application of all the rules of 10.5. The use of the word "context" in the title of Clause 10.5 "The context of overload resolution" is not formally defined. In fact, throughout the LRM the word "context" is used freely and somewhat loosely. Some implementations interpret "independent of context" in an informal way. Since its not completely clear just what is meant by "context" it is even less clear what is intended by phrases like "independent of context". The ISAC believes that this situation is best remedied by removing the references to context independence and by making the intent more explicit. Under the ISAC interpretation the concatenation expression in question is ambiguous. The VHDL-2002 LRM has three areas which state that certain types must be determined independent of context. These areas are: 1) Discrete ranges defined by a range in constrained array definitions, iteration schemes or generation schemes (Clause 3.2.1.1), 2) Type conversions (7.3.5), and 3) Case statements (8.8). In addition VHDL-200X version D4.0 states in Clause 6.7, External names, that the static expression used with generate statement labels in external pathnames "shall be determined independently of the context." It also states in Clause 9.7, Generate statements, that the type of the case expression "shall be determinable independently of the context in which the expression occurs..." VASG-ISAC Recommendation for IEEE Std 1076-2002 ----------------------------------------------- Interpret the LRM as if the Recommendation for Future Revisions were in place. However, it is recognized that not all implementations conform to this interpretation. VASG-ISAC Recommendation for Future Revisions --------------------------------------------- Make the following changes to VHDL-2002: Clause 3.2.1.1 Index constraints and discrete ranges Change the paragraph reading: "For a discrete range used in a constrained array definition ... Otherwise, both bounds must be of the same discrete type, other than universal_integer; this type must be determined independently of the context but using the fact that the type must be discrete and that both bounds must have the same type...." To: "For a discrete range used in a constrained array definition ... Otherwise, both bounds must be of the same discrete type, other than universal_integer; this type must be determined by applying the rules of Clause 10.5 to the two bounds without using any other information from the definition except the facts that both bounds must have the same type and that this type must be discrete...." Clause 7.3.5 Type conversions Change the paragraph reading: "The target type of a type conversion is the base type of the type mark. The type of the operand of a type conversion must be determinable independent of the context (in particular, independent of the target type)... TO; "The target type of a type conversion is the base type of the type mark. The type of the operand of a type conversion must be determinable by applying the rules of Clause 10.5 to the operand without using any other information from the statement or declaration. (In particular, the type of the operand must be determinable independent of the target type)... Clause 8.8 Case statement Change the paragraph reading: "The expression must be of a discrete type, or of a one-dimensional array type whose element base type is a character type. This type must be determinable independently of the context in which the expression occurs, but using the fact that the expression must be of a discrete type or a one-dimensional character array type...." To: "The expression must be of a discrete type, or of a one-dimensional array type whose element base type is a character type. This type must be determinable by applying the rules of Clause 10.5 to the expression without using any other information from the statement, but using the fact that the expression must be of a discrete type or a one-dimensional character array type. (In particular, the type of the case expression must be determinable independently of the type of the case statement choices.)...." Make the following changes to VHDL-200X LRM version D4.0: Clause 6.7, External names Change the paragraph reading: "5) For a generate statement label,...the type of the expression shall be determined independently of the context, but using the fact that the type shall be discrete..." To: "5) For a generate statement label,...the type of the expression shall be determined by applying the rules of Clause 10.5 to the expression without using any other information from the external name, but using the fact that the type shall be discrete..." VHDL-200X LRM version D4.0 Clause 9.7 Generate statements Change the paragraph reading: "For a case generate statement, the expression shall be globally static, and shall be of a discrete type, or of a one-dimensional array type whose element base type is a character type. This type shall be determinable independently of the context in which the expression occurs, but using the fact that the expression shall be of a discrete type or a one-dimensional character array type..." To: "For a case generate statement, the expression shall be globally static, and shall be of a discrete type, or of a one-dimensional array type whose element base type is a character type. This type shall be determined by applying the rules of Clause 10.5 to the expression without using any other information from the statement, but using the fact that the expression shall be of a discrete type or a one-dimensional character array type..."Received on Thu Feb 7 16:07:52 2008
This archive was generated by hypermail 2.1.8 : Thu Feb 07 2008 - 16:07:58 PST