Tuesday, September 15, 2015

Three State Devices, IC74x541, IC74x245 and VHDL Programming

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, SSRC2SSRC0, 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;



Encoders using ICs with VHDL Programming

Unit-V
COMBINATIONAL LOGIC DESIGN

Encoders

If the device’s output code has fewer bits than the input code, the device is usually called an encoder. Eg., consider a device with eight input bits representing an unsigned binary number, and two output bits indicating whether the number is prime or divisible by 7, then the device is called as a lucky/prime encoder.

Probably the simplest encoder to build is a 2n-to-n or binary encoder. As shown in Figure 1(a), it has just the opposite function as a binary decoder— its input code is the 1-out-of-2n code and its output code is n-bit binary. The equations for an 8-to-3 encoder with inputs I0I7 and outputs Y0Y2 are


The corresponding logic circuit is shown in figure 1(b). In general, a 2n-to-n encoder can be built from n 2n-1-input OR gates. Bit i of the input code is connected to OR gate j if bit j in the binary representation of i is 1.

Figure 1: Binary Encoder (a) General Structure (b) 8-to-3 Encoder

Priority Encoders

The 1-out-of-2n coded outputs of an n-bit binary decoder are generally used to control a set of 2n devices, where at most one device is supposed to be active at any time. Conversely, consider a system with 2n inputs, each of which indicates a request for service, as in Figure 2. This structure is often found in microprocessor input/output subsystems, where the inputs might be interrupt requests.


Figure 2: A system with 2n requestors, and a “request encoder” that indicates which request signal is asserted at any time.

If multiple requests can be made simultaneously, then encoder shown in figure 1 gives undesirable results. Eg., suppose that inputs I2 and I4 of the 8-to-3 encoder are both 1; then the output is 110, the binary encoding of 6.

Solution: Assign priority to the input lines, so that when multiple requests are asserted, the encoding device produces the number of the highest-priority requestor, called as a priority encoder.
 
Figure 3: Logic Symbol for a generic 8-input priority encoder.

The logic symbol for an 8-input priority encoder is shown in Figure 3. Input I7 has the highest priority. Outputs A2–A0 contain the number of the highest priority asserted input, if any. The IDLE output is asserted if no inputs are asserted.

In order to write logic equations for the priority encoder’s outputs, we first define eight intermediate variables H0–H7, such that Hi is 1 if and only if Ii is the highest priority 1 input:


Using these signals, the equations for the A2–A0 outputs are similar to the ones for a simple binary encoder:


 The IDLE output is 1 if no inputs are 1:

 The 74x148 Priority Encoder

The 74x148 is a commercially available, MSI 8-input priority encoder, whose logic symbol is shown in Figure 4 and its schematic is shown in Figure 5.

Table 1: Truth Table for a 74x148 8-input priority encoder



Figure 4: Logic symbol for the 74x148 8-input priority encoder
  


Figure 5: Logic diagram for the 74x148 8-input priority encoder, including pin numbers for a standard 16-pin dual in-line package

The main difference between this IC and the “generic” priority encoder of Figure 5 is that its inputs and outputs are active low. It has an enable input, EI_L, that must be asserted for any of its outputs to be asserted. The complete truth table is given in Table 1. Instead of an IDLE output, the ’148 has a GS_L output that is asserted when the device is enabled and one or more of the request inputs is asserted, called as “Group Select”. The EO_L signal is an enable output designed to be connected to the EI_L input of another ’148 that handles lower-priority requests. /EO is asserted if EI_L is asserted but no request input is asserted; thus, a lower-priority ’148 may be enabled.

Behavioral Modeling

library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;

entity V74x148 is
port (
EI_L: in STD_LOGIC;
I_L: in STD_LOGIC_VECTOR (7 downto 0);
A_L: out STD_LOGIC_VECTOR (2 downto 0);
EO_L, GS_L: out STD_LOGIC
);
end V74x148;

architecture V74x148p of V74x148 is
signal EI: STD_LOGIC;                                   -- active-high version of input
signal I: STD_LOGIC_VECTOR (7 downto 0);  -- active-high version of inputs
signal EO, GS: STD_LOGIC;                           -- active-high version of outputs
signal A: STD_LOGIC_VECTOR (2 downto 0); -- active-high version of outputs
begin
process (EI_L, I_L, EI, EO, GS, I, A)
variable j: INTEGER range 7 downto 0;
begin
EI <= not EI_L; -- convert input
I <= not I_L; -- convert inputs
EO <= '1'; GS <= '0'; A <= "000";
if (EI)='0' then EO <= '0';
else for j in 7 downto 0 loop
if GS = '1' then null;
elsif I(j)='1' then
GS <= '1'; EO <= '0'; A <= CONV_STD_LOGIC_VECTOR(j,3);
end if;
end loop;
end if;
EO_L <= not EO; -- convert output
GS_L <= not GS; -- convert output
A_L <= not A; -- convert outputs
end process;
end V74x148p;

