Using Standard Logic

(from VHDL Made Easy!)


In this chapter, we'll take a close look at two important standards that augment Standard 1076, adding important capabilities for both simulation and synthesis. These two standards are IEEE Standards 1164 and 1076.3.

IEEE Standard 1164

IEEE Standard 1164 was released in the late 1980s, and helped to overcome an important limitation of VHDL and its various commercial implementations. These limitations were created by the fact that VHDL, while being rich in data types, did not include a standard type that would allow multiple values (high-impedance, unknown, etc.) to be represented for a wire. These metalogic values are important for accurate simulation, so VHDL simulation vendors were forced to invent their own proprietary data types using syntactically correct, but non-standard, enumerated types.

IEEE 1164 replaces these proprietary data types (which include systems having four, seven, or even thirteen unique values) with a standard data type having nine values, as shown below:

ValueDescription
'U'Uninitialized
'X'Unknown
'0'Logic 0 (driven)
'1'Logic 1 (driven)
'Z'High impedance
'W'Weak 1
'L'Logic 0 (read)
'H'Logic 1 (read)
'-'Don't-care

These nine values make it possible to accurately model the behavior of a digital circuit during simulation. For synthesis users, the standard has additional benefits for describing circuits that involve output enables, as well as for specifying don't-care logic that can be used to optimize the combinational logic requirements of a circuit.

Advantages of IEEE 1164

There are many compelling reasons to adopt IEEE Standard 1164 for all of your design efforts and to use it as a standard data type for all system interfaces. For simulation purposes, the standard logic data types allow you to apply values other than `0' or `1' as inputs and view the results. This capability could be used, for example, to verify that an input with an unknown (uninitialized or don't-care) value does not cause the circuit to behave in an unexpected manner. The resolved standard logic data types can be used to model the behavior of multiple drivers in your circuit. You might use these types to model, for example, the behavior of a three-state bus driver.

The most important reason to use standard logic data types is portability: if you will be interfacing to other components during simulation (such as those obtained from third party simulation model providers) or moving your design description between different simulation environments, then IEEE 1164 gives you a standard, portable style with which to describe your circuit.

Using The Standard Logic Package

To use the IEEE 1164 standard logic data types, you will need to add at least two statements to your VHDL source files. These statements (shown below) cause the IEEE 1164 standard library (named ieee) to be loaded and its contents (the std_logic_1164 package) made visible:

library ieee;

use ieee.std_logic_1164.all;

In most design descriptions, you will place these two statements at the top of your source file, and repeat them as needed prior to subsequent design units (entity and architecture pairs) in the file. If your source file includes more than one design unit, you need to repeat the use statement just prior to each design unit in order to make the contents of the standard library visible to each design unit, as shown below:

library ieee;

use ieee.std_logic_1164.all;

package my_package is

    . . .

end my_package;



use ieee.std_logic_1164.all;

entity first_one is

    . . .

end first_one;

use ieee.std_logic_1164.all;

architecture structure of first_one is

    . . .

end structure;



use ieee.std_logic_1164.all;

entity second_one is

    . . .

end second_one;

Note:

VHDL has special visibility rules for architectures: it is not necessary to place a use statement prior to an architecture declaration if the corresponding entity declaration includes a use statement. In the above example, the use statement appearing prior to the architecture structure is not actually needed and could be omitted.

Once you have included the ieee library and made the std_logic_1164 package visible in your design description, you can make use of the data types, operators and functions provided for you as a part of the standard.

There are two fundamental data types provided for you in the std_logic_1164 package. These data types, std_logic and std_ulogic, are enumerated types defined with nine symbolic (single character) values. The following definition of std_ulogic is taken directly from the IEEE 1164 standard:

type std_ulogic is ( 'U',  -- Uninitialized

                     'X',  -- Forcing  Unknown

                     '0',  -- Forcing  0

                     '1',  -- Forcing  1

                     'Z',  -- High Impedance   

                     'W',  -- Weak     Unknown

                     'L',  -- Weak     0       

                     'H',  -- Weak     1       

                     '-'   -- Don't care

                        );

The std_ulogic data type is an unresolved type, meaning that it is illegal for two values (such as '0' and '1', or '1' and 'Z') to be simultaneously driven onto a signal of type std_ulogic. If you are not describing a circuit that will be driving different values onto a wire (as you might in the case of a bus interface), then you might want to use the std_ulogic data type to help catch errors (such as incorrectly specified, overlapping combinational logic) in your design description. If you are describing a circuit that involves multiple values being driven onto a wire, then you will need to use the type std_logic. Std_logic is a resolved type based on std_ulogic. Resolved types are declared with resolution functions, as described in Chapter 3, Exploring Objects & Data Types. Resolution functions define the resulting behavior when an object is driven with multiple values simultaneously.

When using either of these data types, you will use them as one-for-one replacements for the built-in type bit. The following example shows how you might use the std_logic data type to describe a simple NAND gate coupled to an output enable:

library ieee;

use ieee.std_logic_1164.all;

entity nandgate is

    port (A, B, OE: in std_logic; Y: out std_logic);

end nandgate;



architecture arch1 of nandgate is

    signal n: std_logic;

begin

    n <= not (A and B);

    Y <= n when OE = '0' else 'Z';

end arch1;

Note:

As written, it is not actually necessary for this circuit to be described using the resolved type std_logic for correct simulation. Operated as a stand-alone circuit, the output Y will never be driven with two different values. When connected through hierarchy into a larger circuit, however, it is highly likely that such a situation will occur, and std_logic will thus be required.


Next, VHDL Made Easy! discusses std_logic_vector and std_ulogic_vector. Examples abound as you learn how to leverage powerful standard logic functions. This chapter also covers type conversion, standard logic data types, standard logic operators, strength stripping functions, edge detection functions, numeric data types, and more! Why wait? Click below to order your copy of VHDL Made Easy!


[How to order VHDL Made Easy!]