Skip to content

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_logicwhat is this physical wire doing? Nine values, because a real wire can be driven, released, pulled, or fought over (lesson 2.2).
  • bitwhat 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.
  • booleanis this condition true? Two values, true and false. It is not a wire at all; it is the answer to a yes/no question, and it is exactly what a comparison like a = '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

TypeValuesWhat it modelsUse it for
std_logic0 1 Z X U W L H - (9)a real wire, with strengthsignals, ports, all RTL
bit0 1 (2)abstract logic, no faultsteaching / pure-logic models
booleantrue false (2)a condition's answerif/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:

std_logic, bit, and boolean and where each is usedstd_logic9 values · the wirebit2 values · abstractbooleantrue / falsesignals & portsall RTL wiringpure-logic modelsno faults neededif / when · generics· assertconditions12
Three scalar types, three jobs. std_logic is the wire type — it carries signals and ports throughout RTL. bit is an abstract two-value type for pure-logic or teaching models. boolean is the condition type: relational operators (=, <, and conditions) PRODUCE boolean, which feeds if/when tests, generics, and assertions. The trap to avoid: a comparison yields boolean, but a wire needs std_logic, so crossing between 'is it true?' and 'what is on the wire?' requires an explicit conversion, never an implicit one.

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:

boolean_in_use.vhd
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
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_logic

Note 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:

the mistake and the fix
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
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 condition

The 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 then for a std_logic a. Illegal — if needs a boolean. Write if a = '1' then.
  • Assigning a comparison to a wire. y <= (a = b); mixes boolean and std_logic; use y <= '1' when a = b else '0';.
  • Using bit for real signals. bit cannot show Z, X, or U, so it hides tri-state, contention, and missing-reset bugs. Use std_logic for anything that is a real wire.
  • Thinking boolean is a one-bit port type. It is a condition type; ports and buses are std_logic / std_logic_vector, not boolean.

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.