⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ch02.18.htm

📁 介绍asci设计的一本书
💻 HTM
字号:
<HTML>

<HEAD>

  <META NAME="GENERATOR" CONTENT="Adobe PageMill 2.0 Mac">

  

  <TITLE> 2.6.6&nbsp;&nbsp;&nbsp;Other Datapath Operators</TITLE>

</HEAD><!--#include file="top.html"--><!--#include file="header.html"-->





<P><A NAME="pgfId=195929"></A><HR ALIGN=LEFT></P>



<P><A HREF="CH02.12.htm">Chapter&nbsp;&nbsp;start</A>&nbsp;&nbsp;&nbsp;<A

HREF="CH02.17.htm">Previous&nbsp;&nbsp;page</A>&nbsp;&nbsp;<A HREF="CH02.19.htm">Next&nbsp;&nbsp;page</A></P>



<H2>2.6.6&nbsp;&nbsp;&nbsp;Other Datapath Operators</H2>



<P><P CLASS="BodyAfterHead"><A NAME="pgfId=195915"></A>Figure&nbsp;2.32

shows symbols for some other datapath elements. The combinational datapath

cells, NAND, NOR, and so on, and sequential datapath cells (flip-flops and

latches) have standard-cell equivalents and function identically. I use

a bold outline (1<SPAN CLASS="White">&nbsp;</SPAN>point)

for datapath cells instead of the regular (0.5<SPAN CLASS="White">&nbsp;</SPAN>point)

line I use for scalar symbols. We call a set of identical cells a <B>vector</B>

of datapath elements in the same way that a bold symbol, <B>A</B> , represents

a vector and A represents a scalar.</P>



<P><TABLE BORDER="0" CELLSPACING="2" CELLPADDING="0">

<TR>

<TD><P><P CLASS="TableFigure"><A NAME="pgfId=195922"></A>&nbsp;</P>



<P><IMG SRC="CH02-112.gif" WIDTH="452" HEIGHT="166" NATURALSIZEFLAG="3"

ALIGN="BOTTOM"></TD></TR>

<TR>

<TD><P CLASS="TableFigureTitle"><A NAME="pgfId=195926"></A>FIGURE&nbsp;2.32&nbsp;&nbsp;Symbols

for datapath elements. (a)&nbsp;An array or vector of flip-flops (a register).

(b)&nbsp;A two-input NAND cell with databus inputs. (c)&nbsp;A two-input

NAND cell with a control input. (d) A buswide MUX. (e)&nbsp;An incrementer/decrementer.

(f)&nbsp;An all-zeros detector. (g)&nbsp;An all-ones detector. (h)&nbsp;An

adder/subtracter.</TD></TR>

</TABLE>

<P CLASS="Body"><A NAME="pgfId=99793"></A>A <B>subtracter</B> is similar

to an adder, except in a <B>full subtracter </B>we have a borrow-in signal,

BIN; a borrow-out signal, BOUT; and a difference signal, DIFF:</P>



<P><P CLASS="EqnNmbrdAlign"><A NAME="pgfId=99886"></A>&nbsp;&nbsp;DIFF<SPAN CLASS="White">&nbsp;</SPAN>=<SPAN CLASS="White">&nbsp;</SPAN>A<SPAN CLASS="White">&nbsp;</SPAN><SPAN CLASS="Symbol">

</SPAN> <SPAN CLASS="White">&nbsp;</SPAN>NOT(B)<SPAN CLASS="Symbol">

<SPAN CLASS="White">&nbsp;</SPAN><SPAN CLASS="White">&nbsp;</SPAN>NOT(</SPAN>

BIN)<SPAN CLASS="White">&nbsp;</SPAN>=<SPAN CLASS="White">&nbsp;</SPAN>SUM(A,

NOT(B), NOT(BIN))(2.65)</P>



<P><P CLASS="EquationAlign"><A NAME="pgfId=99887"></A>&nbsp;&nbsp;NOT(BOUT)<SPAN CLASS="White">&nbsp;</SPAN>=<SPAN CLASS="White">&nbsp;</SPAN>A<SPAN CLASS="White">&nbsp;</SPAN>&middot;<SPAN CLASS="White">&nbsp;</SPAN>NOT(B)<SPAN CLASS="White">&nbsp;</SPAN>+<SPAN CLASS="White">&nbsp;</SPAN>A<SPAN CLASS="White">&nbsp;</SPAN>&middot;<SPAN CLASS="White">&nbsp;</SPAN>NOT(BIN)<SPAN CLASS="White">&nbsp;</SPAN>+<SPAN CLASS="White">&nbsp;</SPAN>NOT(B)<SPAN CLASS="White">&nbsp;</SPAN>&middot;<SPAN CLASS="White">&nbsp;</SPAN>NOT(BIN)</P>



