Objectives
After completing this module, you will be able to:
•
Declare ports and signals using appropriate data types
•
List possible values for each data type
•
Declare scalar and composite data types
–
array and records
•
Declare one-dimensional and two-dimensional arrays
•
Declare and use VHDL subtypes
Data Types
•
The wide range of available data types provides flexibility in hardware
modeling and built-in error checking to ensure signal compatibility in
large, complex models
–
Type checking rules must be obeyed in behavioral and gate-level models
•
Data types are very important in VHDL
–
A given data type allows only values within its range to be applied
–
Each object (signal, variable, constant, or port) must have its type
defined when declared
•
VHDL is a strongly typed language
–
Connected signals must be of the same type
entity REG_4 is
port ( D_IN1 : in std_logic_vector (3 downto 0);
CNTRL : in std_logic_vector (1 downto 0);
CLK, RST : in std_logic;
Q : out std_logic_vector (3 downto 0));
end entity REG_4;
signal A : integer ;
signal B : bit ;
signal C : integer ;
signal D : std_logic ;
A <= C;
A <= C + 1;
A <= B;
D <= C;
B <= D;
Q <= CNTRL;
Signals and Ports
•
Data type and width must match on signal and port assignments
GOOD
GOOD
ERRO
R
ERRO
R
ERRO
R
ERRO
R
type bit is (‘0’, ‘1’) ;
type boolean is (false, true) ;
architecture BEHAVE of MUX is
signal A,B,SEL, Z : bit ;
begin
if SEL = ‘1’ then
Z <= A ;
else
Z <= B ;
end if . . .
if Sel =‘1’, if F >= G
both yield boolean result
Bit and Boolean
•
Concise for modeling hardware, but it does not model high-impedance,
unknown, or don’t care, for example
•
Useful for modeling at a more abstract level
Integer and Real
•
Allows for flexible, intuitive quantities and values
–
It is essential to specify the range of any integer; otherwise, the default is a
minimum 32-bit implementation
•
Allows you to use floating point values
–
Declare reals with the intended range of real values
–
Real values are not synthesizable
type integer is range . . .
type real is range . . .
signal A : integer range 0 to 7;
signal B : integer range 15 downto 0 ;
type CAPACITY is range -25.0 to 25.0 ;
signal SIG_1 : CAPACITY := 3.0 ;
type std_ulogic is ( ‘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
) ;
Recall: type bit is
limited to (‘0’, ‘1’)
Std_logic and Std_ulogic
•
Std_logic was developed from the Multi-Value Logic (MVL) system and
provides for more detailed hardware modeling than bit
–
Supports different signal strengths, don't-care conditions, and 3-state
drivers
–
Defined in package std_logic_1164
Std_logic versus Std_ulogic
•
Both contain the same set of possible values
–
The difference is in implementation
–
The u in ulogic means unresolved
•
If you wish to drive two or more signals to a common output of type
std_logic, use a resolution function (provided in ieee_std_1164 package) to
indicate which driver is actually applied to the output
•
Std_ulogic offers no such capability, but it does provide a built-in means of
error checking for inadvertent wire-oring
signal A,B,C,RES_OUT : std_logic ;
signal OUT_1 : std_ulogic ;
OUT_1 <= A ;
OUT_1 <= B ;
OUT_1 <= C ;
C
B
A
OUT_1
C
B
A
RES_OUT <= A;
RES_OUT <= B;
RES_OUT <= C;
RES_OUT
E
R
R
O
R
G
O
O
D
signal A,B,C, RES_OUT : std_logic ;
C
B
A
RES_OUT <= A when EN0 = ‘1’ else ‘Z’ ;
RES_OUT <= B when EN1 = ‘1’ else ‘Z’ ;
RES_OUT <= C when EN2 = ‘1’ else ‘Z’ ;
RES_OUT
EN0
EN2
EN1
Signal Resolution
•
A given output may not have multiple wire-or drivers
–
To model a 3-state output, use a conditional signal assignment and data
type std_logic
G
O
O
D
Composite Data Types
•
Composite data types are groups of elements in the form of an array or
record
–
Bit_vector, Std_logic_vector, and String are all pre-defined composite types
•
This creates four elements of type bit grouped together in an array
–
There is no pre-defined LSB or MSB interpretation; therefore, this value is
not automatically read by the compiler as ‘3’
Note the use of double quotes (“0011”) for any bit_vector, std_logic_vector,
or string object and the use of single quotes (‘1’) for bit, std_logic, and
character
signal A_WORD : bit_vector (3 downto 0) := “0011” ;
Arrays
•
Arrays are groups of elements, all of the same type
type WORD is array (3 downto 0) of std_logic ;
index position
0123
B_BUS
What are the
possible
values for
each element
of the array
in each case?
signal B_BUS : WORD ;
type DATA is array (3 downto 0) of integer range 0 to 9 ;
signal B_BUS : DATA ;
signal BUS_A, BUS_B: std_logic_vector (3 downto 0) ;
signal BUS_C : std_logic_vector (0 to 3) ;
3 012
3 012
BUS_A
BUS_B
BUS_B <= BUS_A ;
BUS_A
3 012
0 321
BUS_C
Inadvertent bit-swap?
BUS_C <= BUS_A ;
Array Assignments
•
When assigning one array to another:
–
1. The arrays must be the same type
–
2. The arrays must be the same length
–
3. The assignment is positional, from left to right
signal DATA_WORD : std_logic_vector (11 downto 0) ;
Array Assignment Notation
•
To simplify array assignments—and enhance readability—you can
designate a hexadecimal or octal base
–
Underscores can also be used to further enhance readability
DATA_WORD <= X“A6F”;
DATA_WORD <= “101001101111” ;
DATA_WORD <= O“5157”;
DATA_WORD <= B“1010_0110_1111” ;
Creating 2-D Arrays
•
When modeling memory structures, it is necessary to create a
two-dimensional array structure
–
This is effectively an array of arrays (or records)
type MEM_ARRAY is array (0 to 3) of std_logic_vector (7 downto 0);
signal MY_MEM : MEM_ARRAY ;
7 6 5 4 3 2 1 0
0
1
2
3
Assigning to 2-D Arrays
•
For most memory applications, the Read and Write address vector is
converted to integer, referencing an element within the 2-D array
- The conv_integer function is located in the ieee.std_logic_unsigned package
type MEM_ARRAY is array ( 0 to 3 ) of std_logic_vector ( 7 downto 0 );
signal MY_MEM : MEM_ARRAY ;
signal R_ADDR, W_ADDR : std_logic_vector (1 downto 0 ) ;
7 6 5 4 3 2 1 0
0
1
2
3
MY_MEM (conv_integer( W_ADDR)) <= DATA_IN ;
. . .
D_OUT <= MY_MEM (conv_integer ( R_ADDR));
Initializing a ROM Array
•
For ROM applications, an aggregate is a convenient means for initializing
the 2-D array
type ROM_ARRAY is array ( 0 to 3 ) of std_logic_vector ( 7 downto 0);
constant MY_ROM : ROM_ARRAY := continued below
7 6 5 4 3 2 1 0
0
1
2
3
constant MY_ROM : ROM_ARRAY := (
0 => (others => ‘1’) ,
1 => “10100010”,
2 => “00001111”,
3 => “11110000” ) ;
Summary
•
Each object and port must have its type defined
•
VHDL provides scalar and composite data types
•
Enumerated types can be used to enhance code readability
•
A two-dimensional array can be created to model memory structures
•
VHDL subtypes are constrained versions of existing types
•
Aggregate assignments can be made for arrays and records
•
Types on connecting signals must match