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

Proposal

LCS Number: LCS-2016-019 History
Version: 8
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

Voting Results: Cast your votes here

Yes:

  1. Ryan Hinton - 2016-12-12 - ver 2
  2. Patrick Lehmann - 2016-12-31 - ver 2
  3. Jim Lewis- 2017-02-24 - ver 8
  4. Kevin Jennings-2017-2-15 - Ver 3
  5. Rob Gaddi - 2017-03-02 - ver 8

No:

Abstain:

  1. Brent Hayhoe - 2017-02-16 Version 3 - Abstain due to lack of personal time for review.
  2. Thomas Preusser - 2017-02-28 - ver 8 - please consider restricting this LCS to signals only, i.e. without implicit variable constraining - see comment

Style Notes

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

Reviewing Notes

Version 6, 7, 8 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.

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

Is this linked to the correct source doc? It doesn't seem to relate to InitObjectSizing? Or am I missing something?

-- Martin Thompson - 2016-11-28

Well spotted Martin. The table had gotten HTML'asized, which may have had something to do with it.

It should be correct now.

-- Brent Hayhoe - 2016-11-28

I think the name and description of the LCS match up now, but the proposed change appears to be unrelated to the original requirement. I suggest the following change spec.

LRM 5.3.2.2 Index constraints and discrete ranges Page 47, bullet (a)

a) For a constant, variable or signal declared by an object declaration, if the subtype of the constant defines the index range, the index range of the constant is that defined by the subtype; otherwise, the index range of the constant is the corresponding index range of the initial value.

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

-- Ryan Hinton - 2016-12-12

I created version 2 with text similar to that above. Since the desired effect is to make signal and variable declarations act more like constant declarations, I deleted the signal/variable clause and reworked the constant clause to include signals and variables. Also, since signals and variables may not have an initial value, I added a qualifier to handle this case.

-- Ryan Hinton - 2016-12-14

And what if neither the subtype of the object declaration defines the index range, nor an initial value is given?

I think a sentence like the following one should be added to end of the new bullet a):

"It is an error if neither the subtype of the object declaration defines the index range, nor an initial value is given."

-- Martin Zabel - 2017-01-23

I agree with Martin's comment that the definition is incomplete as it doesn't state what happens if the index range is neither defined by the subtype nor the initial value expression. In addition, 14.4.2.5.b) also needs to be changed to correspond to the change proposed here.

-- Ernst Christen - 2017-01-23

Wouldn't the range of the initial value be either:

- An object, in which case the index range is defined

- A literal, in which case the index range is defined by section 9.3.2

- An expression, in which case the index range is defined by the function/expression

In each case, the index range of the initial value would then be defined which implies that the situation of having an initial value expression without an index range cannot occur. Am I missing something?

-- Kevin Jennings - 2017-02-16

@Kevin: The LRM is tricky. See the updated reviewing notes on why the LCS is incomplete at least for variables.

-- Martin Zabel - 2017-02-17

One thing that may be missing, where does it say if the types are incompatible with each other, it is an error: IE; one is 4 bits and the other 5 bits or one is unsigned and the other signed (due to calling a function).

Hence, I am not sure why you think the index range v or s is unconstrained. If you do not think that your edit makes the index range specified for the subtype, change it until it does. However, I think you have done good already.

-- Jim Lewis - 2017-02-19

Update to version 4. Reworked 14.4.2.5 to fully constrain the subtype to avoid the issues Martin found.

-- Ryan Hinton - 2017-02-21

Update to version 5. Reworked text according to JimLewis's suggested improvements.

-- Ryan Hinton - 2017-02-22

Where is item d)?

-- Patrick Lehmann - 2017-02-23

Updated to version 6. Refining 14.4.2.5 elaboration of object declarations

-- Jim Lewis - 2017-02-23

After re-reading clause 5.3.2.2 of the current LRM, I now think that one can determine the index range of a value which has been calculated from an expression, because clause 5.3.2.2, item b) states:

otherwise, the index range of the constant is the corresponding index range of the initial value.

This applies to the value if it is of an array type and also to each array subelement of a composite value.

How about this wording for clause 14.4.2.5 item c) in LCS 019, blue text is my change:

if the subtype of the object is either an unconstrained or partially constrained type, then any unconstrained index ranges of the subtype of the object is imposed from the corresponding index range of the initial value.

The problem here is, to do this, the initial value must already belong to the (initial) subtype from item a), otherwise you can't determine the corresponding index range. But this check is currently delayed until item d).

Still thinking about it.

-- Martin Zabel - 2017-02-23

Before any corresponding index ranges can be determined, one must check wether the initial value belongs to the subtype from the declaration. And this check identifies corresponding index ranges.

It is not easy to implement it here. But, I have posted a possible solution for LCS 019a in the comments there.

-- Martin Zabel - 2017-02-24

I have growing doubts about this implicit constraining at least with respect to variables. While signals can be pictured as physical nodes, variables are much more dynamic entities on a more abstract level. They can easily unfold into an arbitrary number of nodes. Considering this more flexible nature of variables, it might be wiser to leave the door open for allowing unconstrained variables to be exactly this - names of an unconstrained supertype that may dynamically identify any value of a fully constrained subtype. This would, for example, allow a variable of the unconstrained type string to hold string values of arbitrary length. This LCS might make it very difficult or impossible to adopt such a notion in the future due to compatibility issues.

-- Thomas Preusser - 2017-02-27

Topic revision: r1 - 2017-07-22 - 16:27:07 - JimLewis
 
Copyright © 2008-2024 by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding TWiki? Send feedback