Language Change Specification for Scalar Attributes and Function Reference Proposal

(spinoff from FunctionKnowsVectorSize)

LCS Number: LCS-2016-072a
Version: 12
Date: 30-Dec-2016 (Ver 1), 31-Dec-2016 (Ver 2), 2017-Jan-2 (Ver 3), 2017-Jan-4 (Ver 4), 2017-Jan-10 (Ver 5), 2017-Jan-12 (Ver 6), 2017-Feb-8 (Ver 7), 2017-Feb-14 (Ver 8), 2017-Feb-22 (Ver 10), 2017-Mar-12 (Ver 11), 2017-Mar-20 (Ver 12)
Status:
Author: Kevin Jennings
Email: KevinJennings
Source Doc: FunctionKnowsVectorSize, also related to NewPredefinedAttributeActual and ExpressionsInBitStringLiterals
Summary:

Add predefined attributes for scalars and allow functions to have access to these attributes.

This LCS is dependent upon LCS-2016-018

Voting Results: Cast your votes here

Yes:

  1. Kevin Jennings - 2016-11-07 - Ver 12
  2. Morten Zilmer - 2016-12-11 - Vote from before splitting 72 and 72a
  3. Martin Thompson - 2017-03-14 - Ver 11
No:
  1. Ryan Hinton - 2016-12-21 - version 1, reasons in comment with this same date
  2. Ernst Christen - 2016-12-15 - version 6, the reasons I outlined below for V5 have not been addressed.
  3. Jim Lewis - 2017-03-12 - version 11 - See Notes.
  4. Rob Gaddi - 2017-01-26 - version 6
  5. Patrick Lehmann - 2017-01-12 - version 10, I prefer LCS 018 + LCS 060
  6. Lieven Lemiengre - 2017-03-23 - version 12

Abstain:

Details of Language Change

Refer to attachments. Twiki was not kind in regards to font colors and strikethrough. Word and PDF versions are attached.

--


Kevin Jennings - 2016-10-21

Use Model

In the notes above, Kevin stated "search for 'use case' on this page. Specifically in my post on Jan 11 and Jan 26."

Below are hopefully the relevant material from the referenced posts:

From 2017-01-11
A simple use case for an integer target would be for the function to use target'left and target'right to limit the range of the output of the function.

From 2017-01-26
As a simple example, if you were to have "function plus(L,R: integer) return integer;" where the function implements return(L+R) then one could add assertions to check that Target'low >= L'low + R'low and Target'high <= L'high + R'high.

In today's world you would have to perform actual simulation doing whatever needs to be done in order to make sure that the 'corner cases' still work or perform exhaustive testing of each input combination. Obviously that is not a workable solution. However, with the ability to check input/output range validity, the assertion would fire either at t=0 in the simulation or no later then whenever that function is first called. In either case, you know upfront without exhaustive testing or corner case generation that the function will do what it is supposed to.


Martin Thompson 2017-03-15: In addition to the valuable "checking functionality" which Kevin raises, I have just been through my utilities package, and found the following:

I have modulo_increment and _decrement functions:

function modulo_increment (
input : integer;
maximum : integer)
return integer;

Where I am using these I always pass in the 'high from the integer type of the input - it would be useful (and less error-prone!) to have the modulus taken directly from the 'high attribute of the actual input.

Note that LCS 72 allows a return identifier that will also allow the removal of the maximum parameter.


Further thoughts

procedure modulo_increment (
    signal A : inout integer'parent_class
) ;

With anonymous types proposal LCS 16 + LCS 59 one can already do:

procedure modulo_increment (
     signal A : inout type is range <>
) ;

Weakness of anonymous types is that it is not as good with values/expressions being part of the parameter map.

Comments

The added section 16.2.3.2 Predefined attributes of scalars appears to be off-topic. Anyhow, it is still not fully adjusted: (a) Delete index with the remaining references to index range, and (b) Remove the indirections through functions when accessing attributes that originally applied to the individual array dimensions. So, A'LENGTH is of type universal_integer rather than being a function that yields a universal_integer.

--


Thomas Preusser - 2016-11-21

The added section 16.2.3.2 Predefined attributes of scalars is not really off topic, just hidden a bit. In the last paragraph of the 'Requirements' section of the proposal, I did float out the proposal to allow for scalar attributes and where they would be useful. When I wrote the LCS, I included that change since it is part of the proposal, it's been out on the Twiki for over two years, nobody objected and the proposal was 'approved' during the meetings to go ahead with writing up an LCS. Adding scalar attributes also eliminates the need for two other proposals: 'New Predefined Attributes: actual, and formal' and 'Expressions in Bit String Literals' as I mentioned on the 'Collected Requirements' page. I agree that it could've been written as a separate proposal and LCS. If there is significant disagreement about the two main ideas here they could be separated but in reality it would likely mean that one of the ideas just doesn't get implemented so the offending portion would just get deleted from the LCS.

In regards to your comment about using 'range' rather than 'index range', I agree and have changed that.

--


Kevin Jennings - 2016-11-21

  • Reply to @Ryan #5: LRM 6.3 states, "A subtype indication defines a subtype of the base type of the type mark." (Emphasis mine.) If you take a look at the signal declaration rule, signal x: integer range 5 to 10;, the integer range 5 to 10 is a subtype indication, and defines a subtype of integer. When the tool evaluates x'subtype'left, it will give 5, not integer'left. (I confirmed this in a tool that typically implements the standard correctly.)

    KJ reply: But this is not the case within a subprogram. In a subprogram, x'subtype'left returns the 'left attribute of the formal type integer (-2147483648), not the 'left attribute of the constrained actual (5). Below is sample code and output, using tool M, do you want to check it your tool?

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity foo is
end foo;
architecture RTL of foo is
    signal a:   integer range 1 to 5;
    function foo_fn(x: integer) return integer is
    begin
        report "x'subtype'left=" & integer'image(x'subtype'left) & " x'subtype'right=" & integer'image(x'subtype'right);
        return(x);
    end function foo_fn;
begin
    process
        variable b: integer range 2 to 6;
    begin
        wait for 1 ns;
        report "a'subtype'left=" & integer'image(a'subtype'left) & " a'subtype'right=" & integer'image(a'subtype'right);
        report "b'subtype'left=" & integer'image(b'subtype'left) & " b'subtype'right=" & integer'image(b'subtype'right);
        b := foo_fn(b);
        wait;
    end process;
end RTL;
...
# Loading work.foo(rtl)
# ** Note: a'subtype'left=1 a'subtype'right=5
# ** Note: b'subtype'left=2 b'subtype'right=6
# ** Note: x'subtype'left=-2147483648 x'subtype'right=2147483647

--


Kevin Jennings - 2016-12-19

That's a great example of comments @Ryan #4 and @Ryan #5. (@Ryan #5:) You show that objects a and b can get their ranges (aka attributes, constraints, subtype information) directly from the scalar objects instead of from a scalar type. This means that your proposed section 16.2.3.2 is unnecessary. Also, you show (@Ryan #4) that object b is copied by value into function foo parameter x. x is an object of subtype integer. So evaluating its attributes give the range for the integer type. This is why I suggest that your next draft should include changes to 4.2.2.2 where the pass-by-value semantics are given. This will help achieve the effect you were trying to get by modifying the text of the note preceding 4.2.2.2.

--


Ryan Hinton - 2016-12-19

I don't see how you can conclude "This means that your proposed section 16.2.3.2 is unnecessary". The example shows that, within the function, there is currently no way to get at the actual bounds of a parameter (which is what I'm after), so some change is required to implement the proposal. While x'subtype'left returns the bounds of x within the context where x is declared, it does not work inside a subprogram that is called with the parameter set to x. If it did, then the last report statement would have printed "x'subtype'left=2 x'subtype'right=6" rather than printing the bounds of an integer.

The change I proposed is to allow scalar attributes to be accessible and one can access those attributes in the same manner regardless of context and does not break backwards compatibility (i.e. x'subtype'left would still return the bounds of the subtype of the formal when used within a function as it does today). Scalars already have these attributes so that bounds checking can be performed, they are just not called as such in the LRM at present.

--


Kevin Jennings - 2016-12-20

My point is that x inside the function is its own object. Calling x'subtype'left will give exactly the same thing as your proposed x'left. A scalar does not have attributes. It has a value and a subtype. Defining an attribute 'LEFT on a scalar will have to get its "return value" from the subtype of that scalar.

Defining attributes on scalars will not get you the attributes of the formal since constant and variable parameters are passed by value in many cases. You're working on the right problem, but the solution you propose is unrelated.

--


Ryan Hinton - 2016-12-20

RH: Calling x'subtype'left will give exactly the same thing as your proposed x'left. KJ: Not once this LCS gets written up correctly it won't.

RH:: A scalar does not have attributes KJ: But they could have attributes, that's what I'm trying to get added. Putting aside constants and expressions for the moment, a parameter input to a function will have a declaration associated with it. That declaration will define the attributes that are available to be used. The changes I've made to 4.2.2.2 and 4.2.2.3 now address what to do with constants, expressions as well as variables and signals.

RH: Defining attributes on scalars will not get you the attributes of the formal since constant and variable parameters are passed by value in many cases KJ: Did you mean to say formal in the above? If so, then getting the attributes of the formal would be the same as today (i.e. x'subtype'left for example), no change intended. If you meant actual instead of formal, then it's not clear to me how my solution is unrelated. Incomplete or incorrect, OK, but not seeing it as unrelated.

In any case, I've made several edits to address the concerns from you, Ernst and Tristan, summarized along with how I addressed the points in my updated comment above from 2016-12-16. Calling this Version 3. Please review and create new comments below. As you did previously, numbering the issues makes for a handy way to refer to them which in turn helps to get them all addressed.

--


Kevin Jennings - 2016-12-21

RHv3#1 Page 21. I hope one of the tool implementors will chime in here. KJ reply: I agree, Tristan has visited and commented, not sure who are other tool implementors that are in the audience. RH: As far as I know, attributes are never assigned. The attributes come from the subtype. For scalar formals, the subtype of the formal is given in its "declaration" in the interface list. It sounds like what you're asking for is to change the subtype from their declaration. It feels wrong to me to see an input x of subtype integer, but the tool changes its subtype for each call. I suppose it's not that different from what happens with unconstrained array formals. KJ reply: I'm not trying to change anything existing. I'm trying to get information that I know is currently available to the tool by virtue of the existing requirement on the tool to insure that function parameter actuals are within the range of the function parameter formals. I'm trying to use that information to perform something that is new and I think a useful function.

