Section 6.2 Design Examples Using ABEL and PLDs 479
GAL20V8 has available only seven product terms per output. However, the
GAL22V10 (Figure 8-22 on page 684) has more product terms available, so we
DO NOT COPYcanusethatifwelike.
One drawback of the design in Table 6-4 is that the [M3..M0] outputs
are slow; since they use [E2..E0], they take two passes through the PLD. A
faster approach, if it fits, would be to rewrite the “select” terms (E==0, etc.) as
intermediate equations before the equations section, and let ABEL expand the
DO NOT COPYresulting M equations in a single level of logic. Unfortunately, ABEL does not
allow WHEN statements outside of the equations section, so we’ll have to roll up
our sleeves and write our own logic expressions in the intermediate equations.
Table 6-5 shows the modified approach. The expressions for S7–S0 are just
mutually-exclusive AND-terms that indicate exponent values of 7–0 depending
DO NOT COPYon the location of the most significant 1 bit in the fixed-point input number. The
exponent [E2..E0] is a binary encoding of the select terms, and the mantissa
bits [M3..M0] are generated using a select term for each case. It turns out that
these M equations still require 8 product terms per output bit, but at least they’re
DO NOT COPYa lot faster since they use just one level of logic.
COPYTable 6-5
module fpence Alternative ABEL
title 'Fixed-point to Floating-point Encoder' program for the
fixed-point to
DO NOTFPENCE device 'P20L8'; floating-point PLD.
" Input and output pins
B10..B0 pin 1..11;
E2..E0, M3..M0
" Intermediate equations
DO NOT COPYS7 = B10;
pin 21..15 istype 'com';
S6 = !B10 & B9;
S5 = !B10 & !B9 & B8; COPY
S4 = !B10 & !B9 & !B8 & B7;
S3 = !B10 & !B9 & !B8 & !B7 & B6;
S2 = !B10 & !B9 & !B8 & !B7 & !B6 & B5;
DO NOTS1 = !B10 & !B9 & !B8 & !B7 & !B6 & !B5 & B4;
S0 = !B10 & !B9 & !B8 & !B7 & !B6 & !B5 & !B4;
equations
E2 = S7 # S6 # S5 # S4;
DO NOT COPYE1 = S7 # S6 # S3 # S2;
E0 = S7 # S5 # S3 # S1;
[M3..M0] = S0 & [B3..B0] # S1 & [B4..B1] # S2 & [B5..B2]
# S3 & [B6..B3] # S4 & [B7..B4] # S5 & [B8..B5]
DO NOT COPY# S6 & [B9..B6] # S7 & [B10..B7];
end fpenc
Copyright © 1999 by John F. Wakerly Copying Prohibited
480 Chapter 6 Combinational Design Examples
6.2.3 Dual-Priority Encoder
In this example, we’ll design a PLD-based priority encoder that identifies both
DO NOT COPYthe highest-priority and the second-highest-priority asserted signal among a set
of eight active-high request inputs named [R0..R7], where R0 has the highest
priority. We’ll use [A2..A0] and AVALID to identify the highest-priority request,
asserting AVALID only if a highest-priority request is present. Similarly, we’ll
use [B2:B0] and BVALID to identify the second-highest-priority request.
DO NOT COPYTable 6-6 shows an ABEL program for the priority encoder. As usual, a
nested WHEN statement is perfect for expressing priority behavior. To find the
Table 6-6
DO NOT COPYABELprogramfora
title 'Dual Priority Encoder'
PRIORTWO device 'P16V8';
dual priority encoder.
" Input and output pins
R7..R0
AVALID, A2..A0, BVALID, B2..B0
DO NOT COPY" Set definitions
pin 1..8;
pin 19..12 istype 'com';
A = [A2..A0]; B = [B2..B0];
DO NOTequations COPY
WHEN R0==1 THEN A=0; COPY
ELSE WHEN R1==1 THEN A=1;
ELSE WHEN R2==1 THEN A=2;
DO NOTELSE WHEN R3==1 THEN A=3;
ELSE WHEN R4==1 THEN A=4;
ELSE WHEN R5==1 THEN A=5;
ELSE WHEN R6==1 THEN A=6;
ELSE WHEN R7==1 THEN A=7;
AVALID = ([R7..R0] != 0);
WHEN (R0==1) & (A!=0) THEN B=0;
DO NOT COPYELSE WHEN (R1==1) & (A!=1) THEN B=1;
ELSE WHEN (R2==1) & (A!=2) THEN B=2;
ELSE WHEN (R3==1) & (A!=3) THEN B=3;
ELSE WHEN (R4==1) & (A!=4) THEN B=4;
ELSE WHEN (R5==1) & (A!=5) THEN B=5;
ELSE WHEN (R6==1) & (A!=6) THEN B=6;
DO NOT COPYELSE WHEN (R7==1) & (A!=7) THEN B=7;
BVALID = (R0==1) & (A!=0) # (R1==1) & (A!=1)
DO # (R2==1) & (A!=2) # (R3==1) & (A!=3)
# (R4==1) & (A!=4) # (R5==1) & (A!=5)
NOT COPY# (R6==1) & (A!=6) # (R7==1) & (A!=7);
end priortwo
Copyright © 1999 by John F. Wakerly Copying Prohibited
Section 6.2 Design Examples Using ABEL and PLDs 481
P-Terms Fan-in Fan-out Type Name
--------- ------ ------- ---- ----------
DO NOT COPY8/1 8 1 Pin AVALID
Table 6-7
Product-term usage
in the dual priority
4/5 8 1 Pin A2 encoder PLD.
4/5 8 1 Pin A1
4/5
24/8
24/17
DO NOT COPY20/21
8 1 Pin A0
11 1 Pin BVALID
11 1 Pin B2
11 1 Pin B1
18/22 11 1 Pin B0
========= COPY
DO NOT106/84
Best P-Term Total: 76
Total Pins: 16
Average P-Term/Output: 9
second-highest priority input, we exclude an input if its input number matches
the highest-priority input number, which is A. Thus, we’re using two-pass logic
to compute the B outputs. The equation for AVALID is easy; AVALID is 1 if the
DO NOT COPYrequest inputs are not all 0. To compute BVALID, we OR all of the conditions that
set B in the WHEN statement.
Even with two-pass logic, the B outputs use too many product terms to fit in
a 16V8; Table 6-7 shows the product-term usage. The B outputs use too many
DO NOT COPYterms even for a 22V10, which has 16 terms for two of its output pins, and 8–14
for the others. Sometimes you just have to work harder to make things fit!
So, how can we save some product terms? One important thing to notice is
that R0 can never be the second-highest priority asserted input, and therefore B
can never be valid and 0. Thus, we can eliminate the WHEN clause for the R0==1
DO NOT COPYcase. Making this change reduces the minimum number of terms for B2–B0 to
14, 17, and 15, respectively. We can almost fit the design in a 22V10, if we can
just know one term out of the B1 equation.
Well let’s try something else. The second WHEN clause, for the R0==2 case,
DO NOT COPYalso fails to make use of everything we know. We don’t need the full generality
SUMS OF You may recall from Section 4.3.6 that the minimal sum-of-products expression for
PRODUCTS AND the complement of a function can be manipulated through DeMorgan’s theorem to
DO NOT COPYPRODUCTS OF obtain a minimal product-of-sums expression for the original function. You may also
SUMS recall that the number of product terms in the minimal sum of products may differ
(SAY THAT 5 from the number of sum terms in the minimal product of sums. The “P-terms”
TIMES FAST) column in Table 6-7 lists the number of terms in both minimal forms (product/sum
terms). If either minimal form has less than or equal to the number of product terms
DO NOT COPYavailable in a 22V10’s AND-OR array, then the function can be made to fit.
Copyright © 1999 by John F. Wakerly Copying Prohibited
482 Chapter 6 Combinational Design Examples
of A!=0; this case is only important when R0 is 1. So, let us replace the first two
lines of the original WHEN statement with
DO NOT COPYWHEN (R1==1) & (R0==1) THEN B=1;
This subtle change reduces the minimum number of terms for B2–B0 to 12, 16,
and 13, respectively. We made it! Can the number of product terms be reduced
further, enough to fit into a 16V8 while maintaining the same functionality? It’s
DO NOT COPYnot likely, but we’ll leave that as an exercise (6.4) for the reader!
6.2.4 Cascading Comparators
We showed in Section 5.9.5 that equality comparisons are easy to realize in
PLDs, but that magnitude comparisons (greater-than or less-than) of more than
DO NOT COPYa few bits are not good candidates for PLD realization due to the large number
of product terms required. Thus, comparators are best realized using discrete
MSI comparator components or as specialized cells within an FPGA or ASIC
library. However, PLDs are quite suitable for realizing the combinational logic
used in “parallel expansion” schemes that construct wider comparators from
DO NOT COPYsmaller ones, as we’ll show here.
In Section 5.9.4, we showed how to connect 74x85 4-bit comparators in
series to create larger comparators. Although a serial cascading scheme requires
no extra logic to build arbitrarily large comparators, it has the major drawback
that the delay increases linearly with the length of the cascade.
DO NOT COPYIn Section 6.1.4, on the other hand, we showed how multiple copies of the
74x682 8-bit comparator could be used in parallel along with combinational
logic to perform a 24-bit comparison. This scheme can be generalized for com-
parisons of arbitrary width.
DO NOT COPYTable 6-8 is an ABEL program that uses a GAL22V10 to perform a 64-bit
comparison using eight 74x682s to combine the equal (EQ) and greater-than
(GT) outputs from the individual byte to produce all six possible relations of the
two 64-bit input values (=, ≠, >, ≥, <, ≤).
In this program, the PEQQ and PNEQ outputs can be realized with one
DO NOT COPYproduct term each. The remaining eight outputs use eight product terms each. As
we’ve mentioned previously, the 22V10 provides 8-16 product terms per output,
so the design fits.
DO NOT COPYHAVE IT Early PLDs such as the PAL16L8s did not have output-polarity control. Designers
YOUR WAY who used these devices were forced to choose a particular polarity, active high or
active low, for some outputs in order to obtain reduced equations that would fit.
When a 16V8, 20V8, 22V10, or any of a plethora of modern CPLDs is used, no such
restriction exists. If an equation or its complement can be reduced to the number of
DO NOT COPYproduct terms available, then the corresponding output can be made active high or
active low by programming the output-polarity fuse appropriately.
Copyright © 1999 by John F. Wakerly Copying Prohibited
Section 6.2 Design Examples Using ABEL and PLDs 483
module compexp COPYTable 6-8
title 'Expansion logic for 64-bit comparator' ABEL program for
combining eight
DO NOTCOMPEXP device 'P22V10'; 74x682s into a
" Inputs from the individual comparators, active-low, 7 = MSByte
64-bit comparator.
pin 1..11, 13..14, 21..23;
pin 15..20 istype 'com';
EQ_L7..EQ_L0, GT_L7..GT_L0
" Comparison outputs
DO NOT COPYPEQQ, PNEQ, PGTQ, PGEQ, PLTQ, PLEQ
" Active-level conversions
EQ7 = !EQ_L7; EQ6 = !EQ_L6; EQ5 = !EQ_L5; EQ4 = !EQ_L4;
EQ3 = !EQ_L3; EQ2 = !EQ_L2; EQ1 = !EQ_L1; EQ0 = !EQ_L0;
GT7 = !GT_L7; GT6 = !GT_L6; GT5 = !GT_L5; GT4 = !GT_L4;
DO NOT COPYGT3 = !GT_L3; GT2 = !GT_L2; GT1 = !GT_L1; GT0 = !GT_L0;
" Less-than terms
LT7 = !(EQ7 # GT7); LT6 = !(EQ6 # GT6); LT5 = !(EQ5 # GT5);
LT4 = !(EQ4 # GT4); LT3 = !(EQ3 # GT3); LT2 = !(EQ2 # GT2);
DO NOT COPYLT1 = !(EQ1 # GT1); LT0 = !(EQ0 # GT0);
equations
PEQQ = EQ7 & EQ6 & EQ5 & EQ4 & EQ3 & EQ2 & EQ1 & EQ0;
DO NOT COPYPNEQ = !(EQ7 & EQ6 & EQ5 & EQ4 & EQ3 & EQ2 & EQ1 & EQ0);
PGTQ = GT7 # EQ7 & GT6 # EQ7 & EQ6 & GT5
# EQ7 & EQ6 & EQ5 & GT4 # EQ7 & EQ6 & EQ5 & EQ4 & GT3
# EQ7 & EQ6 & EQ5 & EQ4 & EQ3 & GT2
# EQ7 & EQ6 & EQ5 & EQ4 & EQ3 & EQ2 & GT1
DO NOT COPY# EQ7 & EQ6 & EQ5 & EQ4 & EQ3 & EQ2 & EQ1 & GT0;
PLEQ = !(GT7 # EQ7 & GT6 # EQ7 & EQ6 & GT5
# EQ7 & EQ6 & EQ5 & GT4 # EQ7 & EQ6 & EQ5 & EQ4 & GT3
# EQ7 & EQ6 & EQ5 & EQ4 & EQ3 & GT2
# EQ7 & EQ6 & EQ5 & EQ4 & EQ3 & EQ2 & GT1
DO NOT COPY# EQ7 & EQ6 & EQ5 & EQ4 & EQ3 & EQ2 & EQ1 & GT0);
PLTQ = LT7 # EQ7 & LT6 # EQ7 & EQ6 & LT5
# EQ7 & EQ6 & EQ5 & LT4 # EQ7 & EQ6 & EQ5 & EQ4 & LT3
# EQ7 & EQ6 & EQ5 & EQ4 & EQ3 & LT2
# EQ7 & EQ6 & EQ5 & EQ4 & EQ3 & EQ2 & LT1
DO NOT COPY# EQ7 & EQ6 & EQ5 & EQ4 & EQ3 & EQ2 & EQ1 & LT0;
PGEQ = !(LT7 # EQ7 & LT6 # EQ7 & EQ6 & LT5
# EQ7 & EQ6 & EQ5 & LT4 # EQ7 & EQ6 & EQ5 & EQ4 & LT3
# EQ7 & EQ6 & EQ5 & EQ4 & EQ3 & LT2
# EQ7 & EQ6 & EQ5 & EQ4 & EQ3 & EQ2 & LT1
DO NOT COPY# EQ7 & EQ6 & EQ5 & EQ4 & EQ3 & EQ2 & EQ1 & LT0);
end compexp
Copyright © 1999 by John F. Wakerly Copying Prohibited
484 Chapter 6 Combinational Design Examples
DO NOTTable 6-9 COPYM1 M0
Mode-control bits for Comparison
the mode-dependent
comparator. 00 32-bit
01 31-bit
30-bit
not used
DO NOT COPY1 0
11
6.2.5 Mode-Dependent Comparator
For the next example, let us suppose we have a system in which we need to
compare two 32-bit words under normal circumstances, but where we must
sometimes ignore one or two low-order bits of the input words. The operating
DO NOT COPYmode is specified by two mode-control bits, M1 and M0, as shown in Table 6-9.
As we’ve noted previously, comparing, adding, and other “iterative” oper-
ations are usually poor candidates for PLD-based design, because an equivalent
two-level sum-of-products expression has far too many product terms. In
Section 5.9.5, we calculated how many product terms are needed for an n-bit
DO NOT COPYcomparator. Based on these results, we certainly wouldn’t be able to build the
32-bit mode-dependent comparator or even an 8-bit slice of it with a PLD; the
74x682 8-bit comparator is just about the most efficient possible single chip we
can use to perform an 8-bit comparison. However, a PLD-based design is quite
reasonable for handling the mode-control logic and the part of the comparison
DO NOT COPYthat is dependent on mode (the two low-order bits).
Figure 6-9 shows a complete circuit design resulting from this idea, and
Table 6-11 is the ABEL program for a 16V8 MODECOMP PLD that handles the
“random logic.” Four ’682s are used to compare most of the bits, and the 16V8
DO NOT COPYcombines the ’682 outputs and handles the two low-order bits as a function of
the mode. Intermediate expressions EQ30 and GT30 are defined to save typing in
the equations section of the program.
As shown in Table 6-10, the XEQY and XGTY outputs use 7 and 11 product
terms, respectively. Thus, XGTY does not fit into the 7 product terms available on
DO NOT COPYa 16V8 output. However, this is another example where we have some flexibility
in our coding choices. By changing the coding of MODE30 to [1,.X.], we can
reduce the product-term requirements for XGTY to 7/12, and thereby fit the
design into a 16V8.
DO NOT COPYTable 6-10
P-Terms Fan-in Fan-out Type Name
Product-term usage --------- ------ ------- ---- --------
for the MODECOMP7/9
11/13
DO NOT COPYPLD.=========
18/22 10 1 Pin XEQY
14 1 Pin XGTY
Best P-Term Total: 18
Total Pins: 16
Average P-Term/Output: 9
Copyright © 1999 by John F. Wakerly Copying Prohibited
Section 6.2 Design Examples Using ABEL and PLDs 485
M0Y NOT COPY
M1
74x682
DOX
74x682
2 P0 X16 2 P0
3 Q0 Y16 3 Q0
X17 4 P1
DO NOT COPY4 P1
5 Q1 Y17 5 Q1
X2 6 P2 X18 6 P2
DO NOT COPYX4 11 P4Y2 7 Q2
X3 8 P3 P EQ Q 19 EQ0_L Y18 7 Q2 19 EQ2_L X0
X19 8 P3 P EQ Q X1
Y3 9 Q3 Y19 9 Q3 Y0
X20 11 P4
Y1
Y4 12 Q4 Y20 12 Q4
1 GT0_L X21 13 P5 P GT Q 1 GT2_L
Y21 14 Q5
X22 15 P6
Y22 16 Q6
X5 13 P5 P GT Q
Y5 14 Q5
X6 15 P6
DO NOT COPYY6 16 Q6
PAL16V8
1 I1
X7 17 P7 X23 17 P7 2 I2 O1 19 XEQY
DOY7 18 Q7 NOTY23 18 Q7 3 I3 IO2 18
COPYU3
U1 4 I4 IO3 17
5 I5 IO4 16
6 I6 IO5 15
7 I7 IO6 14
8 I8 IO7 13
9 I9 O8 12
11 I10 U5
DO74x682 NOT COPY74x682 XGTY
X8 2 P0 X24 2 P0
Y8 3 Q0 Y24 3 Q0
X9 4 P1 MODECOMP
X25 4 P1
Y9 5 Q1 Y25 5 Q1
X10 6 P2 X26 6 P2
DO NOT COPYY11 9 Q3 EQ1_L
Y10 7 Q2 Y26 7 Q2
X11 8 P3 P EQ Q 19 X27 8 P3 P EQ Q 19 EQ3_L
Y27 9 Q3
X12 11 P4 X28 11 P4
DOY12 12 Q4 Y28 12 Q4
X13 13 P5 P GT Q X29 13 P5 P GT Q
Y13 14 Q5 Y29 14 Q5
X14 15 P6 X30 15 P6
NOT COPY1 GT1_L 1 GT3_L
Y14 16 Q6 Y30 16 Q6
DOX15 17 P7 NOTX31 17 P7 CU4 OPY
Y15 18 Q7 Y31 18 Q7
U2
Figure 6-9 A 32-bit mode-dependent comparator.
Copyright © 1999 by John F. Wakerly Copying Prohibited
486 Chapter 6 Combinational Design Examples
Table 6-11
ABEL program for
DO NOT COPYcombiningeight
module modecomp
title 'Control PLD for Mode-Dependent Comparator'
MODECOMP device 'P16V8';
74x682s into a
64-bit comparator. " Input and output pins
DO NOT COPYXEQY, XGTY pin 1..6;
M0, M1, EQ2_L, GT2_L, EQ0_L, GT0_L
EQ1_L, GT1_L, EQ3_L, GT3_L, X0, X1, Y0, Y1 pin 7..9, 10, 15..18;
pin 19, 12 istype 'com';
" Active-level conversions
EQ3 = !EQ3_L; EQ2 = !EQ2_L; EQ1 = !EQ1_L; EQ0 = !EQ0_L;
GT3 = !GT3_L; GT2 = !GT2_L; GT1 = !GT1_L; GT0 = !GT0_L;
" Mode definitions
DO NOT COPYMODE32 = ([M1,M0] == [0,0]); " 32-bit comparison
MODE31 = ([M1,M0] == [0,1]); " 31-bit comparison
MODE30 = ([M1,M0] == [1,0]); " 30-bit comparison
MODEXX = ([M1,M0] == [1,1]); " Unused
DO NOT COPY" Expressions for 30-bit equal and greater-than
EQ30 = EQ3 & EQ2 & EQ1 & EQ0;
GT30 = GT3 # (EQ3 & GT2) # (EQ3 & EQ2 & GT1) # (EQ3 & EQ2 & EQ1 & GT0);
equations
DO NOT COPYWHEN MODE32 THEN {
XEQY = EQ30 & (X1==Y1) & (X0==Y0);
XGTY = GT30 # (EQ30 & (X1>Y1)) # (EQ30 & (X1==Y1) & (X0>Y0));}
}
ELSE WHEN MODE31 THEN {
XEQY = EQ30 & (X1==Y1);
DO NOT COPYXGTY = GT30 # (EQ30 & (X1>Y1));
ELSE WHEN MODE30 THEN {
XEQY = EQ30;
XGTY = GT30;
DO NOT COPY}
end modecomp
6.2.6 Ones Counter
DO NOT COPYThere are several important algorithms that include the step of counting the
number of “1” bits in a data word. In fact, some microprocessor instruction sets
have been extended recently to include ones counting as a basic instruction.
Counting the ones in a data word can be done easily as an iterative process,
where you scan the word from one end to the other and increment a counter each
DO NOT COPYtime a “1” is encountered. However, this operation must be done more quickly
inside the arithmetic and logic unit of a microprocessor. Ideally, we would like
Copyright © 1999 by John F. Wakerly Copying Prohibited
Section 6.2 Design Examples Using ABEL and PLDs 487
DO NOT COPYD[31:0]
ONESCNT1 ONESCNT2
D[14:0]
D[14:0]
SUM[3:0] A[3:0] A[3:0]
U1SUM[4:0]SUM[4:0]
DO NOT COPYONESCNT1
D[29:15] D[14:0]
B[3:0] B[3:0] COPYFigure 6-10
NOTSUM[3:0] D1 Possible partitioning
DOD30 U2
D31 D0 for the ones-counting
circuit.
U3
ones counting to run as fast as any other arithmetic operation, such as adding two
words. Therefore, a combinational circuit is required.
DO NOT COPYIn this example, let us suppose that we have a requirement to build a 32-bit
ones counter as part of a larger system. Based on the number of inputs and
outputs required, we obviously can’t fit the design into a single 22V10-class
PLD, but we might be able to partition the design into a reasonably small
number of PLDs.
DO NOT COPYFigure 6-10 shows such a partition. Two copies of a first 22V10,
ONESCNT1, are used to count the ones in two 15-bit chunks of the 32-bit input
word D[31:0], each producing a 4-bit sum output. A second 22V10, ONESCNT2,
is used to add the two four bit sums and the last two input bits.
DO NOT COPYThe program for ONESCNT1 is deceptively simple, as shown in
Table 6-12. The statement “@CARRY 1” is included to limit the carry chain to one
stage; as explained in Section 5.10.8, this reduces product-term requirements at
the expense of helper outputs and increased delay.
DO NOT COPYmodule onescnt1
Table 6-12
title 'Count the ones in a 15-bit word' ABEL program for
ONESCNT1 device 'P22V10'; counting the 1 bits
DO NOTSUM3..SUM0
" Input and output pins COPYin a 15-bit word.
D14..D0 pin 1..11, 13..15, 23;
pin 17..20 istype 'com';
equations
@CARRY 1;
[SUM3..SUM0] = D0 + D1 + D2 + D3 + D4 + D5 + D6 + D7
DO NOT COPY+ D8 + D9 + D10 + D11 + D12 + D13 + D14;
end onescnt1
Copyright © 1999 by John F. Wakerly Copying Prohibited
488 Chapter 6 Combinational Design Examples
Unfortunately, when I compiled this program, my computer just sat there,
CPU-bound, for an hour without producing any results. That gave me time to use
DO NOT COPYmy brain, a good exercise for those of us who have become too dependent on
CAD tools. I then realized that I could write the logic function for the SUM0
output by hand in just a few seconds,
SUM0 = D0 ⊕ D1 ⊕ D2 ⊕ D3 ⊕ D4 ⊕ D5 ⊕ D6 ⊕ D7 ⊕ … ⊕ D13 ⊕ D14
DO NOT COPYThe Karnaugh map for this function is a checkerboard, and the minimal sum-of-
products expression has 214 product terms. Obviously this is not going to fit in
one or a few passes through a 22V10! So, anyway, I killed the ABEL compiler
process, and rebooted Windows just in case the compiler had gone awry.
Obviously, a partitioning into smaller chunks is required to design the
DO NOT COPYones-counting circuit. Although we could pursue this further using ABEL and
PLDs, it’s more interesting to do a structural design using VHDL, as we will in
DO NOT COPYSection 6.3.6. The ABEL and PLD version is left as an exercise (6.6).
6.2.7 Tic-Tac-Toe
In this example, we’ll design a combinational circuit that picks a player’s next
move in the game of Tic-Tac-Toe. The first thing we’ll do is decide on a strategy
for picking the next move. Let us try to emulate the typical human’s strategy, by
DO NOT COPYfollowing the decision steps below:
1. Look for a row, column, or diagonal that has two of my marks (X or O,
DO depending on which player I am) and one empty cell. If one exists, place
my mark in the empty cell; I win!
NOT COPY2. Else, look for a row, column, or diagonal that has two of my opponent’s
marks and one empty cell. If one exists, place my mark in the empty cell
to block a potential win by my opponent.
DO
3. Else, pick a cell based on experience. For example, if the middle cell is
open, it’s usually a good bet to take it. Otherwise, the corner cells are good
NOT COPYbets. Intelligent players can also notice and block a developing pattern by
the opponent or “look ahead” to pick a good move.
DO NOT COPYTIC-TAC-TOE, The game of Tic-Tac-Toe is played by two players on a 3 × 3 grid of cells that are
IN CASE YOU initially empty. One player is “X” and the other is “O”. The players alternate in
placing their mark in an empty cell; “X” always goes first. The first player to get three
of his or her own marks in the same row, column, or diagonal wins. Although the first
player to move (X) has a slight advantage, it can be shown that a game between two
intelligent players will always end in a draw; neither player will get three in a row
DO NOT COPYDIDN’TKNOW
before the grid fills up.
Copyright © 1999 by John F. Wakerly Copying Prohibited
Section 6.2 Design Examples Using ABEL and PLDs 489
DO NOT COPY1 X11,Y11 X13,Y12 X13,Y13
1 2 3 column
row
DO NOT COPY2 X21,Y21 X23,Y22 X23,Y23
Figure 6-11
3 X21,Y21 X23,Y22 X23,Y23 Tic-Tac-Toe grid and
ABEL signal names.
DO NOT COPYPlanning ahead, we’ll call the second player “Y” to avoid confusion
between “O” and “0” in our programs. The next thing to think about is how we
might encode the inputs and outputs of the circuit. There are only nine possible
moves that a player can make, so the output can be encoded in just four bits. The
circuit’s input is the current state of the playing grid. There are nine cells, and
DO NOT COPYeach cell has one of three possible states (empty, occupied by X, occupied by Y).
There are several choices of how to code the state of one cell. Because the
game is symmetric, we’ll choose a symmetric encoding that may help us later:
00 Cell is empty.
DO NOT COPY10 Cellisoccupiedby X.
01 Cell is occupied by Y.
So, we can encode the 3 × 3 grid’s state in 18 bits. As shown in Figure 6-11,
we’ll number the grid with row and column numbers, and use ABEL signals Xij
DO NOT COPYand Yij to denote the presence of X or Y in cell i,j. We’ll look at the output cod-
ing later.
With a total of 18 inputs and 4 outputs, the Tic-Tac-Toe circuit could
conceivably fit in just one 22V10. However, experience suggests that there’s just
no way. We’re going to have to find a partitioning of the function, and partition-
DO NOT COPYing along the lines of the decision steps on the preceding page seems like a good
idea.
In fact, steps 1 and 2 are very similar; they differ only in reversing the roles
DO NOT COPYof the player and the opponent. Here’s where our symmetric encoding can pay
COMPACT Since each cell in the Tic-Tac-Toe grid can have only three states, not four, the total
DO NOT COPYENCODING
number of board configurations is 39, or 19,683. This is less than 215, so the board
state can be encoded in only 15 bits. However, such an encoding would lead to much
larger circuits for picking a move, unless the move-picking circuit was a read-only
memory (see Exercise 11.26).
Copyright © 1999 by John F. Wakerly Copying Prohibited
490 Chapter 6 Combinational Design Examples
9TWOINROW
DO NOT COPYX11-X33 X11-X33 PICK
4
MOVE[3:0] XMOVE[3:0]
9
DO NOT COPYY11-Y33 Y11-Y33 U1
4
TWOINROW MOVE[3:0] MOVE[3:0]
X11-X33
4
Figure 6-12 MOVE[3:0] YMOVE[3:0]
Preliminary PLD NOT COPYY11-Y33 U2 X11-X33
partitioning for the 9 Y11-Y33
DOTic-Tac-Toe game. 9
U3
off. A PLD that finds me two of my marks in a row along with one empty cell for
a winning move (step 1) can find two of my opponent’s marks in a row plus an
DO NOT COPYempty for a blocking move (step 2). All we have to do is swap the encodings for
X and Y. With out selected coding, that doesn’t require any logic, just physically
swapping the Xij and Yij signals for each cell. With this in mind, we can use
two copies of the same PLD, TWOINROW, to perform steps 1 and 2 as shown in
Figure 6-12. Notice that the X11–X33 signals are connected to the top inputs of
DO NOT COPYthe first TWOINROW PLD, but to the bottom inputs of the second.
The moves from the two TWOINROW PLDs can be examined in another
PLD, PICK. This device picks a move from the first two PLDs if either found
one; else it performs step 3. It looks like PICK has too many inputs and outputs
DO NOT COPYto fit in a 22V10, but we’ll come back to that later.
Table 6-13 is a program for the TWOINROW PLD. It looks at the grid’s
state from the point of view of X, that is, it looks for a move where X can get three
DO NOT COPYTable 6-13
in a row. The program makes extensive use of intermediate equations to define
module twoinrow
ABEL program to find Title 'Find Two Xs and an empty cell in a row, column, or diagonal'
two in a row in
DO NOT COPYTic-Tac-Toe.
TWOINROW device 'P22V10';
" Inputs and Outputs
X11, X12, X13, X21, X22, X23, X31, X32, X33 pin 1..9;
Y11, Y12, Y13, Y21, Y22, Y23, Y31, Y32, Y33 pin 10,11,13..15,20..23;
MOVE3..MOVE0 pin 16..19 istype 'com';
" MOVE output encodings
MOVE = [MOVE3..MOVE0];
MOVE11 = [1,0,0,0]; MOVE12 = [0,1,0,0]; MOVE13 = [0,0,1,0];
DO NOT COPYMOVE21 = [0,0,0,1]; MOVE22 = [1,1,0,0]; MOVE23 = [0,1,1,1];
MOVE31 = [1,0,1,1]; MOVE32 = [1,1,0,1]; MOVE33 = [1,1,1,0];
NONE = [0,0,0,0];
Copyright © 1999 by John F. Wakerly Copying Prohibited
Section 6.2 Design Examples Using ABEL and PLDs 491
" Find moves in rows. Rxy ==> a move exists in cell xy
R11 = X12 & X13 & !X11 & !Y11;
DO NOT COPYR12 = X11 & X13 & !X12 & !Y12;
Table 6-13
(continued)
R13 = X11 & X12 & !X13 & !Y13;
R21 = X22 & X23 & !X21 & !Y21;
R22 = X21 & X23 & !X22 & !Y22; COPY
R23 = X21 & X22 & !X23 & !Y23;
R31 = X32 & X33 & !X31 & !Y31;
DO NOTR32 = X31 & X33 & !X32 & !Y32;
R33 = X31 & X32 & !X33 & !Y33;
" Find moves in columns. Cxy ==> a move exists in cell xy
C11 = X21 & X31 & !X11 & !Y11;
C12 = X22 & X32 & !X12 & !Y12;
C13 = X23 & X33 & !X13 & !Y13;
DO NOT COPYC21 = X11 & X31 & !X21 & !Y21;
C22 = X12 & X32 & !X22 & !Y22;
C23 = X13 & X33 & !X23 & !Y23; COPY
C31 = X11 & X21 & !X31 & !Y31;
C32 = X12 & X22 & !X32 & !Y32;
DO NOTC33 = X13 & X23 & !X33 & !Y33;
" Find moves in diagonals. Dxy or Exy ==> a move exists in cell xy
D11 = X22 & X33 & !X11 & !Y11; COPY
D22 = X11 & X33 & !X22 & !Y22;
D33 = X11 & X22 & !X33 & !Y33;
E13 = X22 & X31 & !X13 & !Y13;
DO NOTE22 = X13 & X31 & !X22 & !Y22;
E31 = X13 & X22 & !X31 & !Y31;
Gxy ==> a move exists in cell xy
" Combine moves for each cell.
G11 = R11 # C11 # D11;
G12 = R12 # C12;
DO NOT COPYG13 = R13 # C13 # E13;
G21 = R21 # C21;
G22 = R22 # C22 # D22 # E22;
G23 = R23 # C23;
G31 = R31 # C31 # E31;
G32 = R32 # C32;
DO NOT COPYG33 = R33 # C33 # D33;
equations
WHEN G22 THEN MOVE= MOVE22; COPY
ELSE WHEN G11 THEN MOVE = MOVE11; COPY
ELSE WHEN G13 THEN MOVE = MOVE13;
DO NOTELSE WHEN G31 THEN MOVE = MOVE31;
ELSE WHEN G33 THEN MOVE = MOVE33;
ELSE WHEN G12 THEN MOVE = MOVE12;
ELSE WHEN G21 THEN MOVE = MOVE21;
ELSE WHEN G23 THEN MOVE = MOVE23;
ELSE WHEN G32 THEN MOVE = MOVE32;
DO NOTELSE MOVE = NONE;
end twoinrow
Copyright © 1999 by John F. Wakerly Copying Prohibited
492 Chapter 6 Combinational Design Examples
all possible row, column, and diagonal moves. It combines all of the moves for a
cell i,j in an expression for Gij, and finally the equations section uses a WHEN
DO NOT COPYstatementtoselecta move.
Note that a nested WHEN statement must be used rather than nine parallel
WHEN statements or assignments, because we can only select one move even if
multiple moves are available. Also note that G22, the center cell, is checked first,
followed by the corners. This was done hoping that we could minimize the
DO NOT COPYnumber of terms by putting the most common moves early in the nested WHEN.
Alas, the design still requires a ton of product terms, as shown in Table 6-14.
By the way, we still haven’t explained why we chose the output coding that
we did (as defined by MOVE11, MOVE22, etc. in the program). It’s pretty clear that
changing the encoding is never going to save us enough product terms to fit the
DO NOT COPYdesign into a 22V10. But there’s still method to this madness, as we’ll now show.
Clearly we’ll have to split TWOINROW into two or more pieces. As in any
design problem, several different strategies are possible. The first strategy I tried
was to use two different PLDs, one to find moves in all the rows and one of the
DO NOT COPYdiagonals, and the other to work on all the columns and the remaining diagonal.
That helped, but not nearly enough to fit each half into a 22V10.
With the second strategy, I tried slicing the problem a different way. The
first PLD finds all the moves in cells 11, 12, 13, 21, and 22, and the second PLD
finds all the moves in the remaining cells. That worked! The first PLD, named
DO NOT COPYTWOINHAF, is obtained from Table 6-13 simply by commenting out the four
lines of the WHEN statement for the moves to cells 23, 31, 32, and 33.
We could obtain the second PLD from TWOINROW in a similar way, but
let’s wait a minute. In the manufacture of real digital systems, it is always
desirable to minimize the number of distinct parts that are used; this saves on
DO NOT COPYinventory costs and complexity. With programmable parts, it is desirable to min-
imize the number of distinct programs that are used. Even though the physical
parts are identical, a different set of test vectors must be devised at some cost for
each different program. Also, it’s possible that the product will be successful
enough for us to save money by converting the PLDs into hard-coded devices, a
DO NOT COPYdifferent one for each program, again encouraging us to minimize programs.
Table 6-14
Product-term usage
DO NOT COPYforthe TWOINROW
P-Terms Fan-in Fan-out Type Name
--------- ------ ------- ---- -----------
61/142 18 1 Pin MOVE3
PLD. 107/129 18 1 Pin MOVE2
77/88 17 1 Pin MOVE1
DO NOT COPY133/87
=========
378/446
18 1 Pin MOVE0
Best P-Term Total: 332
Total Pins: 22
Average P-Term/Output: 83
Copyright © 1999 by John F. Wakerly Copying Prohibited
Section 6.2 Design Examples Using ABEL and PLDs 493
The Tic-Tac-Toe game is the same game even if we rotate the grid 90° or
180°. Thus, the TWOINHAF PLD can find moves for cells 33, 32, 31, 23, and 22
DO NOT COPYif we rotate the grid 180°. Because of the way we defined the grid state, with a
separate pair of inputs for each cell, we can “rotate the grid” simply by shuffling
the input pairs appropriately. That is, we swap 33↔11, 32↔12, 31↔13, and
23↔21.
Of course, once we rearrange inputs, TWOINHAF will still produce output
DO NOT COPYmove codes corresponding to cells in the top half of the grid. To keep things
straight, we should transform these into codes for the proper cells in the bottom
half of the grid. We would like this transformation to take a minimum of logic.
This is where our choice of output code comes in. If you look carefully at the
MOVE coding defined at the beginning of Table 6-13, you’ll see that the code for
DO NOT COPYa given position in the 180° rotated grid is obtained by complementing and
reversing the order of the code bits for the same position in the unrotated grid. In
other words, the code transformation can be done with four inverters and a
rearrangement of wires. This can be done “for free” in the PLD that looks at the
DO NOT COPYTWOINHAFoutputs.
You probably never thought that Tic-Tac-Toe could be so tricky. Well,
we’re halfway there. Figure 6-13 shows the partitioning of the design as we’ll
DO NOT COPY9
X11-X33
now continue it. Each TWOINROW PLD from our original partition is replaced
TWOINHAF PICK1 Figure 6-13
X11-X33
4
MOVE[3:0] WINA[3:0] COPYFinal PLD partitioning
9 for the Tic-Tac-Toe
Y11-Y33 U1 game.
DO NOTY11-Y33
TWOINHAF
P X11-X33 4
T WINB[3:0]
MOVE[3:0]
DO NOTMOVE[3:0] COPYPICK2
P Y11-Y33 U2
4
TWOINHAF PICK[3:0]
X11-X33
4
DO NOTMOVE[3:0] COP4 Y
BLKA[3:0]
Y11-Y33 U3
TWOINHAF MOVE[3:0] MOVE[3:0]
P X11-X33 T BLKB[3:0]
DO NOT COPY9 Y224
MOVE[3:0] X22
P Y11-Y33 U4 Y22 U5
9 X22
other 14
logic
Copyright © 1999 by John F. Wakerly Copying Prohibited
494 Chapter 6 Combinational Design Examples
by a pair of TWOINHALF PLDs. The bottom PLD of each pair is preceded by a
box labeled “P”, which permutes the inputs to rotate the grid 180° as discussed
DO NOT COPYpreviously. Likewise, it is followed by a box labeled “T”, which compensates for
the rotation by transforming the output code; this box will actually be absorbed
into the PLD that follows it, PICK1.
The function of PICK1 is pretty straightforward. As shown in Table 6-15, it
is simply picks a winning move or a blocking move if one is available. Since
DO NOT COPYthere are two extra input pins available on the 22V10, we use them to input the
state of the center cell. In this way, we can perform the first part of step 3 of the
“human” algorithm on page 488, to pick the center cell if no winning or blocking
DO NOT COPYmove is available. The PICK1 PLD uses at most 9 product terms per output.
Ta b l e 6 - 1 5 ABEL program to pick one move based on four inputs.
module pick1
Title 'Pick One Move from Four Possible'
DO NOT COPYPICK1 device 'P22V10';
" Inputs from TWOINHAF PLDs
WINA3..WINA0 pin 1..4; "Winning moves in cells 11,12,13,21,22
DO NOT COPY" Inputs from grid
WINB3..WINB0 pin 5..8; "Winning moves in cells 11,12,13,21,22 of rotated grid
BLKA3..BLKA0 pin 9..11, 13; "Blocking moves in cells 11,12,13,21,22
BLKB3..BLKB0 pin 14..16, 21; "Blocking moves in cells 11,12,13,21,22 of rotated grid
X22, Y22 pin 22..23; "Center cell; pick if no other moves
" Move outputs to PICK2 PLD
" Sets COPY
DO NOTWINA = [WINA3..WINA0]; WINB = [WINB3..WINB0];
MOVE3..MOVE0 pin 17..20 istype 'com';
BLKA = [BLKA3..BLKA0]; BLKB = [BLKB3..BLKB0];
MOVE = [MOVE3..MOVE0];
" Non-rotated move input and output encoding
DO NOT COPYMOVE11 = [1,0,0,0]; MOVE12 = [0,1,0,0]; MOVE13 = [0,0,1,0];
MOVE21 = [0,0,0,1]; MOVE22 = [1,1,0,0]; MOVE23 = [0,1,1,1];
MOVE31 = [1,0,1,1]; MOVE32 = [1,1,0,1]; MOVE33 = [1,1,1,0];
NONE = [0,0,0,0];
equations
DO NOT COPYWHEN WINA != NONE THEN MOVE = WINA;
ELSE WHEN WINB != NONE THEN MOVE = ![WINB0..WINB3]; " Map rotated coding
ELSE WHEN BLKA != NONE THEN MOVE = BLKA;
ELSE WHEN BLKB != NONE THEN MOVE = ![BLKB0..BLKB3];
ELSE WHEN !X22 & !Y22 THEN MOVE = MOVE22;
DO NOT COPYELSE MOVE = NONE;
" Map rotated coding
" Pick center cell if it’s empty
end pick1
Copyright © 1999 by John F. Wakerly Copying Prohibited
Section 6.2 Design Examples Using ABEL and PLDs 495
The final part of the design in Figure 6-13 is the PICK2 PLD. This PLD
must provide most of the “experience” in step 3 of the human algorithm if PICK1
DO NOT COPYdoesnotfindamove.
We have a little problem with PICK2 in that a 22V10 does not have enough
pins to accommodate the 4-bit input from PICK1, its own 4-bit output, and all 18
bits of grid state; it has only 22 I/O pins. Actually, we don’t need to connect X22
and Y22, since they were already examined in PICK1, but that still leaves us two
DO NOT COPYpins short. So, the purpose of the “other logic” block in Figure 6-13 is to encode
Ta b l e 6 - 1 6 ABEL program to pick one move using “experience.”
module pick2
DO NOT COPYTitle 'Pick a move using experience'
PICK2 device 'P22V10';
" Inputs from PICK1 PLD
PICK3..PICK0
" Inputs from Tic-Tac-Toe grid corners
DO NOT COPYX11, Y11, X13, Y13, X31, Y31, X33, Y33
pin 1..4; " Move, if any, from PICK1 PLD
pin 5..11, 13;
" Combined inputs from external NOR gates; 1 ==> corresponding cell is empty
E12, E21, E23, E32 NOT COPYpin 14..15, 22..23;
" Move output pin 17..20 istype 'com';
DOMOVE3..MOVE0
PICK = [PICK3..PICK0]; " Set definition
" Non-rotated move input and output encoding
MOVE = [MOVE3..MOVE0];
MOVE11 = [1,0,0,0]; MOVE12 = [0,1,0,0]; MOVE13 = [0,0,1,0];
MOVE21 = [0,0,0,1]; MOVE22 = [1,1,0,0]; MOVE23 = [0,1,1,1];
DO NOT COPYMOVE31 = [1,0,1,1]; MOVE32 = [1,1,0,1]; MOVE33 = [1,1,1,0];
NONE = [0,0,0,0];
" Intermediate equations for empty corner cells
E11 = !X11 & !Y11; E13 = !X13 & !Y13; E31 = !X31 & !Y31; E33 = !X33 & !Y33;
DO NOT COPYequations
"Simplest approach -- pick corner if available, else side
WHEN PICK != NONE THEN MOVE = PICK; COPY
ELSE WHEN E11 THEN MOVE = MOVE11;
ELSE WHEN E13 THEN MOVE = MOVE13;
DO NOTELSE WHEN E31 THEN MOVE = MOVE31;
ELSE WHEN E33 THEN MOVE = MOVE33;
ELSE WHEN E12 THEN MOVE = MOVE12;
ELSE WHEN E21 THEN MOVE = MOVE21; COPY
ELSE WHEN E23 THEN MOVE = MOVE23;
ELSE WHEN E32 THEN MOVE = MOVE32;
DO NOTELSE MOVE = NONE;
end pick2
Copyright © 1999 by John F. Wakerly Copying Prohibited
496 Chapter 6 Combinational Design Examples
some of the information to save two pins. The method that we’ll use here is to
combine the signals for the middle edge cells 12, 21, 23, and 32 to produce four
DO NOT COPYsignals E12, E21, E23, and E32 that are asserted if and only if the corresponding
cells are empty. This can be done with four 2-input NOR gates, and actually
leaves two spare inputs or outputs on the 22V10.
Assuming the four NOR gates as “other logic,” Table 6-16 on the preced-
ing page gives a program for the PICK2 PLD. When it must pick a move, this
DO NOT COPYprogram uses the simplest heuristic possible—it picks a corner cell if one is
empty, else it picks a middle edge cell. This program could use some improve-
ment, because it will sometimes lose (see Exercise 6.8). Luckily, the equations
resulting from Table 6-16 require only 8 to 10 terms per output, so it’s possible
DO NOT COPYto put in more intelligence (see Exercises 6.9 and 6.10).
6.3 Design Examples Using VHDL
6.3.1 Barrel Shifter
On page 464, we defined a barrel shifter as a combinational logic circuit with n
DO NOT COPYdata inputs, n data outputs, and a set of control inputs that specify how to shift
the data between input and output. We showed in Section 6.1.1 how to build a
simple barrel shifter that performs only left circular shifts using MSI building
blocks. Later, in Section 6.2.1, we showed how to define a more capable barrel
DO NOT COPYshifter using ABEL, but we also pointed out that PLDs are normally unsuitable
for realizing barrel shifters. In this subsection, we’ll show how VHDL can be
used to describe both the behavior and structure of barrel shifters for FPGA or
ASIC realization.
Table 6-17 is a behavioral VHDL program for a 16-bit barrel shifter that
DO NOT COPYperforms any of six different combinations of shift type and direction. The shift
types are circular, logical, and arithmetic, as defined previously in Table 6-3, and
the directions are of course left and right. As shown in the entity declaration, a
4-bit control input S gives the shift amount, and a 3-bit control input C gives the
shift mode (type and direction). We used the IEEE std_logic_arith package
DO NOT COPYand defined the shift amount S to be type UNSIGNED so we could later use the
CONV_INTEGER function in that package.
Notice that the entity declaration includes six constant definitions that
establish the correspondence between shift modes and the value of C. Although
we didn’t discuss it in Section 4.7, VHDL allows you to put constant, type,
DO NOT COPYsignal, and other declarations within an entity declaration. It makes sense to
define such items within the entity declaration only if they must be the same in
any architecture. In this case, we are pinning down the shift-mode encodings, so
they should go here. Other items should go in the architecture definition.
DO NOT COPYIn the architecture part of the program, we define six functions, one for
each kind of shift on a 16-bit STD_LOGIC_VECTOR. We defined the subtype
DATAWORD to save typing in the function definitions.
Copyright © 1999 by John F. Wakerly Copying Prohibited
Section 6.3 Design Examples Using VHDL 497
Ta b l e 6 - 1 7 VHDL behavioral description of a 6-function barrel shifter.
DO NOT COPYlibrary IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
entity barrel16 is
port (
DO NOT COPYDIN: in STD_LOGIC_VECTOR (15 downto 0); -- Data inputs
S: in UNSIGNED (3 downto 0); -- Shift amount, 0-15
C: in STD_LOGIC_VECTOR (2 downto 0); -- Mode control
DOUT: out STD_LOGIC_VECTOR (15 downto 0) -- Data bus output
);
constant Lrotate: STD_LOGIC_VECTOR := "000"; -- Define the coding of
DO NOT COPYconstant Rrotate: STD_LOGIC_VECTOR := "001"; -- the different shift modes
constant Llogical: STD_LOGIC_VECTOR := "010";
constant Rlogical: STD_LOGIC_VECTOR := "011";
constant Larith: NOTSTD_LOGIC_VECTOR := "100"; COPY
constant Rarith:
STD_LOGIC_VECTOR := "101";
DOend barrel16;
architecture barrel16_behavioral of barrel16 is
subtype DATAWORD is STD_LOGIC_VECTOR(15 downto 0); COPY
function Vrol (D: DATAWORD; S: UNSIGNED)
return DATAWORD is
DO NOTvariable N: INTEGER;
variable TMPD: DATAWORD;
begin COPY
N := CONV_INTEGER(S); TMPD := D;
for i in 1 to N loop
DO NOTTMPD := TMPD(14 downto 0) & TMPD(15);
end loop;
return TMPD;
end Vrol;
...
DO NOT COPYbegin
process(DIN, S, C)
begin
case C is COPY
when Lrotate => DOUT <= Vrol(DIN,S);
when Rrotate => DOUT <= Vror(DIN,S);
DO NOTwhen Llogical => DOUT <= Vsll(DIN,S);
when Rlogical => DOUT <= Vsrl(DIN,S);
when Larith
when Rarith
when others
DO NOTend case;
=> DOUT <= Vsla(DIN,S); COPY
=> DOUT <= Vsra(DIN,S);
=> null;
end process;
end barrel16_behavioral;
Copyright © 1999 by John F. Wakerly Copying Prohibited
498 Chapter 6 Combinational Design Examples
ROLLING VHDL-93 actually has built-in array operators, rol, ror, sll, srl, sla, and sra,
DO NOT COPYYOUR OWN corresponding to the shift operations that we defined in Table 6-3. Since these oper-
ations are not provided in VHDL-87, we’ve defined our own functions in Table 6-17.
Well, actually we’ve only defined one of them (Vrol); the rest are left as an exercise
DO NOT COPYfor the reader (Exercise 6.11).
Table 6-17 shows the details of only the first function (Vrol); the rest are
similar with only a one-line change. We define a variable N for converting the
shift amount S into an integer for the for loop. We also assign the input vector D
DO NOT COPYto a local variable TMPD which is shifted N times in the for loop. In the body of
the for loop, a single assignment statement takes a 15-bit slice of the data word
(TMPD 14 downto 0)) and uses concatenation (&) to put it back together with the
bit that “falls off” the left end (TMPD(15)). Other shift types can be described
with similar operations. Note that the shift functions might not be defined in
DO NOT COPYother, nonbehavioral descriptions of the barrel16 entity, for example in struc-
tural architectures.
The “concurrent statements” part of the architecture is a single process that
has all of the entity’s inputs in its sensitivity list. Within this process, a case
statement assigns a result to DOUT by calling the appropriate function based on
DO NOT COPYthe value of the mode-control input C.
The process in Table 6-17 is a nice behavioral description of the barrel
shifter, but most synthesis tools cannot synthesize a circuit from it. The problem
is that most tools require the range of a for loop to be static at the time it is
analyzed. The range of the for loop in the Vrol function is dynamic; it depends
DO NOT COPYon the value of input signal S when the circuit is operating.
Well, that’s OK, it’s hard to predict what kind of circuit the synthesis tool
would come up with even if it could handle a dynamic for range. This is an
example where as designers we should take little more control over the circuit
DO NOT COPYstructure to obtain a reasonably fast, efficient synthesis result.
In Figure 6-2 on page 466, we showed how to design a 16-bit barrel shifter
for left circular shifts using MSI building blocks. We used a cascade of four
16-bit, 2-input multiplexers to shift their inputs by 0 or 1, 2, 4, or 8 positions
depending of the values of S0 through S3, respectively. We can express the same
DO NOT COPYkind behavior and structure using the VHDL program shown in Table 6-18.
Even though the program uses a process and is therefore “behavioral” in style,
we can be pretty sure that most synthesis engines will generate a 1-input
multiplexer for each “if” statement in the program, thereby creating a cascade
DO NOT COPYsimilarto Figure 6-2.
Copyright © 1999 by John F. Wakerly Copying Prohibited
Section 6.3 Design Examples Using VHDL 499
Ta b l e 6 - 1 8 VHDL program for a 16-bit barrel shifter for left circular shifts only.
DO NOT COPYlibrary IEEE;
use IEEE.std_logic_1164.all;
entity rol16 is
port (
DIN: in STD_LOGIC_VECTOR(15 downto 0);
DO NOT COPYS: in STD_LOGIC_VECTOR (3 downto 0);
-- Data inputs
-- Shift amount, 0-15
DOUT: out STD_LOGIC_VECTOR(15 downto 0) -- Data bus output
);
end rol16;
architecture rol16_arch of rol16 is
DO NOT COPYbegin
process(DIN, S)
variable X, Y, Z: STD_LOGIC_VECTOR(15 downto 0);
begin
if S(0)='1' then X := DIN(14 downto 0) & DIN(15); else X := DIN; end if;
DO NOT COPYif S(1)='1' then Y := X(13 downto 0) & X(15 downto 14); else Y := X; end if;
if S(2)='1' then Z := Y(11 downto 0) & Y(15 downto 12); else Z := Y; end if;
if S(3)='1' then DOUT <= Z(7 downto 0) & Z(15 downto 8); else DOUT <= Z; end if;
end process;
DO NOT COPYend rol16_arch;
Of course, our problem statement requires a barrel shifter that can shift
both left and right. Table 6-19 revises the previous program to do circular shifts
in either direction. An additional input, DIR, specifies the shift direction, 0 for
left, 1 for right. Each rank of shifting is specified by a case statement that picks
DO NOT COPYone of four possibilities based on the values of DIR and the bit of S that controls
that rank. Notice that we created local 2-bit variables CTRLi to hold the pair of
values DIR and S(i); each case statement is controlled by one of these vari-
ables. You might like to eliminate these variables and simply control each case
DO NOT COPYstatement with a concatenation “DIR & S(i)”, but VHDL syntax doesn’t allow
that because the type of this concatenation would be unknown.
A typical VHDL synthesis tool will generate a 3- or 4-input multiplexer for
each of the case statements in Table 6-19. A good synthesis tool will generate
only a 2-input multiplexer for the last case statement.
DO NOT COPYSo, now we have a barrel shifter that will do left or right circular shifts, but
we’re not done yet—we need to take care of the logical and arithmetic shifts in
both directions. Figure 6-14 shows our strategy for completing the design. We
start out with the ROLR16 component that we just completed, and use other logic
DO NOT COPYto control the shift direction as a function of C.
Copyright © 1999 by John F. Wakerly Copying Prohibited
500 Chapter 6 Combinational Design Examples
Ta b l e 6 - 1 9 VHDL program for a 16-bit barrel shifter for left and right circular shifts.
DO NOT COPYlibrary IEEE;
use IEEE.std_logic_1164.all;
entity rolr16 is
port (
DIN: in STD_LOGIC_VECTOR(15 downto 0);
DO NOT COPYS: in STD_LOGIC_VECTOR (3 downto 0);
-- Data inputs
-- Shift amount, 0-15
DIR: in STD_LOGIC; -- Shift direction, 0=>L, 1=>R
DOUT: out STD_LOGIC_VECTOR(15 downto 0) -- Data bus output
);
end rolr16;
DO NOT COPYarchitecture rol16r_arch of rolr16 is
begin
process(DIN, S, DIR)
variable X, Y, Z: STD_LOGIC_VECTOR(15 downto 0);
variable CTRL0, CTRL1, CTRL2, CTRL3: STD_LOGIC_VECTOR(1 downto 0);
DO NOT COPYbegin
CTRL0 := S(0) & DIR; CTRL1 := S(1) & DIR; CTRL2 := S(2) & DIR; CTRL3 := S(3) & DIR;
case CTRL0 is
when "00" | "01" => X := DIN;
when "10" => X := DIN(14 downto 0) & DIN(15);
when "11" => X := DIN(0) & DIN(15 downto 1);
DO NOT COPYwhen others => null; end case;
case CTRL1 is
when "00" | "01" => Y := X;
when "10" => Y := X(13 downto 0) & X(15 downto 14);
when "11" => Y := X(1 downto 0) & X(15 downto 2);
DO NOT COPYwhen others => null; end case;
case CTRL2 is
when "00" | "01" => Z := Y;
when "10" => Z := Y(11 downto 0) & Y(15 downto 12);
when "11" => Z := Y(3 downto 0) & Y(15 downto 4);
when others => null; end case;
DO NOT COPYcase CTRL3 is
when "00" | "01" => DOUT <= Z;
when "10" | "11" => DOUT <= Z(7 downto 0) & Z(15 downto 8);
when others => null; end case;
end process;
DO NOT COPYend rol16r_arch;
Next we must “fix up” some of the result bits if we are doing a logical or
arithmetic shift. For a left logical or arithmetic n-bit shift, we must set the
rightmost n–1 bits to 0 or the original rightmost bit value, respectively. For a
DO NOT COPYright logical or arithmetic n-bit shift, we must set the leftmost n–1 bits to 0 or the
original leftmost bit value, respectively.
Copyright © 1999 by John F. Wakerly Copying Prohibited
Section 6.3 Design Examples Using VHDL 501
DO NOT COPYDIN(15:0)
ROUT(15:0) FIXUP FOUT(15:0) FIXUP
ROLR16 (left) (right)
DOUT(15:0)
ROUT(0) FOUT(15)
S(3:0) Figure 6-14
DO NOT COPYC(2:0)
other logic Barrel-shifter
components.
As shown in Figure 6-14, our strategy is to follow the circular shifter
(ROLR16) with a fix-up circuit (FIXUP) that plugs in appropriate low-order bits
for a left logical or arithmetic shift, and follow that with another fix-up circuit
that plugs in high-order bits for a right logical or arithmetic shift.
DO NOT COPYTable 6-20 is a behavioral VHDL program for the left-shift fix-up circuit.
The circuit has 16 bits of data input and output, DIN and DOUT. Its control inputs
are the shift amount S, an enable input FEN, and the new value FDAT to be
plugged into the fixed-up data bits. For each output bit DOUT(i), the circuit puts
out the fixed-up bit value if i is less than S and the circuit is enabled; else it puts
DO NOT COPYout the unmodified data input DIN(i).
The for loop in Table 6-20 is readily synthesizable, but you can’t really be
sure what kind of logic the synthesis tool will generate. In particular, the “>”
DO NOT COPYTable 6-20 Behavioral VHDL program for left-shift fix-ups.
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
DO NOT COPYentity fixup is
port (
DIN: in STD_LOGIC_VECTOR(15 downto 0); -- Data inputs
DO NOT COPYDOUT: out STD_LOGIC_VECTOR(15 downto 0) -- Data bus output
S: in UNSIGNED(3 downto 0); -- Shift amount, 0-15
FEN: in STD_LOGIC; -- Fixup enable
FDAT: in STD_LOGIC; -- Fixup data
);
end fixup; COPY
architecture fixup_arch of fixup is
begin
DO NOTprocess(DIN, S, FEN, FDAT)
begin
for i in 0 to 15 loop
if (i < CONV_INTEGER(S)) and (FEN = '1') then DOUT(i) <= FDAT;
else DOUT(i) <= DIN(i); end if;
DO NOT COPYend loop;
end process;
end fixup_arch;
Copyright © 1999 by John F. Wakerly Copying Prohibited
502 Chapter 6 Combinational Design Examples
A SERIAL FIX-UP A structural architecture for the fix-up logic is shown in Table 6-21. Here, we have
DO NOT COPYSTRUCTURE defined what is in effect an iterative circuit to create a 16-bit vector FSEL, where
FSEL(i) is 1 if bit i needs fixing up. We start by setting FSEL(15) to 0, since that
bit never needs fixing up. Then we note that for the remaining values of i, FSEL(i)
should be 1 if S equals i+1 or if FSEL(i+1) is already asserted. Thus, the FSEL
assignment within the generate statement creates a serial chain of 2-input OR gates,
DO NOT COPYwhere one input is asserted if S=i (decoded with a 4-input AND gate), and the other
input is connected to the previous OR gate’s output. The DOUT(i) assignment
statement creates 16 2-input multiplexers that select either DIN(i) or the fix-up data
(FDAT) depending of the value of FSEL(i).
Although the serial realization is compact, it is very slow compared to a one
DO NOT COPYthat realizes each FSEL output as a 2-level sum-of-products circuit. However, the
long delay may not matter because the fix-up circuit appears near the end of the data
path. If speed is still a problem, there is a zero-cost trick that cuts the delay in half
DO NOT COPY(seeExercise6.12).
operation in each step of the loop may cause the synthesis of a general-purpose
magnitude comparator, even though one of the operands is a constant and each
output could therefore be generated with no more than a handful of gates. (In
fact, the logic for “7 < CONV_INTEGER(S)” is just a wire, S(3)!) For a structural
DO NOT COPYversion of this function, see the box on this page.
For right shifts, fix-ups start from the opposite end of the data word, so it
would appear that we need a second version of the fix-up circuit. However, we
can use the original version if we just reverse the order of its input and output
bits, as we’ll soon see.
DO NOT COPYTable 6-22 puts together a structural architecture for the complete, 16-bit,
6-function barrel shifter using the design approach of Figure 6-14 on page 501.
The entity declaration for barrel16 is unchanged from the original in Table 6-17
on page 497. The architecture declares two components, rolr16 and fixup;
DO NOT COPYthese use our previous entity definitions. The statement part of the architecture
Ta b l e 6 - 2 1 Structural VHDL architecture for left-shift fix-ups.
architecture fixup_struc of fixup is
DO NOT COPYsignal FSEL: STD_LOGIC_VECTOR(15 downto 0);
-- Fixup select
begin
FSEL(15) <= '0'; DOUT(15) <= DIN(15);
U1: for i in 14 downto 0 generate
FSEL(i) <= '1' when CONV_INTEGER(S) = i+1 else FSEL(i+1);
DOUT(i) <= FDAT when (FSEL(i) = '1' and FEN = '1') else DIN(i);
DO NOT COPYend generate;
end fixup_struc;
Copyright © 1999 by John F. Wakerly Copying Prohibited
Section 6.3 Design Examples Using VHDL 503
instantiates rolr16 and fixup and has several assignment statements that create
needed control signals (the “other logic” in Figure 6-14).
DO NOT COPYFor example, the first assignment statement asserts DIR_RIGHT if C speci-
fies one of the right shifts. The enable inputs for the left and right fix-up circuits
are FIX_LEFT and FIX_RIGHT, asserted for left and right logical and arithmetic
shifts. The fix-up data values are FIX_LEFT_DAT and FIX_RIGHT_DAT.
While all the statements in the architecture execute concurrently, they are
DO NOT COPYlisted in Table 6-22 in the order of the actual dataflow to improve readability.
First, rolr16 is instantiated to perform the basic left or right circular shift as
specified. Its outputs are hooked up to the inputs of the first fixup component
(U2) to handle fix-ups for left logical and arithmetic shifts. Next comes U3, a
DO NOT COPYgenerate statement that reverses the order of the data inputs for the next fixup
Ta b l e 6 - 2 2 VHDL structural architecture for the 6-function barrel shifter.
architecture barrel16_struc of barrel16 is
DO NOT COPYcomponent rolr16 port (
DIN: in STD_LOGIC_VECTOR(15 downto 0); -- Data inputs
S: in UNSIGNED(3 downto 0); -- Shift amount, 0-15
DO NOT COPY); end component;
DIR: in STD_LOGIC; -- Shift direction, 0=>L, 1=>R
DOUT: out STD_LOGIC_VECTOR(15 downto 0) -- Data bus output
component fixup port (
DO NOT COPYFDAT: in STD_LOGIC;
DIN: in STD_LOGIC_VECTOR(15 downto 0); -- Data inputs
S: in UNSIGNED(3 downto 0); -- Shift amount, 0-15
FEN: in STD_LOGIC; -- Fixup enable
-- Fixup data
DOUT: out STD_LOGIC_VECTOR(15 downto 0) -- Data bus output
); end component;
signal DIR_RIGHT, FIX_RIGHT, FIX_RIGHT_DAT, FIX_LEFT, FIX_LEFT_DAT: STD_LOGIC;
DO NOT COPYsignal ROUT, FOUT, RFIXIN, RFIXOUT: STD_LOGIC_VECTOR(15 downto 0);
begin
DIR_RIGHT <= '1' when C = Rrotate or C = Rlogical or C = Rarith else '0';
FIX_LEFT <= '1' when DIR_RIGHT='0' and (C = Llogical or C = Larith) else '0';
FIX_RIGHT <= '1' when DIR_RIGHT='1' and (C = Rlogical or C = Rarith) else '0';
DO NOT COPYFIX_LEFT_DAT <= DIN(0) when C = Larith else '0';
FIX_RIGHT_DAT <= DIN(15) when C = Rarith else '0';
U1: rolr16 port map (DIN, S, DIR_RIGHT, ROUT);
U2: fixup port map (ROUT, S, FIX_LEFT, FIX_LEFT_DAT, FOUT);
U3: for i in 0 to 15 generate RFIXIN(i) <= FOUT(15-i); end generate;
U4: fixup port map (RFIXIN, S, FIX_RIGHT, FIX_RIGHT_DAT, RFIXOUT);
DO NOT COPYU5: for i in 0 to 15 generate DOUT(i) <= RFIXOUT(15-i); end generate;
end barrel16_struc;
Copyright © 1999 by John F. Wakerly Copying Prohibited
504 Chapter 6 Combinational Design Examples
INFORMATION- Based on the encoding of C, you might like to replace the first assignment statement
DO NOT COPYHIDING STYLE in Table 6-21 with “DIR_RIGHT <= C(0)”, which would be guaranteed to lead to a
more efficient realization for that control bit—just a wire! However, this would vio-
late a programming principle of information hiding and lead to possible bugs.
We explicitly wrote the shift encodings using constant definitions in the
barrel16 entity declaration. The architecture does not need to be aware of the
DO NOT COPYencoding details. Suppose that we nevertheless made the architecture change sug-
gested above. If somebody else (or we!) came along later and changed the constant
definitions in the barrel16 entity to make a different encoding, the architecture
would not use the new encodings! Exercise 6.13 asks you to change the definitions
DO NOT COPYso that the cost savings of our suggested change are enabled by the entity definition.
component (U4), which handles fix-ups for right logical and arithmetic shifts.
Finally U5, another generate statement, undoes the bit reversing of U3. Note
DO NOT COPYthat in synthesis, U3 and U5 are merely permutations of wires.
Many other architectures are possible for the original barrel16 entity. In
Exercise 6.14, we suggest an architecture that enables the circular shifting to be
done by the rol16 entity, which uses only 2-input multiplexers, rather than the
DO NOT COPYmoreexpensiverolr16.
6.3.2 Simple Floating-Point Encoder
We defined a simple floating-point number format on page 467, and posed the
design problem of converting a number from fixed-point to this floating point
format. The problem of determining the exponent of the floating-point number
DO NOT COPYmapped nicely into an MSI priority encoder. In an HDL, the same problem maps
into nested “if” statements.
Table 6-23 is a behavioral VHDL program for the floating-point encoder.
Within the fpenc_arch architecture, a nested “if” statement checks the range
of the input B and sets M and E appropriately. Notice that the program uses the
DO NOT COPYIEEE std_logic_arith package; this is done to get the UNSIGNED type and the
comparison operations that go along with it, as we described in Section 5.9.6.
Just to save typing, a variable BU is defined to hold the value of B as converted to
the UNSIGNED type; alternatively, we could have written “UNSIGNED(B)” in each
nested “if” clause.
DO NOT COPYAlthough the code in Table 6-23 is fully synthesizable, some synthesis
tools may not be smart enough to recognize that the nested comparisons require
just one bit to be checked at each level, and might instead generate a full 11-bit
comparator at each level. Such logic would be a lot bigger and slower than what
DO NOT COPYwould be otherwise possible. If faced with this problem, we can always write the
architecture a little differently and more explicitly to help out the tool, as shown
in Table 6-24.
Copyright © 1999 by John F. Wakerly Copying Prohibited
Section 6.3 Design Examples Using VHDL 505
library IEEE; COPYTable 6-23
use IEEE.std_logic_1164.all; Behavioral VHDL
program for fixed-
DO NOTuse IEEE.std_logic_arith.all; point to floating-point
entity fpenc is conversion.
port ();
B: in STD_LOGIC_VECTOR(10 downto 0); -- fixed-point number
M: out STD_LOGIC_VECTOR(3 downto 0); -- floating-point mantissa
DO NOT COPYE: out STD_LOGIC_VECTOR(2 downto 0) -- floating-point exponent
end fpenc;
architecture fpenc_arch of fpenc is
DO NOT COPYbegin
process(B)
variable BU: UNSIGNED(10 downto 0);
begin
BU := UNSIGNED(B);
if BU < 16 then M <= B( 3 downto 0); E <= "000";
DO NOT COPYelsif BU < 32 then M <= B( 4 downto 1); E <= "001";
elsif BU < 64 then M <= B( 5 downto 2); E <= "010";
elsif BU < 128 then M <= B( 6 downto 3); E <= "011";
DO NOT COPYelse
elsif BU < 256 then M <= B( 7 downto 4); E <= "100";
elsif BU < 512 then M <= B( 8 downto 5); E <= "101";
elsif BU < 1024 then M <= B( 9 downto 6); E <= "110";
M <= B(10 downto 7); E <= "111";
end if;
end process;
DO NOT COPYend fpenc_arch;
architecture fpence_arch of fpenc is COPYTable 6-24
begin Alternative VHDL
architecture for
process(B) fixed-point to floating-
point conversion.
DO NOTbegin
if B(10) = '1' then M <= B(10 downto 7); E <= "111";
elsif B(9) = '1' then M <= B( 9 downto 6); E <= "110";
elsif B(8) = '1' then M <= B( 8 downto 5); E <= "101";
elsif B(7) = '1' then M <= B( 7 downto 4); E <= "100";
elsif B(6) = '1' then M <= B( 6 downto 3); E <= "011";
DO NOT COPYelsif B(5) = '1' then M <= B( 5 downto 2); E <= "010";
elsif B(4) = '1' then M <= B( 4 downto 1); E <= "001";
else
end if;
end process;
DO NOT COPYend fpence_arch;
M <= B( 3 downto 0); E <= "000";
Copyright © 1999 by John F. Wakerly Copying Prohibited
506 Chapter 6 Combinational Design Examples
B’S NOT MY TYPE In Table 6-23, we used the expression UNSIGNED(B) to convert B, an array of type
DO NOT COPYSTD_LOGIC_VECTOR, into an array of type UNSIGNED. This is called an explicit type
conversion. VHDL lets you convert between related closely related types by writing
the desired type followed by the value to be converted in parentheses. Two array
types are “closely related” if they have the same element type, the same number of
dimensions, and the same index types (typically INTEGER) or ones that can be type
DO NOT COPYconverted. The values in the old array are placed in corresponding positions, left to
right, in the new array.
On the other hand, we might like to use the real comparators and spend
DO NOT COPYeven more gates to improve the functionality of our design. In particular, the
present design performs truncation rather than rounding when generating the
mantissa bits. A more accurate result is achieved with rounding, but this is a
much more complicated design. First, we will need an adder to add 1 to the
selected mantissa bits when we round up. However, adding 1 when the mantissa
DO NOT COPYis already 1111 will bump us into the next exponent range, so we need to watch
out for this case. Finally, we can never round up if the unrounded mantissa and
exponent are 1111 and 111, because there’s no higher value in our floating-point
representation to round to.
The program in Table 6-25 performs rounding as desired. The function
DO NOT COPYround takes a selected 5-bit slice from the fixed-point number and returns the
four high-order bits, adding 1 if the LSB is 1. Thus, if we think of the binary
point as being just to the left of the LSB, rounding occurs if the truncated part of
the mantissa is 1/2 or more. In each clause in the nested “if” statement in the
DO NOT COPYprocess, the comparison value is selected so that rounding up will occur only if it
does not “overflow,” pushing the result into the next exponent range. Otherwise,
conversion and rounding occurs in the next clause. In the last clause, we ensure
DO NOT COPYthat we do not round up when we’re at the end of the floating-point range.
GOBBLE, GOBBLE The rounding operation does not require a 4-bit adder, only an “incrementer,” since
one of the addends is always 1. Some VHDL tools may synthesize the complete
adder, while others may be smart enough to use an incrementer with far fewer gates.
In some cases, it may not matter. The most sophisticated tools for FPGA and
DO NOT COPYASIC design include gate gobblers. These programs look for gates with constant
inputs and eliminate gates or gate inputs as a result. For example, an AND-gate input
with a constant 1 applied to it can be eliminated, and an AND gate with a constant-0
input can be replaced with a constant-0 signal.
A gate-gobbler program propagates the effects of constant inputs as far as pos-
DO NOT COPYsible in a circuit. Thus, it can transform a 4-bit adder with a constant-1 input into a
more economical 4-bit incrementer.
Copyright © 1999 by John F. Wakerly Copying Prohibited
Section 6.3 Design Examples Using VHDL 507
architecture fpencr_arch of fpenc is
function round (BSLICE: STD_LOGIC_VECTOR(4 downto 0))
DO NOT COPYreturn STD_LOGIC_VECTOR is
Table 6-25
Behavioral VHDL
architecture for fixed-
variable BSU: UNSIGNED(3 downto 0); point to floating-point
begin conversion with
if BSLICE(0) = '0' then return BSLICE(4 downto 1); rounding.
else null;
BSU := UNSIGNED(BSLICE(4 downto 1)) + 1;
DO NOT COPYreturn STD_LOGIC_VECTOR(BSU);
end if;
end;
begin
process(B)
DO NOT COPYvariable BU: UNSIGNED(10 downto 0);
begin
BU := UNSIGNED(B);
DOif BU < 16 then M <= B( 3 downto 0); E <= "000";
elsif BU < 32-1 then M <= round(B( 4 downto 0)); E <= "001";
elsif BU < 64-2 then M <= round(B( 5 downto 1)); E <= "010";
elsif BU < 128-4
NOT COPYthen M <= round(B( 6 downto 2)); E <= "011";
elsif BU < 256-8 then M <= round(B( 7 downto 3)); E <= "100";
elsif BU < 512-16 then M <= round(B( 8 downto 4)); E <= "101";
DO NOT COPYend if;
elsif BU < 1024-32 then M <= round(B( 9 downto 5)); E <= "110";
elsif BU < 2048-64 then M <= round(B(10 downto 6)); E <= "111";
else M <= "1111"; E <= "111";
end process;
end fpencr_arch;
DO NOT COPYOnce again, synthesis results for this behavioral program may or may not
be efficient. Besides the multiple comparison statements, we now must worry
about the multiple 4-bit adders that might be synthesized as a result of the multi-
ple calls to the round function. Restructuring the architecture so that only a
DO NOT COPYsingle adder is synthesized is left as an exercise (6.15).
6.3.3 Dual-Priority Encoder
DO NOT COPYIn this example, we’ll use VHDL to create a behavioral description of a PLD
priority encoder that identifies both the highest-priority and the second-highest-
priority asserted signal among a set of request inputs R(0 to 7), where R(0) has
the highest priority. We’ll use A(2 downto 0) and AVALID to identify the
highest-priority request, asserting AVALID only if a highest-priority request is
DO NOT COPYpresent. Similarly, we’ll use B(2 downto 0) and BVALID to identify the second-
highest-priority request.
Copyright © 1999 by John F. Wakerly Copying Prohibited
508 Chapter 6 Combinational Design Examples
Table 6-26
Behavioral VHDL
DO NOT COPYprogramfora dual
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
priority encoder.
entity Vprior2 is
DO );port (
R: in STD_LOGIC_VECTOR (0 to 7);
A, B: out STD_LOGIC_VECTOR (2 downto 0);
NOT COPYAVALID, BVALID: buffer STD_LOGIC
end Vprior2;
architecture Vprior2_arch of Vprior2 is
DO NOT COPYbegin
process(R, AVALID, BVALID)
begin
DO AVALID <= '0'; BVALID <= '0'; A <= "000"; B <= "000";
for i in 0 to 7 loop
if R(i) = '1' and AVALID = '0' then
NOT COPYA <= CONV_STD_LOGIC_VECTOR(i,3); AVALID <= '1';
elsif R(i) = '1' and BVALID = '0' then
B <= CONV_STD_LOGIC_VECTOR(i,3); BVALID <= '1';
end if;
end loop;
end process;
DO NOT COPYend Vprior2_arch;
Table 6-26 shows a behavioral VHDL program for the priority encoder.
Instead of the nested “if” approach of the previous example, we’ve used a
DO NOT COPY“for” loop. This approach allows us to take care of both the first and the second
priorities within the same loop, working our way from highest to lowest priority.
Besides std_logic_1164, the program uses the IEEE std_logic_arith
package in order to get the CONV_STD_LOGIC_VECTOR function. We also wrote
this function explicitly in Table 4-39 on page 275.
DO NOT COPYNotice in the table that ports AVALID and BVALID are declared as mode
buffer, because they are read within the architecture. If you were stuck with an
entity definition that declared AVALID and BVALID as mode out, you could still
use the same architecture approach, but you would have to declare local
DO NOT COPYvariables corresponding to AVALID and BVALID within the process. Notice also
that we included AVALID and BVALID in the process sensitivity list. Although
this is not strictly necessary, it prevents warnings that the compiler otherwise
would give about using the value of a signal that is not on the sensitivity list.
The nested “if” approach can also be used for the dual-priority encoder,
DO NOT COPYbut it yields a longer program with more accidents waiting to happen, as shown
in Table 6-27. On the other hand, it may yield a better synthesis result; the only
Copyright © 1999 by John F. Wakerly Copying Prohibited
Section 6.3 Design Examples Using VHDL 509
architecture Vprior2i_arch of Vprior2 is COPYTable 6-27
begin Alternative VHDL
architecture for a
DO NOTprocess(R, A, AVALID, BVALID) dual priority encoder.
begin
if R(0) = '1' then A <= "000"; AVALID <= '1';
elsif R(1) = '1' then A <= "001"; AVALID <= '1';
elsif R(2) = '1' then A <= "010"; AVALID <= '1';
elsif R(3) = '1' then A <= "011"; AVALID <= '1';
DO NOT COPYelsif R(4) = '1' then A <= "100"; AVALID <= '1';
elsif R(5) = '1' then A <= "101"; AVALID <= '1';
elsif R(6) = '1' then A <= "110"; AVALID <= '1';
DO NOT COPYend if;
elsif R(7) = '1' then A <= "111"; AVALID <= '1';
else A <= "000"; AVALID <= '0';
if R(1) = '1' and A /= "001" then B <= "001"; BVALID <= '1';
elsif R(2) = '1' and A /= "010" then B <= "010"; BVALID <= '1';
elsif R(3) = '1' and A /= "011" then B <= "011"; BVALID <= '1';
elsif R(4) = '1' and A /= "100" then B <= "100"; BVALID <= '1';
elsif R(5) = '1' and A /= "101" then B <= "101"; BVALID <= '1';
DO NOT COPYelsif R(6) = '1' and A /= "110" then B <= "110"; BVALID <= '1';
elsif R(7) = '1' and A /= "111" then B <= "111"; BVALID <= '1';
else B <= "000"; BVALID <= '0';
end if;
end process;
DO NOT COPYend Vprior2i_arch;
way to know with a particular tool is to synthesize the circuit and analyze the
results in terms of delay and cell or gate count.
Both nested “if” statements and “for” statements may lead to long delay
DO NOT COPYchains in synthesis. To get guarantee that you get a faster dual-priority encoder,
you must follow a structural or semi-structural design approach. For example,
you can start by writing a dataflow model of a fast 8-input priority encoder using
the ideas found in the 74x148 logic diagram (Figure 5-50 on page 375) or in a
DO NOT COPYrelated ABEL program (Table 5-24 on page 378). Then you can put two of these
together in a structure that “knocks out” the highest-priority input in order to
find the second, as we showed in Figure 6-6 on page 471.
DO NOT COPY6.3.4 Cascading Comparators
Cascading comparators is something we typically would not do in a VHDL
behavioral model, because the language and the IEEE std_logic_arith
package let us define comparators of any desired length directly. However, we
may indeed need to write structural or semi-structural VHDL programs that
DO NOT COPYhook up smaller comparator components in a specific way to obtain high
performance.
Copyright © 1999 by John F. Wakerly Copying Prohibited
510 Chapter 6 Combinational Design Examples
Table 6-28
Behavioral VHDL
DO NOT COPYprogram fora 64-bit
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;
comparator.
entity comp64 is
port ( A, B: in STD_LOGIC_VECTOR (63 downto 0);
EQ, GT: out STD_LOGIC );
DO NOT COPYend comp64;
architecture comp64_arch of comp64 is
begin
EQ <= '1' when A = B else '0';
GT <= '1' when A > B else '0';
DO NOT COPYend comp64_arch;
Table 6-28 is a simple behavioral model of a 64-bit comparator with equals
and greater-than outputs. This program uses the IEEE std_logic_unsigned
package, whose built-in comparison functions automatically treat all signals of
DO NOT COPYtype STD_LOGIC_VECTOR as unsigned integers. Although the program is fully
synthesizable, the speed and size of the result depends on the “intelligence” of
the particular tool that is used.
An alternative is to build the comparator by cascading smaller components,
DO NOT COPYsuch as 8-bit comparators. Table 6-29 is the behavioral model of an 8-bit
comparator. A particular tool may or may not synthesize a very fast comparator
from this program, but it’s sure to be significantly faster than a 64-bit comparator
in any case.
Next, we can write a structural program that instantiates eight of these 8-bit
DO NOT COPYcomparators and hooks up their individual outputs through additional logic to
calculate the overall comparison result. One way to do this is shown Table 6-30.
A generate statement creates not only the individual 8-bit comparators, but
DO NOT COPYVHDL program for an use IEEE.std_logic_1164.all;
Table 6-29 library IEEE;
8-bit comparator. use IEEE.std_logic_unsigned.all;
entity comp8 is
port ( A, B: in STD_LOGIC_VECTOR (7 downto 0);
DO NOT COPYEQ, GT: out STD_LOGIC );
end comp8;
architecture comp8_arch of comp8 is
begin
EQ <= '1' when A = B else '0';
DO NOT COPYGT <= '1' when A > B else '0';
end comp8_arch;
Copyright © 1999 by John F. Wakerly Copying Prohibited
Section 6.3 Design Examples Using VHDL 511
Ta b l e 6 - 3 0 VHDL structural architecture for a 64-bit comparator.
DO NOT COPYarchitecture comp64s_arch of comp64 is
component comp8
port ( A, B: in STD_LOGIC_VECTOR (7 downto 0);
EQ, GT: out STD_LOGIC);
end component;
signal EQ8, GT8: STD_LOGIC_VECTOR (7 downto 0); -- =, > for 8-bit slice
DO NOT COPYsignal SEQ, SGT: STD_LOGIC_VECTOR (8 downto 0); -- serial chain of slice results
begin
SEQ(8) <= '1'; SGT(8) <= '0';
U1: for i in 7 downto 0 generate
U2: comp8 port map (A(7+i*8 downto i*8), B(7+i*8 downto i*8), EQ8(i), GT8(i));
SEQ(i) <= SEQ(i+1) and EQ8(i);
DO NOT COPYSGT(i) <= SGT(i+1) or (SEQ(i+1) and GT8(i));
end generate;
EQ <= SEQ(0); GT <= SGT(0);
DO NOT COPYend comp64s_arch;
also cascading logic that serially builds up the overall result from most signifi-
cant to least significant stage.
An unsophisticated tool could synthesize a slow iterative comparator
circuit for our original 64-bit comparator architecture in Table 6-28. In this
DO NOT COPYsituation, the architecture in Table 6-30 yields a faster synthesized circuit
because it explicitly “pulls” out the cascading information for each 8-bit slice
and combines it in a faster combinational circuit (just 8 levels of AND-OR logic,
not 64). A more sophisticated tool might flatten the 8-bit comparator into faster,
non-iterative structure similar to the 74x682 MSI comparator (Figure 5-84 on
DO NOT COPYpage 421), and it might flatten our iterative cascading logic in Table 6-30 into
two-level sum-of-products equations similar to the ones in the ABEL solution
on page 483.
DO NOT COPY6.3.5 Mode-Dependent Comparator
For the next example, let us suppose we have a system in which we need to
compare two 32-bit words under normal circumstances, but where we must
sometimes ignore one or two low-order bits of the input words. The operating
mode is specified by two mode-control bits, M1 and M0, as shown in Table 6-9
DO NOT COPYonpage484.
The desired functionality can be obtained very easily in VHDL using a
case statement to select the behavior by mode, as shown in the program in
Table 6-31. This is a perfectly good behavioral description that is also fully
synthesizable. However, it has one major drawback in synthesis—it will, in all
DO NOT COPYlikelihood, cause the creation of three separate equality and magnitude compar-
ators (32-, 31-, and 30-bit), one for each case in the case statement. The
Copyright © 1999 by John F. Wakerly Copying Prohibited
512 Chapter 6 Combinational Design Examples
Ta b l e 6 - 3 1 VHDL behavioral architecture of a 32-bit mode-dependent comparator.
DO NOT COPYlibrary IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;
DO NOT COPYA, B: in STD_LOGIC_VECTOR (31 downto 0); -- unsigned integers
entity Vmodecmp is
port ( M: in STD_LOGIC_VECTOR (1 downto 0); -- mode
EQ, GT: out STD_LOGIC ); -- comparison results
end Vmodecmp;
architecture Vmodecmp_arch of Vmodecmp is
begin
DO NOT COPYprocess (M, A, B)
begin
case M is
when "00" =>
if A = B then EQ <= '1'; else EQ <= '0'; end if;
if A > B then GT <= '1'; else GT <= '0'; end if;
DO NOT COPYwhen "01" =>
if A(31 downto 1) = B(31 downto 1) then EQ <= '1'; else EQ <= '0'; end if;
if A(31 downto 1) > B(31 downto 1) then GT <= '1'; else GT <= '0'; end if;
when "10" =>
if A(31 downto 2) = B(31 downto 2) then EQ <= '1'; else EQ <= '0'; end if;
if A(31 downto 2) > B(31 downto 2) then GT <= '1'; else GT <= '0'; end if;
DO NOT COPYwhen others => EQ <= '0'; GT <= '0';
end case;
end process;
end Vmodecmp_arch;
DO NOT COPYindividual comparators may or may not be fast, as discussed in the previous sub-
section, but we won’t worry about speed for this example.
A more efficient alternative is to perform just one comparison for the 30
high-order bits of the inputs, and use additional logic that is dependent on mode
to give a final result using the low-order bits as necessary. This approach is
DO NOT COPYshown in Table 6-32. Two variables EQ30 and GT30 are used within the process
to hold the results of the comparison of the 30 high-order bits. A case statement
similar to the previous architecture’s is then used to obtain the final results as a
function of the mode. If desired, the speed of the 30-bit comparison can be opti-
DO NOT COPYmized using the methods discussed in the preceding subsection.
6.3.6 Ones Counter
Several important algorithms include the step of counting the number of “1” bits
in a data word. In fact, some microprocessor instruction sets have been extended
DO NOT COPYrecently to include ones counting as a basic instruction. In this example, let us
suppose that we have a requirement to design a combinational circuit that counts
ones in a 32-bit word as part of the arithmetic and logic unit of a microprocessor.
Copyright © 1999 by John F. Wakerly Copying Prohibited
Section 6.3 Design Examples Using VHDL 513
Ta b l e 6 - 3 2 More efficient architecture for a 32-bit mode-dependent comparator.
DO NOT COPYarchitecture Vmodecpe_arch of Vmodecmp is
begin
process (M, A, B)
variable EQ30, GT30: STD_LOGIC; -- 30-bit comparison results
begin
if A(31 downto 2) = B(31 downto 2) then EQ30 := '1'; else EQ30 := '0'; end if;
DO NOT COPYif A(31 downto 2) > B(31 downto 2) then GT30 := '1'; else GT30 := '0'; end if;
case M is
when "00" =>
if EQ30='1' and A(1 downto 0) = B(1 downto 0) then
EQ <= '1'; else EQ <= '0'; end if;
if GT30='1' or (EQ30='1' and A(1 downto 0) > B(1 downto 0)) then
DO NOT COPYGT <= '1'; else GT <= '0'; end if;
when "01" =>
if EQ30='1' and A(1) = B(1) then EQ <= '1'; else EQ <= '0'; end if;
if GT30='1' or (EQ30='1' and A(1) > B(1)) then
GT <= '1'; else GT <= '0'; end if;
when "10" => EQ <= EQ30; GT <= GT30;
DO NOT COPYwhen others => EQ <= '0'; GT <= '0';
end case;
end process;
end Vmodecpe_arch;
DO NOT COPYOnes counting can be described very easily by a behavioral VHDL
program, as shown in Table 6-33. This program is fully synthesizable, but it may
generate a very slow, inefficient realization with 32 5-bit adders in series.
DO NOT COPYlibrary IEEE;
Table 6-33
use IEEE.std_logic_1164.all; Behavioral VHDL
use IEEE.std_logic_unsigned.all; program for a 32-bit
entity Vcnt1s is
port ( D: in STD_LOGIC_VECTOR (31 downto 0);
DO NOT COPYSUM: out STD_LOGIC_VECTOR (4 downto 0) );
ones counter.
end Vcnt1s;
architecture Vcnt1s_arch of Vcnt1s is COPY
begin COPY
process (D)
variable S: STD_LOGIC_VECTOR(4 downto 0);
DO NOTbegin
S := "00000";
for i in 0 to 31 loop
if D(i) = '1' then S := S + "00001"; end if;
end loop;
DO NOTSUM <= S;
end process;
end Vcnt1s_arch;
Copyright © 1999 by John F. Wakerly Copying Prohibited
514 Chapter 6 Combinational Design Examples
DO NOT COPYD[2:0]2 D[24]
FA 3 D[28]
2 ADDER2
D[5:3] FA 4
2 D[25] ADDER3
D[8:6]FA 3 D[30] D[31]
DO NOT COPYD[11:9]2 ADDER2 5
FA 6
2 D[26] ADDER4 INCR5 SUM[5:0]
D[14:12] FA 3
D[17:15]2ADDER2 D[29]
DO NOT COPYD[20:18]FA 4
2 D[27] ADDER3
FA
3
2 ADDER2
D[23:21]
DO NOT COPYsignalnames P[0:7][1:0]FA
Q[0:3][2:0] R[0:1][3:0] S[4:0]
Figure 6-15 Structure of 32-bit ones counter.
To synthesize a more efficient realization of the ones counter, we must
come up with an efficient structure and then write an architecture that describes
DO NOT COPYit. Such a structure is the adder tree shown in Figure 6-15. A full adder (FA) adds
three input bits to produce a 2-bit sum. Pairs of 2-bit numbers are added by 2-bit
adders (ADDER2), each of which also has a carry input that can include add
another 1-bit input to its sum. The resulting 3-bit sums are combined by 3-bit
adders (ADDER3), and the final pair of 4-bit sums are combined in a 4-bit adder
DO NOT COPY(ADDER4). By making use of the available carry inputs, this tree structure can
combine 31 bits. A separate 5-bit incrementer is used at the end to handle the one
remaining input bit.
The structure of Figure 6-15 can be created nicely by a structural VHDL
architecture, as shown in Table 6-34. The program begins by declaring all of the
DO NOT COPYcomponents that will be used in the design, corresponding to the blocks in the
figure.
The letter under each column of signals in Figure 6-15 corresponds to the
name used for that signal in the program. Each of signals P, Q, and R is an array
with one STD_LOGIC_VECTOR per connection in the corresponding column. The
DO NOT COPYprogram defines a corresponding type for each of these, followed by the actual
signal declaration.
The program in Table 6-34 makes good use of generate statements to
create the multiple adder components on the left-hand side of the figure—eight
DO NOT COPYFAs, four ADDER2s, and two ADDER3s. Finally, it instantiates one each of
ADDER4 and INCR5.
Copyright © 1999 by John F. Wakerly Copying Prohibited
Section 6.3 Design Examples Using VHDL 515
architecture Vcnt1str_arch of Vcnt1str is COPYTable 6-34
VHDL structural
DO NOTcomponent FA port ( A, B, CI: in STD_LOGIC; architecture for a
S, CO: out STD_LOGIC ); 32-bit ones counter.
end component;
component ADDER2 port ( A, B: in STD_LOGIC_VECTOR(1 downto 0);
CI: in STD_LOGIC;
DO NOT COPYS: out STD_LOGIC_VECTOR(2 downto 0) );
end component;
component ADDER3 port ( A, B: in STD_LOGIC_VECTOR(2 downto 0);
CI: in STD_LOGIC;
S: out STD_LOGIC_VECTOR(3 downto 0) );
DO NOT COPYend component;
component ADDER4 port ( A, B: in STD_LOGIC_VECTOR(3 downto 0);
CI: in STD_LOGIC;
S: out STD_LOGIC_VECTOR(4 downto 0) );
DO NOT COPYcomponent INCR5 port ( A: in STD_LOGIC_VECTOR(4 downto 0);
end component;
CI: in STD_LOGIC;
S: out STD_LOGIC_VECTOR(5 downto 0) );
type Ptype is array (0 to 7) of STD_LOGIC_VECTOR(1 downto 0);
DO NOT COPYtype Qtype is array (0 to 3) of STD_LOGIC_VECTOR(2 downto 0);
end component;
type Rtype is array (0 to 1) of STD_LOGIC_VECTOR(3 downto 0);
signal P: Ptype; signal Q: Qtype; signal R: Rtype;
signal S: STD_LOGIC_VECTOR(4 downto 0);
begin
DO NOT COPYU1: for i in 0 to 7 generate
U1C: FA port map (D(3*i), D(3*i+1), D(3*i+2), P(i)(0), P(i)(1));
end generate;
U2: for i in 0 to 3 generate
U2C: ADDER2 port map (P(2*i), P(2*i+1), D(24+i), Q(i));
DO NOT COPYend generate;
U3: for i in 0 to 1 generate
U3C: ADDER3 port map (Q(2*i), Q(2*i+1), D(28+i), R(i));
end generate; COPY
U4: ADDER4 port map (R(0), R(1), D(30), S);
U5: INCR5 port map (S, D(31), SUM);
DO NOTend Vcnt1str_arch;
The definitions of the ones counter’s individual component entities and
architectures, from FA to INCR, can be made in separate structural or behavioral
DO NOT COPYprograms. For example, Table 6-35 is a structural program for FA. The rest of the
components are left as exercises (6.20–6.22).
Copyright © 1999 by John F. Wakerly Copying Prohibited
516 Chapter 6 Combinational Design Examples
Table 6-35
Structural VHDL
DO NOT COPYprogramfora
library IEEE;
use IEEE.std_logic_1164.all;
full adder. entity FA is
port ( A, B, CI: in STD_LOGIC;
DO NOT COPYarchitecture FA_arch of FA is
S, CO: out STD_LOGIC );
end FA;
begin
S <= A xor B xor CI;
CO <= (A and B) or (A and CI) or (B and CI);
DO NOT COPYend FA_arch;
6.3.7 Tic-Tac-Toe
Our last example is the design of a combinational circuit that picks a player’s
next move in the game of Tic-Tac-Toe. In case you’re not familiar with the game,
DO NOT COPYthe rules are explained in the box on page 488. We’ll repeat here our strategy for
playing and winning the game:
DO 1. Look for a row, column, or diagonal that has two of my marks (X or O,
depending on which player I am) and one empty cell. If one exists, place
NOT COPYmy mark in the empty cell; I win!
2. Else, look for a row, column, or diagonal that has two of my opponent’s
marks and one empty cell. If one exists, place my mark in the empty cell
DO to block a potential win by my opponent.
3. Else, pick a cell based on experience. For example, if the middle cell is
NOT COPYopen, it’s usually a good bet to take it. Otherwise, the corner cells are good
bets. Intelligent players can also notice and block a developing pattern by
the opponent or “look ahead” to pick a good move.
To avoid confusion between “O” and “0” in our programs, we’ll call the
DO NOT COPYsecond player “Y”. Now we can think about how to encode the inputs and out-
puts of the circuit. The inputs represent the current state of the playing grid.
There are nine cells, and each cell has one of three possible states (empty, occu-
pied by X, occupied by Y). The outputs represent the move to make, assuming
that it is X’s turn. There are only nine possible moves that a player can make, so
DO NOT COPYthe output can be encoded in just four bits.
There are several choices of how to code the state of one cell. Because the
game is symmetric, we choose a symmetric encoding that can help us later:
00 Cell is empty.
DO NOT COPY10 Cellisoccupiedby X.
01 Cell is occupied by Y.
Copyright © 1999 by John F. Wakerly Copying Prohibited
Section 6.3 Design Examples Using VHDL 517
library IEEE; COPYTable 6-36
VHDL package with
DO NOTuse IEEE.std_logic_1164.all; definitions for the
Tic-Tac-Toe project.
package TTTdefs is
type TTTgrid is array (1 to 3) of STD_LOGIC_VECTOR(1 to 3);
subtype TTTmove is STD_LOGIC_VECTOR (3 downto 0);
DO NOT COPYconstant MOVE11: TTTmove := "1000";
constant MOVE12: TTTmove := "0100";
constant MOVE13: TTTmove := "0010"; COPY
constant MOVE21: TTTmove := "0001";
constant MOVE22: TTTmove := "1100";
constant MOVE23: TTTmove := "0111";
DO NOTconstant MOVE31: TTTmove := "1011";
constant MOVE32: TTTmove := "1101";
constant MOVE33: TTTmove := "1110"; COPY
constant NONE: TTTmove := "0000";
DO NOTend TTTdefs;
So, we can encode the 3 × 3 grid’s state in 18 bits. Since VHDL supports
arrays, it is useful to define an array type, TTTgrid, that contains elements
corresponding to the cells in the grid. Since this type will be used throughout our
DO NOT COPYTic-Tac-Toe project, it is convenient to put this definition, along with several
others that we’ll come to, in a VHDL package, as shown in Table 6-36.
It would be natural to define TTTgrid as a two-dimensional array of
STD_LOGIC, but not all VHDL tools support two-dimensional arrays. Instead,
DO NOT COPYwe define it as an array of 3-bit STD_LOGIC_VECTORs, which is almost the same
thing. To represent the Tic-Tac-Toe grid, we’ll use two signals X and Y of this
type, where an element of a variable is 1 if the like-named player has a mark in
the corresponding cell. Figure 6-11 shows the correspondence between signal
DO NOT COPYnames andcellsinthegrid.
1 2 3 column Figure 6-16
Tic-Tac-Toe grid and
row VHDL signal names.
1 X(1)(1) X(1)(2) X(1)(2)
DO NOT COPYY(1)(1) Y(1)(2) Y(1)(2)
2 X(2)(1) X(2)(2) X(2)(2)
COPY
Y(2)(1) Y(2)(2) Y(2)(2)
DO NOT3 X(3)(1) X(3)(2) X(3)(2)
Y(3)(1) Y(3)(2) Y(3)(2)
Copyright © 1999 by John F. Wakerly Copying Prohibited
518 Chapter 6 Combinational Design Examples
DO NOT9 TwoInRow COPYPICK
DO X WINMV
X
Figure 6-17 4
DOEntity partitioning for MOVE
the Tic-Tac-Toe game. 9
NOTY Y U1 MOVECOPY4MOVE
TwoInRow
X 4
MOVE BLKMV
NOTY U2 CX OPY
9 Y U3
9
The package in Table 6-36 also defines a 4-bit type TTTmove for encoded
moves. A player has nine possible moves, and one more code is used for the case
DO NOT COPYwhere no move is possible. This particular coding was chosen and used in the
package for no other reason than that it’s the same coding that was used in the
ABEL version of this example in Section 6.2.7. By defining the coding in the
package, we can easily change the definition later without having to change the
DO NOT COPYentities that use it (for example, see Exercise 6.23).
Rather than try to design the Tic-Tac-Toe move-finding circuit as a single
monolithic entity, it makes sense for us to try to partition it into smaller pieces. In
fact, partitioning it along the lines of the three-step strategy at the beginning of
this section seems like a good idea.
DO NOT COPYWe note that steps 1 and 2 of our strategy are very similar; they differ only
in reversing the roles of the player and the opponent. An entity that finds a win-
ning move for me can also find a blocking move for my opponent. Looking at
this characteristic from another point of view, an entity that finds a winning
move for me can find a blocking move for me if the encodings for me and my
DO NOT COPYopponent are swapped. Here’s where our symmetric encoding pays off—we can
swap players merely by swapping signals X and Y.
With this in mind, we can use two copies of the same entity, TwoInRow, to
perform steps 1 and 2 as shown in Figure 6-17. Notice that signal X is connected
to the top input of the first TwoInRow entity, but to the bottom input of the sec-
DO NOT COPYond. A third entity, PICK, picks a winning move if one is available from U1, else
it picks a blocking move if available from U2, else it uses “experience” (step 3)
to pick a move.
Table 6-37 is a structural VHDL program for the top-level entity, GETMOVE.
DO NOT COPYIn addition to the IEEE std_logic_1164 package, it uses our TTTdefs
package. Notice that the “use” clause for the TTTdefs packages specifies that it
is stored in the “work” library, which is automatically created for our project.
Copyright © 1999 by John F. Wakerly Copying Prohibited
Section 6.3 Design Examples Using VHDL 519
library IEEE; COPYTable 6-37
use IEEE.std_logic_1164.all; Top-level structural
VHDL entity for
DO NOTuse work.TTTdefs.all; picking a move in
Tic-Tac-Toe.
entity GETMOVE is
port ( X, Y: in TTTgrid; COPY
MOVE: out TTTmove );
DO NOTend GETMOVE;
architecture GETMOVE_arch of GETMOVE is
component TwoInRow port ( X, Y: in TTTgrid;
MOVE: out STD_LOGIC_VECTOR(3 downto 0) );
DO NOT COPYend component;
component PICK port ( X, Y: in TTTgrid;
WINMV, BLKMV: in STD_LOGIC_VECTOR(3 downto 0);
DO NOT COPYend component;
MOVE: out STD_LOGIC_VECTOR(3 downto 0) );
signal WIN, BLK: STD_LOGIC_VECTOR(3 downto 0);
begin COPY
U1: TwoInRow port map (X, Y, WIN);
U2: TwoInRow port map (Y, X, BLK);
DO NOTU3: PICK port map (X, Y, WIN, BLK, MOVE);
end GETMOVE_arch;
The architecture in Table 6-37 declares and uses just two components,
DO NOT COPYTwoInRow and PICK, which will be defined shortly. The only internal signals are
WIN and BLK, which pass winning and blocking moves from the two instances of
TwoInRow to PICK, as in Figure 6-17. The statement part of the architecture has
just three statements to instantiate the three blocks in the figure.
Now comes the interesting part, the design of the individual entities in
DO NOT COPYFigure 6-17. We’ll start with TwoInRow since it accounts for two-thirds of the
design. Its entity definition is very simple, as shown in Table 6-38. But there’s
plenty to discuss about its architecture, shown in Table 6-39.
DO NOT COPYlibrary IEEE;
Table 6-38
use IEEE.std_logic_1164.all; Declaration of
use work.TTTdefs.all; COPYTwoInRow entity.
entity TwoInRow is
port ( X, Y: in TTTgrid;
DO NOTMOVE: out TTTmove );
end TwoInRow;
Copyright © 1999 by John F. Wakerly Copying Prohibited
520 Chapter 6 Combinational Design Examples
Ta b l e 6 - 3 9 Architecture of TwoInRow entity.
DO NOT COPYarchitecture TwoInRow_arch of TwoInRow is
function R(X, Y: TTTgrid; i, j: INTEGER) return BOOLEAN is
variable result: BOOLEAN;
begin
result := TRUE;
DO NOT COPYfor jj in 1 to 3 loop
-- Find 2-in-row with empty cell i,j
if jj = j then result := result and X(i)(jj)='0' and Y(i)(jj)='0';
else result := result and X(i)(jj)='1'; end if;
end loop;
return result;
DO NOT COPYend R;
function C(X, Y: TTTgrid; i, j: INTEGER) return BOOLEAN is
variable result: BOOLEAN;
begin
result := TRUE;
DO NOT COPYfor ii in 1 to 3 loop
-- Find 2-in-column with empty cell i,j
if ii = i then result := result and X(ii)(j)='0' and Y(ii)(j)='0';
else result := result and X(ii)(j)='1'; end if;
end loop;
return result;
DO NOT COPYend C;
function D(X, Y: TTTgrid; i, j: INTEGER) return BOOLEAN is
-- Find 2-in-diagonal with empty cell i,j.
-- This is for 11, 22, 33 diagonal.
variable result: BOOLEAN;
begin
result := TRUE;
DO NOT COPYfor ii in 1 to 3 loop
if ii = i then result := result and X(ii)(ii)='0' and Y(ii)(ii)='0';
else result := result and X(ii)(ii)='1'; end if;
end loop;
return result;
DO NOT COPYend D;
function E(X, Y: TTTgrid; i, j: INTEGER) return BOOLEAN is
variable result: BOOLEAN; -- Find 2-in-diagonal with empty cell i,j.
DO NOT COPYif ii = i then result := result and X(ii)(4-ii)='0' and Y(ii)(4-ii)='0';
begin -- This is for 13, 22, 31 diagonal.
result := TRUE;
for ii in 1 to 3 loop
else result := result and X(ii)(4-ii)='1'; end if;
end loop;
return result;
DO NOT COPYend E;
Copyright © 1999 by John F. Wakerly Copying Prohibited
Section 6.3 Design Examples Using VHDL 521
begin
process (X, Y)
DO NOT COPYvariable G11, G12, G13, G21, G22, G23, G31, G32, G33: BOOLEAN;
Table 6-39
(continued)
begin
G11 := R(X,Y,1,1) or C(X,Y,1,1) or D(X,Y,1,1);
G12 := R(X,Y,1,2) or C(X,Y,1,2);
G13 := R(X,Y,1,3) or C(X,Y,1,3) or E(X,Y,1,3);
G21 := R(X,Y,2,1) or C(X,Y,2,1);
DO NOT COPYG22 := R(X,Y,2,2) or C(X,Y,2,2) or D(X,Y,2,2) or E(X,Y,2,2);
G23 := R(X,Y,2,3) or C(X,Y,2,3);
G31 := R(X,Y,3,1) or C(X,Y,3,1) or E(X,Y,3,1); COPY
G32 := R(X,Y,3,2) or C(X,Y,3,2);
G33 := R(X,Y,3,3) or C(X,Y,3,3) or D(X,Y,3,3);
DO NOTif G11 then MOVE <= MOVE11;
elsif G12 then MOVE <= MOVE12;
elsif G13 then MOVE <= MOVE13;
elsif G21 then MOVE <= MOVE21; COPY
elsif G22 then MOVE <= MOVE22;
elsif G23 then MOVE <= MOVE23;
DO NOTelsif G31 then MOVE <= MOVE31;
elsif G32 then MOVE <= MOVE32;
elsif G33 then MOVE <= MOVE33;
DO NOTend TwoInRow_arch; COPY
else MOVE <= NONE;
end if;
end process;
The architecture defines several functions, each of which determines
whether there is a winning move (from X’s point of view) in a particular cell i,j.
DO NOT COPYA winning move exists if cell i,j is empty and the other two cells in the same
row, column, or diagonal contain an X. Functions R and C look for winning
moves in cell i,j’s row and column, respectively. Functions D and E look in the
two diagonals.
Within the architecture’s single process, nine BOOLEAN variables G11–G33
DO NOT COPYare declared to indicate whether each of the cells has a winning move possible.
Assignment statements at the beginning of the process set each variable to TRUE
if there is such a move, calling and combining all of the appropriate functions for
cell i,j.
DO NOT COPYThe rest of the process is a deeply nested “if” statement that looks for a
winning move in all possible cells. Although it typically results in slower synthe-
sized logic nested “if” is required rather than some form of “case” statement,
because multiple moves may be possible. If no winning move is possible, the
DO NOT COPYvalue “NONE” isassigned.
Copyright © 1999 by John F. Wakerly Copying Prohibited
522 Chapter 6 Combinational Design Examples
EXPLICIT In addition to a cell index i,j, the functions R, C, D, and E in Table 6-39 are passed
DO NOT COPYIMPURITY the grid state X and Y. This is necessary because VHDL functions are by default pure,
which means that signals and variables declared in the function’s parents are not
directly visible within the function. However, you can relax this restriction by
explicitly declaring a function to be impure by placing the keyword impure before
DO NOT COPYthe keyword function in its definition.
The PICK entity combines the results of two TwoInRow entities according
to the program in Table 6-40. First priority is given to a winning move, followed
by a blocking move. Otherwise, function MT is called for each cell, starting with
DO NOT COPYthe middle and ending with the side cells, to find an available move. This com-
pletes the design of the Tic-Tac-Toe circuit.
DO NOTa winning or blocking use work.TTTdefs.all; COPY
Table 6-40 library IEEE;
VHDL program to pick use IEEE.std_logic_1164.all;
Tic-Tac-Toe move, or entity PICK is
DO NOT COPYelse use “experience.”
port ( X, Y: in TTTgrid;
WINMV, BLKMV: in STD_LOGIC_VECTOR(3 downto 0);
MOVE: out STD_LOGIC_VECTOR(3 downto 0) );
end PICK;
architecture PICK_arch of PICK is
DO NOT COPYend MT;
function MT(X, Y: TTTgrid; i, j: INTEGER) return BOOLEAN is
begin -- Determine if cell i,j is empty
return X(i)(j)='0' and Y(i)(j)='0';
begin
DO process (X, Y, WINMV, BLKMV)
begin
if WINMV /= NONE then MOVE <= WINMV;
NOT COPYelsif BLKMV /= NONE then MOVE <= BLKMV;
-- If available, pick:
-- winning move
-- else blocking move
elsif MT(X,Y,2,2) then MOVE <= MOVE22; -- else center cell
elsif MT(X,Y,1,1) then MOVE <= MOVE11; -- else corner cells
DO NOT COPYelsif MT(X,Y,1,3)
elsif MT(X,Y,3,1)
elsif MT(X,Y,3,3)
elsif MT(X,Y,1,2)
then MOVE <= MOVE13;
then MOVE <= MOVE31;
then MOVE <= MOVE33;
then MOVE <= MOVE12; -- else side cells
elsif MT(X,Y,2,1) then MOVE <= MOVE21;
then MOVE <= MOVE23;
then MOVE <= MOVE32;
MOVE <= NONE; -- else grid is full
DO NOT COPYelsif MT(X,Y,2,3)
elsif MT(X,Y,3,2)
else
end if;
end process;
end PICK_arch;
Copyright © 1999 by John F. Wakerly Copying Prohibited
Exercises 523
Exercises
6.1 Explain how the 16-bit barrel shifter of Section 6.1.1 can be realized with a com-
DO NOT COPYbination of 74x157s and 74x151s. How does this approach compare with the
others in delay and parts count?
6.2 Show how the 16-bit barrel shifter of Section 6.1.1 can be realized in eight
identical GAL22V10s.
6.3 Find a coding of the shift amounts (S[3:0]) and modes (C[2:0]) in the barrel
DO NOT COPYshifter of Table 6-3 that further reduces the total number of product terms used by
the design.
6.4 Make changes to the dual priority encoder program of Table 6-6 to further reduce
the number of product terms required. State whether your changes increase the
delay of the circuit when realized in a GAL22V10. Can you reduce the product
DO NOT COPYterms enough to fit the design into a GAL16V8?
6.5 Here’s an exercise where you can use your brain, like the author had to when
figuring out the equation for the SUM0 output in Table 6-12. Do each of the
SUM1–SUM3 outputs require more terms or fewer terms than SUM0?
DO NOT COPY6.6 Complete the design of the ABEL and PLD based ones counting circuit that was
started in Section 6.2.6. Use 22V10 or smaller PLDs, and try to minimize the total
number of PLDs required. State the total delay of your design in terms of the
worst-case number of PLD delays in a signal path from input to output.
6.7 Find another code for the Tic-Tac-Toe moves in Table 6-13 that has the same rota-
DO NOT COPYtion properties as the original code. That is, it should be possible to compensate
for a 180° rotation of the grid using just inverters and wire rearrangement. Deter-
mine whether the TWOINHAF equations will still fit in a single 22V10 using the
new code.
6.8 Using a simulator, demonstrate a sequence of moves in which the PICK2 PLD in
DO NOT COPYTable 6-16 will lose a Tic-Tac-Toe game, even if X goes first.
6.9 Modify the program in Table 6-16 to give the program a better chance of winning,
or at least not losing. Can your new program still lose?
6.10 Modify the both the “other logic” in Figure 6-13 and the program in Table 6-16
to give the program a better chance of winning, or at least not losing. Can your
DO NOT COPYnew program stilllose?
6.11 Write the VHDL functions for Vror, Vsll, Vsrl, Vsla, and Vsra in Table 6-17
using the ror, sll, srl, sla, and sra operations as defined in Table 6-3.
6.12 The iterative-circuit version of fixup in Table 6-20 has a worst-case delay path
of 15 OR gates from the first decoded value of i (14) to the FSEL(0) signal.
DO NOT COPYFigure out a trick that cuts this delay path almost in half with no cost (or negative
cost) in gates. How can this trick be extended further to save gates or gate inputs?
6.13 Rewrite the barrel16 entity definition in Table 6-17 and the architecture in
Table 6-22 so that a single direction-control bit is made explicitly available to the
DO NOT COPYarchitecture.
Copyright © 1999 by John F. Wakerly Copying Prohibited
524 Chapter 6 Combinational Design Examples
DO NOT COPYDIN(15:0)MOUT(15:0) ROUT(15:0) FOUT(15:0)
MAGIC ROL16 FIXUP MAGIC DOUT(15:0)
ROUT(0)
S(3:0)
other logic
C(2:0)
DO NOT COPYFigureX6.14
6.14 Rewrite the barrel16 architecture definition in Table 6-22 to use the approach
shown in Figure X6.14.
6.15 Write a semi-behavioral or structural version of the fpencr_arch architecture of
Table 6-25 that generates only one adder in synthesis, and that does not generate
DO NOT COPYmultiple 10-bit comparators for the nested “if” statement.
6.16 Repeat Exercise 6.15, including a structural definition of an efficient rounding
circuit that performs the round function. Your circuit should require significantly
fewer gates than a 4-bit adder.
6.17 Redesign the VHDL dual priority encoder of Section 6.3.3 to get better, known
DO NOT COPYperformance, as suggested in the last paragraph of the section.
6.18 Write a structural VHDL architecture for a 64-bit comparator that is similar to
Table 6-30 except that it builds up the comparison result serially from least to
most significant stage.
DO NOT COPY6.19 What significant change occurs in the synthesis of the VHDL program in
Table 6-31 if we change the statements in the “when others” case to “null”?
6.20 Write behavioral VHDL programs for the “ADDERx” components used in
Table 6-34.
6.21 Write a structural VHDL programs for the “ADDERx” components in Table 6-34.
DO NOT COPYUse a generic definition so that the same entity can be instantiated for ADDER2,
ADDER3, and ADDER5, and show what changes must be made in Table 6-34 to
do this.
6.22 Write a structural VHDL program for the “INCR5” component in Table 6-34.
6.23 Using an available VHDL synthesis tool, synthesize the Tic-Tac-Toe design of
DO NOT COPYSection 6.3.7, fit it into an available FPGA, and determine how many internal
resources it uses. Then try to reduce the resource requirements by specifying a
different encoding of the moves in the TTTdefs package.
6.24 The Tic-Tac-Toe program in Section 6.3.7 eventually loses against an intelligent
opponent if applied to the grid state shown in Figure X6.24. Use an available
VHDL simulator to prove that this is true. Then modify the PICK entity to win in
Y
DO NOT COPYX
this and similar situations and verify your design using the simulator.
Y
DO NOT COPYFigureX6.24
Copyright © 1999 by John F. Wakerly Copying Prohibited
••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••DO NOT 7c h a p t e r
COPY
DO NOT
Sequential
COPYLogic Design Principles
LDO NOTogic circuits are classified into two types, “combinational” and
“sequential.” A combinational logic circuit is one whose outputs
depend only on its current inputs. The rotary channel selector knob
COPYon an old-fashioned TV is like a combinational circuit—its
“output” selects a channel based only on its current “input”—the position of
the knob.
A sequential logic circuit is one whose outputs depend not only on its
current inputs, but also on the past sequence of inputs, possibly arbitrarily
DO NOTfar back in time. The circuit controlled by the channel-up and channel-down
pushbuttons on a TV or VCR is a sequential circuit—the channel selection
depends on the past sequence of up/down pushes, at least since when you
started viewing 10 hours before, and perhaps as far back as when you first
plugged the device into the wall.
COPYSo it is inconvenient, and often impossible, to describe the behavior of
a sequential circuit by means of a table that lists outputs as a function of the
input sequence that has been received up until the current time. To know
where you’re going next, you need to know where you are now. With the
TV channel selector, it is impossible to determine what channel is currently
DO NOTselected by looking only at the preceding sequence of presses on the up and
down pushbuttons, whether we look at the preceding 10 presses or the
preceding 1,000. More information, the current “state” of the channel
selector, is needed. Probably the best definition of “state” that I’ve seen
Copyright © 1999 by John F. Wakerly Copying Prohibited 431
432 Chapter 7 Sequential Logic Design Principles
appeared in Herbert Hellerman’s book on Digital Computer System Principles
(McGraw-Hill, 1967):
DO NOT COPYstate The state of a sequential circuit is a collection of state variables whose
state variable values at any one time contain all the information about the past necessary
to account for the circuit’s future behavior.
In the channel-selector example, the current channel number is the current
DO NOT COPYstate. Inside the TV, this state might be stored as seven binary state variables
representing a decimal number between 0 and 127. Given the current state
(channel number), we can always predict the next state as a function of the inputs
(presses of the up/down pushbuttons). In this example, one highly visible output
of the sequential circuit is an encoding of the state itself—the channel-number
DO NOT COPYdisplay. Other outputs, internal to the TV, may be combinational functions of the
state alone (e.g., VHF/UHF/cable tuner selection) or of both state and input
(e.g., turning off the TV if the current state is 0 and the “down” button is
pressed).
State variables need not have direct physical significance, and there are
DO NOT COPYoften many ways to choose them to describe a particular sequential circuit. For
example, in the TV channel selector, the state might be stored as three BCD
digits or 12 bits, with many of the bit combinations (4,096 possible) going
unused.
DO NOT COPYIn a digital logic circuit, state variables are binary values, corresponding to
certain logic signals in the circuit, as we’ll see in later sections. A circuit with n
binary state variables has 2n possible states. As large as it might be, 2n is always
DO NOT COPYfinite-statemachine
finite, never infinite, so sequential circuits are sometimes called finite-state
machines.
The state changes of most sequential circuits occur at times specified by a
clock free-running clock signal. Figure 7-1 gives timing diagrams and nomenclature
for typical clock signals. By convention, a clock signal is active high if state
changes occur at the clock’s rising edge or when the clock is HIGH, and active
low in the complementary case. The clock period is the time between successive
transitions in the same direction, and the clock frequency is the reciprocal of the
clock period
DO NOT COPYclockfrequency
clock tick period. The first edge or pulse in a clock period or sometimes the period itself is
called a clock tick. The duty cycle is the percentage of time that the clock signal
DO NOT COPYdutycycle
NON-FINITE- A group of mathematicians recently proposed a non-finite-state machine, but they’re
DO NOT COPYSTATEMACHINES
still busy listing its states. . . . Sorry, that’s just a joke. There are mathematical mod-
els for infinite-state machines, such as Turing machines. They typically contain a
small finite-state-machine control unit, and an infinite amount of auxiliary memory,
such as an endless tape.
Copyright © 1999 by John F. Wakerly Copying Prohibited
Section 7.1 Bistable Elements 433
(a)
DO NOT COPYCLK
state changes occur here
tH tL period = tper
tper frequency = 1 / tper
duty cycle = tH / tper
DO NOT COPY(b) statechangesoccurhere
CLK_L Figure 7-1
DO Clock signals:
tL
NOT COPYtper
tH (a) active high;
(b) active low.
duty cycle = tL / tper
is at its asserted level. Typical digital systems, from digital watches to supercom-
puters, use a quartz-crystal oscillator to generate a free-running clock signal.
Clock frequencies might range from 32.768 kHz (for a watch) to 500 MHz (for a
CMOS RISC microprocessor with a cycle time of 2 ns); “typical” systems using
DO NOT COPYTTL and CMOS parts have clock frequencies in the 5–150 MHz range.
In this chapter we’ll discuss two types of sequential circuits that account
for the majority of practical discrete designs. A feedback sequential circuit uses
ordinary gates and feedback loops to obtain memory in a logic circuit, thereby
creating sequential-circuit building blocks such as latches and flip-flops that are
DO NOT COPYused in higher-level designs. A clocked synchronous state machine uses these
feedback sequential
circuit
clocked synchronous
building blocks, in particular edge-triggered D flip-flops, to create circuits state machine
whose inputs are examined and whose outputs change in accordance with a
controlling clock signal. There are other sequential circuit types, such as general
DO NOT COPYfundamental mode, multiple pulse mode, and multiphase circuits, which are
sometimes useful in high-performance systems and VLSI, and are discussed in
advanced texts.
DO NOT COPY7.1 Bistable Elements
The simplest sequential circuit consists of a pair of inverters forming a feedback
loop, as shown in Figure 7-2. It has no inputs and two outputs, Q and Q_L.
7.1.1 Digital Analysis
DO NOT COPYThe circuit of Figure 7-2 is often called a bistable, since a strictly digital analysis bistable
shows that it has two stable states. If Q is HIGH, then the bottom inverter has a
HIGH input and a LOW output, which forces the top inverter’s output HIGH as
we assumed in the first place. But if Q is LOW, then the bottom inverter has a
LOW input and a HIGH output, which forces Q LOW, another stable situation.
DO NOT COPYWe could use a single state variable, the state of signal Q, to describe the state of
the circuit; there are two possible states, Q = 0 and Q = 1.
Copyright © 1999 by John F. Wakerly Copying Prohibited
434 Chapter 7 Sequential Logic Design Principles
DO NOT COPYFigure 7-2 Vin1 Vout1 Q
DO
NOT COPYA pair of inverters forming Vin2 Vout2 Q_L
a bistable element.
The bistable element is so simple that it has no inputs and therefore no way
of controlling or changing its state. When power is first applied to the circuit, it
randomly comes up in one state or the other and stays there forever. Still, it
serves our illustrative purposes very well, and we will actually show a couple of
DO NOT COPYapplications for it in Sections 8.2.3 and 8.2.4.
7.1.2 Analog Analysis
The analysis of the bistable has more to reveal if we consider its operation from
an analog point of view. The dark line in Figure 7-3 shows the steady-state (DC)
transfer function T for a single inverter; the output voltage is a function of input
DO NOT COPYvoltage, Vout = T(Vin). With two inverters connected in a feedback loop as in
Figure 7-2, we know that Vin1 = Vout2 and Vin2 = Vout1; therefore, we can plot the
transfer functions for both inverters on the same graph with an appropriate
labeling of the axes. Thus, the dark line is the transfer function for the top
DO NOT COPYinverter in Figure 7-2, and the colored line is the transfer function for the bottom
one.
Considering only the steady-state behavior of the bistable’s feedback loop,
and not dynamic effects, the loop is in equilibrium if the input and output
voltages of both inverters are constant DC values consistent with the loop
DO NOT COPYconnection and the inverters’ DC transfer function. That is, we must have
Vin1 = Vout2
DO NOT COPY= T(Vin2)
= T(Vout1)
= T(T(Vin1))
Figure 7-3 stableVout1
DOTransfer functions for NOT COPY=Vin2
metastable Transfer function:
inverters in a bistable
feedback loop. Vout1 = T(Vin1)
Vout2 = T(Vin2)
DO NOT COPYstable
Vin1 = Vout2
Copying Prohibited
Copyright © 1999 by John F. Wakerly