Figure 6 shows how four 74x148s can be connected in this way to accept 32 request inputs and produce a 5-bit output, RA4–RA0, indicating the highest-priority requestor. Since the A2–A0 outputs of at most one ’148 will be enabled at any time, the outputs of the individual ’148s can be ORed to produce RA2–RA0. Similarly, the individual GS_L outputs can be combined in a 4-to-2 encoder to produce RA4 and RA3. The RGS output is asserted if any GS output is asserted.

Structural Model

library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;

entity V32to5en is
port (REQ_L: in STD_LOGIC_VECTOR(31 downto 0);
RGS: out STD_LOGIC;
RA: out STD_LOGIC_VECTOR(4 downto 0));
end V32to5en;

architecture structural of V32to5en is

signal GEO_L: STD_LOGIC_VECTOR(3 downto 1);
signal G0A_L, G1A_L, G2A_L, G3A_L: STD_LOGIC_VECTOR(2 downto 0);
signal GGS_L: STD_LOGIC_VECTOR(3 downto 0);

component V74x148
port ( EI_L: in STD_LOGIC;
I_L: in STD_LOGIC_VECTOR (7 downto 0);
A_L: out STD_LOGIC_VECTOR (2 downto 0);
EO_L, GS_L: out STD_LOGIC);
end component;

component V74x20
port (I0,I1,I2,I3: in STD_LOGIC;
       O: out STD_LOGIC);
end component;

component V74x00
port (I0, I1: in STD_LOGIC;
O: out STD_LOGIC);
end component;

begin
U1: V74x148 port map (‘0’, REQ_L(31 downto 24), G3A_L(2 downto 0), GEO_L(3),GGS_L(3));
U2: V74x148 port map (GEO_L(3), REQ_L(23 downto 16), G2A_L(2 downto 0), GEO_L(2),GGS_L(2));
U3: V74x148 port map (GEO_L(2), REQ_L(15 downto 8), G1A_L(2 downto 0), GEO_L(1),GGS_L(1));
U4: V74x148 port map (GEO_L(1), REQ_L(7 downto 0), G0A_L(2 downto 0), OPEN,GGS_L(0));

U5: nand2 port map (GGS_L(3),GGS_L(2),RA(4));
U6: nand2 port map (GGS_L(3),GGS_L(1),RA(3));
U7: nand4 port map (G3A_L(2),G2A_L(2),G1A_L(2),G0A_L(2),RA(2));
U8: nand4 port map (G3A_L(1),G2A_L(1),G1A_L(1),G0A_L(1),RA(1));
U9: nand4 port map (G3A_L(0),G2A_L(0),G1A_L(0),G0A_L(0),RA(0));
U10: nand4 port map (GGS_L(3),GGS_L(2),GGS_L(1),GGS_L(0),RGS);
end structural;

library IEEE;
use IEEE.std_logic_1164.all;

entity V74x00 is
port (I0,I1: in STD_LOGIC;
O: out STD_LOGIC);
end V74x00;

architecture dataflow of V74x00 is
begin
O <= I0 nand I1;
end dataflow;

library IEEE;
use IEEE.std_logic_1164.all;

entity V74x20 is
port (I0,I1,I2,I3: in STD_LOGIC;
O: out STD_LOGIC);
end V74x20;

architecture dataflow of V74x20 is
begin
O <= (I0 nand I1) nand (I2 nand I3);
end dataflow;

library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;

entity V74x148 is
port (
EI_L: in STD_LOGIC;
I_L: in STD_LOGIC_VECTOR (7 downto 0);
A_L: out STD_LOGIC_VECTOR (2 downto 0);
EO_L, GS_L: out STD_LOGIC
);
end V74x148;

architecture V74x148p of V74x148 is
signal EI: STD_LOGIC;                                   
signal I: STD_LOGIC_VECTOR (7 downto 0);  
signal EO, GS: STD_LOGIC;                           
signal A: STD_LOGIC_VECTOR (2 downto 0);
begin
process (EI_L, I_L, EI, EO, GS, I, A)
variable j: INTEGER range 7 downto 0;
begin
EI <= not EI_L; -- convert input
I <= not I_L; -- convert inputs
EO <= '1'; GS <= '0'; A <= "000";
if (EI)='0' then EO <= '0';
else for j in 7 downto 0 loop
if GS = '1' then null;
elsif  I(j)='1' then
GS <= '1'; EO <= '0'; A <= CONV_STD_LOGIC_VECTOR (j,3);
end if;
end loop;
end if;
EO_L <= not EO;
GS_L <= not GS;
A_L <= not A;
end process;
end V74x148p;


Figure 6: Four 74x148s cascaded to handle 32 requests