VHDL · Chapter 2.3 · Data Types
std_logic vs bit and boolean
Beginners meet standard logic, bit, and boolean and assume they are three names for the same idea. They are not, and strong typing means VHDL will not let you mix them. Standard logic is the nine-value type you wire signals with, bit is an abstract two-value type with no notion of high-impedance or unknown, and boolean is true or false and is what every comparison produces. The one that trips everyone is that a comparison result is a boolean, not a one-bit signal, so it cannot be assigned to a wire without converting. This lesson pins down each type's value set and hardware meaning, shows why that assignment fails, and gives the simple rule for which type to reach for in each situation.
Foundation12 min readVHDLstd_logicbitbooleanTypesStrong Typing
1. Intuition — a wire, an abstraction, and a question
The three types answer three different questions:
std_logic— what is this physical wire doing? Nine values, because a real wire can be driven, released, pulled, or fought over (lesson 2.2).bit— what is this logic value, ideally? Two values,'0'and'1', with no notion of high-Z, unknown, or uninitialised. A clean abstraction with no electrical realism.boolean— is this condition true? Two values,trueandfalse. It is not a wire at all; it is the answer to a yes/no question, and it is exactly what a comparison likea = '1'returns.
They look similar — two of them even have two values — but they model different things, and VHDL's strong typing keeps them strictly apart.
2. The three types at a glance
| Type | Values | What it models | Use it for |
|---|---|---|---|
std_logic | 0 1 Z X U W L H - (9) | a real wire, with strength | signals, ports, all RTL |
bit | 0 1 (2) | abstract logic, no faults | teaching / pure-logic models |
boolean | true false (2) | a condition's answer | if/when tests, generics, assertions |
std_logic and bit are both enumeration types whose values are bit-like, so both can
drive hardware — but bit cannot represent Z, X, or U, so it cannot model tri-state,
contention, or "never driven." boolean is also an enumeration type, but its values are
true/false: it is the type of a test result, not of a wire.
3. Where each belongs — a compatibility map
The types do not flow into each other freely. This map shows what each is for and the one boundary that needs a conversion:
There is no waveform on this page on purpose: choosing a type is a modelling decision, not a timing one. The three types differ in what values they can represent and where they are legal — not in how a signal moves over time — so a comparison map, not a waveform, is the artifact that teaches it.
4. boolean is produced by comparisons — and it gates logic
You rarely declare a boolean signal; you generate booleans by comparing things, and
feed them to if, when, and assertions:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
-- `en = '1'` and `count = 0` are BOOLEAN expressions (true/false),
-- not std_logic values:
process (clk)
begin
if rising_edge(clk) then
if en = '1' then -- boolean test gates the load
q <= d;
end if;
end if;
end process;
is_zero <= '1' when count = 0 else '0'; -- boolean (count = 0) selects a std_logicNote the second line: count = 0 is a boolean, but is_zero is a std_logic, so the
when ... else chooses a std_logic ('1' or '0') based on the boolean. You convert
between the two worlds by selecting a wire value from a condition — never by assigning a
boolean to a wire directly.
5. Debugging example — "cannot assign boolean to std_logic"
The classic first-week error comes from forgetting boolean is not a wire:
signal a, b, y : std_logic;
-- y <= (a = b); -- error: (a = b) is BOOLEAN, y is STD_LOGIC
y <= '1' when a = b else '0'; -- select a std_logic from the boolean conditionThe message ("expression of type boolean does not match type std_logic of target") is
telling you that a = b answered a question (true/false), but y is a wire that
needs '1'/'0'. The fix turns the boolean into a wire value with when ... else. The
mirror-image mistake is if a then ... when a is std_logic — also illegal, because
if wants a boolean; write if a = '1' then.
6. Common mistakes & what to watch for
if a thenfor a std_logica. Illegal —ifneeds aboolean. Writeif a = '1' then.- Assigning a comparison to a wire.
y <= (a = b);mixes boolean and std_logic; usey <= '1' when a = b else '0';. - Using
bitfor real signals.bitcannot showZ,X, orU, so it hides tri-state, contention, and missing-reset bugs. Usestd_logicfor anything that is a real wire. - Thinking
booleanis a one-bit port type. It is a condition type; ports and buses arestd_logic/std_logic_vector, notboolean.
7. Engineering insight
Keeping these three straight is the everyday face of strong typing. The rule is short:
std_logic for wires, boolean for conditions, bit almost never. Comparisons and
logic tests live in the boolean world; signals and ports live in the std_logic world; you
cross between them deliberately with when ... else or an explicit test. Internalising that
boundary removes the single most common category of beginner type errors — and makes the
compiler's messages read like helpful hints instead of obstacles.
8. Summary & next step
std_logic, bit, and boolean are three distinct scalar types: std_logic is the
nine-value wire type for all RTL, bit is an abstract two-value type with no fault states,
and boolean is the true/false type that comparisons produce and conditions consume.
Strong typing keeps them apart, so you cross from a condition to a wire with when ... else,
never by implicit assignment.
So far the chapter has stayed on single, scalar wires. Real designs carry buses — many
wires at once. The chapter continues into std_logic_vector and the composite types that
group scalars into the structured data RTL actually moves around.