35 views

Uploaded by hjmesa

- Module 5 - Arithmetic Operations Advanced Assembly4
- digital
- Digital System Design Bee3133
- Ari Th Circuits 1
- DG Lab- 2019-20.pdf
- Design the High Speed Kogge-Stone Adder by Using
- Verilog Codes
- High Speed ALU Processor by Using Efficient Multiplication Technique
- ece_1308560678 (1)
- Dave07
- CSC 204 - 3.1 and 3.2 Study Guide
- Sources
- ch08
- 1. Avionics Lab Record
- CHAP_6.8
- DIGI260_Lab6
- 7th sem project.docx
- ECEN 248 Lab10_report
- dm74ls138_2
- DHD Lab File work

You are on page 1of 20

Combinational logic circuits can also perform arithmetic functions. In chapter 8, for example, we

saw how logic circuits could be used to perform addition and subtraction, but logic circuits can

perform other functions as well. Again, many of these have proved to be useful design building

blocks, and many are available commercially as standard logic chips. In this chapter, we will see

how these devices are designed, write VHDL models for them, and list some standard logic chips

that implement them.

11.1 Magnitude Comparators

There are several combinational building blocks that perform arithmetic operations. Probably the

simplest of these is the magnitude comparator. A magnitude comparator takes two binary numbers

and reports whether or not they are the same. More sophisticated comparators also report which

of the two is greater in the event they are different. Some can be cascaded, which means multiple

comparators can be combined to compare numbers with more bits.

When comparators are cascaded, they take as input, the comparison results from less significant

bits. Then, if its two input signals are equal, these earlier comparison results are forwarded on to

the outputs.

Schematic Symbol

A comparator is drawn as a rectangle, with its inputs drawn on the left and its outputs on the right.

The comparison inputs from less significant bits are usually drawn halfway down, splitting the

numeric inputs above and below (Figure 11-1).

Figure 11-1 Schematic Symbol for 4-bit cascade comparator.

A3

A2

A1

A0

A=Bin A=Bout

B3

B2

B1

B0

Gate Implementation

The workhorse of the magnitude comparator is the exclusive-or gate (or the exclusive-nor gate)

shown in Figure 11-2.

(a) Exclusive OR (b) exclusive NOR

Function Table Function Table

A B Y A B Y

L L L L L H

L H H L H L

H L H H L L

H H L H H H

Figure 11-2 Exclusive OR and Exclusive NOR gates.

We have neglected exclusive-or until now because it can be derived from the other Boolean

operations we have studied. (Recall from Chapter 4 that AB = AB+AB.) The important thing to