<P><P CLASS="EqnNmbrdAlign"><A NAME="pgfId=99898"></A>&nbsp;&nbsp;<SPAN CLASS="White">&nbsp;</SPAN>=<SPAN CLASS="White">&nbsp;</SPAN>MAJ(NOT(A),

B, NOT(BIN))(2.66)</P>



<P><P CLASS="Body"><A NAME="pgfId=100048"></A>These equations are the same

as those for the FA (Eqs.&nbsp;2.38 and 2.39) except that the B input is

inverted and the sense of the carry chain is inverted. To build a subtracter

that calculates (A<SPAN CLASS="White">&nbsp;</SPAN><SPAN CLASS="White">&nbsp;</SPAN>B)

we invert the entire B input bus and connect the BIN[0] input to VDD (not

to VSS as we did for CIN[0] in an adder). As an example, to subtract B<SPAN CLASS="White">&nbsp;</SPAN>=<SPAN CLASS="White">&nbsp;</SPAN>'0011'

from A<SPAN CLASS="White">&nbsp;</SPAN>=<SPAN CLASS="White">&nbsp;</SPAN>'1001'

we calculate '1001'<SPAN CLASS="White">&nbsp;</SPAN>+<SPAN CLASS="White">&nbsp;</SPAN>'1100'<SPAN CLASS="White">&nbsp;</SPAN>+<SPAN CLASS="White">&nbsp;</SPAN>'1'<SPAN CLASS="White">&nbsp;</SPAN>=<SPAN CLASS="White">&nbsp;</SPAN><SPAN CLASS="White">&nbsp;</SPAN>'0110'.

As with an adder, the true overflow is XOR(BOUT[MSB], BOUT[MSB<SPAN CLASS="White">&nbsp;</SPAN><SPAN CLASS="White">&nbsp;</SPAN>1]).</P>



<P><P CLASS="Body"><A NAME="pgfId=99979"></A>We can build a ripple-borrow

subtracter (a type of borrow-propagate subtracter), a borrow-save subtracter,

and a borrow-select subtracter in the same way we built these adder architectures.

An <B>adder/subtracter</B> has a control signal that gates the A input with

an exclusive-OR cell (forming a programmable inversion) to switch between

an adder or subtracter. Some adder/subtracters gate both inputs to allow

us to compute (A<SPAN CLASS="White">&nbsp;</SPAN><SPAN CLASS="White">&nbsp;</SPAN>B).

We must be careful to connect the input to the LSB of the carry chain (CIN[0]

or BIN[0]) when changing between addition (connect to VSS) and subtraction

(connect to VDD).</P>



<P><P CLASS="Body"><A NAME="pgfId=89197"></A>A <B>barrel shifter</B> rotates

or shifts an input bus by a specified amount. For example if we have an

eight-input barrel shifter with input '1111&nbsp;0000' and we specify a

shift of '0001&nbsp;0000' (3, coded by bit position) the right-shifted 8-bit

output is '0001&nbsp;1110'. A barrel shifter may rotate left or right (or

switch between the two under a separate control). A barrel shifter may also

have an output width that is smaller than the input. To use a simple example,

we may have an 8-bit input and a 4-bit output. This situation is equivalent

to having a barrel shifter with two 4-bit inputs and a 4-bit output. Barrel

shifters are used extensively in floating-point arithmetic to align (we

call this <B>normalize</B> and <B>denormalize</B> ) floating-point numbers

(with sign, exponent, and mantissa).</P>



<P><P CLASS="Body"><A NAME="pgfId=99485"></A>A <B>leading-one detector</B>

is used with a normalizing (left-shift) barrel shifter to align mantissas

in floating-point numbers. The input is an <SPAN CLASS="EquationVariables">

n</SPAN> -bit bus A, the output is an <SPAN CLASS="EquationVariables"> n</SPAN>

-bit bus, S, with a single '1' in the bit position corresponding to the

most significant '1' in the input. Thus, for example, if the input is A<SPAN CLASS="White">&nbsp;</SPAN>=<SPAN CLASS="White">&nbsp;</SPAN>'0000&nbsp;0101'

the leading-one detector output is S<SPAN CLASS="White">&nbsp;</SPAN>=<SPAN CLASS="White">&nbsp;</SPAN>'0000&nbsp;0100',

indicating the leading one in A is in bit position 2 (bit 7 is the MSB,

bit zero is the LSB). If we feed the output, S, of the leading-one detector

to the shift select input of a normalizing (left-shift) barrel shifter,

the shifter will normalize the input A. In our example, with an input of

A<SPAN CLASS="White">&nbsp;</SPAN>=<SPAN CLASS="White">&nbsp;</SPAN>'0000&nbsp;0101',

