In VHDL (VHSIC Hardware Description Language), a data type is a name associated with a set of values and a set of operations. VHDL is a strongly typed language, meaning that connected data objects must be of the same type. This strict typing helps prevent errors and improves code reliability. Let’s explore the various data types in VHDL and their characteristics.
Scalar Data Types
Scalar data types in VHDL represent single values. These are the fundamental building blocks for more complex data structures.
- bit
- Takes values ‘0’ & ‘1’
- Deprecated: It’s recommended to use std_logic instead
- boolean
- Takes values True and False
- Often used in test benches and behavioural modelling
- Synthesizable
- std_logic
- Can have the following values (same as std_ulogic):
- ‘U’ Uninitialized
- ‘X’ Forcing Unknown
- ‘0’ Forcing zero
- ‘1’ Forcing one
- ‘Z’ High Impedance
- ‘W’ Weak unknown
- ‘L’ Weak zero
- ‘H’ Weak one
- ‘-‘ Don’t care
- Defined in the IEEE.std_logic_1164 package
- Is resolved, whereas std_ulogic is unresolved
- std_logic must be used for three-state signals
- Can have the following values (same as std_ulogic):
- integer
- Has the range of -2^31+1 to 2^31-1
- Comparisons are possible: <, >, >=, <=, =, /=
- real
- Allows use of floating-point values
- Has a range of approximately -1e38 to 1e38
- Generally not synthesizable
- character & string
- Are synthesizable
- Example: constant MY_CHAR : character := ‘Q’;
- Strings have fixed size once defined
- Example: constant MSG : string(1 to 10) := “setup time”;
- physical
- The only pre-defined physical type is time
- Generally not synthesizable
- Example: constant TPD : time := 3 ns;
- enumerated
- User-defined type with a list of possible values
- Example: type STATE_TYPE is (IDLE, ACTIVE, DONE);
U | X | 0 | 1 | z | w | L | H | - | ||
---|---|---|---|---|---|---|---|---|---|---|
uninitialized unknown | U | U | U | U | U | U | U | U | U | U |
forcing low | 0 | U | X | 0 | x | 0 | 0 | 0 | 0 | x |
forcing high | 1 | U | x | x | 1 | 1 | 1 | 1 | 1 | x |
high impedance | z | U | x | 0 | 1 | z | w | L | H | x |
weak unknown | w | U | x | 0 | 1 | w | w | w | w | x |
weak low | L | U | x | 0 | 1 | L | w | L | w | x |
weak high | H | U | x | 0 | 1 | H | w | w | H | x |
Don't Care | - | U | x | x | x | x | x | x | x | x |
Composite Data Types
Composite data types are constructed from scalar types and other composite types. The two main composite types in VHDL are arrays and records.
Arrays
Arrays are collections of elements of the same type. VHDL supports both one-dimensional and multi-dimensional arrays.
-- One-dimensional array type BYTE_ARRAY is array (0 to 7) of std_logic; -- Two-dimensional array type MEMORY is array (0 to 255, 0 to 7) of std_logic; -- Unconstrained array type VECTOR is array (natural range <>) of std_logic;
Records
Records allow grouping of related data of different types.
type REGISTER_TYPE is record DATA : std_logic_vector(7 downto 0); VALID : boolean; ID : integer range 0 to 15; end record;
Data Type Conversion
VHDL provides mechanisms for converting between different data types when necessary.
Casting
- Used to convert between std_logic_vector and signed/unsigned types
- Type cast between std_logic_vector and signed/unsigned can be used as long as the original and destination signals have the same bit width
signal ex1 : std_logic_vector(3 downto 0); signal ex2 : signed(3 downto 0); signal ex3 : unsigned(3 downto 0); ex2 <= signed(ex1); ex3 <= unsigned(ex1); ex1 <= std_logic_vector(ex2);
Conversion
- Used to convert between signed/unsigned and integer types
- Function from integer to signed/unsigned includes a specification of the intended bit width
signal ex1 : signed(3 downto 0); signal ex2 : integer; ex1 <= to_signed(ex2, ex1'length); ex2 <= to_integer(ex1);
Here’s a comprehensive conversion table for common VHDL data types:
From \ To | std_logic_vector | signed | unsigned | integer |
---|---|---|---|---|
std_logic_vector | – | signed() | unsigned() | to_integer(signed()) |
signed | std_logic_vector() | – | unsigned() | to_integer() |
unsigned | std_logic_vector() | signed() | – | to_integer() |
integer | std_logic_vector(to_unsigned()) | to_signed() | to_unsigned() | – |
Types & Subtypes
Types
- Type defines a set of values
- STD package defines a collection of types
- New types can be created using enumeration, arrays, records, etc.
type mem_array is array (integer range 0 to 1023) of std_logic_vector(15 downto 0); type color is (RED, GREEN, BLUE);
Subtypes
- Provide a mechanism for limiting the range of a type
- Used in simulation to do boundary checking
- Useful for specifying constraints on existing types
subtype is [range ]; subtype ROM_MEMORY_RANGE is integer range 0 to 255; subtype SMALL_INT is integer range -128 to 127;
Understanding and properly using VHDL data types is crucial for writing efficient, error-free, and synthesizable VHDL code. By leveraging the strong typing system of VHDL, designers can create more robust and reliable hardware descriptions.