Unit-V
COMBINATIONAL
LOGIC DESIGN
Three State Devices
The electrical design of CMOS and TTL devices whose outputs may be
in one of three states—0, 1, or Hi-Z.
Three-State Buffers
The most basic three-state
device is a three-state buffer, often called a three-state driver.
The logic symbols for four physically different three-state buffers are shown
in Figure 1.
Figure 1: Three state buffers (a) noninverting, active-high enable
(b) noninverting, active-low enable (c) inverting, active-high enable (d)
inverting, active-low enable
The basic symbol is that of
a noninverting buffer (a, b) or an inverter (c, d). The extra signal at the top
of the symbol is a three-state enable input, which may be active high
(a, c) or active low (b, d). When the enable input is asserted, the device
behaves like an ordinary buffer or inverter. When the enable input is negated,
the device output “floats”; that is, it goes to high impedance (Hi-Z),
disconnected state and functionally behaves as if it weren’t even there.
Figure 2: Eight Sources sharing a three-state parity line
Figure 2 shows an example
of how the three-state devices allow multiple sources to share a single “party
line,” as long as only one device “talks” on the line at a time. Three input
bits, SSRC2–SSRC0, select one of eight sources of data that may drive a single
line, SDATA. A 3-to-8 decoder, the 74x138, ensures that only one of the eight
SEL lines is asserted at a time, enabling only one three-state buffer
to drive SDATA. However, if not all of the EN
lines are asserted, and
then none of the three-state buffers is enabled. The logic value on SDATA will be undefined.
Typical three-state devices are
designed so that they go into the Hi-Z state faster than they come out of the
Hi-Z state. (In terms of the specifications in a data book, tpLZ and tpHZ
are both less than tpZL and tpZH) i.e., if the outputs of two
three-state devices are connected to the same party line, and we simultaneously
disable one and enable the other, the first device will get off the party line
before the second one gets on. This is important because, if both devices were
to drive the party line at the same time, and if both were trying to maintain
opposite output values (0 and 1), then excessive current would flow and create
noise in the system, often called fighting.
Unfortunately, delays and timing skews
in control circuits make it difficult to ensure that the enable inputs of different
three-state devices change “simultaneously.”
Even when this is possible, a problem arises
if three-state devices from different - speed logic families (or even different
ICs manufactured on different days) are connected to the same party line. The
turn-on time (tpZL or tpZH) of a “fast” device may be shorter
than the turn-off time (tpLZ or tpHZ) of a “slow” one, and the
outputs may still fight. The only really safe way to use three-state devices is
to design control logic that guarantees a dead time on the party line
during which no one is driving it.
Figure 3: Timing Diagram for the three-state
parity line
The dead time must be long
enough to account for the worst-case differences between turn-off and turn-on
times of the devices and for skews in the three-state control signals. Figure 3
shows the operation for the party line of Figure 2, i.e., a drawing convention for
three-state signals—when in the Hi-Z state, they are shown at an “undefined”
level halfway between 0 and 1.
Standard SSI and MSI Three-State Buffers
Like logic gates, several
independent three-state buffers may be packaged in a single SSI IC. Figure 4 shows
the pinouts of 74x125 and 74x126, each of which contains four
independent noninverting three-state buffers in a 14-pin package. The
three-state enable inputs in the ’125 are active low, and in the ’126 they are
active high.
Figure 4: Pinouts of the 74x125 and 74x126 three-state buffers
Most party-line
applications use a bus with more than one bit of data. For example, in an 8-bit
microprocessor system, the data bus is eight bits wide, and peripheral devices
normally place data on the bus eight bits at a time. Thus, a peripheral device
enables eight three-state drivers to drive the bus, all at the same time.
Independent enable inputs, as in the ’125 and ’126, are not necessary.
Thus, to reduce the package
size in wide-bus applications, most commonly used MSI parts contain multiple
three-state buffers with common enable inputs. Eg., Figure 5 shows the logic
diagram and symbol for a 74x541 octal noninverting three-state buffer. Octal
means that the part contains eight individual
buffers. Both enable inputs, G1_L and G2_L,
must be asserted to enable the device’s three-state outputs. The little
rectangular symbols inside the buffer symbols indicate hysteresis, an
electrical characteristic of the inputs that improves noise immunity; the
74x541 inputs typically have 0.4 volts of hysteresis.
Figure 5: The 74x541 octal
three-state buffer (a) logic diagram including pin numbers for a standard
20-pin dual in-line package (b) traditional logic symbol
VHDL Program Code
Library ieee;
Use
ieee.std_logic_1164.all;
Entity IC74541 is
Port(A: in
std_logic_vector(7 downto 0);
G1_L,G2_L: in std_logic;
Y: out std_logic_vector(7 downto 0));
End IC74541;
Architecture behav of
IC74541 is
Begin
Process(a,G1_L, G2_L)
Begin
If(G1_L=‘0’ and G2_L=‘0’ )
then
Y<=A;
else
Y<=“ZZZZZZZZ”;
End if;
End process;
End behav;
Figure 6 shows part of a microprocessor
system with an 8-bit data bus, DB[0–7], and a 74x541 used as an input port. The microprocessor
selects Input Port 1 by asserting INSEL1 and requests a read operation by asserting READ. The selected 74x541 responds by
driving the microprocessor data bus with user supplied input data. Other input
ports may be selected when a different INSEL line is asserted along with READ.
Figure 6: Using a 74x541 as
a microprocessor input port
Many other varieties of
octal three-state buffers are commercially available. Eg., the 74x540 is
identical to the 74x541 except that it contains inverting buffers. The 74x240
and 74x241 are similar to the ’540 and ’541, except that they are
split into two 4-bit sections, each with a single enable line. A bus
transceiver contains pairs of three-state buffers connected in opposite
directions between each pair of pins, so that data can be transferred in either
direction. Figure 7 shows the logic diagram and symbol for a 74x245 octal
three-state transceiver. The DIR input determines
the direction of transfer, from A to B (DIR = 1) or from B to A (DIR = 0). The three-state buffer for the selected direction is
enabled only if G_L is
asserted.
Figure 7: The 74x245 octal
three-state transceiver (a) Logic Diagram (b) Traditional Logic Symbol
VHDL Program Code
Library ieee;
Use ieee.std_logic_1164.all;
Entity IC74245 is
Port(G_L,DIR: in std_logic;
A,B:
inout std_logic_vector(7 downto 0);
Y: out std_logic_vector(7 downto 0));
End IC74245;
Architecture behav of IC74245 is
Begin
Process (G_L, DIR, A,B)
Begin
If(G_L=‘0’ and DIR=’1’) then
B<=A;
Elsif (G_L=’0’ and DIR=‘0’) then
A<=B;
End if;
End process;
End behav;
A bus transceiver is typically used
between two bidirectional buses, as shown in Figure 8. Three different
modes of operation are possible, depending on the state of G_L and DIR, as shown in Table 1. As usual, it is the designer’s
responsibility to ensure that neither bus is ever driven simultaneously by two
devices. However, independent transfers where both buses are driven at the same
time may occur when the transceiver is disabled, as indicated in the last row
of the table.
Figure 8: Bidirectional buses and
transceiver operation
Table
1: Modes of Operation for a pair of bidirectional buses
Program Code:
IEEE 1164 package declarations for STD_ULOGIC and STD_LOGIC
PACKAGE std_logic_1164 IS
-- 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
);
-- unconstrained array of std_ulogic
TYPE std_ulogic_vector IS ARRAY ( NATURAL RANGE <> ) OF
std_ulogic;
-- resolution function
FUNCTION resolved ( s : std_ulogic_vector ) RETURN std_ulogic;
-- *** industry standard logic type ***
SUBTYPE std_logic IS resolved std_ulogic;
...
IEEE 1164 package body for STD_ULOGIC and STD_LOGIC
PACKAGE BODY std_logic_1164 IS
-- local type
TYPE stdlogic_table IS ARRAY(std_ulogic, std_ulogic) OF
std_ulogic;
-- resolution function
CONSTANT resolution_table : stdlogic_table := (
--
---------------------------------------------------------
-- | 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' ) -- | - |
);
FUNCTION resolved ( s : std_ulogic_vector ) RETURN std_ulogic IS
VARIABLE result : std_ulogic := 'Z'; -- weakest state default
BEGIN
-- the test for a single driver is essential otherwise the
-- loop would return 'X' for a single driver of '-' and
that
-- would conflict with the value of a single driver
unresolved
-- signal.
IF (s'LENGTH = 1) THEN RETURN s(s'LOW);
ELSE
FOR i IN s'RANGE LOOP
result := resolution_table(result, s(i));
END LOOP;
END IF;
RETURN result;
END resolved;
...
VHDL program with four 8-bit three-state drivers
library IEEE;
use IEEE.std_logic_1164.all;
entity V3statex is
port (
G_L: in STD_LOGIC; -- Global output enable
SEL: in STD_LOGIC_VECTOR (1 downto 0); -- Input select 0,1,2,3
==> A,B,C,D
A, B, C, D: in STD_LOGIC_VECTOR (1 to 8); -- Input buses
X: out STD_ULOGIC_VECTOR (1 to 8) -- Output bus (three-state)
);
end V3statex;
architecture V3states of V3statex is
constant ZZZZZZZZ: STD_ULOGIC_VECTOR :=
('Z','Z','Z','Z','Z','Z','Z','Z');
begin
process (G_L, SEL, A)
begin
if G_L='0' and SEL = "00" then X <=
To_StdULogicVector(A);
else X <= ZZZZZZZZ;
end if;
end process;
process (G_L, SEL, B)
begin
if G_L='0' and SEL = "01" then X <=
To_StdULogicVector(B);
else X <= ZZZZZZZZ;
end if;
end process;
process (G_L, SEL, C)
begin
if G_L='0' and SEL = "10" then X <=
To_StdULogicVector(C);
else X <= ZZZZZZZZ;
end if;
end process;
process (G_L, SEL, D)
begin
if G_L='0' and SEL = "11" then X <=
To_StdULogicVector(D);
else X <= ZZZZZZZZ;
end if;
end process;
end V3states;