and a left-shift of S<SPAN CLASS="White">&nbsp;</SPAN>=<SPAN CLASS="White">&nbsp;</SPAN>'0000&nbsp;0100',

the barrel shifter will shift A left by five bits and the output of the

shifter is Z<SPAN CLASS="White">&nbsp;</SPAN>=<SPAN CLASS="White">&nbsp;</SPAN>'1010&nbsp;0000'.

Now that Z is aligned (with the MSB equal to '1') we can multiply Z with

another normalized number.</P>



<P><P CLASS="Body"><A NAME="pgfId=99707"></A>The output of a <B>priority

encoder</B> is the binary-encoded position of the leading one in an input.

For example, with an input A<SPAN CLASS="White">&nbsp;</SPAN>=<SPAN CLASS="White">&nbsp;</SPAN>'0000&nbsp;0101'

the leading 1 is in bit position 3 (MSB is bit position 7) so the output

of a 4-bit priority encoder would be Z<SPAN CLASS="White">&nbsp;</SPAN>=<SPAN CLASS="White">&nbsp;</SPAN>'0011'

(3). In some cell libraries the encoding is reversed so that the MSB has

an output code of zero, in this case Z<SPAN CLASS="White">&nbsp;</SPAN>=<SPAN CLASS="White">&nbsp;</SPAN>'0101'

(5). This second, reversed, encoding scheme is useful in floating-point

arithmetic. If A is a mantissa and we normalize A to '1010&nbsp;0000' we

have to subtract 5 from the exponent, this <B>exponent correction</B> is

equal to the output of the priority encoder.</P>



<P><P CLASS="Body"><A NAME="pgfId=129141"></A>An <B>accumulator</B> is an

adder/subtracter and a register. Sometimes these are combined with a multiplier

to form a <B>multiplieraccumulator</B> (<B> MAC</B> ). An <B>incrementer</B>

adds 1 to the input bus, Z<SPAN CLASS="White">&nbsp;</SPAN>=<SPAN CLASS="White">&nbsp;</SPAN>

A<SPAN CLASS="White">&nbsp;</SPAN>+<SPAN CLASS="White">&nbsp;</SPAN>1,

so we can use this function, together with a register, to negate a two's

complement number for example. The implementation is Z[<SPAN CLASS="EquationVariables">

i</SPAN> ]<SPAN CLASS="White">&nbsp;</SPAN>=<SPAN CLASS="White">&nbsp;</SPAN>XOR(A[<SPAN CLASS="EquationVariables">

i</SPAN> ], CIN[<SPAN CLASS="EquationVariables"> i</SPAN> ]), and COUT[<SPAN CLASS="EquationVariables">

i</SPAN> ]<SPAN CLASS="White">&nbsp;</SPAN>=<SPAN CLASS="White">&nbsp;</SPAN>AND(A[<SPAN CLASS="EquationVariables">

i</SPAN> ], CIN[<SPAN CLASS="EquationVariables"> i</SPAN> ]). The carry-in

control input, CIN[0], thus acts as an enable: If it is set to '0' the output

is the same as the input.</P>



<P><P CLASS="Body"><A NAME="pgfId=100166"></A>The implementation of arithmetic

cells is often a little more complicated than we have explained. CMOS logic

is naturally inverting, so that it is faster to implement an incrementer

as</P>



<P><P CLASS="Equation"><A NAME="pgfId=100156"></A>Z[<SPAN CLASS="EquationVariables">

i</SPAN> (even)]<SPAN CLASS="White">&nbsp;</SPAN>=<SPAN CLASS="White">&nbsp;</SPAN>XOR(A[<SPAN CLASS="EquationVariables">

i</SPAN> ], CIN[<SPAN CLASS="EquationVariables"> i</SPAN> ]) and COUT[<SPAN CLASS="EquationVariables">

i</SPAN> (even)]<SPAN CLASS="White">&nbsp;</SPAN>=<SPAN CLASS="White">&nbsp;</SPAN>NAND(A[<SPAN CLASS="EquationVariables">

i</SPAN> ], CIN[<SPAN CLASS="EquationVariables"> i</SPAN> ]).</P>



<P><P CLASS="Body"><A NAME="pgfId=100165"></A>This inverts COUT, so that

in the following stage we must invert it again. If we push an inverting

bubble to the input CIN we find that:</P>



