courses:system_design:vhdl_language_and_syntax:extended_data_types:more

More

architecture EXAMPLE of AGGREGATE is
  type MONTH_NAME is (JAN, FEB, MAR,
                      APR, MAY, JUN,
                      JUL, AUG, SEP,
                      OCT, NOV, DEC);
  type DATE is record
    DAY   :   integer range 1 to 31;
    MONTH :   MONTH_NAME;
    YEAR  :   integer range 0 to 4000;
  end record;
 
 type PERSON is record
    NAME     : string (0 to 8);
    BIRTHDAY : DATE;
  end record;
 
  signal TODAY     : DATE;
  signal STUDENT_1 : PERSON;
  signal STUDENT_2 : PERSON;
begin
  TODAY     <= (26, JUL, 1988);
  STUDENT_1 <= ("Franziska", TODAY);
  STUDENT_2 <= STUDENT_1;
  STUDENT_2.BIRTHDAY.YEAR <= 1974;
end EXAMPLE;
  • Elements of different type
  • Possible assignments
    • record ⇐ record
    • record ⇐ aggregate
    • record.element ⇐ value

Notes

In contrast to array types, records admit different data types within the newly created structure.

Three choices exist for value assignments: The most obvious method is to assign one record to another (’STUDENT_2 ⇐ STUDENT_1’). This does not allow to set individual values, however. Again, aggregates are commonly used for this purpose, i.e. the different element values are grouped together (e.g. ’TODAY ⇐ (26, JUL, 1988)’). The single elements are addressed via RECORD.ELEMENT constructs, like ’STUDENT_2.BIRTHDAY.YEAR ⇐ 1974’. As can be seen, this syntax applies also to nested records.

architecture EXAMPLE of CONVERSION is
  type MY_BYTE is array (7 downto 0) of std_logic;
 
  signal VECTOR: std_logic_vector(7 downto 0);
  signal SOME_BITS : bit_vector(7 downto 0);
  signal BYTE      : MY_BYTE;
 
begin
 
  SOME_BITS <= VECTOR;                 -- wrong
  SOME_BITS <= Convert_to_Bit(VECTOR);
 
  BYTE <= VECTOR;                      -- wrong
  BYTE <= MY_BYTE(VECTOR);
 
end EXAMPLE;
  • Data types have to match for assignment
    • Type conversion functions
    • Type cast
  • Closely related types
    • integer ↔ real
    • Arrays with the same length, index set and element types

Notes

Matching data types are a strict language requirement in assignment operations. This can always be achieved via type conversion functions that have to be defined by the user for all necessary pairs of data types.

If the data types in question are so called “closely related”, the call of a conversion function can be replaced by a more simple type cast. ’integer’ and ’real’ are closely related, for example, i.e. the following code line represents legal VHDL: REAL_SIGNAL ⇐ real(INTEGER_SIGNAL);

The syntax is similar to a function call, except that the desired data type is used directly as prefix.

architecture EXAMPLE of SUBTYPES is
  type MY_WORD is array(15 downto 0) of std_logic;
  subtype SUB_WORD is std_logic_vector(15 downto 0);
 
  subtype MS_BYTE is integer range 15 downto 8;
  subtype LS_BYTE is integer range 7 downto 0;
 
  signal VECTOR : std_logic_vector(15 downto 0);
  signal SOME_BITS : bit_vector(15 downto 0);
  signal WORD_1 : MY_WORD;
  signal WORD_2 : SUB_WORD;
 
begin
  SOME_BITS <= VECTOR;                -- wrong
  SOME_BITS <= Convert_to_Bit(VECTOR);
 
  WORD_1 <= VECTOR;                   -- wrong
  WORD_1 <= MY_WORD(VECTOR);
 
  WORD_2 <= VECTOR;                 -- correct
 
 WORD_2(LS_BYTE) <= "11110000";
end EXAMPLE;
  • Subsets of existing types
  • Same type as the original type
  • More readable signal assignments
    • Eliminates type casts and type conversions
    • Symbolic names for array ranges

Notes

Arrays are also called closely related when they are built of the same data type for their elements and coincide in their length and index set. Consequently, type casts occur frequently when dealing with vector operations as bit vectors (’bit_vector’, ’std_(u)logic_vector’) themselves do not have a numerical interpretation associated with them. The arithmetic and relational operators for bit vectors operate with ’signed’ or ’unsigned’ data types that interprete the bit values as 2-complement (sign bit + absolute value) of an arbitrary integer number or binary representation of a positive integer value, respectively. These new data types are built of the same basic types (’bit’, ’std_logic’), i.e. whenever numerical operations are to be carried out with vectors, their interpretation is provided via the corresponding type cast expression. Of course, the type and operator definitions must be made available first (’use IEEE.numeric_bit/std.all’).

architecture EXAMPLE of ALIAS is
  signal DATA : bit_vector(9 downto 0);
 
  alias STARTBIT: bit is DATA(9);
  alias MESSAGE: bit_vector(6 downto 0) is
      DATA(8 downto 2);
 
  alias PARITY:   bit is DATA(1);
  alias STOPBIT:  bit is DATA(0);
  alias REVERSE:  bit_vector(1 to 10) is DATA;
 
 function CALC_PARITY(data: bit_vector)
      return bit is
     ...
 
begin
  STARTBIT    <=0;
  MESSAGE     <= "1100011";
  PARITY      <= CALC_PARITY(MESSAGE);
  REVERSE(10) <=1;
 
end EXAMPLE;
  • Given new names to already existing objects
  • Make it easier to handle complex data structures
Aliases are not always supported by synthesis tools

Notes

Instead of declaring a completely new data type it is possible to declare so called “subtypes”, if the new type that is required is just a somewhat restricted version of another type. Subtypes have the same type as their original type and are therefore compatible to the basic type without the need for type casts or conversion functions. Subtypes can also be used to create symbolic names for array ranges.

This is synthesizable alternative to the ’alias’ construct in VHDL. Aliases are used to give another name to already existing objects. This way it is possible to break down complex data structures into simpler parts that can be accessed directly.


Chapters of System Design > VHDL Language and Syntax > Extended Data Types