Language Change Specification for Inferring Constraints from Initial Values for Signals and Variables

Proposal

LCS Number: LCS-2016-019
Version: 7
Date: 2017-02-24
Status:  
Author: Ryan Hinton
Martin Zabel
Jim Lewis
Email: Main.RyanHinton
Main.MartinZabel
Main.JimLewis
Source Doc: Inferring Constraints from Initial Values for Signals and Variables
Summary: Allow for signal and variable subtype constraints to be inferred from initial value
Related LCS: LCS_2016_019

Voting Results: Cast your votes here

Yes:

  1. Jim Lewis - 2017-02-24 ver 7

No:

Abstain:

Style Notes

Changes are shown in red font.
Deletions are crossed out.
Editing or reviewing notes in green font.

Reviewing Notes

Version 6 & 7 by Jim Lewis

Version 4 and 5 by Ryan Hinton

A message to the reflector on 10 Feb 2017 received no response. I can only assume that the following solution is acceptable.

Previously, 14.4.2.5 "establishes the subtype of [an] object" solely from the subtype indication. Index range constraints from an initial value for a constant are tacked on in some sense, and are referenced by 5.3.2.2 and predefined attributes. The proposed text ensures that explicitly declared objects (besides deferred constants) have fully-constrained subtypes by making the subtype determination a two-step process.

Details of Language Change

LRM 5.3.2.2 Index constraints and discrete ranges

Bulleted list from the end of page 47 to the beginning of page 48

The index range for each index of an array object or array subelement of a composite object is determined as follows:

a) ... [Remove this item and fix bullet labels of ensuing list.]

ba) For a constant, variable, or signal declared by an object declaration, if the subtype indication of the constant defines the index range, then the index range of the constant object is that defined by the subtype indication; otherwise, the index range of the constant object is the corresponding index range of the initial value if one is given. For a constant with an initialization expression, a variable, or a signal, it is an error if the index range is not determinable from either the subtype indication or the initialization expression.

LRM 14.4.2.5 Object declarations

The rules of this subclause apply only to explicitly declared objects (see 6.4.2.1). Generic declarations, port declarations, and other interface declarations are elaborated as described in 14.3.2 through 14.3.5 and 14.6.

Elaboration of an object declaration that declares an object other than a file object or an object of a protected type proceeds as follows:

a) The subtype indication is first elaborated; this establishes the subtype of the object.

b) If the object declaration includes an explicit initialization expression, then the initial value of the object is obtained by evaluating the expression. It is an error if the value of the expression does not belong to the subtype of the object; if the object is a composite object, then an implicit subtype conversion is first performed on the value unless the object is a constant whose subtype indication denotes an unconstrained type. Otherwise, any implicit initial value for the object is determined.

a) The subtype indication is first elaborated; this establishes an initial subtype of the object.

b) If the object declaration includes an initialization expression,

  • The initial value of the object is obtained by evaluating the expression.
  • If the object is a composite object, then an implicit subtype conversion is performed on the initial value.
  • It is an error if the initial value does not belong to the subtype of the object.
  • If the subtype of the object is either an unconstrained or partially constrained type, for each index range that is not determined, the corresponding index range of the initial value is used.
  • It is an error if an index range cannot be determined from either the subtype indication or the initial value.

c) If the object declaration is a signal or variable and does not include an initialization expression,

  • It is an error if the subtype of the object is either an unconstrained or partially constrained type.
  • Any implicit initial value for the object is determined.
d c) The object is created.

e d) Any initial value is assigned to the object.

(Delete following paragraph because it repeats information from the steps above (for VHDL-2008) without clarification or additional information.)

The initialization of such an object (either the declared object or one of its subelements) involves a check that the initial value belongs to the subtype of the object. For a composite object declared by an object declaration, an implicit subtype conversion is first applied as for an assignment statement, unless the object is a constant whose subtype is an unconstrained type.

(Remainder of section on file objects and protecte type objects remains unmodified.)

Old Reviewing Notes

Version 3 by Martin Zabel (out-dated)

I added the sentence from my comment, and I also fixed the section indicated by Ernst Christen. But I can't tell whether the LCS is now complete. Consider the following declarations:

variable v : bit_vector := "1010";
signal s :  bit_vector := "1010";

