New Predefined Attributes: 'actual, and 'formal
Proposal Editing Information
- Who Updates: Brent Hayhoe
- Date Proposed: 2014-07-14
- Date Last Updated:
- Priority:
- Complexity:
- Focus:
Requirement Summary
The ability to select either the 'formal part' or 'actual part' of an element of an association list structure.
Related Issues:
Modular types.
Proposal
Current Situation
In subprograms, if a parameter type is an unconstrained array, the subprogram can be constrained by accessing the subtype constraints of the actual part of the association element (i.e. what's connected to it). This is normally accomplished using predefined attributes of arrays (e.g. 'length, 'low, 'range, etc.) applied to a parameter of the subprogram.
However, for scaler types this is not the case. Any attempt to access type constraints via these attributes will return values corresponding to the formal part of the association element.
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.
Implementation details
Add two new predefined attributes 'actual and 'formal to be used as a prefix to another attribute:
where E is an association element of an instantiated interface
E'actual - returns the actual part of the element
E'formal - returns the formal part of the element
Code Examples
function my_function( arg : integer)
is
variable my_variable : integer range
arg'actual'subtype'low to arg'actual'subtype'high;
begin
---
end process my_model;
This would give the range of the actual connected to the instantiated function and would then form the subtype of the variable within the function.
Use Cases
Arguments FOR
This gives explicity control to the user over which part of the association list element is accessed.
Arguments AGAINST
General Comments
I think a cleaner approach would be to allow scalar objects to have attributes, not just scalar types. I first semi-proposed this a while back in the proposal
FunctionKnowsVectorSize:
This idea can be extended further to include scalar objects but would require adoption of another (as yet unwritten) proposal. For scalars, it is valid today to refer to attributes such as 'left, 'right, etc. of a
type, but not for an
object of that type. Assuming that one could get attributes of a scalar object, then object'left, object'right would then return the left and right bounds of that scalar (i.e. signal xyz: integer range 2 to 5 --> xyz'left = 2; xyz'right = 5). All of the other usual attributes would also be available, not just 'left and 'right. On the assumption that this new proposal happens, then this proposal would automatically inherit the ability to access scalar attributes as well. This would allow the function to know the range of the output object. It has been suggested in separate e-mails that this would be a benefit. --
KevinJennings - 2014-04-23
If objects had attributes, they would allow you to do what you're proposing here as well, but I don't see that there would be a need for a new keyword.--
KevinJennings - 2014-08-26
<Brent Hayhoe> - The 'subtype' attribute gives you what you're after, I think, as it appends to objects.
The proposed new 'actual' & 'formal' attributes give the ability to point to the formal port object within a subprogram, or the object that is associated with it as the actual part when it is instantiated at elaboration time. They give the user the ability to explicitly specify which object is to be referenced.
</Brent Hayhoe> - 2014-08-27
While it appends to object, the 'subtype attribute doesn't quite do the trick since it returns the range of the (sub)type, not of the object itself. For example:
signal xyz: natural range 2 to 4;
When xyz is passed to a function or procedure...
xyz'subtype'left returns 0 (the 'left of subtype 'natural', not the leftmost allowable range of xyz which is 2)
xyz'subtype'right returns 2147483647 (the 'right of subtype 'natural', not the rightmost allowable range of xyz which is 4).
I think this type of behavior is what you are referring to when you refer to the 'formal port' in your discussion.
What you seem to be after when you say the 'actual port', seems to be the same as the semi-proposal that I mentioned. My interpretation is that we both want something that would return '2' for 'left and 'low and '4' for 'right and 'high whether inside a subprogram or not.
It makes no sense to me why xyz'left does not return 2 today. Also, it would seem that this could be implemented without breaking any existing code since currently xyz'left will produce a compiler error. So get rid of this compiler error and have it return something useful.
Do we agree that if xyz'left returned the left bound of the actual object (the number 2 in the example here), that it would meet the needs of your intended usage for your current proposal? It seems like it should since you could use xyz'subtype'left to get at the 'formal' and xyz'left to get at the 'actual'. --
KevinJennings - 2014-08-28
<Brent Hayhoe> - I've just tried the following code in
ModelSim:
subtype COUNT_jst is Integer range 2 to 9;
signal COUNT_js : COUNT_jst;
constant COUNT_LOW_jc : Integer := COUNT_js'subtype'low;
constant COUNT_HIGH_jc : Integer := COUNT_js'subtype'high;
constant COUNT_LEFT_jc : Integer := COUNT_js'subtype'left;
constant COUNT_RIGHT_jc : Integer := COUNT_js'subtype'right;
signal st_COUNT_js : Integer range 2 to 9;
constant st_COUNT_LOW_jc : Integer := st_COUNT_js'subtype'low;
constant st_COUNT_HIGH_jc : Integer := st_COUNT_js'subtype'high;
constant st_COUNT_LEFT_jc : Integer := st_COUNT_js'subtype'left;
constant st_COUNT_RIGHT_jc : Integer := st_COUNT_js'subtype'right;
I thought that defining an explicit subtype might have different behaviour, but no. All low/left constants evaluate to 2 and all high/right to 9, as expected.
All these were defined in an architecture declarative region.
</Brent Hayhoe> - 2014-09-04
You're correct that within the architecture you do get the expected result. What I was trying to get across was the idea of xyz'left (which is illegal today when xyz is a scalar) returning the 'left value of the range of xyz, whether xyz was something within the architecture (where 'subtype'left does the trick today) or within a subprogram (where 'subtype'left does not do what is needed). I've rewritten my original posting on this proposal a bit to clarify. I'm in agreement with you (and have been since the start, even back to when I wrote my semi-proposal) with the idea that functions and procedures should be able to access the actual ranges of any parameter, I'm just suggesting something that I think is cleaner.
The only suggestion I am making to your proposal was that instead of defining two new keywords to accomplish the goal, why not simply let xyz'left return the actual 'left of the parameter xyz? Today that syntax returns an error when xyz is a scalar. If xyz'left instead would return the leftmost value for xyz (whether xyz was in the architecture or something within a subprogram) then there would be no need for your 'actual keyword. Using xyz'subtype'left already returns the leftmost of the subtype of xyz within a subprogram which I think is what you are trying to get at with 'formal. If that's the case, then there is already no need for defining the 'formal keyword.
I think the approach I outlined is 'cleaner' in the sense that
- There are no new keywords
- The usage to get at what you're calling the 'formal' and 'actual' is at least as clear to the reader
- It removes a 'special case' from the current language. Unlike other types, the various static attributes 'left, 'right, etc. for a scalar currently produce a compiler error whereas they could be made to be legal code by returning something useful instead.
--
KevinJennings - 2014-09-05
<Brent Hayhoe> - I agree with you about the xyz_scaler'left problem and changing the current attributes to handle this would make the subtype attribute redundant.
At present, my suggested string of attributes is very verbose. I like verbosity, but too much verbosity can easily obscure design intent - not good.
I think I should post to reflector to see if anyone knows why the 'subtype attribute was added, in case there are any use cases we've overlooked.
With regards to the new 'actual attribute, I still prefer it in that it provides explicitness. I'm all for implied syntax in code, just as long as there is the ability to code explicitly as well. The reason I added the 'formal attribute was to provide this explicitness.
I think I would prefer to add the new attribute names and get rid of the 'subtype attribute.
</Brent Hayhoe> - 2014-09-05
Supporters
--
Brent Hayhoe - 2014-07-13
Add your signature here to indicate your support for the proposal