RHv3#2 general suggestion. I suggest you split off the scalar attributes and related changes into an independent LCS. The title of the proposal is "Method to allow functions to know the output vector size." I agree that this would be a great feature to have. I can remember only a handful of times where knowing the input subtype would be similarly useful. Really they are two different changes and deserve to be voted independently. For what it's worth, I like the 'actual and 'formal approach much better -- it seems a MUCH easier change to implement. (I would create one new attribute, 'subtype_actual to get access to the subtype of the actual similar to the current 'subtype which gives the subtype of the formal.) KJ reply: The ideas are a bit more linked than perhaps you've considered. When writing the proposal, and later the LCS, it immediately becomes apparent that one needs to have a mechanism to refer to the attributes of the target itself, not to the type/subtype of the target. What I used here as my mental model, is that the end user should think of the 'target' as being like another input that is available to the function, but an input where the only legal actions are to refer to attributes. The most straightforward way then to get at the length attribute (for example) then would be as "target'length" which would be the exact same form that one would use outside the function. Now, given this model that treats 'target' as being just another (but somewhat restricted) input parameter, it is a small leap to then say that if one were to want to refer to the attributes of the actual (not the subtype of the actual) that one would want to also use the same form "parameter'left". There are proposals such as NewPredefinedAttributeActual that do indicate demand for the same thing that I'm trying to get implemented here in this LCS with function parameters. I think it would be a mistake to require the end user to use different syntax to get at the attributes of the target (which is needed for this proposal/LCS) and the attributes of the parameters passed into a function which is also different than how one accesses the attributes of an object outside of the context of a function. If this LCS was split in two, then there would either have to be a dependency of this LCS on that new LCS (or some alternate proposal/LCS such as NewPredefinedAttributeActual) otherwise one risks coming up with different mechanisms for the end user to simply be able to access attributes of something. I don't think that's a good thing. I do all of this without introducing new keywords unlike NewPredefinedAttributeActual so that's a bonus as well. Because a new keyword is created, NewPredefinedAttributeActual is not going to be backwards compatible and could break existing code (although I admit it is probably not terribly likely).

RHv3#3 Page 21 editorial note. I suggest replacing the colon in the first new sentence with a comma and making the following "If" lower-case. This makes it correct grammatically and follows the pattern of the nearby paragraphs. KJ reply: Fixed.

RHv3#4 Page 21. I don't understand why you have distinct cases for "if the actual is an identifier" and "otherwise." In your big addition for page 20, you specify that only the "otherwise" attributes may be used. KJ reply: What I'm trying to get across is that when the parameter actual to a function is an identified object such as "signal FingerCount: natural range 1 to 10;" then the new attributes that get passed into the function are the attributes of FingerCount (i.e. left=1; right=10). I'm covering this situation with "the attributes of the parameter shall be assigned from the corresponding attributes of the actual". However, if the input to the function is an expression or a literal, then you don't immediately have those attributes. What I was covering with the "Otherwise..." is the case for when a literal is assigned to the parameter. In a sense, the tool is fabricating attributes for the literal in order to be able to pass them into the function, but I think what I specified is straightforward. I do see though that what I have does not cover the case where the function parameter comes from an expression. I'll have to ponder a bit on how to word that and add that into that same area of the LRM. If you have some preferred wording, feel free to suggest something.

RHv3#5 Page 244. You missed red markings on "scalar" in S'LEFT. Also, a scalar subtype doesn't have "ranges"; it has a "range" (singular, not plural). KJ reply: Instnaces of "ranges are" changed to "range is". Twiki keeps mangling and removing font coloring. I found a whole bunch of black font "scalar" that I know had been red. <RANT>I think we would have been far better off using PDF attachments for the LCS as I had originally done and not try to use a tool such as Twiki which destroys things randomly. The coloring is important and Twiki keeps messing it up for no apparent reason. I'm tired of having to recolor things that had been colored.</RANT>

RHv3#6 Page 244. The result type should be the base type of the scalar or scalar subtype. KJ reply: I'm not sure I follow or whether you're referring to all of the result types or just one. In any case, I think what I have is correct since it was based on existing LRM text and simply removing array referencing. Can you clarify a bit about what exactly is wrong? Is it actually 'wrong' or just not how you would word it?

RHv3#7 Section 16 changes. I still object to adding all this text because it doesn't provide anything not already available via S'SUBTYPE'attr. From my best guess of your intent, the subtype of the formal will be the subtype of the actual. So x'subtype'left will still be the same as x'left: both will refer to the subtype of the actual instead of the subtype of the formal (current behavior of the former). KJ reply: With the current LRM, x'subtype'left does not return what is needed, when used within a function. Please refer back to the sample code that I posted. Within the architecture and the process if one has signal xyz: integer range 1 to 5 then x'subtype'left = x'left = 1, but when xyz is passed into a function such as Func(x: integer) as Func(x=>xyz) then x'subtype'left returns the left bound of integer and there is no mechanism for the function to know that the left bound of the actual that is bound to x is actually 1. What I'm adding is that inside a function you will now be able to refer to xyz'left which is currently illegal so there will be no backwards compatiblity issues with doing so. Now it will be legal syntax in a function and will return the left bound of the actual that is assigned to parameter x which, in this case, is the left bound of xyz, which is 1. So this is providing something new and doing so in a way that makes currently illegal syntax legal and useful.