The first one declares a variable (object) with an unconstrained subtype (see 14.4.2.5), and an index range of 0 to 3 (see 5.3.2.2). Same applies to the signal declaration.

The problem now is, that a lot of rules for signal and variable assignments target the subtype of the object, e.g. the implicit subtype conversion in 10.6.2.2. But, this subtype can be unconstrained now, in the current LRM, the subtype of signals and variables are always constrained. constants do not matter because they cannot be assigned. Maybe the following must be prohibited explicitly:

v := "10101";
s <= "10101";

Thus, I can't tell whether more changes in the LRM need to be updated. There may be to many places.

Update 2017-02-17 (out-dated)

The LCS is incomplete, at least for variables.

Clause 10.6.2.2 "Composite variable assignments" reads:

If the target of an assignment statement is a name denoting a composite variable (including a slice), the value assigned to the target is implicitly converted to the subtype of the composite variable; the result of this subtype conversion becomes the new value of the composite variable.

This means that the new value of each element of the composite variable is specified by the matching element (see 9.2.3) in the corresponding composite value obtained by evaluation of the expression. The subtype conversion checks that for each element of the composite variable there is a matching element in the composite value, and vice versa. An error occurs if this check fails.

But the implicit subtype conversion does not prevent the assignment in the example above. The relevant part of clause 9.3.6 are:

In certain cases, an implicit subtype conversion is performed. A subtype conversion involves a type conversion in which the target subtype is the subtype to which the operand is converted and the target type is the base type of the target subtype.

In a type conversion where the target type is an array type, the following rules apply:

  1. If the target subtype is an array type or subtype for which the index ranges are not defined, then, for each index position, the index range of the result is determined as follows:
    • [...]
    • If the index type of the operand and the index type of the target type are closely related, then the bounds of the index range of the result are obtained by converting the bounds of the index range of the operand to the index type of the target type, and the direction of the index range of the result is the direction of the index type of the operand.

In the case of conversions between array types, if the target subtype is an array type for which the index ranges are not defined, then, for each index position, a check is made that the bounds of the result belong to the corresponding index subtype of the target type.

There is no reference to clause 5.3.2.2 here. Thus, the range 0 to 4 of the literal in the above example is just checked against the index subtype which is natural. The check succeeds and the variable will now have the value "10101". But, if the variable is passed to a subprogram with a formal of type bit_vector, then the index range is still determined by clause 5.3.2.2 resulting in the index range 0 to 3. This is a conflict.

TODO Signals.

Comments

Jim,

I also do not like "the initial set of constraints". To check whether the initial value belongs to the subtype from the declaration, I recommend to clearly differentiate between this subtype and the final subtype of the object.

For case a) I prefer the following updates, changed text in bold (for final wording see below):

a) If the object declaration includes an initialization expression:

  • The subtype indication is first elaborated; this establishes the initial subtype.

  • The initial value of the object is obtained by evaluating the expression. It is an error if the value does not belong to the initial subtype; this check identifies corresponding index ranges.

  • The subtype of the object is obtained by imposing index constraints on the initial subtype as follows: for each index range of the initial subtype that is not determined, the corresponding index range of the initial value is used.

  • DELETED

  • If the object is a composite object, then an implicit subtype conversion is first performed on the value of the initialization expression.

  • DELETED

The wording for the 3rd bullet has been taken from page 45, last item.

Your 6th bullet is not needed any more, because the type check, i.e. belong to, has been moved to the 2nd bullet.

All index ranges of the initial value are defined, and the type check in the 2nd bullet does identify all corresponding index ranges, if the check succeeds. Thus your 4th bullet is not needed any more.

The final wording is: (raw text includes all formatting needed for copy and paste)

a) If the object declaration includes an initialization expression:

  • The subtype indication is first elaborated; this establishes the initial subtype.

  • The initial value of the object is obtained by evaluating the expression. It is an error if the value does not belong to the initial subtype; this check identifies corresponding index ranges.

  • The subtype of the object is obtained by imposing index constraints on the initial subtype as follows: for each index range of the initial subtype that is not determined, the corresponding index range of the initial value is used.

  • If the object is a composite object, then an implicit subtype conversion is first performed on the value of the initialization expression.

-- Martin Zabel - 2017-02-24

Topic revision: r7 - 2020-02-17 - 15:34:41 - JimLewis
 
Copyright © 2008-2021 by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding TWiki? Send feedback