note about the exclusive-or gate is that its complement (AB

same. For this reason, the exclusive-nor gate is sometimes called an equivalence gate.

But if we wish to think of these as equivalence gates whose output is true when A=B, the bubble on

the output of the gate is exactly backwards; the output of the exclusive-or (which has no bubble)

would be active low and the output of the exclusive-nor (which has a bubble) would be active high.

Sadly, there is nothing we can do about it unless we are willing to define a new schematic symbol,

which we are not.

We compare two multi-bit signals by comparing each pair of corresponding bits independently, and

if all are equal, the multi-bit signals are equal. For a 4-bit comparator, the logic expression for

A=Bout is:

A=B

out

= (A

0

B

0

)(A

1

B

1

)(A

2

B

2

)(A

3

B

3

)(A=B

n

) (11.1)

The A=Bin term is the cascaded input that tells whether less significant bits are equal. Clearly if they

are not, we should not assert A=Bout. The implementation of this comparator in gates is

straightforward and is shown in Figure 11-3.

Y

A

B

Y

A

B

Figure 11-3 A 4-bit comparator with a cascade A=B input.

Now, suppose we wish to also generate an A>B output. Clearly, if A3 is 1 and B3 is 0 (i.e. A3B3), A is

greater than B. Then, if A3=B3 and A2 is 1 and B2 is 0 (i.e. (A

3

B

3

Continuing this pattern, we have:

A>B

out

= A

3

B

3

+(A

3

B

3

)A

2

B

2

+(A

3

B

3

)(A

2

B

2

)A

1

B

1

+

(A

3

B

3

)(A

2

B

2

)(A

1

B

1

)A

0

B

0

+(A

3

B

3

)(A

2

B

2

)(A

1

B

1

)(A

0

B

0

)(A>B

n

) (11.2)

This expression is not a complicated as it looks because the exclusive-nor terms already exist in

Figure 11-3. Modifying Figure 11-3 to include A>B is left as an exercise for the student.

Standard Logic Chips

The most popular comparator available in the 7400 series of standard logic chips is the 85. This is a

4-bit cascadable comparator with A>B, A<B and A=B inputs and outputs. The 682, and the 688 are

8-bit comparators available primarily in the LS and HC logic families. The 682 is a non-cascadable

comparator with A=B and A>B outputs. The 688 can be cascaded, but it has only the A=B output.

VHDL Model

The VHDL model for a comparator is so simple that it rarely justifies a separate entity. In VHDL,

any two signals of the same type can be compared using the equals operator (=) or the not-equals

operator (/ =). The result of that operation is of type Boolean, but we can use that in a conditional

statement to get any output we wish. Figure 11-4 shows a simple comparator that only generates

an A=B output and cannot be cascaded. (Library and entity declarations are omitted for brevity.)

architecture behavioral of comparitor1 is

begin

AeqB_H <=1 when A=B else 0; -- A and B are vectors of the same length.

end behavioral;

Figure 11-4 A comparator model using a conditional assignment statement.

A comparator that generates an A>B output is not much more difficult, that is if the package

ieee.std_logic_unsigned (or one of the other numeric packages) is used. IEEE.std_logic_unsigned

A3

B3

A2

B2

A1

B1

A0

B0

A=Bin

A=Bout

defines the relational operators <. >, <=and >=for signals of type std_logic_vector. To illustrate how

these operators can be used to model a comparator, consider Figure 11-5, the model of a

comparator with both an A=B and an A>B output.

architecture behavioral of comparitor2 is

begin

AeqB_H <=1 when A=B else 0; -- A and B are vectors of the same length.

AgtB_H <=1 when A>B else 0; -- Assumes A and B are unsigned binary numbers.

end behavioral;

Figure 11-5 A comparator that provides an A=B and A>B output.

The ease with which VHDL handles comparisons like A<B or A>B has a downside. It is easy to forget

that these comparisons require substantially more hardware to implement than A=B and AB. A

good engineer will favor the equality comparisons and use greater-than and less-than comparisons

only when necessary.

In VHDL, there is not much need for comparators that can be cascaded because it is easy to design

them to be the right size in the first place. We will therefore forgo any discussion of cascading in

VHDL.

11.2 Adders

The half adders and full adders we discussed in Chapter 8 are fundamental building blocks that are

used in all manner of arithmetic devices such as fast carry adders and multipliers. From Figure 8-6,

the logic equations for a full adder is:

=A

C

n

+A

B C

in

+A B C

n

+A B

C

in

, and (11.3)

C

out

=AB +AC

n

+BC

n

. (11.4)

It is worthwhile to note that an equivalent expression for S using exclusive-or is:

=A B C

n

(11.5)

Verification that Equation 11.3 is equivalent to 11.5 is left as an exercise. A half adder behaves the

same as a full adder when Cin is false, so, substituting Cin =0 into Equations 11.4 and 11.5 we have:

C

out

=AB, =A B. (11.6)

Schematic Symbol

The schematic symbol for a 1-bit half or full adder is a rectangle (often a square) with inputs and

outputs placed wherever it is convenient. (When these devices are drawn in larger circuits such as

array multipliers or fast-carry adders, circuit topology dictates the best place to make the

connections.) A multi-bit adder is drawn as a rectangle with inputs on the left and outputs on the

right. (Figure 11-6). Half adders and Full adders are sometimes denoted HA and FA respectively.

Figure 11-6 Schematic symbols for (a) 1-bit half adder, (b) 1-bit full adder and (c) 4-bit full adder.

Gate Implementation/ Fast Carry Adder

Gate implementations for the 1-bit half adder, the 1-bit full adder and the ripple carry adder were

addressed in Chapter 8, and they need not be repeated here. But there is another adder called the

fast carry adder that we should discuss. The ripple carry adder suffers from a large propagation

delay because the critical path from carry-in to carry-out carry passes through every single 1-bit

adder; if the number of bits is large, this delay can become substantial. The fast carry adder. On the

other hand, is able to predict the carry input to each adder simultaneously. To understand how this

works, we will need to introduce some new concepts.

We first define Gi, a Boolean variable that is true if adder i generates a carry, and Pi, a Boolean

variable that is true if adder i propagates a carry (i.e. if adder i generates a carry when it receives

one). These two variables can be determined based on the A and B inputs alone, without regard to

the carry input, Cin. Specifically,

0

=A

, and P

=A

. (11.7)

The fast carry adder doesnt generate a carry-out for each bit, but each 1-bit adder needs a carry-in

and we will denote that Ci. The carry-in for the least significant adder, C0, is simply Cin. Carry C1 is 1

if either (a) adder 0 generates a carry, or (b) Cin is 1 and adder 0 propagates it. Carry C2 is 1 if (a)

adder 1 generates a carry, (b) adder 0 generates a carry and adder 1 propagates it, or (c) Cin is 1 and

both adder 0 and adder 1 propagate it. This pattern is best illustrated using the logic expressions in

Equation 11.8, below:

C

0

=C

n

C

1

=0

0

+P

0

C

n

C

2

=0

1

+P

1

0

0

+P

1

P

0

C

n

C

3

=0

2

+P

2

0

1

+P

2

P

1

0

0

+P

2

P

1

P

0

C

n

(11.8)

If a carry-out is needed for the entire n-bit adder, it can be obtained by generating Cn, where n is

the number of bits in the adder. Once the carry-in is known for each 1-bit adder, each bit of the

sum can be obtained using Equation 11.9.

=A

(11.9)

A B

HA

Co

A B Ci

FA

Co

A3

A2

A1

A0

Ci

B3

B2

B1

B0

Co

3

2

1

0

(a) (b) (c)

Suppose we wish to build a fast carry adder using gates. What Equations 11.7-11.9 teach us is that

the fast carry adder computes the sum in three stages. First, it produces the generate and propagate

signals, Gi and Pi. From these, it produces carry-in signals, Ci, for each bit of the adder. Finally, it

generates the sum bits, i. These stages are illustrated in the 4-bit fast carry adder shown in Figure

11-7. For simplicity, positive logic is assumed throughout.

Note that Pi is implemented with Ai+Bi instead of Ai

Bi. This implementation is simpler and faster

than the exclusive-or, and it turns out to work just as well.

Figure 11-7 Four-bit fast carry adder.

The adder in Figure 11-7 cannot be combined with others to make an 8- or 16-bit adder. There are

two ways to modify it so that it can be. The first is to have the 4-bit adder produce Group Generate

(GG) and Group Propagate (GP) signals:

00 =0

3

+P

3

0

2

+P

3

P

2

0

1

+P

3

P

2

P

1

0

0

(11.10)

0P =P

3

P

2

P

1

P

0

(11.11)

These signals can then be used in a manner similar to Equation 11.8 to produce the carry inputs for

all the 4-bit adders in the system. This approach is very fast, especially for large adders, but it does

require extra carry lookahead logic circuitry. For more information about how to cascade fast carry

adders, please refer to [ROTH].

Another approach is to have the adder generate a carry-out signal:

C

out

=C

4

=0

3

+P

3

0

2

+P

3

P

2

0

1

+P

3

P

2

P

1

0

0

+P

3

P

2

P

1

P

0

C

n

(11.12)

This carry-out can be connected to the carry-in of the next 4-bit adder. It works very much like a

ripple carry adder, except it is faster because the carry propagates 4-bits at a time. This type of

adder is called a carry lookahead adder.

A3

B3

P3

G3

A2

B2

P2

G2

A1

B1

P1

G1

A0

B0

P0

G0

G1

P2

G2

G0

P1

P2

Cin

P0

P1

P2

C3

G1

G0

P1

Cin

P0

P1

C2

G0

Cin

P0

C1

3

A3

B3

C3

2

A2

B2

C2

1

A1

B1

C1

0

A0

B0

Cin

Standard Logic Chips

The 7400 series of standard logic chips defines two adders that are still in common use today. The

83 and the 283 are 4-bit full, carry look-ahead adders that differ only in the order the pins are

connected. The 83 and the 283 may be used either as a positive logic device or a negative logic

device. In other words, the inputs and outputs of the 83 and the 283 can all be active low or high

and the device will still perform addition.

The 7400 series does not define a combinational subtractor. If subtraction is necessary, as in

Section 8.4, it can be performed by the by inverting the 4-bit subtrahend (B) input, the carry-in and

the carry-out. Alternatively (or in addition) you may think of the 283 as a subtractor with active

low borrow-in, borrow-out, and subtrahend (Figure 11-8).

Figure 11-8 A 4-bit full subtractor using a 74HC283.

The port labels on the 283 are a little confusing because the bits are numbered 1-4 rather than 0-3,

the carry-in is labeled C0 (zero, not O) and the carry-out is labeled C4.

Note that if you cascade multiple subtractors, only two inverters are needed for borrow: one at the

beginning of the borrow-in/ borrow-out chain and one at the end. One last point that should be

made about subtraction is the 83 and 283 will also perform subtraction if the A and inputs are

inverted. This approach is less popular because it uses more inverters for positive logic, but if you

find yourself working on a design where either A or are active low, it is an option worth

considering.

VHDL Model

Half and full adders only need to be modeled individually when they are part of a larger structural

model. Models for the half and full adders are shown in Figure 11-9. These models introduce a new

A3

A3

Bin

A3

A3

B3

D0

Bout

B2

B1

B0

A4

A3

A2

A1

C0

B4

B3

B2

B1

C4

4

3

2

1

D1

D2

D3

U2

7

5

14

12

3

6

2

15

9

4

11

4

13

10

1

3

2 1

6 5

8 9

10 11

12 13

U1A

U1B

U1C

U1D

U1E

U1F

Designator Part

U1 74HC04

U2 74HC283

VHDL operator, xor, which simply evaluates the exclusive-or of its operands. Again, the library and

entity declarations are omitted for brevity.

architecture structural of half_adder is

begin

Sum <=A xor B;

Cout <=A and B;

end structural;

architecture structural of full_adder is

begin

Sum <=A xor B xor Cin;

Cout <=(A and B) or (A and Cin) or (B and Cin);

end structural;

(a) Half Adder (b) Full Adder

Figure 11-9 VHDL models for a half and full adder.

Multi-bit half adders (ones with no carry-in) can be modeled about as easily as comparators in

VHDL so long as an arithmetic package like IEEE.std_logic_unsigned is used. The package defines

addition (and subtraction) for std_logic_vector, so that two signals can be added together using

the + symbol. For example, an 8-bit half adder can be modeled in VHDL as shown in Figure 11-10.

Library IEEE;

use IEEE.std_logic_1164.all;

use IEEE.std_logic_unsigned.all;

entity half_adder8 is

port ( A, B: in std_logic_vector(7 downto 0); -- input addends

Sum: out std_logic_vector(7 downto 0) ); -- output sum

end half_adder8;

architecture behavioral of half_adder8 is

begin

Sum <=A+B; -- Calculate A+B, ignoring carry

end behavioral;

Figure 11-10 A model for an 8-bit half adder with no carry-out.

This model can be synthesized, but there are so many ways to make an adder, you cant tell exactly

what you are going to get. You may get a ripple carry adder; you may get a fast carry adder, or you

may get something else entirely. Usually, youll be satisfied with the adder that the synthesizer

gives you, but if it is important to model the adder in a particular way, youll probably have to use a

structural model.

Suppose now that we wish to generate a carry-out from the adder in Figure 11-10. One way to do

this is to extend the length of one of the operands (e.g. signal A) by one bit. (Operands of different

sizes may be added, and the sum is the size of the longest operand.) We can lengthen one of the

operands by concatenating a leading 0 as shown in Figure 11-11.

architecture behavioral of half_adder8 is

signal T: std_logic_vector (8 downto 0); -- 9-bit temporary signal to receive sum

begin

T <=(0 & A)+B; -- Extend A to 9-bits so the carry-out wont be lost

Cout <=T(8); -- Calculate A+B, putting the sum in T(7 downto 0)

Sum <=T(7 downto 0); -- and the carry in T(8).

end behavioral;

Figure 11-11 A model for an 8-bit half adder with carry-out.

Note that a temporary 9-bit std_logic_vector signal had to be declared to receive the 9-bit sum.

Suppose now that we wish to include a carry input in the computation. Fortunately the package

std_logic_unsigned also defines addition for signals of type std_logic (e.g. carry-in), so all thats

needed is to include the carry in the addition (Figure 11-12).

architecture behavioral of full_adder8 is

signal T: std_logic_vector (8 downto 0); -- 9-bit temporary signal to receive sum

begin

T <=(0 & A)+B+Cin; -- Extend A to 9-bits so the carry-out wont be lost

Cout <=T(8); -- Calculate A+B, putting the sum in T(7 downto 0)

Sum <=T(7 downto 0); -- and the carry in T(8).

end behavioral;

Figure 11-12 A model for an 8-bit full adder with carry-in and carry-out.

Suppose we need to design an adder for signed 2s complement numbers that also generates an

overflow output. (Recall that the overflow condition occurs when the carry-out from the last two

1-bit adders are different.) Here, the library packages are of little value because they do not give us

access to the intermediate carries. Instead, we need to write a loop (as we did in Section 10.3) that

computes both the sum and the carries, then we will use the last 2 carries to generate the overflow.

(See Figure 11-13, the library declaration is omitted for brevity).

entity signed_adder8 is

port ( A, B: in std_logic_vector(7 downto 0); -- input addends

Overflow: out std_logic; -- carry output

Sum: out std_logic_vector(7 downto 0) ); -- output sum

end signed_adder8;

architecture behavioral of signed_add8 is

begin

process (A, B) -- wait for any signal to change

variable C: std_logic_vector (0 to 8);

begin

C(0) :=0; -- this could be the carry-in if we had one

for i in 0 to 7 loop -- loop once for each adder

Sum(i) <=A(i) xor B(i) xor C(i);

C(i+1) :=(A(i) and B(i)) or (A(i) and C(i)) or (B(i) and C(i));

end loop;

Overflow <=C(8) xor C(7); -- equals 1 if C(8) C(7)

end process;

end behavioral;

Figure 11-13 An 8-bit signed adder with overflow output.

There are a couple things we should say about Figure 11-13. The first is to point out that this loop

is synthesizable. It can be unrolled, even though the intermediate carries are variables instead of

signals. Second, the range of the carry vector, C, is declared to be (0 to 8) but could just as easily

have been (8 downto 0). Since we never use it as a data signal, either ordering is okay, and

(0 to 8) seems more natural in this case.

On a related subject, subtraction can also be modeled with VHDL. All that is needed is to change the

signs on B and Cin (and, of course, most of the signal names and comments) in Figures 11-10

through 11-12. Figure 11-13 can also be modified to perform signed subtraction by changing the

expression for C(i+1); of course, C would then be a vector of borrows instead of carries. This

modification is left as an exercise.

One final note on modeling addition and subtraction in VHDL, many engineers use the package

IEEE.numeric_std because it allows both signed and unsigned arithmetic in the same module.

Rather than defining arithmetic operations for std_logic_vector (as IEEE.std_logic_unsigned does), it

defines different types for signed and unsigned numbers, each with its own operators. The upshot

is that if you want to, say, compare two unsigned values, they must be converted to the unsigned

type first. Fortunately, the package also defines functions to perform the conversions (Table 11-1).

Table 11-1 Conversion Functions for IEEE.numeric_std

Convert From Convert To Conversion Function

std_logic_vector unsigned u <=unsigned(v)

std_logic_vector signed s <=signed(v)

unsigned integer i <=to_integer(u)

signed integer i <=to_integer(s)

integer unsigned u <=to_unsigned(i,bits)

integer signed s <=to_signed(i,bits)

unsigned std_logic_vector v <=std_logic_vector(u)

signed std_logic_vector v <=std_logic_vector(s)

The other pitfall to watch out for when using IEEE.numeric_std is that none of the arithmetic

operators work on std_logic. If you have a single bit (e.g. carry-in) that needs to be added or

subtracted, it is necessary to turn it into a vector first. This can be done using the same syntax we

used to initialize constant arrays in Section 10.2. To make a 1-bit vector out of Cin (which would be

needed in Figure 11-12), we simply write (0=>Cin). This expression defines a vector and initializes

entry 0 to Cin. The type of the vector is somewhat ambiguous; it can be used wherever signed,

unsigned or std_logic_vector signals are expected. (If you need it to be unambiguous, you may use a

qualified expression to force the vector to be whichever type you wish. This is done by preceding the

vector with a type name and a single quote, e.g. unsigned'(0=>Cin).)

Figure 11-14 illustrates how to model the 8-bit full adder in Figure 11-12 using the package

IEEE.numeric_std. Note that the type of the intermediate signal, T, was changed to unsigned. This

change was simply for convenience. Otherwise we would have had to convert A and B to unsigned,

add them, and convert the sum back to std_logic_vector, all before assigning the result to T.

Library IEEE;

use IEEE.std_logic_1164.all;

use IEEE.numeric_std.all;

entity full_adder8 is

port ( A, B: in std_logic_vector(7 downto 0); -- input addends

Cin: in std_logic; -- carry input

Cout: out std_logic; -- carry output

Sum: out std_logic_vector(7 downto 0) ); -- output sum

end full _adder8;

architecture behavioral of full_adder8 is

signal T: unsigned (8 downto 0); -- 9-bit temporary signal to receive sum

begin

T <=unsigned(0 & A) +unsigned(B) +(0=>Cin);

Sum <=std_logic_vector(T(7 downto 0)); -- The sum is in T(7 downto 0)

Cout <=T(8); -- and the carry is in T(8).

end behavioral;

Figure 11-14 A model for an 8-bit full adder using IEEE.numeric_std.

11.3 Shifters

In binary, multiplication and division by 2

k

can be accomplished by shifting a value k bits left or k

bits right respectively. The shifter provides a means to do just that. It takes an input value and a

shift count and produces a result that is the original value shifted (left or right) by the shift count.

Usually, if the shift count is n-bits, the number of bits in the input and output signals is 2

n

. Shifters

are characterized by the number of bits they shift, so for example, a 32-bit shifter has 32 input lines,

32 output lines and a 5-bit shift count input. (Recall 2

5

=32).

Shifters come in several flavors. A zero-backfill shifter fills in the vacated bits with zeros. A sign

extend shifter only shifts right and fills the vacated bits with copies of the sign bit (this results in

signed, 2s complement division). An end-around or barrel shifter fills the vacated bits with the bits

shifted out of the other end. For simplicity, this text will only address zero-backfill shifters. Once

they are understood, other shifters are not difficult to grasp.

Schematic Symbol

While there is no universally accepted way to draw a shifter, it can be drawn as a rectangle, with the

multi-bit input signal drawn on the left and the (same sized) multi-bit output signal drawn on the

right. The shift count may be drawn on the top, bottom, or on the left next to the other input bus

(Figure 11-15).

Figure 11-15 Schematic Symbols for a 2

n

-bit shifter.

Implementation

A shifter can be implemented with n stages of 2-to-1 multiplexers. If we use S to denote the shift

count, then stage connected to S0 shifts the value one bit if S0 is one, or leaves it alone if S0 is zero.

Likewise the stage connected to S1 either shifts the value 2-bits or 0-bits depending on S1. It doesnt

matter which stage is first or, for that matter, what order the stages are in. As an example, Figure

11-16 shows a 4-bit zero-backfill right-shifter. Depending on the value of S, this shifter can divide a

4-bit binary number by 1, 2, 4, or 8.)

Notice that the first stage optionally shifts right (upward) 1 bit. Stage 2 optionally shifts right 2 bits.

If there were a third stage, it would optionally shift 4 bits, depending on S. The order of the stages

doesnt matter because the shifts can occur in any order with the same result.

It is also possible to use larger multiplexers (such as 4-to-1 line MUXs) to implement a shifter. This

reduces the number of stages and therefore the propagation delay, but if the multiplexers get too

large, there is an adverse effect on the fan-out. As an exercise, the student is encouraged to

implement the shifter in Figure 11-16 using only 4-to-1 line multiplexers.

I

2

n

n

2

n

O

S

I

2

n

n

2

n

O

S

Figure 11-16 Implementation of a 4-bit, zero backfill shifter.

Standard Logic Chips

The only shifter defined in the 7400 series of standard logic chips is the 350, but this chip is

practically unavailable. If it is necessary to build a shifter using standard logic chips, the best

alternative is to use standard multiplexers (151s, 153s and 157s) configured similar to those in

Figure 11-16.

VHDL Model

Technically, VHDL has operators that model the shift and rotate functions performed by a shifter,

but in practice, designers rarely use them. The reason is that VHDL provides enough flexibility in

the way it defines index ranges that a shift can be performed in a simple assignment. (That, and

those operators are not defined for std_logic_vector.) The general approach is to concatenate some

of the bits from the input with the backfill bits to form the correct output. As an example, the VHDL

fragment in Figure 11-17 shows how to model the shifter in Figure 11-16. Again, the library and

entity declarations are omitted for brevity.

architecture behavioral of shifter4 is

signal k: integer range 0 to 3;

begin

k <=conv_integer(S); -- get number of bits to shift, as an integer

O <=(k downto 1=>'0') & I(3 downto k); -- shift I right by k, pad left side with zeros

end behavioral;

Figure 11-17 A model for of a 4-bit, zero backfill shifter.

Y

I0

I1 S

S0

Y

I0

I1 S

Y

I0

I1 S

Y

I0

I1 S

I0

I1

I2

I3

Y

I0

I1 S

S1

Y

I0

I1 S

Y

I0

I1 S

Y

I0

I1 S

O0

O1

O2

O3

The first thing we do in Figure 11-17 is represent S, the number of bits to shift, as an integer called

k. Then, we use it to create two variable-length vectors that are concatenated to form the output, O.

Even though the vectors have variable lengths, their sum is always 4 (the size of the shifter in bits).

In this case, we are shifting right by k, so the first vector is a pad of k zeros and the second consists

of the leftmost 4-k bits of the input. The student is encouraged to take a moment to verify that this

output is the same as the output from Figure 11-16.

Lets list some other statements that we could have used in Figure 11-17 to model different shifters.

These statements are shown in Figure 11-18, along with comments that explain the direction and

type of the shifter.

-- shift right with sign extension, back fill with the sign bit, I(3)

O <=(k downto 1 =>I(3)) & I(3 downto k);

-- shift left, back fill with zeros

O <=I(3-k downto 0) & (k downto 1 =>0);

-- shift right, end-around or barrel shift (also called rotate right)

O <=I(k-1 downto 0) & I(3 downto k);

-- shift left, end-around or barrel shift (also called rotate left)

O <=I(3-k downto 0) & I(3 downto 4-k);

Figure 11-18 Models for various 4-bit shifters.

Of course, for shifters with more than four bits, it is a trivial matter to change the constants (3s and

4s) in Figures 11-17 and 11-18 to reflect the larger number of bits.

11.4 Arithmetic Logic Units

An arithmetic logic unit (or ALU) is a device that performs an arbitrary operation on its input

signal(s) and outputs the result. The ALU has two main data inputs (that, like the adder are

traditionally labeled A and B). These serve as operands for an arithmetic or logical operation

performed by the ALU based on the function code input. The function set of the ALU is a list of all

valid function codes and the operations they perform. For example, one function code may cause

the ALU to compute A-B while another may cause the ALU to compute AB. Each ALU design has

its own function set, but some common ALU functions are given in Figure 11-19.

Function Result Function Result

Add A+B AND NOT A and B (bitwise)

Add w/ carry A+B+Cin OR A or B (bitwise)

Subtract A-B XOR A B (bitwise)

Subtract w/ borrow A-B-Cin Shift Left A, Shifted left by B bits

Negate -A Shift Right A, Shifted right by B bits

Complement A Rotate Left A, Rotated left by B bits

AND A and B (bitwise) Rotate Right A, Rotated right by B bits

Figure 11-19 Common ALU functions.

An ALU is characterized both by its function set and its word size (the number of bits in its inputs

and result). For example, an ALU with 16 bit word size is referred to as a 16-bit ALU. Note that

the ALU may also have some 1-bit ancillary inputs and outputs such as carry-in and carry-out.

These inputs and outputs may be used for some functions but not others, depending on the function

set.

Schematic Symbol

Like the multiplexer, the ALU has its own schematic symbol, which is a trapezoid with a notch on

the long base. The inputs are drawn coming into the large base (with A on one side of the notch and

B on the other). The output is drawn coming out of the smaller base. The function code connects to

one side. Ancillary signals, if they exist, are placed on one of the bases, depending on whether they

are inputs or outputs (Figure 11-20).

Figure 11-20 Schematic Symbol for an n-bit ALU with carry-in and carry-out.

One common ancillary signal not shown in Figure 11-20 that should be mentioned is the zero signal,

which is true if the result of the ALU operation is zero.

Implementation

An ALU is too large a device to break down into gates (at least all at once), so we will take a lesson

from our design steps and start at a higher level of abstraction (i.e. considering objects in terms of

their characteristics rather than concrete realities). The simplest way to design an ALU (and the

only one we will cover in this text) is to simultaneously compute every possible result and use a

multiplexer to select between them (based on the function code). Figure 11-21 illustrates such an

ALU that is 8-bits wide and has four function codes: add, subtract, shift left and shift right.

R

n

F

A

B

Cin

n

n

Cout

m

Figure 11-21 Eight-bit ALU with 4 functions.

Note that each signal shown in Figure 11-21 is a bus (multi-bit signal). Some have 8 bits; some have

fewer. Busses are usually drawn with thicker lines and often have markings to indicate the number

of bits (lines or wires) that comprise them. When data are placed on the A and B inputs, all four

functional units (the adder, subtractor, left shifter and right shifter) start computing their result,

but only the one selected by the function code, F, will be output to R. (Note, the S inputs on the

shifters have only 3 bits, so only 3 bits of B, probably the least significant, are connected to it.)

We can easily derive the function set for this ALU from the schematic diagram in Figure 11-21.

When F is 002, the sum A+B is output. When F is 012, the difference A-B is output. If we continue this

process, we get the function set shown in Figure 11-22.

Function Code (F) ALU Output

00 A+B, Carry is ignored

01 A-B, Borrow is ignored

10 A shifted left by B2..B0

11 A shifted right by B2..B0

Figure 11-22 Function Set for the ALU in Figure 11-21.

Y

I0

I1

I2

I3

S

A

B

ADDER

A

B

SUBTRACTOR

I

S

O

LEFT SHIFT

I

S

O

RIGHT SHIFT

8

8

3

8

8

8

8

8

A

B

F

R

2

Standard Logic Chips

There are several ALUs defined in the 7400 series, but only the 74LS181 is still available today.

This 4-bit ALU uses a 5-bit function code and can perform 32 different operations, including AND,

OR, NOT, XOR, add with carry, subtract with borrow and shift left (by one bit). The ALU can be

cascaded up to 64 bits using a 74LS182 to perform fast carry addition and subtraction, or it can be

cascaded to any number of bits using the look-ahead/ ripple carry approach (similar to the 183

adder discussed in Section 11.2).

VHDL Model

Modeling the behavior of an ALU using VHDL is very similar to modeling a multiplexer, except that

arithmetic or logical expressions take the place of the inputs. To illustrate, we will model the ALU

in Figure 11-21 using VHDL (Figure 11-23).

Library IEEE;

use IEEE.std_logic_1164.all;

use IEEE.std_logic_unsigned.all;

entity ALU8 is

port ( A, B: in std_logic_vector(7 downto 0); -- input operands

F: in std_logic_vector(1 downto 0); -- input function

R: out std_logic_vector(7 downto 0) ); -- output result

end ALU8;

architecture behavioral of ALU8 is

signal k: integer range 0 to 7;

signal R0, R1, R2, R3: std_logic_vector(7 downto 0);

begin

k <=conv_integer(B(2 downto 0)); -- number of bits for shift operators

-- compute the result of each function unit

R0 <=A+B; -- add

R1 <=A-B; -- subtract

R2 <=A(7-k downto 0) & (k downto 1 =>0); -- shift left

R3 <= (k downto 1=>'0') & A(7 downto k); -- shift right

R <=R0 when F =00 else -- add

R1 when F =01 else -- subtract

R2 when F =10 else -- shift left

R3 when F =11 else -- shift right

--------; -- handle meta-values

end behavioral;

Figure 11-23 A model for an 8-bit ALU in Figure 10-61.

There should be nothing in Figure 11-23 that is new to us, however you may wonder why we

declared intermediate signals R0-R3 instead of simply writing those expressions in the conditional

assignment statement. The reason is practical, not technical. When we simulate a module, it is

possible to look at any signal that has a name. When a circuit does not perform the way we expect,

it is handy to have intermediate signals to look at so we can isolate the cause of the problem. The

intermediate signals are also more convenient when functional units are replaced with structural

models.

Example 11.1. Write a VHDL behavioral model for a 16-bit ALU. The ALU has two 16-bit inputs (A

and B), a 16-bit result (R), and a 3-bit function code (F), all active high. It also has an active-high

carry input (Cin) and output (Cout) as well as an active-low zero output (Z_L). The ALU should

support the following function set:

Function code (F) Function ALU Output (R) Carry Output (Cout)

000 Add A+B 1 if A+B generates carry, else 0

001 Subtract A-B 1 if A-B generates a borrow, else 0

010 Add w/ carry A+B+Cin 1 if A+B+Cin generates carry, else 0

011 Subtract w/ borrow A-B-Cin 1 if A-B-Cin generates borrow, else 0

100 Bitwise AND A and B Cin

101 Bitwise OR A or B Cin

110 Bitwise XOR AB Cin

111 Complement A Cin

Solution: We will use Figure 10-63 as a template, but this ALU has two additional outputs: carry-out

(Cout) and zero (Z_L). The carry-out is a little tricky. Recall that in VHDL we get the carry-out by

enlarging the result one bit to accommodate it. We will want to do this for the ALU as well, so we

will have a 17-bit internal result that can be split into R and Cout for output. Generation of the zero

signal (Z_L) is straightforward, given that we have access to the internal ALU result. The VHDL

module below should do the trick:

Library IEEE;

use IEEE.std_logic_1164.all;

use IEEE.std_logic_unsigned.all;

entity ALU16 is

port ( A, B: in std_logic_vector (15 downto 0); -- input binary operands

F: in std_logic_vector (2 downto 0); -- input function code

Cin: in std_logic; -- carry input

Z_L, Cout: out std_logic; -- ancillary results

R: out std_logic_vector(15 downto 0) -- main result of the ALU

);

end ALU16;

architecture behavioral of ALU16 is

signal Result, R0, R1, R2, R3, R4, R5, R6, R7: std_logic_vector(16 downto 0);

begin

R0 <=(0 & A)+B; -- add without carry

R1 <=(0 & A)-B; -- subtract without borrow

R2 <=(0 & A)+B+Cin; -- add with carry

R3 <=(0 & A)-B-Cin; -- subtract with borrow

R4 <=Cin & (A and B); -- bitwise and, retaining carry-out =carry-in

R5 <=Cin & (A or B); -- bitwise or, retaining carry-out =carry-in

R6 <=Cin & (A xor B); -- bitwise or, retaining carry-out =carry-in

R7 <=Cin & (not A); -- complement input A

Result <=R0 when F=000 else -- add without carry

R1 when F=001 else -- subtract without borrow

R2 when F=010 else -- add with carry

R3 when F=011 else -- subtract with borrow

R4 when F=100 else -- bitwise and, retaining carry-out =carry-in

R5 when F=101 else -- bitwise or, retaining carry-out =carry-in

R6 when F=110 else -- bitwise or, retaining carry-out =carry-in

R7 when F=111 else -- complement input A

(others =>-); -- handles meta-values

Cout <=Result(16); -- strip out carry flag

R <=Result(15 downto 0); -- strip out the ALU result

Z_L <=0 when Result(15 downto 0) =0 else 1;

end Behavioral;

It is worthwhile at this point to stop and consider the size and complexity of the ALU in Example

11-1. This circuit requires well over 500 gates to implement, yet we could have drawn its schematic

on one page using abstract building blocks like those in Figure 11-21, and we did write its VHDL

model in about 35 lines of text. For complicated designs, we need the ability to use abstractions like

these to think of objects in terms of their characteristics rather than their gates. Without them, we

would never be able to design the complicated circuits that give life to computers, portable phones

or tablets, and that would mean that we would never get to play angry birds.

Exercises

1. Modify Figure 11-3 to include an output for A>B.

2. Verify Equation 11.3 and Equation 11.5 are equivalent.

3. Modify the VHDL code in Figure 11-13 so that it performs a signed subtraction.

4. Write a test fixture and simulate your VHDL code from problem 3, above.

5. Implement the 4-bit, zero backfill shifter in Figure 11-18 using only 4-to-1 line multiplexers.

6. Modify your shifter in problem 5 to get a 4-bit barrel shifter. Do not add or remove any

components (just rewire it).

- Module 5 - Arithmetic Operations Advanced Assembly4Uploaded byImranul Islam
- digitalUploaded byawesomejk
- Digital System Design Bee3133Uploaded byMuhamad Zulhilmi Hamizi
- Ari Th Circuits 1Uploaded byYermakov Vadim Ivanovich
- DG Lab- 2019-20.pdfUploaded byGopinathan M
- Design the High Speed Kogge-Stone Adder by UsingUploaded byAnonymous 7VPPkWS8O
- Verilog CodesUploaded bynvrkrishna456
- High Speed ALU Processor by Using Efficient Multiplication TechniqueUploaded byIRJET Journal
- ece_1308560678 (1)Uploaded byhkajai
- Dave07Uploaded byYermakov Vadim Ivanovich
- CSC 204 - 3.1 and 3.2 Study GuideUploaded byFVCproductions
- SourcesUploaded byAnamaria Slabu
- ch08Uploaded byLuis Eduardo García Quesada
- 1. Avionics Lab RecordUploaded byDaffodil
- CHAP_6.8Uploaded byDjokata
- DIGI260_Lab6Uploaded byAkchat Jha
- 7th sem project.docxUploaded byLisa Singh
- ECEN 248 Lab10_reportUploaded byRebecca Sontheimer
- dm74ls138_2Uploaded byapi-3712914
- DHD Lab File workUploaded byAmit Poonia
- 0603Uploaded byshadowpwner
- StructuralUploaded byRama Subrahmanyam B
- e03b035Uploaded byTariq Zuhluf
- 74 Series IC Data Sheet IndexUploaded bykranthikiran211
- Lect05 2Design ExampUploaded bypurwant10168
- Chapter 4-Practical PDH Higher Order SystemsUploaded byswaranks
- Water Level IndicatorUploaded byindiangauravsharma_2
- msg00260Uploaded bysivanee007
- DLD 7 StudentUploaded byAminul Islam
- Class VhdlUploaded bymathhoang

- Problema 16 Resuelto Por c3a1rbol de Decisic3b3nUploaded byhjmesa
- Analisi de SensibilidadUploaded byhjmesa
- transporte_udemUploaded byhjmesa
- método de la Gran M.docxUploaded byhjmesa
- Disco duroUploaded byhjmesa
- EntireWinAsmPgmUploaded byapi-3834265
- Examen Unidad8 1ºBACH B(Soluciones)Uploaded byAlejandro Valverde Sacristán
- Solucion Simplex 1Uploaded byhjmesa
- Funciones SolUploaded byhjmesa
- Teoria de ColasUploaded byJaime Bahamondes Navarrete
- A Scheduling Based in MILP for Non-continuous Serial Production. Data and ResultsUploaded byhjmesa
- Guia didactica Calculo diferencial 2019-1.docxUploaded byhjmesa
- Guia de InstalacionUploaded bySB
- FUNCIONES TRIGONOMÉTRICAS HIPERBÓLICASUploaded byAlejandro Jácome
- Analisis de Decisiones 20141Uploaded byhjmesa
- CoprocesadorUploaded byHenry Chavez
- 4 Interior Del PcUploaded byhjmesa
- h03 Essential MathUploaded byakyadav123
- Exer3.1Uploaded byhjmesa
- arq_RISC1Uploaded byhjmesa
- Conociendo El PcUploaded byElvis Torres Quispe
- CSU07 13 Anexo7 Presentacion Doc. IngenieriaCivilUploaded byhjmesa
- ErrataUploaded byhjmesa
- Analisis de Riesgo Simulacion Montecarlo[1]Uploaded byhjmesa
- Guia Series Alternantes y Convergencia Absoluta 2Uploaded byhjmesa
- Planos.docUploaded byhjmesa
- Micro InstUploaded byhjmesa
- Juego MichiUploaded byhjmesa
- Intro a la AC - Soluciones a los Problemas de Diseño, Coste y RendimientoUploaded byDanny Sandin

- A Design Technique for Faster Dadda MultiplierUploaded bySebastian Ossa
- vlsi lab VTUUploaded byKeith Fernandes
- tutorialUploaded bykarimM
- IEEE-754 floating point multipler in VerilogUploaded byShyam Shankar
- VHDL for Engineers - Kenneth L. Short.pdfUploaded byTongjie Liu
- 04_Chapter 4 - Modular Comb Logic_2Uploaded byTho Maftuhin
- SAP-1-2Uploaded byBrandon Maciel
- Digital Electronics - Logic CircuitsUploaded bysanjay975
- High Performance MAC Unit for FFT ImplementationUploaded byIJMER
- MCQ edugrip.docxUploaded byArasanfiveSteven
- Digital Electronics & MicroprocessorsUploaded byAnonymous FRJktAGZm
- Modul Bee2233 - Ver 2010 -Part 2Uploaded bycakunza
- vahid_digitaldesign_ch04Uploaded byMauricio Alves
- BEEE UNIT-5 Digital Elns NotesUploaded byAniket Singh
- Implementation of Single Precision Floating Point Multiplier on FPGAUploaded byInternational Journal for Scientific Research and Development - IJSRD
- NCL2Uploaded byAnn V Rajan
- Design and Synthesis of ALU using Reversible Logic for MAC ApplicationsUploaded byIJSTE
- 52639378 Mcq Digital Electronics 1Uploaded byKalyanbrata Ghosh
- lab manual electronicsUploaded byNaveen Rockzz Bhavans
- analog and digital electronicsUploaded byrajeshnaik_965429910
- Lesson 2Uploaded byTrần Ngọc Lâm
- Ppt March 15Uploaded byAnonymous 0mogHr
- Lab QuizUploaded byNisha Kotyan G R
- HDL lab manualUploaded byshubham
- Exp-4_5Uploaded byGECM85
- Digital Integrated Circuits Syllabus'Uploaded byshiv123charan
- A Low Power Adder Using Reversible Logic GatesUploaded byInternational Journal of Research in Engineering and Technology
- Power Optimization of Combinational Quaternary Logic CircuitsUploaded byEditor IJRITCC
- Electronics Lab ManualUploaded bychaitanya
- Class Notes Digital Lec26Uploaded bySazzad Hossain Lemon