(#7 cont.) Perhaps you're intending x'subtype'left to continue to give the left bound of the subtype of the formal while x'left gives the left bound of the subtype of the actual. KJ reply: If you mean the '1' in signal xyz: integer range 1 to 10; and xyz is passed into a function then YES!" RH: I'll vote against that as against the "do it explicitly" spirit of VHDL. Nothing about x'left suggests to me that the tool is reaching outside the scope of the subprogram to grab attributes from the subtype of the actual. *KJ reply: x'left suggests to me the obvious which is that it is retrieving the left bound of x, not the left bound of the subtype of x. As you've already stated, you like the idea (but not the method) being presented here of being able to access the attributes of the actual and you have had very little use for accessing the attributes of the subtype which was added in 2008. That has been my experience as well. Based on the limited polling of two people, this suggests that what was added in 2008 is possibly of limited use to an end user. I think there is quite a bit of value for the end user in being able to use the exact same syntax (i.e. xyz'left) regardless of the context. It works the same whether you're in an architecture, a process or a subprogram. I can't sway you if your reason is 'against that as against the "do it explicitly" spirit of VHDL' but I will say that reason is not a technical one that can be resolved technically. That will take either gentle persuasion, arm twisting or pistols at 20 paces.

(#7 cont.) An object has a value and a subtype. "An object is a named entity that contains (has) a value of a type." (6.4.1) It does not have a range. (Point me to the LRM if I'm wrong.) KJ reply: But an object also has attributes hence xyz'left does return the left bound of an integer. RH: The text "Left bound of the range of S" is nonsense because a scalar object S has no range defined in the language. These changes reference concepts that don't exist. If you want x'left to return the left bound of the subtype of x (formal or actual), your changes are still incomplete. KJ reply: OK, so taking one sample, can you suggest wording that is correct?

Currently in LCS: "Result type: Type of the left bound of the Nth index range of SA"

Noting that section 5.2.1 Scalar Types - General does refer to 'range' which is the usage that I'm intending.

range_constraint ::= range range
range ::=
       range_attribute_name
     | simple_expression direction simple_expression

(#7 cont.) Arrays are fundamentally different in this respect. A scalar object of an appropriate integer subtype may contain the value 3. 3 doesn't have a range. On the other hand, an object of an appropriate bit_vector subtype may contain the value (4 to 7 => "1011"). An array value obviously has a length. In fact, the LRM gives array values an index range as well, as anyone who's used the fixed_pkg can attest. Scalar values in expressions are handled according to their base type (see the enhanced integer discussions). Array values keep their bounds in expressions. On assignment, an implicit subtype conversion occurs for arrays and a subtype check occurs for scalars (5.3.2.2, 10.6.2.1, 14.7.3.4, etc.). KJ reply: OK, but not seeing the relevance to this LCS so not seeing anything that is actionable here.

(#7 cont.) I don't see an easy way to change this difference between array and scalar values. That's why I would prefer a variant of the 'actual attribute proposal ( NewPredefinedAttributeActual). That's why I suggest splitting out the scalar attributes portion of this LCS that is supposed to be about vector sizes. KJ reply: OK, I prefer not to add keywords and possibly break backwards compatiblity and to provide the end user the same syntax to get at attributes regardless of context. Your preference is noted but is not a technical point that I can respond to so I think we will have to simply have to agree to disagree.

RHv3#8. You have specified in your page 20 changes when a function with a named return value should be called. This should be done instead by modifying the overloading rules and signature rules in 4.5. Possibly 12.5 may need to be changed also. KJ reply: To be blunt and honest, I don't know what the heck needs to change in order to get across the point that there can be instances where using this new form of function is not allowed. Not asking you in particular to do this, but I've taken two swings at it and missed both times so I think I need some help from somebody to define this limitation properly.

RHv3#9 Page 186. I would put the formal return identifier at position (d) in the list next to the formal parameter declaration. KJ reply: I put it at the end of the list so as not to break anything. There are LRM references to some of the labeled bullet items so I would prefer not to insert in the middle and shift the others down and then accidentally miss updating a reference. The list is not a priority order, there is a flow to it, but that flow is cosmetic.

KJ general: Thanks for all your input, it is helping. It appears to me that we are having fewer technical objections as the LCS gets revised which is good, progress is being made and hopefully get to a point of no technical disagreements. Can't help much with the non-technical other than to explain my reasoning and thought process.

--


Ryan Hinton - 2016-12-21

with KJ replies KevinJennings 2016-12-23

Version 1 of this LCS created by stripping it out of LCS-2016-072 and making it a new standalone LCS. Comments from LCS-2016-072 that were relevant to this new LCS have been copied over to this LCS.

--


Kevin Jennings - 2016-12-30

I see two separate issues here: 1) Make attributes in subprograms 2) Add/modify attributes in Annex C.

Can you please split these into two separate LCS. They are separate thoughts and need to be voted on separately.

Going further, item #1 above is an extension to your current LCS and is appropriate with the "a" extension.

Item #2 above fits very nicely in the "extended capability" of the proposal Attributes for Enumerated Types. Note, I just finished refactoring that proposal based on the comments - it was interesting that you wanted to do what I consider the extended capability. Hence, I recommend that these additions become part of LCS-2016-018 - all I would ask is that you add my 'POS_RANGE. I would also recommend that your changes that you enumerated above become part of section 16.2.2 rather than a new section as the title is already appropriate. Also many of your changes only need to modify the "prefix" text of 16.2.2. For example for T'LEFT, your proposed prefix subsumes the prefix of 16.2.2 and if you don't put them in the same section, then the one in 16.2.2. would need to be deleted anyway as it already addresses types and subtypes.

--


Jim Lewis - 2016-12-30

Version 2 created. No functional changes to the intent of the LCS. Minor changes to:

- Clarify the conditions which define when an actual has attributes or not (see Determinable index range conditions )

- Add editor note that the reference to Determinable index range conditions is contained in another LCS and what to do if that LCS is not approved.

- Deleted 'Annex C - Syntax Summary'. There are no changes by this LCS to Annex C, it was left in accidentally when version 1 of this LCS was created by separating it from LCS-2016-072 (which does have changes to Annex C).

--


Kevin Jennings - 2016-12-31

@Jim: While there are two separate ideas, I don't believe they should be separated because they are too closely linked. Approving one without the other would make no sense so they should remain at one votable LCS. Reasoning is:

- Gaining access to attributes of scalar actuals is totally dependent on there being such attributes in the first place (so #1 depends on #2)

- The only use case that I see for scalar attributes is to allow them to then be used within a subprogram. Outside of that context, one can already get the attributes that you need (so the only use for #2 is within #1).

As for section 16.2.2, while the title of the section is "Predefined attributes of types and objects", the only 'object' attribute listed is 'subtype', the rest of the attributes are for types. It makes more sense to me to leave 16.2.2 devoted (almost) exclusively to attributes of types rather than to add in all of my changes to attributes of scalars which would muddle the primary point of the current 16.2.2. I chose to subsection the existing 16.2.3 Predefined attributes of arrays rather than add my section in as a new 16.2.4 and renumber the current 16.2.4 to be 16.2.5 in order to not potentially break current references in the LRM (but searching for 16.2.4 actually didn't match anything, so maybe it is OK). Creating the hierarchy in the new section 16.2.3 is not necessarily a bad thing, but I'm not strongly opposed to renumbering my new section as 16.2.4 and bumping the current .4 to .5 but I don't see that as any sort of 'improvement'.

I'm also not in favor of putting 'POS_RANGE into this LCS since that attribute would work with types, not scalars so the 'POS_RANGE change belongs in 16.2.2.

My changes do not impact or subsume what is currently defined in 16.2.2. That section works with prefixes that are types or subtypes. That is still useful. Adding scalars there just muddies that whole section rather than having it focus exclusively on attributes of types (except as mentioned for 'subtype which operates on an object).

--


Kevin Jennings - 2016-12-31

First, it still looks like there are two proposals here. One on importing certain attributes into a subprogram. The other on adding attributes for scalars. They need to be two separate proposals.

My negative vote is based on your definition of 'LEFT, 'RIGHT, ...

You state that you want these to operate on scalars. What do you mean by scalars? My definition is an object which has a scalar type. This includes an object that has an enumerated type.

In your prefix of 'LEFT there is text that says, "or that denotes a scalar subtype". This makes your definition of 'LEFT overlap with the definition of 'LEFT in 16.2.2.

In your prefix, what do you mean by "whose range is defined by a constraint?" Are you trying to talk about scalars that are integers?

If I write,

   subtype int10 is integer range 1 to 10 ;
   signal A : int10 ;
   signal B : integer range 1 to 10;

using the attributes from 16.2.2, int10'LEFT has the value 1. Does your new attribute make: A'LEFT = B'LEFT = 1?

If I write,

  type StateType is (S0, S1, S2) ;
   signal State : StateType ;

Using 16.2.2, StateType 'LEFT = S0. Since State is a scalar it would be nice if State'LEFT = S0. If your proposal prohibits this, then my vote will remain no.

Next section,

  • 16.2.3 defines attributes for arrays. This includes array types and objects.
  • 16.2.2 defines attributes for types and objects. This section is a mix of types, scalar types, and objects.

Since 16.2.2 already defines these attributes for scalar types, then the edits to add objects of a scalar type should be there too. This would make 16.2.2 much more similar to 16.2.3.

I suggest that the attributes of 16.2.2 be extended to read as follows: T'LEFT Kind: Value. Prefix: Any prefix T that is appropriate for a scalar object, or an alias thereof, or that denotes a scalar subtype . Result type: Subtype of T. Result: The left bound of the subtype of T.

Note that the prefix for 'range on a scalar subtype needs to exclude real numbers since they do not have a range.

--


Jim Lewis - 2017-01-02

Version 3 created. Changes are: - Add text to section 6.4.1 Objects - General to state that scalar objects have attributes. - Restrict usage of 'Range to not include floating point types

--


Kevin Jennings - 2017-01-02

JL: First, it still looks like there are two proposals here. One on importing certain attributes into a subprogram. The other on adding attributes for scalars. KJ reply: Already responded to in my Dec 31 comment The comment started @Jim

JL: They need to be two separate proposals. . KJ reply: The reason for maintaining one LCS is explained in my Dec 31 comment. Please state your source for this new, non-technical, procedural requirement. In addition explain your reason for applying this requirement given my previously posted explanation for why the two are linked and do not stand on their own.

JL: My negative vote is based on your definition of 'LEFT, 'RIGHT, ...KJ reply: Rather non-specific here, is this just a lead-in to something?

JL: You state that you want these to operate on scalars. . KJ reply: Not in the LCS I don t talk about operate so your comment is somewhat off topic, but likely you are just not very specific about what it is you are referring to.

JL: What do you mean by scalars? My definition is an object which has a scalar type. This includes an object that has an enumerated type. KJ reply: I don t have my own definition as you have; I m using that defined in the LRM. As a non-technical aside, I think we may be operating with the same definition.

JL: In your prefix of 'LEFT there is text that says, "or that denotes a scalar subtype". This makes your definition of 'LEFT overlap with the definition of 'LEFT in 16.2.2. KJ reply: You ve sliced out a portion of the statement and taken it out of context. The full text, without markup is:

          Any prefix S that is appropriate for a scalar object, or an alias thereof, or that denotes a scalar subtype whose range is defined by a constraint.

The text in the LCS is the scalar version of current text in the LRM for the LEFT attribute of arrays as defined in section 16.2.3. The full text for that array attribute is:

          Any prefix A that is appropriate for an array object, or an alias thereof, or that denotes an array subtype whose index ranges are defined by a constraint.

By your reasoning, this current LRM definition of array attributes also overlaps with the definition of LEFT in 16.2.2 because it contains the phrase or that denotes an array subtype . With this LCS, I ve expanded upon scalars in the same manner as has been previously done with arrays in order to be consistent with the current LRM structuring. What you re suggesting then is that 16.2.3 is already a problem in your mind. If so, then there should be a separate LCS to cover your proposed restructuring. My 2 cents is that the current structuring is fine as it is and trying to combine attributes of types, arrays and scalars into a single section would be a mistake again as I have already mentioned in my Dec 31 @Jim comment (seems like you didn t even read that comment even though it was directed to you).

JL: In your prefix, what do you mean by "whose range is defined by a constraint?" Are you trying to talk about scalars that are integers? KJ reply: The LCS editorial comment states, This content of this new section is based solely on the text from 16.2.3.1, but removing all references to arrays so my meaning is simply the new scalar version of whatever may be meant by the array version text.

JL: If I write,

subtype int10 is integer range 1 to 10 ;

signal A : int10 ;

signal B : integer range 1 to 10;

using the attributes from 16.2.2, int10'LEFT has the value 1. Does your new attribute make: A'LEFT = B'LEFT = 1? KJ reply: Yes, as has already been discussed in the comments, most recently in my Dec 23 reply to Ryan on point RHv3#7 (#7 cont)

JL: If I write,

type StateType is (S0, S1, S2) ;

signal State : StateType ;

Using 16.2.2, StateType 'LEFT = S0. Since State is a scalar it would be nice if State'LEFT = S0. If your proposal prohibits this, then my vote will remain no. KJ reply: The proposal and the LCS have always been defined such that State Left in your example would return S0 so there is no basis here for your No vote unless you haven t understood that until this time. Since this is the only specific technical reason you've mentioned for voting 'No', and I've shown that reason to have no factual basis, I look forward to your 'Yes' vote.

JL: Next section,

  • 16.2.3 defines attributes for arrays. This includes array types and objects.
  • 16.2.2 defines attributes for types and objects. This section is a mix of types, scalar types, and objects. KJ reply: We disagree and you are being very misleading here for some reason. 16.2.2 is not a mix of types, scalar types, and objects . With the single exception of the SUBTYPE attribute, 16.2.2 is exclusively about attributes of types and nothing else. Section 16.2.2 defines 15 attributes, 14 are exclusive to types. By that measure, section 16.2.2 is 93% about types and only 7% about objects. You are correct that the section covers scalar types, but you re misleading in that the section also encompasses enumeration types, composite types, access types, file types, protected types, floating-point types and, in particular, array types. Array type attributes have their own separate section, 16.2.3 so why aren t you railing against that section?

JL: Since 16.2.2 already defines these attributes for scalar types, then the edits to add objects of a scalar type should be there too. This would make 16.2.2 much more similar to 16.2.3. KJ reply: But since you are not also proposing that 16.2.3 be merged into 16.2.2, following your suggestion would muddle the 93% focused 16.2.2 and actually would turn it into a mix of types, scalar types, and objects (and array types if you now do think that 16.2.3 should be rolled into 16.2.2). Respectfully decline this non-technical suggestion.

JL: I suggest that the attributes of 16.2.2 be extended to read as follows: T'LEFT Kind: Value. Prefix: Any prefix T that is appropriate for a scalar object, or an alias thereof, or that denotes a scalar subtype . Result type: Subtype of T. Result: The left bound of the subtype of T. KJ reply: Your suggestion, if applied to 16.2.2 then would preclude it s current prefix of Any scalar type or subtype T. which would break backwards compatibility. Respectfully decline this suggestion.

JL: Note that the prefix for 'range on a scalar subtype needs to exclude real numbers since they do not have a range. KJ reply: Fixed in version 3, good catch.

--


Kevin Jennings - 2017-01-02

RHv3a#-1: Consider ripping out all of the "Details of language change" text from this page, and simply reference the attached document. Maybe make the document reference in a large font. smile

RHv3a#0: Consider the following assuming this proposal is implemented.

  signal bob  : integer range 0 to 7
  function fun(inp : integer range 7 downto 0) return integer is
  begin
    -- when called "fun(bob)", should inp'left be 7 or 0?
  end;

Repeating the question in the function body comment, when fun(bob) is called, should inp'left be 0 or 7? Should inp'subtype'left be 0 or 7? When fun(2*bob) is called, what should inp'left be?

RHv3a#1: Regarding changes to 4.2.2.2, section 9.3.3.3 applies only to arrays. So it doesn't apply to scalar attributes.

RHv3a#2: Regarding changes to 4.2.2.3, I don't think you want to reference the formal for attributes like 'simple_name, 'instance_name, or 'path_name.

RHv3a#3: Regarding changes to page 66, are you trying to say that an object has (a value (if any?) of a type) and (attributes, if any, of a type), or are you trying to say that an object has (attributes, if any) and (a value of a type)? I suggest rewording to be clear.

RHv3a#4: Regarding changes to page 67, objects do have attributes like 'subtype, 'path_name, etc.

RHv3a#5: Jim brought up the point that language like "defined by a constraint" doesn't belong in a scalar attribute prefix description. I know you copied this pretty closely from the array section. Copy it less closely. Something like the following.

S'LEFT \ Kind: Value
  Prefix: Any prefix S that is appropriate for a scalar object, or an alias thereof. (If you're going to include "subtype" here, then I agree with Jim that it should be merged.)
  Result type: The base type of S.
  Result: Left bound of the subtype of S. (... (alias case clarification) )
--


Ryan Hinton - 2017-01-02

@Ryan

RHv3a#-1: Consider ripping out all of the "Details of language change" text from this page, and simply reference the attached document. Maybe make the document reference in a large font. KJ reply: I didn’t want to ruffle too many feathers by doing just that right off the bat when I first switched to using attachments and as long as nobody objects to not having the LCS text directly in the Twiki page, I’ll do it.

RHv3a#0: Consider the following assuming this proposal is implemented.

  signal bob  : integer range 0 to 7
  function fun(inp : integer range 7 downto 0) return integer is
  begin
    -- when called "fun(bob)", should inp'left be 7 or 0?
  end;

Repeating the question in the function body comment, when fun(bob) is called, should inp'left be 0 or 7? Should inp'subtype'left be 0 or 7? KJ reply: inp’left=bob’left=0 (this is the new stuff); bob'subtype'left=0, inp’subtype’left=7 (this is meant to remain unchanged).

RH: When fun(2*bob) is called, what should inp'left be? KJ reply: For fun(2*bob), since the parameter is bound to an expression, I believe that the expression will not meet any of the conditions listed in “Determinable index range conditions listed in section 9.3.3.3” (but also see my reply to RHv3a#1). In that situation, according to what I defined as the change to 4.2.2.2 'Page 21, near middle' inp’left=inp’right=inp’high=inp’low=2*bob. So that would mean that every time that bob changes value and fun(2*bob) is evaluated the attributes would change along with the value of the expression 2*bob. I don’t think that there is much value in using it this way, but I’m not sure there is anything inherently ‘bad’. However, it could be that having ‘bounds attributes' be dynamic like this becomes an implementation issue. If it is, I don’t have any problem with making this an error instead. Not allowing ‘bounds attributes’ like ‘left to be dynamic might fit in better anyway.

RHv3a#1: Regarding changes to 4.2.2.2, section 9.3.3.3 applies only to arrays. So it doesn't apply to scalar attributes. KJ reply: The section does not apply but I was thinking the list of conditions did so I could reference rather than copy/paste/edit. However, it looks like I need to copy/paste that list and change the phrase “fully constrained array subtype” to “fully constrained subtype” throughout. Do you agree?

RHv3a#2: Regarding changes to 4.2.2.3, I don't think you want to reference the formal for attributes like 'simple_name, 'instance_name, or 'path_name. KJ reply: Not sure I understand what you’re getting at. Those attributes are not listed as attributes of scalars and the only mention of formal in section 4.2.2.3 is in text that has not been changed.

RHv3a#3: Regarding changes to page 66, are you trying to say that an object has (a value (if any?) of a type) and (attributes, if any, of a type), or are you trying to say that an object has (attributes, if any) and (a value of a type)? I suggest rewording to be clear. KJ reply: Actually I’m thinking of deleting that entire recent addition of 6.4.1 changes on pages 66 and 67. I was trying to make clear that scalar objects now would have attributes. I’d like to put that reference in the same place that the LRM defines that array objects have attributes but I didn’t actually find that spot. Maybe a better change would be in section 16.2.1 where it says “Predefined attributes denote values, functions, types, subtypes, signals, and ranges associated…” but even there, the current LRM doesn’t seem to define that a variable that is an array has any attributes (signals yes, but where are variables?). 16.2.3 describes the attributes of arrays, but where does it say that an array has attributes in the first place?

RHv3a#4: Regarding changes to page 67, objects do have attributes like 'subtype, 'path_name, etc. KJ reply: Another good reason for removing this recent addition completely as I just mentioned.

RHv3a#5: Jim brought up the point that language like "defined by a constraint" doesn't belong in a scalar attribute prefix description. I know you copied this pretty closely from the array section. Copy it less closely. KJ reply: Jim only asked a question “What do I mean by…”, If he was thinking what you’re saying here, he certainly didn’t put his thought into words. His big push seems to be that my new section was stomping on current 16.2.2 definitions and my stuff should be merged into 16.2.2 (which he and I do not agree). I do like your suggestion to terminate after “or an alias thereof”. Will ponder some more on that but likely get your suggestion into the next version.

--


Kevin Jennings - 2017-01-03

This is not as simple as revising a couple of words from the array based attributes. In the definition you provide for scalar attributes, your prefix, result type, and result need some work. My previous post identified the issue. It is up to you to do the research and understand or not. Hence, my vote is still no.

--


Jim Lewis - 2017-01-03

@Jim

--


Kevin Jennings - 2017-01-03

Version 4 created. Changes are:

- Corrected definition of determinable index range conditions

- Deleted changes to section 6.4.1. Not needed, what was intended to be added is already covered in 6.7.

- Clarified the definition of the prefix and the result for each of the scalar attributes.

--


Kevin Jennings - 2017-01-05

I'm looking forward to resolve the differences between LCS 018 series and this LCS.

There are several issues in your proposed changes (version 3):

  • Why is ASCENDING a constant value of TRUE?
  • You are adding in section 6.4.1: “Objects of other types do not have attributes.”


All objects have a SUBTYPE attribute, this removes that attribute.



Counter example: Objects of type class record, access and protected are objects, not scalar and not array.

  • Section 16.2.3.2 replicates a lot of text. I think we agreed in one of the meetings that we don’t want to replicate texts over and over again.


LCS 018b accomplishes the same much shorter and comprehensive. It’s also more forward-looking from my point of view.

  • The attribute LENGTH misses the proper handling of null ranges. My LCS 018 return length 0 for all null ranges, so null ranges can be


compared based on their length, while the bounds are not modified. This is essential for range based arithmetic.

  • A scalar types cannot have an ELEMENT attribute, because they have no elements.

--


Patrick Lehmann - 2017-01-05

PL: Why is ASCENDING a constant value of TRUE?

KJ: Because I think it should be set to something. This assignment is intended only to come up if the parameter is a literal or expression where there is no explicit declaration available. Please see my last post to Ryan the item that starts "RH: When fun(2*bob) is called..."

PL: You are adding in section 6.4.1

KJ: I removed changes to 6.4.1 in version 4 (which just came out last night), I think you are reviewing version 3.

PL: Section 16.2.3.2 replicates a lot of text

KJ: The down side to combining is that the combined text will have exceptions (like this applies to scalars, but not arrays... this applies to types and arrays but not scalars...). The current LRM separates types and arrays, I continued that to add a section for scalars. For someone using the LRM I think that organization makes it easier to understand rather than the 'all in one with exceptions sprinkled about' approach. At the end of the day, while we want the LRM to be accurate, we don't want it to be a pain in the backside either. Making it easier for us as the producer of the LRM at the expense of all of the users of the LRM is not the choice I would recommend. My two cents.

PL: The attribute LENGTH misses the proper handling of null ranges

KJ:The LCS states "... if the Nth index range of S is a null range, then the result is 0."Do you have something else in mind?

PL: A scalar types cannot have an ELEMENT attribute

KJ: Thanks, wasn't quite sure about that one either. Will fix for the next version

Thanks for your input.

--


Kevin Jennings - 2017-01-05

KJ: Because I think it should be set to something. This assignment is intended only to come up if the parameter is a literal or expression where there is no explicit declaration available. Please see my last post to Ryan the item that starts "RH: When fun(2*bob) is called..."

PL: The direction is based on the index range's direction. So for example a STRING is defined with an integer range in TO direction, so it is ascending. That's also true for std_logic_vector. Every string literal defaults to that direction. So variable foo : std_logic_vector : "01001010";= is in TO direction, because std_logic_vector's index range is an INTEGER and INTEGER is defined a TO. If you would define a REVERSE_INTEGER and define a new REV_STD_LOGIC_VECTOR, then the shown variable would be in DOWNTO direction.

KJ: The LCS states "... if the Nth index range of S is a null range, then the result is 0." Do you have something else in mind?

PL: Sorry, I missed the zero in the text.

KJ: <long text>

PL: My LCS-2016-018 (without a letter) also does some cleanup and separates types from objects. Which I think don't belong under the same headline. I'm a bit against these long prefix rules like Jim proposes, which mixes up objects and types in the same attribute description table.

In general:

  • Your proposed changes create completely new attributes.
  • Jim's proposed changes create new attributes, but refers to existing attributes as a shorthand.
  • My proposed change describes two rules how object attributes are "derived" from type attributes.

--


Patrick Lehmann - 2017-01-05

The note that you edit on page 21 just before section 4.2.2.2 (end of 4.2.2.1), currently says:

NOTE—Attributes of an actual are never passed into a subprogram. References to an attribute of a formal parameter are legal only if that formal has such an attribute. Such references retrieve the value of the attribute associated with the formal.

I note your LCS changed the last word from formal to actual without actually noting the change. I also think this is something you cannot change and instead need to introduce a method, such as 'actual, to designate you want to access attributes of the actual.

--


Jim Lewis - 2017-01-08

Version 5 created, changes are:

- Red font added to word 'actual' in the 4.2.2.2 note

- Added reviewer's note at start of changes to 4.2.2.2, page 21, near middle

- Added reviewer's note query regarding how to set the ASCENDING attribute

- Changed 'signals' to 'variables' two places under "Determinable index range conditions", bullet g)

- Changed the last sentence under change for 4.2.2.3 page 22 near middle to limit the scope to "signal parameter of a scalar object" rather than "signal parameter". The current LRM functionality as it applies to arrays was not intended to be changed by this LCS. Only intend to create a mechanism here to access scalar objects.

- Deleted entire section referencing changes to 16.2.3 - Predefined attributes of arrays. The intent of this change is now being covered by LCS-2016-018c. LCS 72a is now dependent upon 18c.

--


Kevin Jennings - 2017-01-10

I have several concerns with this LCS. The main issue is that it breaks existing code. Consider the following example:

subtype zeroone is range 0 to 1; 
function toggle(x: zeroone) return zeroone is
begin 
   case x of 
   when 1 => return 0; 
   when 0 => return 1; 
   end case;
end function toggle; 
variable v: zeroone := 0; 
v := toggle(v); 
v := toggle(0);

The case statement satisfies the rules laid out in 10.9: "For an ordinary case statement, … if the expression is the name of an object whose subtype is locally static, whether a scalar type or an array type, then each value of the subtype shall be represented once and only once in the set of choices of the case statement, and no other value is allowed;"

In 1076-2008, during the function call, the value of the actual v is copied into the formal x, with the appropriate subtype check that passes. The function call fails if the value of the actual is outside the range of the subtype of the formal. According to these rules both function calls succeed.

With the proposed change the situation changes. The first function call succeeds because the subtype of the actual is the same as the subtype of the formal. The problem occurs with the second function call because the literal is of type universal_integer. According to my reading of the LCS, x'subtype would become universal_integer, which makes the case statement illegal as it doesn't cover all possible values of the expression subtype. This reading is supported by the statement that the attributes 'left etc. of the parameter (I assume the formal parameter) are set to the value of the actual, which for consistency implies that the subtype has to be appropriate.

It is possible that the author focused on parameters with a composite type and didn't consider the implications for parameters of a scalar type. This perspective is supported by the LCS not making a distinction between attributes 'left, 'right, 'low, 'high of a type and of an array object.

--


Ernst Christen - 2017-01-10

EC: The problem occurs with the second function call because the literal is of type universal_integer. According to my reading of the LCS, x'subtype would become universal_integer

KJ: It is not the intention of this LCS to change the subtype of function parameters. If I have, please indicate where in the LCS you see this happening so I can correct (or if you have preferred re-wording that would be even better). What the LCS does intend to do is to provide additional information which is not available today inside the function about that function parameter.

Given that, the intention of the LCS is that what is legal today will still be legal after implementing this LCS. What this LCS intends to do is to make use of syntax which is currently illegal and turn that into something that is legal and provides useful additional information for use inside a subprogram.

In your posted 'toggle' function, the call toggle(0) is intended to result in the following inside the function:

x'subtype'left=0; -- This is unchanged from current LRM defined behavior

x'left=integer'left=–2147483647; -- Note: Currently this is an error since x is not a type mark. This LCS intends to make it legal

While x'left is outside of the bounds of the subtype that the function is expecting for x that, in itself, is not an error. However, inside the function, if a new variable of subtype 'zeroone' is declared and is assigned with x'left then yes that assignment would fail, but that is nothing new. What it would mean from a practical perspective is that x'left would most likely only be of use if the parameter is defined to be a type such as 'integer' without any range constraint. This is analogous to the situation today with arrays. If the parameter is defined as an unconstrained array such as function toggle(x: std_ulogic_vector) and called as toggle("10101") then x'left, x'right would return the left bounds of the actual (in this case x'left=0, x'right=4). If you don't think the LCS accomplishes this same type of behavior for scalars, I would appreciate pointing to the offending text.

If a subprogram uses some constrained subtype (like in your example), that function would probably have no use for knowing the bounds of the actual since it has already taken the position that it only wants to work within the constrained subtype range. However, a more generalized function that intends to work with the full type range might want to make use of the smaller constrained range that is actually being used by one of the actuals. Where I see the practical use cases for this functionality is in combination with LCS-2016-072 which introduces the concept that a function can retrieve the attributes of the target of a function. While that proposal was originally written as a way to get at the array attributes of a target, there is nothing preventing it (I hope) from retrieving the attributes of a scalar object (which are defined by LCS-2016-018). A simple use case for an integer target would be for the function to use target'left and target'right to limit the range of the output of the function.

Originally, LCS-2016-072 was written to encompass the following three ideas:

1. Allow a function to retrieve the attributes of the target to which it is assigning

2. Define attributes of a scalar object

3. Allow a function to retrieve attributes of a scalar object


#1 on it's own is still useful, the canonical example being x := to_unsigned(8); (Note that no sizing parameter is needed). However, #2 and #3 on their own, I'm not clear what use case is actually helped out. #3 has an obvious dependency on #2. #2 without #1 may have a use case but nobody has articulated it. What started as one LCS that fully encompassed the use case has now morphed into three with either direct interdependencies (#3 on #2) or indirect (what is the use case for #2 without #1?).

EC: It is possible that the author focused on parameters with a composite type and didn't consider the implications for parameters of a scalar type

KJ: This LCS has always been solely about scalar objects. Thanks for your input.

--


Kevin Jennings - 2017-01-11

KJ (in response to Ernst Christen):

x'left=integer'left=–2147483647; -- Note: Currently this is an error since x is not a type mark. This LCS intends to make it legal

MZ: How does this LCS (version 5) make x'left legal, if x is a formal parameter of a scalar (sub-) type as in the example from Ernst?

Accessing attributes of scalar objects was part of version 1 of this proposal but has removed later on.

--


Martin Zabel - 2017-01-11

KJ (in response to Ernst Christen): It is not the intention of this LCS to change the subtype of function parameters.

MZ: In my opinion, the proposed changes for section 5.2.1 does change the subtype of function parameters. The only solution I see is to remove this particular change.

--


Martin Zabel - 2017-01-11

MZ: How does this LCS (version 5) make x'left legal, if x is a formal parameter of a scalar (sub-) type as in the example from Ernst?

KJ: What this LCS is now doing is only creating a connection between:

- The attributes of a scalar object from where it is declared

- The body of a function which can now retrieve those attributes.

MZ: Accessing attributes of scalar objects was part of version 1 of this proposal but has removed later on.

KJ: The history is that LCS-2016-018 was essentially spun off of LCS 72a and modified to conform with the format that the author of LCS 18 wanted in order to create a separate votable LCS. That LCS says that scalar objects now can have attributes (in addition to types and arrays). The next step then is to remove that now duplicated attribute definition from this LCS 72a but that removal also creates a dependency between LCS 72a and LCS 18. That dependency is documented in the summary box at the top of this Twiki page. To further confuse things, there is also LCS 60 which does the same thing as LCS 72a but it does so in a different manner and also goes beyond the scope of 72a.

Quick summary: Given this code...

variable abc: integer range 2 to 7;
...
foo(x => abc); -- Call the procedure foo, defined below
... procedure foo(x: integer) is begin -- Today: x'left is illegal -- Today: x'subtype'left returns integer'left=-2147483647 -- With LCS 18: x'left returns integer'left=-2147483647 -- With LCS 18 and LCS 72a: x'left returns abc'left=2
-- With LCS 18 and LCS 60: x'left is legal but returns integer'left. x'actual'left returns abc'left=2. -- With or without the additions of LCS 18, LCS 72a, LCS 60: x'subtype'left will still return integer'left=-2147483647 as it does today end procedure foo;

--


Kevin Jennings - 2017-01-11

KJ: -- With LCS 18 and LCS 60: x'left is still illegal but x'actual'left returns abc'left!=2.

PL: But LCS 018 defines x'left, so it's not illegal anymore. The rule for allowed prefixes was expanded to also cover objects.


patrick Lehmann - 2017-01-11

PL: But LCS 018 defines x'left, so it's not illegal anymore

KJ: You're right, thanks, I fixed the example.

--


Kevin Jennings - 2017-01-11

KJ: It is not the intention of this LCS to change the subtype of function parameters. If I have, please indicate where in the LCS you see this happening so I can correct.

EC: If this is the case, how should the sentence "For a nonforeign subprogram having a parameter class constant or variable, if the actual meets any of the conditions of 'Determinable index range conditions', the attributes of the parameter shall be assigned from the corresponding attributes of the actual. If the actual does not meet any of the conditions of 'Determinable index range conditions', the attributes of the parameter shall be assigned as: … LEFT, RIGHT, HIGH, LOW: Set to the value of the actual." in the LCS V5 be interpreted? In the example I have given, the parameter is of a scalar subtype and none of the determinable index range conditions applies because the concept of a fully constrained subtype only applies to composite subtypes. Hence, I conclude that the bullet list applies. In the second function call, the actual parameter is a literal of the anonymous type universal_integer. The LCS says that in this case the attributes LEFT, RIGHT, LOW, HIGH are set to the value of the actual. It is silent which attributes these are, the ones of the subtype or the ones of an array object. PL adds that there is now also a third set of attributes, per LCS 018 those of the parameter. The crucial point may be what attributes LEFT, etc. are to be updated from the actual. This must be clarified in the LCS (and ultimately the LRM), the comments on this page are not sufficient.

KJ: This LCS has always been solely about scalar objects.

EC: This is certainly not apparent from the LCS, which in most parts refers to actuals with a fully constrained subtype, which only applies to array subtypes and record subtypes (LRM 5.1)

--


Ernst Christen - 2017-01-11

KJ -- With or without the additions of LCS 18, LCS 72a, LCS 60: x'subtype'left will still return integer'left=-2147483647 as it does today

MZ Really? The requested changes for Section 5.2.1 says: "The subtype of the object is the subtype of the actual associated with the object." Thus, x'subtype will return integer range 2 to 7 in your example, and then x'subtype'left will be 2. Thus, it will break existing code.

Anyway, I think it will be also to confusing if x'left returns something else than x'subtype'left.

To be constructive: The best solution will be if scalars behave like arrays. But, this would be only possible if the type of the scalar parameter can be marked as unconstrained as pointed out by Jim Lewis in his email "From subtype actual attributes to integers".

--


Martin Zabel - 2017-01-12

KJ: You're right, thanks. x'left is legal but does not return the desired attribute of the actual. x'left is equivalent to x'subtype'left so it would return the attribute of the formal.

PL: The intention if LCS 018 is not to return actual values; therefore we have LCS 060. So if you explicitly need the actual information, you can get them through LCS 060.

--


Patrick Lehmann - 2017-01-12

Version 6 created, changes are:

Section 4.2.2.1 page 21 changes: Fixed the referenced LRM section (used to be 4.2.1)
  • Section 4.2.2.1 page 21 changes:Expanded note to say where attributes are retrieved from for scalars and non-scalars
  • Section 4.2.2.2:Clarified which attributes are being used in the area dealing with when there are no explicitly defined attributes of an actual.
  • Section 4.2.2.2:Determinable index range conditions, changed usage of "fully constrained subtype" to be "scalar subtype with an explicit range constraint"
  • Section 5.2.1:Deleted.Changes to this section should have been removed when the version that added the area dealing with when there are no explicitly defined attributes of an actual.
--


Kevin Jennings - 2017-01-12

Regarding Version 6:

@KevinJennings: If I understand you right, the intention of this LCS is that for scalar objects:

x'subtype'left will behave as in the current LRM, i.e., return the left bound of the subtype of the formal,
x'left will return the left bound of the subtype of the actual.

(see also your comment dated from 2017-01-11)

But, to accomplish this, x'subtype has still to return the subtype of the formal. But this behavior will be changed by this LCS when x meets of one the listed ‘Determinable index range conditions’ because in this case x'subtype will be taken from the actual and not from the formal anymore. See "[...] if the actual meets any of the conditions of ‘Determinable index range conditions’, the attributes of the parameter shall be assigned from the corresponding attributes of the actual." (page 21) and also the proposed changes for the note above.

In the same way x'base should also always return the base type of the formal to minimize confusion.

Anyway the list of ‘Determinable index range conditions’ seems to be appropriate only on how this function is called, see also my comment on LCS-2016-072, but not whether the actual associated with an parameter meets a specific condition. For example, how should one decide if the actual meets "As the default expression for a generic constant" as in case c)?

--


Martin Zabel - 2017-01-21

To be constructive:

Even with LCS-2016-018, attributes like 'LEFT can be only retrieved from objects or subtypes, but not from expressions. But, according to clause 4.2.2.1: "The actual designator associated with a formal of class constant shall be an expression." For parameters of class signal, variable or file, there is no problem, because these parameters must already be associated with objects.

For parameters of a scalar type and class constant, there are at least two possible solutions:

1) For functions which access the attributes of the formal parameter of a scalar type and class constant, the associated actual designator shall be a name denoting an scalar object. Such formal parameters cannot have a default expression. When accessing the attribute of the formal, the attribute of the actual is returned instead, except of 'SUBTYPE which is always returned from the formal.

2) If an attribute of a formal parameter of a scalar type and class constant is accessed, then:

  • the attribute of the actual is retrieved if and only if the formal parameter is associated with an scalar object and the attribute is not 'SUBTYPE,
  • the attribute of the formal is retrieved otherwise.

I prefer solution 1 because it will mimic the concept of call by reference.

In any solution, I prefer that x'base should also always return the base type of the formal to minimize confusion.

For parameters of a scalar type and class variable, the LCS must state,that the attribute of the actual is referenced, like it is already done for signals.

EDIT Also for variables and signals: 'SUBTYPE must return the subtype of the formal whereas 'BASE should return the base type of the formal.

I will post a similar comment below LCS-2016-060 because that LCS has the same problem.

--


Martin Zabel - 2017-01-21

Martin,

To your first post on Jan 17, how about if the LCS is reworded so that only the LEFT, RIGHT, HIGH, LOW and ASCENDING attributes of the actual are copied? Those are the only attributes that would be needed by the use case which attempts to get at the range of a scalar target from within a function.

Reword the LCS as...

For a nonforeign subprogram having a parameter of class constant or variable, if the actual meets any of the conditions of ‘Determinable index range conditions’, the LEFT, RIGHT, HIGH, LOW and ASCENDING attributes of the parameter shall be assigned from the corresponding attributes of the actual. All other attributes are assigned from the formal.

Remove BASE and SUBTYPE from the subsequent bulleted list.

--


Kevin Jennings - 2017-01-23

Kevin,

such an explicit list of attributes (which might be taken from the actual) would be very good.

(I think you responded to my first post on Jan 21, not Jan 17. wink

--


Martin Zabel - 2017-01-23

Why does this proposal need to get attributes of an actual parameter? I thought that LCS_2016_72 needs to get access to attributes of the target via a named return type. These are not parameters of a function. Formal and actual parameters are mapped with the association list. Return values are not.

--


Jim Lewis - 2017-01-26

EC: version 6, the reasons I outlined below for V5 have not been addressed

KJ: I believe I have addressed the reasons you listed from V5. When you give no specific detail of what you now think is wrong, as you've done with this last comment, it makes it difficult to figure out what you think is in error.

JL:version 6 - I concur with the issues identified by Martin Zabel, Patrick, and Ernst

KJ: Ditto my response to Ernst. I'll also add that we've discussed this lack of specificity before and I thought you agreed not to do that anymore. Since Ernst didn't specify what specifically is wrong that was not addressed in V6, and neither did you, I don't know you're concurring with him about. A solution to Martin's last remaining objection has been agreed, so I'm not sure what issue from Martin you think is still relevant (other than to update the actual LCS). Lastly, Patrick has not commented on version 6 so how can you concur with him?

<soapbox>We're all volunteers here. Having specific objections and not stating them but instead leaving it for 'someone else' to figure out what your objection means, is rather unprofessional. We should all be working towards getting all of the technical issues out there and addressed. Thinking that you've found something and keeping the details to yourself is not a productive way to close technical issues. I mentioned that in one of the recent calls, maybe posting it out for all to see will be more motivating.</soapbox>

--


Kevin Jennings - 2017-01-26

JL:Why does this proposal need to get attributes of an actual parameter? I thought that LCS_2016_72 needs to get access to attributes of the target via a named return type. These are not parameters of a function. Formal and actual parameters are mapped with the association list. Return values are not.

KJ: You're right in that LCS 72 does not need 72a, but LCS 72 is the only stated use case that I'm aware of for LCS 72a and.LCS 60. LCS 72 + LCS 18 solves how to use target scalar attributes in a function. LCS 72a allows for whatever additional cases that went along with the proposal that first talked about 'actual and 'formal. 72a accomplishes the goal of LCS 60 in a way that is more intuitive and less error prone. On the other hand, if LCS 60 is implemented it will give you more to talk about in regards to pitfalls to avoid when you're providing VHDL training.

Looking back at the proposal that backs LCS 60, there are no use cases listed, instead justifying itself only with the statement "This seems to me to be unusual in VHDL, as the user has no means to explicitly define which object these constraints should be applied to" without explaining why that should be important.

For the record, here is a particular use case for wanting to get at attributes of parameter actuals as well as the attributes of the target actual: Being able to check the range(s) of the input parameters to a function and validate that the range of the function target is adequate. As a simple example, if you were to have "function plus(L,R: integer) return integer;" where the function implements return(L+R) then one could add assertions to check that Target'low >= L'low + R'low and Target'high <= L'high + R'high. In today's world you would have to perform actual simulation doing whatever needs to be done in order to make sure that the 'corner cases' still work or perform exhaustive testing of each input combination. Obviously that is not a workable solution. However, with the ability to check input/output range validity, the assertion would fire either at t=0 in the simulation or no later then whenever that function is first called. In either case, you know upfront without exhaustive testing or corner case generation that the function will do what it is supposed to.

So there is a use case for LCS 72a/60 but note that neither of those by themselves allows for this use case. It is only in combination with LCS 72.

--


Kevin Jennings - 2017-01-26

Version 7 created, changes are:

- Limit the attributes of the actual to only be LEFT, RIGHT, LOW and HIGH. Specifically, this is meant to remove BASE and SUBTYPE. ASCENDING is most likely just not going to be needed for the intended applications. This addresses Martin's concern. No one else has explicitly identified any other technical issues and my mind-reading ability has been offline.

--


Kevin Jennings - 2017-02-08

Currently in VHDL within a subprogram, if an attribute is defined for the formal that value is returned. Hence, without some other indication, I see this as something that cannot be changed. Your proposal simply provides a rationale and does it.

I think if you want to access attributes of a actual parameter, even when the formal has them, you need to add something to the formal parameter to designate that attributes of the actual should be passed along with the call.

Your proposal requires a subprogram to pass them along always. If it is not always, then what happens when you access them in a subprogram that is called by another subprogram?

Having reviewed 72 now, including the blue text. I don't think 72a is necessary for the blue text in 72 to be ok - if it can ever be ok since I do not know how to create a scalar type without bounds - hence, it is always true for a scalar

--
Jim Lewis - 2017-02-09

JL: Currently in VHDL within a subprogram, if an attribute is defined for the formal that value is returned

KJ: Currently in VHDL scalar'left is an error within a subprogram. While LCS-2016-018 takes away the error condition, this LCS intends to make it return something useful rather than something that is redundant with currently legal syntax. This is also the only opportunity to get it right. If LCS 18 is approved and 72a is not, then forever more we'll be saddled with a crummy syntax if some form of 72a gets approved down the road because of backwards compatibility. LCS 18, on it's own, only provides a redundant mechansim to access something that can be accessed with 8 additional keystrokes. While those keystroke savings are a plus, there is a cost that the end user will be saddled with if some form of 72a is later incorporated. I harranged on that in detail on LCS 60.

JL: I think if you want to access attributes of a actual parameter, even when the formal has them...

KJ: But that's the point, currently scalar parameters of a function do not have attributes directly. You use 'subtype first to get at anything and then you get the attributes of the formal (which will still be the case if 72a is approved).

JL: you need to add something to the formal parameter to designate that attributes of the actual should be passed along with the call.

KJ: Or, they can always be passed along with the call. Just like arrays.

JL: Your proposal requires a subprogram to pass them along always

KJ: Yes, but the information is already available since it is used at run-time to validate that the actual is within the bounds of the formal. I'm not buying the argument that somehow this LCS is requiring 'new' or 'more' information to be generated and passed around and therefore has some inherent performance or memory footprint impact. My contention is that the information is already there by virtue of the run-time bounds checking. This LCS is just making that information visible to the end user.

JL: Having reviewed 72 now, including the blue text. I don't think 72a is necessary for the blue text in 72 to be ok...- hence, it is always true for a scalar

KJ: That's the same conclusion I came to when reading your comments on 72. I think the blue text in 72 gets deleted.

Thanks for the input. I don't see anything actionable on this LCS as a result that would require a revision at this time.

--
Kevin Jennings - 2017-02-09

Regarding Version 7:

Kevin, sorry to say that, but the LCS has still issues.

1) Regarding new text for page 21:

Quote: if the actual meets any of the conditions of ‘Determinable index range conditions’, the LEFT, RIGHT, HIGH and LOW attributes of the paramet er shall be assigned from the corresponding attributes of the actual.

Therefor: if conditions are met, then take listed attributes from the actual. Which actually means, take the non-listed attributes from the formal.

Quote: If the actual does not meet any of the conditions of ‘Determinable index range conditions’, the object attribute (see section 16.2.2) of the actual of each of the parameters shall be assigned as: LEFT, RIGHT, HIGH, LOW: Set to the value of the object attributes of the actual; All other attributes set to the corresponding attributes of the formal.

Therefor: if conditions are not met, then take listed attributes from the actual and take the non-listed attributes from the formal.

So where is the difference?

2) You didn't addressed my second comment on 2017-01-21.

So what is printed in the following cases? And which condition of "Determinable index range conditions" is met, if any.

entity e is
end entity e;

architecture a of e is
  procedure foo(x : integer) is
  begin
    report "x'left=" & integer'image(x'left);
  end procedure;

  impure function f return integer is
  begin
    return now / 1 ns;
  end function;
begin

  process
    variable v : integer range 0 to 10 := 0;
  begin
    foo(5);
    foo(v);
    for i in 20 to 21 loop
      foo(i);
    end loop;
    foo(v-10);
    foo(f);
    wait;
  end process;
    
end architecture;

EDIT 3) To be constructive

