> 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