ch10.02.htm
来自「介绍asci设计的一本书」· HTM 代码 · 共 609 行 · 第 1/2 页
HTM
609 行
<P><P CLASS="TableLeft"><A NAME="pgfId=282421"></A>SH Shift, active high</P>
<P><P CLASS="TableLeft"><A NAME="pgfId=282406"></A>DIR Direction, 1 = left</P>
<P><P CLASS="TableLeft"><A NAME="pgfId=282407"></A>D Data in</P>
<P><P CLASS="TableLeft"><A NAME="pgfId=282438"></A>Q Data out</P>
<P><P CLASS="TableLeft"><A NAME="pgfId=282561"></A> </P>
<P><P CLASS="TableLeft"><A NAME="pgfId=282562"></A>Variable-width shift
register. Input width must be less than output width. Output is left-shifted
or right-shifted under control of DIR. Unused MSBs are zero-padded during
load. Clear is asynchronous. Load is synchronous.</P>
<P><P CLASS="TableLeft"><A NAME="pgfId=285768"></A> </P>
<P><P CLASS="TableLeft"><A NAME="pgfId=285769"></A>Timing:</P>
<P><P CLASS="TableLeft"><A NAME="pgfId=287358"></A><CODE>TCQ</CODE> (CLR
to Q) = 0.3 ns</P>
<P><P CLASS="TableLeft"><A NAME="pgfId=287367"></A><CODE>TLQ</CODE> (LD
to Q) = 0.5 ns</P>
<P><P CLASS="TableLeft"><A NAME="pgfId=287372"></A><CODE>TSQ</CODE> (SH
to Q) = 0. 7 ns</TD></TR>
</TABLE>
</P>
<H3>10.2.5 A State Machine</H3>
<P><P CLASS="BodyAfterHead">To multiply two binary numbers <CODE>A</CODE>
and <CODE>B</CODE> , we can use the following algorithm:</P>
<P><P CLASS="NumberFirst">If the LSB of <CODE>A</CODE> is <CODE>'1'</CODE>,
then add <CODE>B</CODE> into an accumulator.</P>
<P><P CLASS="NumberList">Shift <CODE>A</CODE> one bit to the right and <CODE>B</CODE>
one bit to the left.</P>
<P><P CLASS="NumberList">Stop when all bits of <CODE>A</CODE> are zero.</P>
<P><P CLASS="Body">Table 10.8 shows the VHDL model for a Moore (outputs
depend only on the state) finite-state machine for the multiplier, together
with its state diagram.</P>
<P><TABLE BORDER="1" CELLSPACING="2" CELLPADDING="2">
<TR>
<TH COLSPAN="2" ALIGN="LEFT"><P ALIGN=LEFT><P CLASS="TableTitle"><A NAME="pgfId=290391"></A>TABLE 10.8 A
Moore state machine for the multiplier.</TH></TR>
<TR>
<TD ROWSPAN="2"><PRE><B>entity</B> SM_1 <B>is</B>
<B>generic</B> (TPD : TIME := 1 ns);
<B>port</B>(Start, Clk, LSB, Stop, Reset: <B>in</B> BIT;
Init, Shift, Add, Done : <B>out</B> BIT);
<B>end</B>;
<B>architecture</B> Moore <B>of</B> SM_1 <B>is</B>
<B>type</B> STATETYPE <B>is</B> (I, C, A, S, E);
<B>signal</B> State: STATETYPE;
<B>begin</B>
Init <= '1' <B>after</B> TPD <B>when</B> State = I
<B>else</B> '0' <B>after</B> TPD;
Add <= '1' <B>after</B> TPD <B>when</B> State = A
<B>else</B> '0' <B>after</B> TPD;
Shift <= '1' <B>after</B> TPD <B>when</B> State = S
<B>else </B>'0' <B>after</B> TPD;
Done <= '1' <B>after</B> TPD <B>when</B> State = E
<B>else</B> '0' <B>after</B> TPD;
<B>process</B> (CLK, Reset) <B>begin</B>
<B>if</B> Reset = '1' <B>then</B> State <= E;
<B>elsif</B> CLK'EVENT and CLK = '1' <B>then</B>
<B>case</B> State <B>is</B>
<B>when</B> I => State <= C;
<B>when</B> C =>
<B>if</B> LSB = '1' <B>then</B> State <= A;
<B>elsif</B> Stop = '0' <B>then</B> State <= S;
<B>else</B> State <= E;
<B>end</B> <B>if</B>;
<B>when</B> A => State <= S;
<B>when</B> S => State <= C;
<B>when</B> E =>
<B>if</B> Start = '1' <B>then</B> State <= I; <B>end</B> <B>if</B>;
<B>end</B> <B>case</B>;
<B>end</B> <B>if</B>;
<B>end</B> <B>process</B>;
<B>end</B>;</PRE>
</TD>
<TD><P><P CLASS="Table"><A NAME="pgfId=290430"></A><P CLASS="Superscript"></P>
<P> </P>
<P><IMG SRC="CH10-8.gif" WIDTH="196" HEIGHT="262" NATURALSIZEFLAG="3" ALIGN=
"BOTTOM"></TD></TR>
<TR>
<TD><P>State Function</P>
<P> </P>
<P>E End of multiply cycle.</P>
<P>I Initialize: clear output</P>
<P>register and load input</P>
<P>registers.</P>
<P>C Check if LSB of register A</P>
<P>is zero.</P>
<P>A Add shift register B to</P>
<P>accumulator.</P>
<P>S Shift input register A right</P>
<P>and input register B left.</TD></TR>
</TABLE>
</P>
<H3><A NAME="pgfId=280317"></A>10.2.6 A Multiplier</H3>
<P><P CLASS="BodyAfterHead"><A NAME="pgfId=280364"></A>Table 10.9 shows
a schematic and the VHDL code that describes the interconnection of all
the components for the multiplier. Notice that the schematic comprises two
halves: an 8-bit-wide datapath section (consisting of the registers, adder,
multiplexer, and zero detector) and a control section (the finite-state
machine). The arrows in the schematic denote the inputs and outputs of each
component. As we shall see in Section 10.7, VHDL has strict rules about
the direction of connections.</P>
<P><TABLE BORDER="1" CELLSPACING="2" CELLPADDING="2">
<TR>
<TH ALIGN="LEFT"><P ALIGN=LEFT><P CLASS="TableTitle"><A NAME="pgfId=281004"></A>TABLE 10.9 A
4-bit by 4-bit multiplier.</TH></TR>
<TR>
<TD><P><P CLASS="Table"><A NAME="pgfId=281075"></A> </P>
<P><IMG SRC="CH10-9.gif" WIDTH="444" HEIGHT="268" NATURALSIZEFLAG="3" ALIGN=
"BOTTOM"></TD></TR>
<TR>
<TD><PRE><B>entity</B> Mult8 <B>is</B>
<B>port</B> (A, B: <B>in</B> BIT_VECTOR(3 <B>downto</B> 0); Start, CLK, Reset: <B>in</B> BIT;
Result: <B>out</B> BIT_VECTOR(7 <B>downto</B> 0); Done: <B>out </B>BIT); <B>end</B> Mult8;
<B>architecture</B> Structure <B>of</B> Mult8 <B>is use</B> work.Mult_Components.<B>all</B>;
<B>signal</B> SRA, SRB, ADDout, MUXout, REGout: BIT_VECTOR(7 <B>downto</B> 0);
<B>signal</B> Zero, Init, Shift, Add, Low: BIT := '0'; <B>signal</B> High: BIT := '1';
<B>signal</B> F, OFL, REGclr: BIT;
<B>begin </B>
REGclr <= Init <B>or</B> Reset; Result <= REGout;
SR1 : ShiftN <B>port</B> <B>map</B>(CLK=>CLK,CLR=>Reset,LD=>Init,SH=>Shift,DIR=>Low ,D=>A,Q=>SRA);
SR2 : ShiftN <B>port</B> <B>map</B>(CLK=>CLK,CLR=>Reset,LD=>Init,SH=>Shift,DIR=>High,D=>B,Q=>SRB);
Z1 : AllZero <B>port</B> <B>map</B>(X=>SRA,F=>Zero);
A1 : Adder8 <B>port</B> <B>map</B>(A=>SRB,B=>REGout,Cin=>Low,Cout=>OFL,Sum=>ADDout);
M1 : Mux8 <B>port</B> <B>map</B>(A=>ADDout,B=>REGout,Sel=>Add,Y=>MUXout);
R1 : Register8 <B>port</B> <B>map</B>(D=>MUXout,Q=>REGout,Clk=>CLK,Clr=>REGclr);
F1 : SM_1 <B>port</B> <B>map</B>(Start,CLK,SRA(0),Zero,Reset,Init,Shift,Add,Done);
<B>end</B>;</PRE>
</TD></TR>
</TABLE>
</P>
<H3><A NAME="pgfId=289578"></A>10.2.7 Packages and Testbench</H3>
<P><P CLASS="BodyAfterHead"><A NAME="pgfId=293310"></A>To complete and test
the multiplier design we need a few more items. First we need the following
"components list" for the items in Table 10.9:</P>
<PRE><B>package</B> Mult_Components <B>is</B>
<B>component</B> Mux8 <B>port</B> (A,B:BIT_VECTOR(7 <B>downto</B> 0);
Sel:BIT;Y:<B>out</B> BIT_VECTOR(7 <B>downto</B> 0));<B>end</B> <B>component</B>;
<B>component</B> AllZero <B>port</B> (X : BIT_VECTOR;
F:<B>out</B> BIT );<B>end</B> <B>component</B>;
<B>component</B> Adder8 <B>port</B> (A,B:BIT_VECTOR(7 <B>downto</B> 0);Cin:BIT;
Cout:<B>out</B> BIT;Sum:<B>out</B> BIT_VECTOR(7 <B>downto</B> 0));<B>end component</B>;
<B>component</B> Register8 <B>port</B> (D:BIT_VECTOR(7 <B>downto</B> 0);
Clk,Clr:BIT; Q:<B>out</B> BIT_VECTOR(7 <B>downto</B> 0));<B>end</B> <B>component</B>;
<B>component</B> ShiftN <B>port</B> (CLK,CLR,LD,SH,DIR:BIT;D:BIT_VECTOR;
Q:<B>out</B> BIT_VECTOR);<B>end</B> <B>component</B>;
<B>component</B> SM_1 <B>port</B> (Start,CLK,LSB,Stop,Reset:BIT;
Init,Shift,Add,Done:<B>out</B> BIT);<B>end</B> <B>component</B>;
<B>end</B>;</PRE>
<P><P CLASS="Body"><A NAME="pgfId=293429"></A>Next we need some utility
code to help test the multiplier. The following VHDL generates a clock with
programmable "high" time (<CODE> HT</CODE> ) and "low"
time (<CODE> LT</CODE> ):</P>
<PRE><B>package</B> Clock_Utils <B>is</B>
<B>procedure</B> Clock (<B>signal</B> C: <B>out</B> Bit; HT, LT:TIME);
<B>end</B> Clock_Utils;
<B>package</B> <B>body</B> Clock_Utils <B>is</B>
<B>procedure</B> Clock (<B>signal</B> C: <B>out</B> Bit; HT, LT:TIME) <B>is</B>
<B>begin</B>
<B> loop</B> C<='1' <B>after</B> LT, '0' <B>after</B> LT + HT; <B>wait</B> <B>for</B> LT + HT;
<B>end</B> <B>loop</B>;
<B>end</B>;
<B>end</B> Clock_Utils;</PRE>
<P><P CLASS="Body"><A NAME="pgfId=322895"></A>Finally, the following code
defines two functions that we shall also use for testing--the functions
convert an array of bits to a number and vice versa:</P>
<PRE><B>package</B> Utils <B>is</B>
<B> function</B> Convert (N,L: NATURAL) <B>return</B> BIT_VECTOR;
<B> function</B> Convert (B: BIT_VECTOR) <B>return</B> NATURAL;
<B>end</B> Utils;
<B>package</B> <B>body</B> Utils <B>is</B>
<B> function</B> Convert (N,L: NATURAL) <B>return</B> BIT_VECTOR <B>is</B>
<B>variable</B> T:BIT_VECTOR(L-1 <B>downto</B> 0);
<B> variable</B> V:NATURAL:= N;
<B> begin</B> <B>for</B> i <B>in</B> T'RIGHT <B>to</B> T'LEFT <B>loop</B>
T(i) := BIT'VAL(V <B>mod</B> 2); V:= V/2;
<B>end</B> <B>loop</B>; <B>return</B> T;
<B> end</B>;
<B> function</B> Convert (B: BIT_VECTOR) <B>return</B> NATURAL <B>is</B>
<B>variable</B> T:BIT_VECTOR(B'LENGTH-1 <B>downto</B> 0) := B;
<B>variable</B> V:NATURAL:= 0;
<B>begin</B> <B>for</B> i <B>in</B> T'RIGHT <B>to</B> T'LEFT <B>loop</B>
<B>if</B> T(i) = '1' <B>then</B> V:= V + (2**i); <B>end</B> <B>if</B>;
<B>end</B> <B>loop</B>; <B>return</B> V;
<B>end</B>;
<B>end</B> Utils;</PRE>
<P><P CLASS="Body"><A NAME="pgfId=363460"></A>The following code tests the
multiplier model. This is a testbench (this simple example is not a comprehensive
test). First we reset the logic (line 17) and then apply a series of values
to the inputs, <CODE>A</CODE> and <CODE>B</CODE> . The clock generator (line
14) supplies a clock with a 20 ns period. The inputs are changed 1 ns after
a positive clock edge, and remain stable for 20 ns through the next positive
clock edge.</P>
<PRE><B>entity</B> Test_Mult8_1 <B>is</B> <B>end</B>; -- runs forever, use break!!
<B>architecture</B> Structure <B>of</B> Test_Mult8_1 <B>is</B>
<B>use</B> Work.Utils.<B>all</B>; <B>use</B> Work.Clock_Utils.<B>all</B>;
<B> component</B> Mult8 <B>port</B>
(A, B : BIT_VECTOR(3 <B>downto</B> 0); Start, CLK, Reset : BIT;
Result : <B>out</B> BIT_VECTOR(7 <B>downto</B> 0); Done : <B>out</B> BIT);
<B> end</B> <B>component</B>;
<B>signal</B> A, B : BIT_VECTOR(3 <B>downto</B> 0);
<B>signal</B> Start, Done : BIT := '0';
<B>signal</B> CLK, Reset : BIT;
<B>signal</B> Result : BIT_VECTOR(7 <B>downto</B> 0);
<B>signal</B> DA, DB, DR : INTEGER <B>range</B> 0 <B>to</B> 255;
<B>begin</B>
C: Clock(CLK, 10 ns, 10 ns);
UUT: Mult8 <B>port</B> <B>map</B> (A, B, Start, CLK, Reset, Result, Done);
DR <= Convert(Result);
Reset <= '1', '0' <B>after</B> 1 ns;
<B>process</B> <B>begin</B>
<B> for</B> i <B>in</B> 1 <B>to</B> 3 <B>loop</B> <B>for</B> j <B>in</B> 4 <B>to</B> 7 <B>loop</B>
DA <= i; DB <= j;
A<=Convert(i,A'Length);B<=Convert(j,B'Length);
<B> wait</B> <B>until</B> CLK'EVENT <B>and</B> CLK='1'; <B>wait</B> <B>for</B> 1 ns;
Start <= '1', '0' <B>after</B> 20 ns; <B>wait</B> <B>until</B> Done = '1';
<B> wait</B> <B>until</B> CLK'EVENT <B>and</B> CLK='1';
<B> end</B> <B>loop</B>; <B>end</B> <B>loop</B>;
<B> for</B> i <B>in</B> 0 <B>to</B> 1 <B>loop</B> <B>for</B> j <B>in</B> 0 <B>to</B> 15 <B>loop</B>
DA <= i; DB <= j;
A<=Convert(i,A'Length);B<=Convert(j,B'Length);
<B> wait</B> <B>until</B> CLK'EVENT <B>and</B> CLK='1'; <B>wait</B> <B>for</B> 1 ns;
Start <= '1', '0' <B>after</B> 20 ns; <B>wait</B> <B>until</B> Done = '1';
<B> wait</B> <B>until</B> CLK'EVENT <B>and</B> CLK='1';
<B> end</B> <B>loop</B>; <B>end</B> <B>loop</B>;
<B> wait</B>;
<B>end</B> <B>process</B>;
<B>end</B>;</PRE>
<P><P CLASS="Body"><A NAME="pgfId=325368"></A>Here is the signal trace output
from the Compass Scout simulator:</P>
<PRE> Time(fs) + Cycle da db dr
---------------------- ------------ ------------ ------------
0+ 0: 0 0 0
0+ 1: * 1 * 4 * 0
...
92000000+ 3: 1 4 * 4
...
150000000+ 1: * 1 * 5 4
...
193000000+ 3: 1 5 * 0
...
252000000+ 3: 1 5 * 5
...
310000000+ 1: * 1 * 6 5
...
353000000+ 3: 1 6 * 0
...
412000000+ 3: 1 6 * 6</PRE>
<P><P CLASS="Body"><A NAME="pgfId=343318"></A>Positive clock edges occur
at 10, 30, 50, 70, 90, ... ns. You can see that the output (<CODE>dr</CODE>)
changes from <CODE>'0'</CODE> to <CODE>'4'</CODE> at 92 ns, after five clock
edges (with a 2 ns delay due to the output register, <CODE>R1</CODE>).</P>
<P><HR ALIGN=LEFT></P>
<P><A HREF="CH10.htm">Chapter start</A> <A HREF="CH10.01.htm">Previous page</A> <A HREF="CH10.03.htm">Next page</A>
</BODY>
<!--#include file="Copyright.html"--><!--#include file="footer.html"-->
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?