If you want that subprogram parameters of scalar types behave like parameters of an array type, then you will need something like clause 5.3.2.2 bullet e) on page 48.

--
Martin Zabel - 2017-02-09

MZ1: Meant to say " Set to the value of the actual" rather than " Set to the value of the object attributes of the actual". The intent is that when something like a constant or an expression is input to the function, then the 'left, 'right, 'high, 'low attributes should simply take on the value of that constant or expression.

MZ2: I thought limiting the available attributes that come from the actual would address your concern, but apparently not. I'll analyze your new example case (thanks!) and respond later.

Thanks for your input.

--
Kevin Jennings - 2017-02-09

Version 8 created, changes are: - Address Martin's comment #1 on Version 7. - Simplified/clarified the conditions for determining where attributes get assigned from. Now it simply comes down to "If the actual is declared with an explicit range constraint" then assign from the attributes of the actual, otherwise fabricate the attributes from the value of the actual.

--
Kevin Jennings - 2017-02-14

@Martin: I think the version 8 changes now make it simple to address your questions on your posted code. The left/right/low/high attributes for your use cases will be:

- Foo(5) attributes 5/5/5/5 (left/right/low/high) since the actual assigned to the parameter is not declared with an explicit range definition

- Foo(v) attributes 0/10/0/10 since the actual assigned to the parameter is declared with an explicit range definition

