VHDL · Chapter 1.8 · Foundation
The std_logic_1164 Package
Almost every VHDL file imports the standard logic package on its first line, and this lesson is what that line buys you. The standard logic type represents a single wire, and unlike a plain bit it carries nine values instead of two, so it can model the things real hardware actually does: tri-state buses, driver contention, uninitialised power-up, and weak pull-ups. You will learn what each value means in hardware, why this is a resolved type and why that is what makes buses possible, and what the package provides beyond the type itself. Understanding these values is what lets your design represent and detect the situations that actually go wrong on real wires, which a two-value type simply cannot describe.
Foundation14 min readVHDLstd_logicstd_logic_vectorTri-stateResolutionTypes
1. Intuition — a real wire is more than 0 and 1
If a wire could only ever be 0 or 1, a two-value type would be enough. But real
wires do more: they can be left undriven (floating), fought over by two drivers,
not yet powered up, or driven weakly through a pull-up resistor. A type that only
knows 0 and 1 cannot describe any of that — and so cannot model real hardware or warn
you when something is wrong.
std_logic is VHDL's answer: a single-bit type with nine possible values, chosen so
that the situations a digital wire can actually be in each have a name. That is why it,
not bit, is the type you use for essentially every signal in a real design.
2. The nine values
| Value | Name | Hardware meaning |
|---|---|---|
'0' | Forcing 0 | strongly driven low (GND) |
'1' | Forcing 1 | strongly driven high (VDD) |
'Z' | High impedance | not driven — tri-state / released bus |
'X' | Forcing unknown | conflict or unknown — cannot tell 0 or 1 |
'U' | Uninitialised | never assigned yet (every signal's start value) |
'W' | Weak unknown | weak conflict |
'L' | Weak 0 | weakly pulled low (pull-down) |
'H' | Weak 1 | weakly pulled high (pull-up) |
'-' | Don't care | value is irrelevant (synthesis optimisation / matching) |
The three you will meet constantly are '0'/'1' (normal logic), 'Z'
(a driver that has let go of the wire), and 'X' (something is wrong — two drivers
disagree, or a value is genuinely unknown). 'U' is what every signal is before it
is first assigned, so seeing 'U' in a waveform usually means "you forgot to drive or
reset this." The weak values ('L'/'H'/'W') model resistive pulls; '-' is a
designer's "I don't care" for optimisation and case matching.
3. std_logic_vector — buses of std_logic
A bus is just many std_logic wires bundled together — that is std_logic_vector:
library ieee;
use ieee.std_logic_1164.all;
signal byte_bus : std_logic_vector(7 downto 0); -- 8 wires, each a std_logic
signal one_bit : std_logic; -- a single wireEach element of the vector is a full nine-valued std_logic, so a bus can carry normal
data, be released to 'Z' element-by-element, or show 'X' on exactly the bits that are
in conflict. std_logic and std_logic_vector are the two types almost all RTL is
written in.
4. Resolution — why std_logic can model a bus
Here is the deep reason nine values matter: std_logic is a resolved type. If two
parts of a design drive the same signal, VHDL does not pick "the last one" — it runs a
resolution function that combines the drivers into a single value. That is precisely
how real wired buses behave, and it is why std_logic (not bit) can model them:
A tri-state driver is written by choosing between a value and 'Z':
-- drive the bus when enabled, otherwise let go (high-impedance)
bus_line <= data_out when enable = '1' else 'Z';When every driver on the bus releases to 'Z' except one, resolution yields that one
driver's value. If two drive opposite values at once, resolution yields 'X' — and now
you can see the contention instead of getting a silent wrong answer.
5. The nine values over time
A waveform makes std_logic's extra states concrete in a way bit never could — watch a
single bus wire move through uninitialised, driven, released, and contended:
One std_logic wire: U (power-up) → driven 0/1 → Z (released) → X (contention)
6 cycles6. What the package gives you
std_logic_1164 is more than the type. Importing it with
use ieee.std_logic_1164.all; brings in:
- the
std_logicandstd_logic_vectortypes (and their resolution), - the logic operators (
and,or,not,xor, …) defined over them, - edge detectors
rising_edge()andfalling_edge()used in every clocked process, - conversions between
std_logic/std_ulogicand related helpers.
That is why the package is the one line at the top of nearly every file: without it, the
type your whole design is written in does not exist. (Arithmetic on vectors is a separate
package — numeric_std — covered with the libraries lesson.)
7. Common mistakes & what to watch for
- Using
bitfor real signals. It cannot expressZ,X, orU, so it hides the very faults you need to see. Usestd_logic. - Seeing
'U'and ignoring it.'U'means never driven/reset — almost always a missing reset or an unconnected signal, not a harmless default. - Treating
'X'as random.'X'is a signal of a problem — usually contention or an uninitialised value propagating. Trace it; do not mask it. - Reaching for tri-state (
'Z') internally. On-chip, tri-state belongs at true shared buses and pads; inside a block, use a multiplexer, not'Z'.
8. Summary & next step
std_logic is the standard single-wire type, and its nine values exist so VHDL can
model what real wires do: 0/1 for normal logic, Z for tri-state, X for contention
or unknown, U for uninitialised, and weak/don't-care states for pulls and
optimisation. Because it is a resolved type, multiple drivers combine through a
resolution function — which is what makes buses and contention representable, and is why
RTL uses std_logic/std_logic_vector rather than bit. The std_logic_1164 package
ships the type, its operators, and rising_edge/falling_edge.
You now have the foundations' core vocabulary — design units, entities, ports, libraries,
and the std_logic type. The next lesson steps up to how a tool actually turns these files
into a working design: compilation, elaboration, and the build flow.