When to use STD_LOGIC over BIT in VHDL
Bit
is a predefined type and only can only have the value 0
or 1
. The Bit
type is an idealized value.
type Bit is ('0', '1');
std_logic
is part of the std_logic_1164
package and provides more realistic modeling of signals within a digital system. It is capable of having nine different values. Typically within your code you will only use 0
, 1
, and Z
(High-Z). But U
(Uninitialized) and X
(Unknown) are also very useful when modeling the system in a testbench.
-------------------------------------------------------------------
-- logic state system (unresolved)
-------------------------------------------------------------------
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
);
-- attribute ENUM_ENCODING of std_ulogic : type is "U D 0 1 Z D 0 1 D";
-------------------------------------------------------------------
-- *** industry standard logic type ***
-------------------------------------------------------------------
SUBTYPE std_logic IS resolved std_ulogic;
The std_logic_1164
package also provides conversion functions to convert std_logic
to Bit
.
Most people use std_logic
. That allows for u
(undefined), x
(unknown) and z
(high impedance), which bit doesn't. While you may never tristate in a chip and therefore don't need z
, u
is useful for finding missing resets. x
is useful for finding multiple drivers.
std_logic
has a resolution function
Not only does std_logic
have more useful states besides 1
and 0
, it also has a resolution function defined.
A resolution function is a VHDL language concept. It is a function that is associated to a type, and it determines what happens when multiple values of that type are applied to a single signal. The syntax is:
SUBTYPE std_logic IS resolved std_ulogic;
where std_ulogic
is the unresolved (and thus much less useful) version of std_logic
.
In particular, this implies nice things like 0
and 1
leads to X
:
library ieee;
use ieee.std_logic_1164.all;
entity std_logic_tb is
end std_logic_tb;
architecture behav of std_logic_tb is
signal s0 : std_logic;
begin
s0 <= '0';
s0 <= '1';
process
begin
wait for 1 ns;
assert s0 = 'X';
wait;
end process;
end behav;
This makes intuitive sense, as we understand X
to be the state where multiple incompatible values are applied to a single wire.
std_logic
also knows how to resolve every other possible pair of input signals according to a table present on the LRM.
bit
on the other hand, does not have a resolution function, and if we had used it on the above example, it would lead to a simulation error on GHDL 0.34.
The possible values of std_logic
are a good choice because they are standardized by IEEE 1164 and deal with many common use cases.
Related: https://stackoverflow.com/questions/12504884/what-is-the-purpose-of-the-std-logic-enumerated-type-in-vhdl