- Foo(v-10) attributes -10/0/-10/0 since the actual assigned to the parameter is not declared with an explicit range definition. Note: It is not an error for the attributes of the actual to be outside of the bounds of the formal.

- Foo(f) left/right/low/high attributes are all 'now / 1 ns' since the actual assigned to the parameter is not declared with an explicit range definition

--
Kevin Jennings - 2017-02-14

@Kevin, thanks for the update, it is much better to read.

1) The LRM doesn't define the term "explicit range constraint", or I haven't found it. I think what you mean instead, is (red are your additions, blue are my modifications):

* If the actual is a declared with an explicit range constraint object or a subelement thereof, the LEFT, RIGHT, HIGH, LOW RANGE and REVERSE_RANGE object attributes of the parameter shall be assigned from the corresponding attributes of the subtype of the actual.

2) And regarding the examples, I think there is an error in your comment just above.

For Foo(v-10) the left/right/low/high attributes are all 'v-10', i.e. determined from the current value of 'v', because the actual is not an object. Thus, it works like Foo(f).

-- Martin Zabel - 2017-02-15

I agree that 'explicit range constraint' is not in the LRM. However, I'll point out that the word 'explicit' is added to many terms and the resulting new term is not defined. For example, 'explicit block statement' is the first usage of the word 'explicit' in the LRM and appears on page 14 as: If the block is an internal block, the defining block statement is either an explicit block statement or an implicit block statement that is itself defined by a generate statement. The term 'explicit block statement' also appears on page 140 but again, not as a definition. Nowhere else is the term 'explicit block statement' used in the LRM.