<P><P CLASS="Equation"><A NAME="pgfId=100169"></A>Z[<SPAN CLASS="EquationVariables">

i</SPAN> (odd)]<SPAN CLASS="White">&nbsp;</SPAN>=<SPAN CLASS="White">&nbsp;</SPAN>XNOR(A[<SPAN CLASS="EquationVariables">

i</SPAN> ],&nbsp;CIN[<SPAN CLASS="EquationVariables"> i</SPAN> ]) and COUT[<SPAN CLASS="EquationVariables">

i</SPAN> (even)]<SPAN CLASS="White">&nbsp;</SPAN>=<SPAN CLASS="White">&nbsp;</SPAN>NOR(NOT(A[<SPAN CLASS="EquationVariables">

i</SPAN> ]),&nbsp;CIN[<SPAN CLASS="EquationVariables"> i</SPAN> ]).</P>



<P><P CLASS="Body"><A NAME="pgfId=100151"></A>In many datapath implementations

all odd-bit cells operate on inverted carry signals, and thus the odd-bit

and even-bit datapath elements are different. In fact, all the adder and

subtracter datapath elements we have described may use this technique. Normally

this is completely hidden from the designer in the datapath assembly and

any output control signals are inverted, if necessary, by inserting buffers.</P>



<P><P CLASS="Body"><A NAME="pgfId=100182"></A>A <B>decrementer</B> subtracts

1 from the input bus, the logical implementation is Z[<SPAN CLASS="EquationVariables">

i</SPAN> ]<SPAN CLASS="White">&nbsp;</SPAN>=<SPAN CLASS="White">&nbsp;</SPAN>XOR(A[<SPAN CLASS="EquationVariables">

i</SPAN> ], CIN[<SPAN CLASS="EquationVariables"> i</SPAN> ]) and COUT[<SPAN CLASS="EquationVariables">

i</SPAN> ]<SPAN CLASS="White">&nbsp;</SPAN>=<SPAN CLASS="White">&nbsp;</SPAN>AND(NOT(A[<SPAN CLASS="EquationVariables">

i</SPAN> ]), CIN[<SPAN CLASS="EquationVariables"> i</SPAN> ]). The implementation

may invert the odd carry signals, with CIN[0] again acting as an enable.</P>



<P><P CLASS="Body"><A NAME="pgfId=100198"></A>An <B>incrementer/decrementer</B>

has a second control input that gates the input, inverting the input to

the carry chain. This has the effect of selecting either the increment or

decrement function.</P>



<P><P CLASS="Body"><A NAME="pgfId=89779"></A>Using the <B>all-zeros detectors</B>

and <B>all-ones detectors</B> , remember that, for a 4-bit number, for example,

zero in ones' complement arithmetic is '1111' or '0000', and that zero in

signed magnitude arithmetic is '1000' or '0000'.</P>



<P><P CLASS="Body"><A NAME="pgfId=86986"></A>A <B>register file</B> (or

scratchpad memory) is a bank of flip-flops arranged across the bus; sometimes

these have the option of multiple ports (multiport register files) for read

and write. Normally these register files are the densest logic and hardest

to fit in a datapath. For large register files it may be more appropriate

to use a multiport memory. We can add control logic to a register file to

create a <B>first-in first-out register</B> (<B> FIFO</B> ), or <B>last-in

first-out register</B> (<B> LIFO</B> ).</P>



<P><P CLASS="Body"><A NAME="pgfId=142494"></A>In Section&nbsp;2.5 we saw

that the standard-cell version and gate-array macro version of the sequential

cells (latches and flip-flops) each contain their own clock buffers. The

reason for this is that (without intelligent placement software) we do not

know where a standard cell or a gate-array macro will be placed on a chip.

We also have no idea of the condition of the clock signal coming into a

sequential cell. The ability to place the clock buffers outside the sequential

cells in a datapath gives us more flexibility and saves space. For example,

we can place the clock buffers for all the clocked elements at the top of

the datapath (together with the buffers for the control signals) and <B>river

route</B> (in river routing the interconnect lines all flow in the same

direction on the same layer) the connections to the clock lines. This saves

space and allows us to guarantee the clock skew and timing. It may mean,

however, that there is a fixed overhead associated with a datapath. For

example, it might make no sense to build a 4-bit datapath if the clock and

control buffers take up twice the space of the datapath logic. Some tools

allow us to design logic using a <B>portable netlist</B> . After we complete

the design we can decide whether to implement the portable netlist in a

datapath, standard cells, or even a gate array, based on area, speed, or

power considerations.</P>



<P><HR ALIGN=LEFT></P>



<P><A HREF="CH02.12.htm">Chapter&nbsp;&nbsp;start</A>&nbsp;&nbsp;&nbsp;<A

HREF="CH02.17.htm">Previous&nbsp;&nbsp;page</A>&nbsp;&nbsp;<A HREF="CH02.19.htm">Next&nbsp;&nbsp;page</A>

</BODY>



<!--#include file="Copyright.html"--><!--#include file="footer.html"-->

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -