What is the purpose of the `std_logic` enumerated type in VHDL?
题
What is the purpose of the std_logic
enumerated type?
'U': uninitialized. This signal hasn't been set yet.
'X': unknown. Impossible to determine this value/result.
'0': logic 0
'1': logic 1
'Z': High Impedance
'W': Weak signal, can't tell if it should be 0 or 1.
'L': Weak signal that should probably go to 0
'H': Weak signal that should probably go to 1
'-': Don't care.
解决方案
std_logic is basically a single wire or bit. You can use logical operators (and, or, xor, etc.) on them. When simulating a design I believe I have only seen 'X', '0', or '1'. Obviously you want '0' or '1'. An 'X' indicates that the value is unknown (possibly not connected to anything or there is a glitch in the signal). Also, std_logic_vector can be used for signals that need to be more than 1 bit wide. I'm not sure if this answers your question...
其他提示
- 'X' usually is caused by two statements driving the same signal in opposite directions,i.e., '0' and '1'
- 'Z' is used to build a tri stated output/input
- 'L' and 'H' are used to model a pulldown or pullup respectively
- '-' is used in comparisons when you don't care about certain bits in a vector
The std_logic
type was introduced by the IEEE-1164 standard as an accurate representative of a single wire or bit. The VHDL language itself does not provide a single-bit type that is robust enough to represent "real" logic. That is, to represent all the possible states of modelable and synthesizable logic in a modern programmable logic device.
Early in the history of VHDL, different developers were essentially authoring their own versions of std_logic
out of the need to represent real-world signals. IEEE-1164 introduced this standardized logic type in an effort to enhance interoperability of code written by different developers for different architectures.
The wikipedia article for the standard provides a succinct description:
In addition to the answers that have already been provided, I think that it is worth mentioning that STD_LOGIC is what is called a resolved type, that means that there is a priority to the signal. For example, 1 and 0 have a higher priority to H or L so if a signal was driven with an L and a 1 simultaneously, the output would be high (logic 1) because 1 has a higher priority than L.
It just so happens that the order you have listed the values in, in your question is the order of the priority, the one caveat is that some values have equal priority and so if you drive them with both of those signals there is no clear "winner" so the result is the next "unknown" state ('X' or 'W') up the hierarchy, a simple example is if a signal is driven with an 'H' and an 'L', the result will be 'W'.
The resolution table for STD_LOGIC looks something like this:
-- ---------------------------------------------------------
-- | U X 0 1 Z W L H - | |
-- ---------------------------------------------------------
( 'U', 'U', 'U', 'U', 'U', 'U', 'U', 'U', 'U' ), -- | U |
( 'U', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X' ), -- | X |
( 'U', 'X', '0', 'X', '0', '0', '0', '0', 'X' ), -- | 0 |
( 'U', 'X', 'X', '1', '1', '1', '1', '1', 'X' ), -- | 1 |
( 'U', 'X', '0', '1', 'Z', 'W', 'L', 'H', 'X' ), -- | Z |
( 'U', 'X', '0', '1', 'W', 'W', 'W', 'W', 'X' ), -- | W |
( 'U', 'X', '0', '1', 'L', 'W', 'L', 'W', 'X' ), -- | L |
( 'U', 'X', '0', '1', 'H', 'W', 'W', 'H', 'X' ), -- | H |
( 'U', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X' ) -- | - |
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://electronics.stackexchange.com/questions/51848/when-to-use-std-logic-over-bit-in-vhdl
I've observed this behavior in Xilinx's simulator ISim:
- 'U' - is the default state of all signals that are not explicitly set with a default value. I recommend setting a default value for every signal.
- 'X' - is assigned when the signal is driven by two or more drivers with different values
- 'Z' - is the explicitly high Z state. Keep in mind this can only be realized in hardware with elements that support tri-state. I recommend using this for IO pins only, since these resources are rare in the fabric.
- '0' and '1' are the normal states.
- I've never seen any of the other states, and I don't expect them to apply to FPGAs.
It's not possible to examine variables in ISim, but I assume the same rules apply.