The term 'explicit component configuration' and 'explicit configuration items' are also similarly used and not formally defined either. From that I conclude that the LRM allows the use of the modifier 'explicit' to be added to a defined term without formally defining the 'explicit' term. Therefore since 'range constraint' is a defined term, I'm on solid ground.

Striking out the phrase 'with an explicit range constraint' as you did is not what I'm intending. If that phrase is struck, then it would apply to everything. In that case, if function Foo was called as Foo(1), then inside function Foo, the attributes for the parameter would be integer'low, integer'high which is not going to be of much practical use.

I do like the other change you suggest and would propose the following, let me know if you agree and if you have any other comments/reservations/objections etc.

If the actual is a declared object, or a subelement thereof, with an explicit range constraint, the LEFT, RIGHT, HIGH, LOW RANGE and REVERSE_RANGE object attributes of the parameter shall be assigned from the corresponding attributes of the subtype of the actual.

Foo(v-10) attributes work the same as Foo(f), you are correct.

Thanks for your input

-- Kevin Jennings - 2017-02-15

Version 9 created, changes are:

- Page 21 paragraph: Clarified wording to say that an "object or a subelement thereof" and not just an "actual" must have an explicit range constraint

- Page 22 paragraph: Clarified that only references to LEFT, RIGHT, HIGH, LOW, RANGE or REVERSE_RANGE attributes refer back to the actual and any other attributes refer back to the formal

