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

Tags:

Vhdl