[vhdl-200x] Proposal for improved physical types

From: Kevin Thibedeau <kevin.thibedeau@gmail.com>
Date: Thu Jan 08 2015 - 13:41:32 PST
The current implementation of user defined physical types in VHDL is tied
to the implementation of integer which is a problem with most tools only
supporting 32-bit integers. The 31-bit positive range of the typical
integer only covers nine orders of magnitude or three SI prefixes. This
severely restricts the practicality of user defined physical types. The
built-in time type is typically implemented as a 64-bit integer, covering a
much more useful eighteen orders of magnitude.

I would like to propose a system where a new integral subtype "physical" is
provided that is guaranteed to cover the same range as the built-in time
type. It would be restricted to use only in definitions of physical types
to eliminate problems with using it directly as a separate integral type in
other contexts.

    -- Implicit subtype to be defined in std.standard
    subtype physical is $UNIVERSAL_INTEGER
        range time'pos(time'low) to time'pos(time'high);


While VHDL permits larger integers, at this point many tool vendors are
retrenched in their restriction to 32-bit implementations. It seems
unlikely that this status quo will ever change due to concerns about
backward compatibility. Such a situation doesn't exist for physical types
which, in general, have seen limited use. The machinery for handling 64-bit
time already exists in most, if not all, current tools so it would not be
an undue burden to extend that to other physical types. All of the implicit
operators would work as they do with time. By implementing this through a
new special purpose subtype, existing code using integer as the basis for
physical types will be unaffected.


With today's tools one must compromise between precision and maximum range
when defining a physical type:

    -- Definition of a "frequency" physical type using today's tools
    type frequency is range 0 to integer'high units
      Hz;
      kHz = 1000 Hz;
      MHz = 1000 kHz;
      GHz = 1000 MHz; -- Usually limited to 2**31 = 2.1 GHz
    end units;

We can make the primary unit kHz to extend the range while sacrificing the
ability to represent low frequencies:

    type frequency is range 0 to integer'high units
      kHz;
      MHz = 1000 kHz;
      GHz = 1000 MHz;
      THz = 1000 GHz; -- Now support up to 2.1 THz
    end units;

It would be nice to have support for mHz or better precision for more
accurate representation of fractional frequencies. Using current
implementations, though, a primary unit of mHz would limit the maximum
frequency to 2.1 MHz which is too low for many practical uses of a
frequency type.

With a 64-bit integer for physical types we can define a more useful
frequency type that permits large values as well as accurately representing
fractional frequencies:

    -- Implicit subtype to be defined in std.standard
    subtype physical is $UNIVERSAL_INTEGER
        range time'pos(time'low) to time'pos(time'high);

    type frequency is range 0 to physical'high units
      uHz;
      milliHz = 1000 uHz;
      Hz  = 1000 milliHz;
      kHz = 1000 Hz;
      MHz = 1000 kHz;
      GHz = 1000 MHz;
      THz = 1000 GHz; -- Up to 9.2 THz with a 63-bit positive range
    end units;

    -- Using "physical" elsewhere is prohibited
    variable not_allowed : physical;
    type invalid_array is array(physical'range) of bit;


Having special rules for when a type can be used subverts the purity of the
type system but I think it is a reasonably pragmatic solution in light of
the benefits it would provide.

--
Kevin Thibedeau

-- 
This message has been scanned for viruses and
dangerous content by MailScanner, and is
believed to be clean.
Received on Thu Jan 8 13:41:48 2015

This archive was generated by hypermail 2.1.8 : Thu Jan 08 2015 - 13:42:30 PST