[Fwd: Re: Recently submitted VHDL Issue]

From: Chuck Swart - MTI <cswart_at_.....>
Date: Thu Jun 26 2008 - 13:53:56 PDT
This is a copy of an email and its response concerning
IR 2132    Submitted                       Method to allow functions 
that return arrays to have knowledge of the array bounds

-- 
This message has been scanned for viruses and
dangerous content by MailScanner, and is
believed to be clean.


attached mail follows:


Chuck,

Thanks for submitting, I was able to find the description of issue report #2132 and the status out on the website but nothing more detailed (not sure if there is supposed to be anything more detailed).

To answer your question about how to determine the size of 1 in this expression

X <= to_unsigned(1)+Y;

My answer is the language wouldn't have to, it could simply be flagged as an error since the needed size in bits required to represent '1' can not be determined without backtracking through the overloading of 'numeric_std."+"' in order to figure it out.  This use case however is already well covered by the 1993 numeric_std anyway and would be written as

X <= 1+Y;

Or, for the people who prefer clunky looking code

X <= to_unsigned(1, Y'length)+Y;

In synthesizable code, most of the assignments of numeric literal values to signed/unsigned that I tend to see are typically of the form

X <= 0;
X <= 1;

Today this must be written as

X <= (others => '0');
X <= to_unsigned(0, X'length);
X <= (0=> '1', others => '0');
X <= to_unsigned(1, X'length);

To say the least, these are all ugly representations that obscure the designer's intent (which I claim is to convert a literal integer number into an unsigned representation 'X').  All of this gets cleaned up by being able to simply say

X<= to_unsigned(0);
X<= to_unsigned(1);

In testbench code, I tend to see more examples of performing math functions and then converting it to fit into the bit fields of some port so this testbench code gets littered with statements like the following

Pointer_Port.Pointer    := std_ulogic_vector(to_unsigned(Base_Port_Address + Offset, Pointer_Port.Pointer'length));

Again, this would clean up as
Pointer_Port.Pointer    := std_ulogic_vector(to_unsigned(Base_Port_Address + Offset));

Here though the math tends to be done on real numeric types, the casting is done after the calculation in order to change the representation from a numeric type into whatever type is required for the thing that the testbench is testing.  This case also shows that the 'target' of the function could be another function.  Presumably, it should not be difficult to know that the attributes of the final 'std_ulogic_vector' type conversion function are the same as the left hand side (Pointer_Port.Pointer) but maybe that's the fly in the ointment, or maybe not.

As far as the utility of the request being limited, I'd hazard a guess to say that the use cases for my suggestion most likely cover completely (or almost) with whatever use cases were proposed that led to the 'sized bit string literals' proposal which leads to the following solution

X <= 10X"1";

To be blunt, this solution is rather bad...and seems to have come from some Verilog double agent.  It is certainly not intuitively obvious about what the intent here is (for those who might not up on the latest language syntax).  Second, you can't parameterize the range on 'X' since there is no way to change that hard coded bit width of '10'.  While hard coded widths are used in many situations, they are rarely used in code that is intended to be reused, thus limiting the utility of 'sized bit string literals' as a possible solution to one-off types of situations.

Off hand, I don't really see any use cases for sized bit string literals that could not be covered by my suggestion of allowing an overloaded function (identified by the new 'constrained' keyword somehow) that would have access to the constraints (i.e. 'length, 'range', 'left, 'right, etc.)

The other use case that comes to mind with my proposal is with the new fixed point package.  There the 'resize' function typically stands in as the function that would really benefit from knowing the constraints of the target.  Today you can express a simple multiplication and resize as

X1G1_Resized    <= resize(X1*G1, X1G1_Resized, fixed_wrap, fixed_truncate);
X1G1_Resized    <= resize(X1*G1, X1G1_Resized); -- Take the defaults

Again, to the casual observer, one immediately wonders what is served by having 'X1G1_Resized' on both sides of the assignment operator.  This gets cleaned up and the intent expressed more succinctly using my proposal as

X1G1_Resized <= resize(X1*G1, fixed_wrap, fixed_truncate);
X1G1_Resized <= resize(X1*G1); -- Take the defaults

The other solution that addresses the problem is overloading of the assignment operators themselves which is also out on the web site as a proposal from Jonathon Bromley I believe.  While this would allow for the even more elegant representation as

X1G1_Resized <= X1*G1;

The problem comes in when the user doesn't want to accept the default wrapping and truncation methods.  Now the "<=" overloaded function would seem to need some more parameters just to do the job.  How would one represent this?  I'd hazard a guess to say that it won't be a very intuitive representation of intent.

X1G1_Resized <=(fixed_wrap, fixed_truncate) X1*G1; This??

Also, I'm not sure that operator overload would help out in the use case previously listed

Pointer_Port.Pointer := std_ulogic_vector(to_unsigned(Base_Port_Address + Offset));

Although I suspect that whatever it would take to get the attributes of the left hand side over to the 'to_unsigned' function would be the same as with my proposal, the whole intent of the assignment overload would be to get rid of the 'to_unsigned' in the first place, so now you're performing math on numeric types and casting them to std_ulogic_vector...std_logic_arith comes darkly to mind.

This example shows that, while 'hiding' some of the conversion functions may give the appearance of being neat and tidy, it can also lead to the same sort of ugly ambiguities that std_logic_arith brought to the game that to this day are still with us.  Preserving these functions explicitly in the code makes things easier to inspect, conforms more closely with strong type checking which I, for one, think is one of the strengths of the language.

So, while the intended scope of my proposal may be pretty narrow from a language perspective (i.e. the target of a function is a vector of known size) it addresses a very basic readability/understandability issue with the language.

My proposal
- Fixes the issue.
- Could prevent future similar issues if someone dreams up a new package with new data types that would otherwise face similar problems.
- Inherently works with parameterized code which is important for reusable code.
- Does not get 'ugly' when used in an acceptable (but perhaps off the beaten path) manner like I think would happen with assignment overload and the fixed point package.
- By limiting the scope to the particular case where the target has a known range, it 'seems' like it should also be a fairly easy thing to actually implement since no in depth analysis need be done to try to 'figure out' the attributes of the target.
- Preserves strong type checking.

I understand that this proposal is way late in the game when it comes to VHDL200X, but presumably there will be a VHDL201X...I retire in VHDL202X so it would be nice to have it by that point.

Kevin Jennings, P.E.  |  Image & Recognition Hardware |  Payment Systems Engineering & Support

Unisys  |  41100 Plymouth Rd  |  Plymouth MI  48170-1892  |  734-737-4268

THIS COMMUNICATION MAY CONTAIN CONFIDENTIAL AND/OR OTHERWISE PROPRIETARY MATERIAL and is thus for use only by the intended recipient. If you received this in error, please contact the sender and delete the e-mail and its attachments from all computers


> -----Original Message-----
> From: Chuck Swart - MTI [mailto:cswart@model.com]
> Sent: Wednesday, June 18, 2008 8:18 PM
> To: Jennings, Kevin F
> Subject: Recently submitted VHDL Issue
>
> Hello Kevin:
>
> We have received the Issue Report you have submitted and assigned it
> number
> 2132. You can find it on the same website you used to submit the report.
>
> We probably won't look at it seriously until VHDL200X goes out the door,
> but we expect that to happen within a couple of months.
>
> One thing that I would like you to think about in this request:
> I often see the various signed/unsigned operations used in much more
> complicated expressions that simple signal assignments.
> For example, you might have something like:
>
> X <= to_unsigned(1)+Y;
>
> How do we determine the size of 1 in this expression?
> If we don't automatically determine size information, then the
> utility of your request is pretty limited, but if we have to pass
> size information up and down the expression tree that will make expression
> evaluation much more complicated.  These are the kinds of questions we
> deal with when considering new features.
>
> Chuck Swart
> Chair, ISAC
>
Received on Thu Jun 26 13:54:37 2008

This archive was generated by hypermail 2.1.8 : Thu Jun 26 2008 - 13:54:38 PDT