> On 27 Jul 2016, at 7:29 pm, Patrick Lehmann <patrick.lehm...@tu-dresden.de> 
> wrote:
> 
> The languages doesn't forbid large integers, but must tools are restricted
> in handling such large literals/signals/variables. You could create your own
> "64 bit" integer:

It's safer to say that the language does not permit integer types with a range 
wider than the range of the widest integer defined by the implementation. (And 
that would be in package STANDARD).

> constant BITS : positive := 64;
> type long is range -2**(BITS-1)+1 to 2**(BITS-1) - 1;


-  2 ** ( BITS - 1 ) + 1

The "-" is the unary operator negation.

Left to right with "**", parentheses enclosing it's right operand.

The right operand is type INTEGER (POSITIVE is a subtype). 
The left operand is an abstract literal an integer literal (type 
universal_integer) the result type is the same as the left (IEEE Std 1076-2008 
9.2.8 Miscellaneous operators) and that's universal_integer.

Now for the kicker:

9.5 Universal expressions

A universal_expression is either an expression that delivers a result of type 
universal_integer or one that delivers a result of type universal_real.

 ...

For the evaluation of an operation of a universal expression, the following 
rules apply. If the result is of type universal_integer, then the values of the 
operands and the result shall lie within the range of the integer type with the 
widest range provided by the implementation, excluding type universal_integer 
itself. ...

 -- 

(And that means the result of the exponentiation operator shall lie within the 
range of the integer type INTEGER. 2 ** (64 - 1) is outside the range of type 
INTEGER.)

There's only one type in a VHDL with a 32 bit INTEGER that can have a value 
outside the range of INTEGER  and that's type TIME, a scalar type but not an 
integer type. You cannot use it's 'LEFT or 'RIGHT  or 'LOW and 'HIGH because 
the their values are same type as the prefix TIME. 

And no you can't use TIME'POS(T'RIGHT), it's a function that returns a 
universal_integer (an expression of type universal_integer) and is a is limited 
by 9.5 as well.

If you were to try the expression TIME'LEFT / 1 fs the result would be type 
universal_integer (See 9.2.7, the second table with physical type operands for 
"/"). That's limited by 9.5 as well.

Trying to express the bounds  with literals:

range -9223372036854775808 to 9223372036854775807 

An integer literal is an abstract literal (a numeric literal). It's value is 
realized by a basic operation (See 5.1).  It's an expression (9.1, primary - 
literal, 9.3.2 literal, numeric_literal).

And back to 5.1:

A type is characterized by a set of values and a set of operations. The set of 
operations of a type includes the explicitly declared subprograms that have a 
parameter or result of the type. The remaining operations of a type are the 
basic operations and the predefined operations (see 5.2.6, 5.3.2.4, 5.4.3, and 
5.5.2). ...
 --

So a basic operation is an operation of a type. And 5.2.3.1 

Integer literals are the literals of an anonymous predefined type that is 
called universal_integer in this standard. Other integer types have no 
literals. However, for each integer type there exists an implicit conversion 
that converts a value of type universal_integer into the corresponding value 
(if any) of the integer type (see 9.3.6).
 --

Which gets us back to our kicker in 9.5.

You can demonstrate this in ghdl with the above range:

 ghdl -a fum.vhdl
fum.vhdl:6:45: literal beyond integer bounds
ghdl: compilation error

Your long declaration gives:

ghdl -a fum.vhdl
fum.vhdl:4:26:warning: arithmetic overflow in static expression
fum.vhdl:4:43:warning: arithmetic overflow in static expression
fum.vhdl:4:36: overflow in left bound
fum.vhdl:4:54: overflow in right bound

And the source:
 --

package fum is
    constant BITS : positive := 64;
    type long is range -2**(BITS-1)+1 to 2**(BITS-1) - 1;
    
    -- type myint is range -9223372036854775808 to 9223372036854775807;
end package;
 --

(line 1 is empty).


You can't define an INTEGER with a width greater than type INTEGER (which is 
required to include the range –2147483647 to +2147483647. (5.2.3.2).

ghdl --disp-standard reports:

type integer is range -2147483648 to 2147483647;
 ...
type time is range -9223372036854775808 fs to 9223372036854775807 fs ...

The restriction is that you can't define an integer type outside the range of 
the largest integer type defined by the implementation, which is found in 
package STANDARD and is type INTEGER.

There is a bit about restricting the range of integer types comes from 5.2.3.1:

An implementation may restrict the bounds of the range constraint of integer 
types other than type universal_integer. However, an implementation shall allow 
the declaration of any integer type whose range is wholly contained within the 
bounds –2147483647 and +2147483647 inclusive.
 --

Unfortunately it's not the implementation that's restricting the bounds it's 
the kicker in 9.5. That "shall lie within" has mandatory weight:

1.3.1:

In this document, the word shall is used to indicate a mandatory requirement. 
The word should is used to indicate a recommendation. The word may is used to 
indicate a permissible action. The word can is used for statements of 
possibility and capability.

 --

That restriction is found in the -1987 revision (using "must" which had 
mandatory weight). The inclusion of basic operations as operation of a type was 
introduced in the -1993 revision, part of making VHDL an actual formal notation 
(at least for hardware descriptions).

And yes there are undoubtedly implementations that are not compliant but ghdl 
is not among them. I know of two personally, neither are synthesis tools which 
beggars the question of what value it would have (and why an implementation 
ignoring the restriction would generally only be of curiosity value). There is 
no portability in trying to rely on non-compliance with the standard. 

Relying on larger integers is also non-portable.  

Annex D:

The use of the following constructs may lead to nonportable VHDL descriptions:
 ...
—  Declarations of integer or physical types that have a secondary unit whose 
position number is outside of the range –(2**31–1) to 2**31–1
 --



_______________________________________________
Ghdl-discuss mailing list
Ghdl-discuss@gna.org
https://mail.gna.org/listinfo/ghdl-discuss

Reply via email to