-- Kevin Jennings - 2017-02-16

@Kevin: Right, explicit is not formally defined for all kinds of usage. It is often (always?) used to distinguish between something which has been explicitly written down by the designer, and something which has been implicitly inferred from LRM rules. OTOH things like explicit declared type (6.2) and other explicit declarations are well defined.

1) A range constraint is part of a subtype indication (6.3) which can be itself part of subtype or object declaration. So when is such a range constraint explicit? Examples:

variable v1 : integer;
variable v2 : integer range 0 to 3;
subtype int8 is integer range -128 to 127;
variable v3 : int8;

And if 'v1' has no explicit range conditions, then the attributes would be set to the current value of v1 in a call of foo(v1). Is this intended?

If all these variables declarations have an explicit range constraint, then please give an example of an object declaration with an implicit range constraint.

2) KJ: Striking out the phrase 'with an explicit range constraint' as you did is not what I'm intending. If that phrase is struck, then it would apply to everything. In that case, if function Foo was called as Foo(1), then inside function Foo, the attributes for the parameter would be integer'low, integer'high which is not going to be of much practical use.

No, '1' is a literal, not an object and thus will also not satisfy my shorter requirement. Thus, the attributes would be all set to 1.

-- Martin Zabel - 2017-02-16

Version 10 created to address Martin's observations (sent in separate email):

- For a scalar parameter, the condition used to choose from parameters of the actual vs. using the value of the actual changed to "- If the actual is a declared object, or a subelement thereof"

- Removed the phrase "using the value of the actual" from RANGE and REVERSE_RANGE attributes (typo).

All identified technical objections that have been identified at this time have been addressed.

-- Kevin Jennings - 2017-02-22

Setting the direction of the RANGE attribute to ascending is still wrong. The same is true for setting the REVERSE_RANGE to descending. Furthermore it creates a contradiction between the attribute ASCENDING and the direction of the range / reverse range, because the value of ASCENDING is not overwritten. However as I said. It's wrong because you can declare scalar types with descending ranges.

type foo is range 7 downto 0;

Why does LCS 072a overwrite that direction?

Your text assigns the values of attributes. Attributes can not be assigned. The reflect properties of the underlying VHDL construct like a type, subtype or object. Changing the attribute values requires to exchange the subtype of an object like a parameter.

You can't overwrite the values of attributes without changing the underlying subtype, because these attributes are the property of a subtype. So in consequence you need to patch the subtype at elaboration time! That's not allowed and not possible.

What fore is the difference between declare and not declared objects?

-- Patrick Lehmann - 2017-02-22

PL: Setting the direction of the RANGE attribute to ascending is still wrong. The same is true for setting the REVERSE_RANGE to descending.

KJ: As stated in the LCS, this is only done "If the actual is not a declared object". Examples of an actual that is not a declared object would be a literal or an expression. Existing LRM wording which is listed in the LCS states: "...the values and attributes of the actual or formal are transferred into or out of the subprogram call. The manner of such transfers, and the accompanying access privileges that are granted for constant and variable parameters, are described in this subclause." In the following paragraphs that I added, I describe the special treatment manner for transferring scalars into a subprogram which seems to be the area of confusion.

PL: Furthermore it creates a contradiction between the attribute ASCENDING and the direction of the range / reverse range, because the value of ASCENDING is not overwritten.

KJ: I'm not sure what you mean by "value of ASCENDING is not overwritten". However, referencing section 5.2.1 (Scalar Types - General), it states: "The range L to R is called an ascending range; if L > R, then the range is a null range. The range L downto R is called a descending range; if L < R, then the range is a null range. L is called the left bound of the range...". In the LCS, I state "range attribute shall be assigned an ascending range". I don't see the contradiction.

Given that the attributes are assigned from the value of the actual at run time and left=right=low=high=value of the actual, then the setting of an ascending or descending range to this sort of 'quasi-subtype local to the function' that consists of only value I think is arbitrary. Ascending tends to be used in the LRM for otherwise undeclared directions so I chose to follow that lead and use an ascending range here. I could also say that the range is assigned from the range of the actual but since the actual is an expression or a literal, I think the range will be ascending anyway.

If we are at least on the same page about what I am trying to accomplish (i.e. things such as literals or expressions use the actual value to set the value of the attributes) then do you have some other wording that accomplishes the goal?

PL: However as I said. It's wrong because you can declare scalar types with descending ranges. type foo is range 7 downto 0; Why does LCS 072a overwrite that direction?

KJ: Presumably, you're talking about the case then where you declare something of type foo such as "variable foo_object: foo;" and then pass foo_object into the function such as "y <= foo_fn(foo_object);". Is that correct? If so, then for that situation, foo_object meets the first condition "If the actual is a declared object..." and the left, right, high, low, range and reverse_range attributes would be assigned from foo_object. The direction is not changed, foo_fn would see the descending range of the foo_object actual from the declarations.

PL: Your text assigns the values of attributes. Attributes can not be assigned. The reflect properties of the underlying VHDL construct like a type, subtype or object. Changing the attribute values requires to exchange the subtype of an object like a parameter. You can't overwrite the values of attributes without changing the underlying subtype, because these attributes are the property of a subtype. So in consequence you need to patch the subtype at elaboration time! That's not allowed and not possible.

KJ: What I'm saying is that the tools, once they recognize that a scalar parameter is not a declared object, that they patch what the subprogram receives as an attribute for that scalar. I would think that the detection of this condition could be done very early in the process. The actual assignment to 'attributes' that only the function would receive would occur at runtime since they are assigned from the value of the actual.

PL: What fore is the difference between declare and not declared objects?

KJ: From 6.4.2.1 (Object Declarations - General) it states: "An object declaration declares an object of a specified type. Such an object is called an explicitly declared object." Perhaps I should change the wording in the LCS to add 'explicitly'?

Current wording:

If the actual is a declared object

If the actual is not a declared object

How about this wording instead?:

If the actual is an explicitly declared object

If the actual is not an explicitly declared object

You might want to reword the objection to your vote. Preferring LCS-018 to this one is not really relevant, they do not do the same thing. LCS 72a does build upon LCS 18 and if LCS 18 is approved and LCS 72a is not, it will prevent any future 72a from being realized in the form presented here due to backwards compatibility differences. For the record, I'm OK with the 'new attributes' portion of LCS 18, but not the adding of object attributes without approving 72a at the same time.

In any case, I see that you are still opposed but appreciate the time you took to review and comment. I will update the LCS to say "explicitly declared object" pending any other feedback that others might have. Let me know if you have any other feedback.

-- Kevin Jennings - 2017-02-23

@Kevin, regarding "explicitly declared":

I would not change this because "An alias of an explicitly declared object is not an explicitly declared object", see NOTE on top of page 92.

Also every implicitly declared object should have the required attributes.

-- Martin Zabel - 2017-02-23

On the Mar 2 call, Jim L and Rob G expressed concern that the simulator's call stack for a subprogram would be larger than it is today because of having to pass in the low and high scalar object attributes even if those attributes are not used. Both also stated that they would support the LCS if a way was found so that the compiler could determine if those attributes are needed based solely on analysis of the function declaration, rather than the function body. During the call, a method was proposed for doing this that, to me at least, is more complex than needed and is prone to user error. Version 11 of the LCS provides a simpler and user error free way to meet this request.

Version 11 defines a new term 'subtype_indication_with_explicit_constraint' which is a 'subtype_indication' in which the constraint is explicit (i.e. a: integer range 1 to 10; is 'explicit' whereas a: integer; is not 'explicit'). If the scalar range is not explicitly defined, then the attributes of the actual will be needed and this is clearly determined solely from the function declaration. This change will still allow this LCS to have scalers work in a similar fashion as vectors where attributes of actuals are returned when the declaration is for an unconstrained vector.

-- Kevin Jennings - 2017-03-12

Updated my vote - this still seems very useful to me (more so than having a'left return the attributes from the formal which seems to be what will happen if this LCS is not included)

-- Martin Thompson - 2017-03-14

1) Need syntax that enables passing with the default being that the passing is disabled.
2) WRT use models, I copied them to a "use model section:. You seem to imply some sort of static checking. Just having this LCS is not sufficient to write decent rules. It is somewhere we probably want to go, however, I don't think we should go there with only a partial solution.

your use models, which I copied to a use model section, should be able to be done by a static checking tool anyway.

-- Jim Lewis - 2017-03-15

JL: 1) Need syntax that enables passing with the default being that the passing is disabled

KJ: I believe that the source for why you state this 'need' to change the default behavior is because you think that adding the two integers worth of additional information (i.e. 'LEFT, 'RIGHT, with the other attributes derived from those two, if and when they are actually used within the function) will have an impact on simulation performance or memory usage. Is this correct?

- If correct, I have already shown that the concern is not valid for one commercially available simulator. The full benchmark code and results were posted on the reflector for others to confirm if they choose. I hope to get GHDL installed so I can then run the test on that platform as well but feedback I've received from one of the developers indicates that it will be a non-issue there as well, But even without the GHDL results just yet, it doesn't seem likely that if something as benign as growing the call stack by a couple of bytes on one simulator produced repeatable results that showed absolutely no measurable impact then why would significantly different results be expected using a different simulator? Which leads then to the question: If the results do show an impact, what is the acceptable level? 10% is clearly not acceptable; 1%? 0.1%? Nothing other than 0? This is somewhat rhetorical, but to get one thinking about what is an acceptable limit. Requiring 0 without basis is rather dictatorial but so far has been achieved. Also remember that the change that was proposed to add "subtype of", will impact each and every user because they will be required to use different syntax for scalar parameters versus array parameters whereas what I proposed has 0 impact on the end user (i.e. they don't have to remember anything 'new', what used to be flagged as an error, now it just works). Many of these discussions have focused too much (in my opinion) on what the reader thinks things 'should be' from their own perspective and to some extent the first customer (the tool developers) but not considering at all the perspective of the end user customer which ultimately is the thing that keeps the product viable (or not).

- If the source is not as I mentioned, then what is the source for your declared 'need'? The current syntax that I've proposed does not break existing working code since everything from VHDL-1987 thru VHDL-2008 treats ScalarObject 'left as an error. Now the error is gone and would be replaced with something that the end user writing code can actually use.

JL: You seem to imply some sort of static checking. Just having this LCS is not sufficient to write decent rules

KJ: Not sure what you mean by static in this situation. As for not sufficient to write decent rules, let me just say that having nothing is even less sufficient than having something.

JL: It is somewhere we probably want to go, however, I don't think we should go there with only a partial solution.

KJ: We may all be dead by that time. As far as I know, this is not even something that has been considered as a language feature but you probably know more than I do in that regard. In any case, I don't think it was a feature requested in the 6+ years of this LRM development. That lack of explicit request could indicate that formal checking is not really that important or it could be that people have resigned themselves that to get any formal checking they must use a separate tool...but today they must because their is no alternative with their existing simulator...yet. While I'm not a developer, I don't think that this is a 'difficult' thing to implement. Before one even considers having a 'full solution' as you indicate that you would prefer, I would think it would be important to get feedback on the acceptance of this 'partial solution'

Remember, at the end of the day, all that is happening is removing an error condition from today's language syntax and providing a new feature available only through 72a. If we accept 18 but not 72a, there will be no 72a for the next go-round. One will most likely have to use something like "subtype of" and forever more burden end users with one syntax for array type parameters and another for scalar type parameters.

JL: should be able to be done by a static checking tool anyway.

KJ: That statement is showing a bias towards formal analysis tools over simulation tools. I know of open source simulators, is there an open source formal tool? That would be cool to have. Not everyone using VHDL develops products that require huge teams of developers and inspections of every single line of code that of course wouldn't even be considered until it has been fully linted and formally checked.

This new version of the LRM produces things that are essentially productivity improvements rather than actual new functionality. I'm certainly not trying to downplay the importance of productivity improvements but new functionality is important as well. While you are dismissive of this particular new functionality because of the limited scope, there is also relatively little cost to adding the feature which comes about as a replacement for today's error condition.

-- Kevin Jennings - 2017-03-15

@Martin T...thank you for your vote.

-- Kevin Jennings - 2017-03-15

The text "For a nonforeign subprogram having a parameter of class signal and a scalar subtype" was inadvertently left out. Also did some indentation to show the scope of the two "For a nonforeign..." statements.

-- Kevin Jennings - 2017-03-21

Summarizing the working group discussion from 3/23. Jim, Patrick, Rob and Lieven were all 'No' votes coming in. Prior to the meeting, all had stated that they would support the LCS if the subprogram declaration was changed to require "subtype of" prior to the type for each parameter. The stated objection at that time for which "subtype of" was considered the solution was that by increasing the size of the call stack, performance would be impacted. Kevin already provided measurement data to the group showing that, under limited (but reasonable) testing, there was no measurable performance impact and the worst that could reasonably be expected with further testing is negligible impact. Based on that, going into the call, there were no technical objections that had not already been shown to be invalid. One the 3/23 call itself:

Jim and Lieven offered no further technical objections, but neither agreed to change their vote.

Patrick objected that this LCS would break "internals of the language". Besides not defining the specifics of "internals of the language", no justification was provided for why this LCS with the change to include "subtype of" would not also break those same "internals of the language" even though Patrick stated that he would support the LCS with exactly that change.

Rob provided the following use case for discussion. Going somewhat from memory here but given the following:

type littleint is integer range -15 to 15;
...
function foo(x: littleint) return integer is
begin
   return(x'left);
end function foo;
...
function foo2(x: integer range -15 to 15) return integer; -- Same function body as foo.
...
variable a: littleint;
constant c:  integer := 5;
...
a1 := foo(a);  a2 := foo2(a);
c1 := foo(c);  c2 := foo2(c);

Rob's first concern was that the results would not be the same (i.e. a1 /= a2 and c1 /= c2). After working through the examples using the LCS, Rob seemed to agree that the examples do in fact work correctly and would return the same result.

Rob's next concern was that the identity O'SUBTYPE'LEFT must equal O'LEFT as it has for the past 30 years. Besides the fact that O'SUBTYPE has only been around since the 2008 LRM, Kevin asked when he had ever used, or would ever use, this identity. Rob admitted he had not. Kevin pointed out the following identity that a typical user would likely expect:

assert X'LEFT = foo(X)

Kevin noted that with the approval of LCS 18, this above assertion would fail. With the approval of LCS 18 and LCS 72, the assertion would pass. Rob gave no justification for why he thought letting this assertion to fail is the correct thing to do. Instead he reverted back to his assertion and claimed it should be true because it was part of his mental model even if it would never be part of his actual code.

Rob's final objection was one of uncertainty over 'other' effects without specifying in what direction those 'other' effects might be. Then a vote was called for.

This LCS has been heavily scrutinized and open for review for six months. During that time, every single objection was either addressed by changing the LCS or, in nearly all cases, shown that the objection itself was not valid. The intent behind the LCS has not changed at all during the entire time. The 12 revisions are simply iterations at getting the LCS text to match that intent. Claims of violating "internals of the language" or breaking "mental models" or vague "uncertainty" cannot be addressed technically, since they have no technical basis. Without a technical basis, there can be no rational discussion. Therefore, it is concluded that this LCS was voted down by the working group due either to undisclosed reasons or for irrational reasons that have no technical basis.

-- Kevin Jennings - 2017-03-28

Topic attachments
I Attachment Action Size Date Who Comment
Microsoft Word filedocx LCS_2016_072a_Ver_1.docx manage 24.5 K 2016-12-30 - 02:07 KevinJennings  
PDFpdf LCS_2016_072a_Ver_1.pdf manage 294.8 K 2016-12-30 - 02:07 KevinJennings  
Microsoft Word filertf LCS_2016_072a_Ver_1.rtf manage 104.5 K 2016-12-30 - 02:08 KevinJennings  
Microsoft Word filedocx LCS_2016_072a_Ver_10.docx manage 19.9 K 2017-02-22 - 18:09 KevinJennings  
PDFpdf LCS_2016_072a_Ver_10.pdf manage 213.2 K 2017-02-22 - 18:09 KevinJennings  
Microsoft Word filedocx LCS_2016_072a_Ver_11.docx manage 22.3 K 2017-03-12 - 18:35 KevinJennings  
PDFpdf LCS_2016_072a_Ver_11.pdf manage 253.7 K 2017-03-12 - 18:35 KevinJennings  
Microsoft Word filedocx LCS_2016_072a_Ver_12.docx manage 22.5 K 2017-03-21 - 02:25 KevinJennings  
PDFpdf LCS_2016_072a_Ver_12.pdf manage 254.1 K 2017-03-21 - 02:25 KevinJennings  
Microsoft Word filedocx LCS_2016_072a_Ver_2.docx manage 24.9 K 2016-12-31 - 17:12 KevinJennings  
PDFpdf LCS_2016_072a_Ver_2.pdf manage 298.7 K 2016-12-31 - 17:13 KevinJennings  
Microsoft Word filertf LCS_2016_072a_Ver_2.rtf manage 106.1 K 2016-12-31 - 17:13 KevinJennings  
Microsoft Word filedocx LCS_2016_072a_Ver_3.docx manage 25.8 K 2017-01-02 - 16:21 KevinJennings  
PDFpdf LCS_2016_072a_Ver_3.pdf manage 308.8 K 2017-01-02 - 16:22 KevinJennings  
Microsoft Word filertf LCS_2016_072a_Ver_3.rtf manage 109.0 K 2017-01-02 - 16:22 KevinJennings  
Microsoft Word filedocx LCS_2016_072a_Ver_4.docx manage 25.7 K 2017-01-05 - 03:43 KevinJennings  
PDFpdf LCS_2016_072a_Ver_4.pdf manage 297.5 K 2017-01-05 - 03:43 KevinJennings  
Microsoft Word filertf LCS_2016_072a_Ver_4.rtf manage 102.3 K 2017-01-05 - 03:43 KevinJennings  
Microsoft Word filedocx LCS_2016_072a_Ver_5.docx manage 19.8 K 2017-01-10 - 17:29 KevinJennings  
PDFpdf LCS_2016_072a_Ver_5.pdf manage 188.7 K 2017-01-10 - 17:29 KevinJennings  
Microsoft Word filertf LCS_2016_072a_Ver_5.rtf manage 56.8 K 2017-01-10 - 17:29 KevinJennings  
Microsoft Word filedocx LCS_2016_072a_Ver_6.docx manage 20.3 K 2017-01-12 - 13:42 KevinJennings  
PDFpdf LCS_2016_072a_Ver_6.pdf manage 192.9 K 2017-01-12 - 13:43 KevinJennings  
Microsoft Word filertf LCS_2016_072a_Ver_6.rtf manage 60.6 K 2017-01-12 - 13:43 KevinJennings  
Microsoft Word filedocx LCS_2016_072a_Ver_7.docx manage 20.0 K 2017-02-08 - 21:33 KevinJennings  
PDFpdf LCS_2016_072a_Ver_7.pdf manage 189.6 K 2017-02-08 - 21:33 KevinJennings  
Microsoft Word filedocx LCS_2016_072a_Ver_8.docx manage 19.9 K 2017-02-15 - 01:27 KevinJennings  
PDFpdf LCS_2016_072a_Ver_8.pdf manage 244.4 K 2017-02-15 - 01:27 KevinJennings  
Microsoft Word filedocx LCS_2016_072a_Ver_9.docx manage 20.1 K 2017-02-16 - 04:13 KevinJennings  
PDFpdf LCS_2016_072a_Ver_9.pdf manage 240.3 K 2017-02-16 - 04:13 KevinJennings  
Topic revision: r75 - 2017-04-02 - 12:19:48 - PatrickLehmann
 
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