# Notes on VHDL Integral Arithmetic

The LRM for 2008 and earlier puts no constraints on the precision of `integer`

or
`universal_integer`

, other than the width must be at least 32 bits. The 2019 LRM
mandates 64 bits of precision.

For maximum legacy code compatibility, we use 32-bit integers for VHDL2008 and earlier, and 64-bit integers for VHDL2019. This treatment applies only to integral types; physical types use 64-bit representation regardless of language version selected.

VHDL requires integral overflow checking. e.g. LRM2008 5.2.3.1: "The same arithmetic operators are predefined for all integer types (see 9.2). It is an error if the execution of such an operation (in particular, an implicit conversion) cannot deliver the correct result (that is, if the value corresponding to the mathematical result is not a value of the integer type)."

Integer overflow checking incurs some overhead, and many VHDL implementations do not
perform overflow checking for this reason. DSim does by default; this can be disabled
with the `-vhdl-no-ov-chk`

analysis and elaboration time option.

NOTE: Overflow checking is different from bounds checking. e.g.:

variable a,b,c: integer; b := 65536; c := 65536; a := b * c;

In this example, assuming 32-bit integers, the arithmetic result of multiplying 65536 by 65536
is `2**32`

. However, this is congruent to zero modulo `2**32`

. A range check will not fail here,
as the wrapped value zero is within the bounds of an integer. An overflow check *will* fail
here, as the represented result is not equal to the infinitely precise mathematical result.