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>&nbsp;</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>&nbsp;</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&nbsp; 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&nbsp;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&nbsp;10.8&nbsp;&nbsp;&nbsp;&nbsp;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&nbsp;&lt;= '1' <B>after</B> TPD <B>when</B> State = I

	<B>else</B> '0' <B>after</B> TPD;

Add&nbsp;&nbsp;&lt;= '1' <B>after</B> TPD <B>when</B> State = A

	<B>else</B> '0' <B>after</B> TPD;

Shift &lt;= '1' <B>after</B> TPD <B>when</B> State = S

	<B>else </B>'0' <B>after</B> TPD;

Done&nbsp;&lt;= '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 &lt;= E;

	<B>elsif</B> CLK'EVENT and CLK = '1' <B>then</B>

		<B>case</B> State <B>is</B>

		<B>when</B> I =&gt; State &lt;= C;

		<B>when</B> C =&gt; 

			<B>if</B> LSB = '1' <B>then</B> State &lt;= A;

			<B>elsif</B> Stop = '0' <B>then</B> State &lt;= S;

			<B>else</B> State &lt;= E;

			<B>end</B> <B>if</B>;

		<B>when</B> A =&gt; State &lt;= S;

		<B>when</B> S =&gt; State &lt;= C;

		<B>when</B> E =&gt; 

			<B>if</B> Start = '1' <B>then</B> State &lt;= 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>&nbsp;</P>



<P><IMG SRC="CH10-8.gif" WIDTH="196" HEIGHT="262" NATURALSIZEFLAG="3" ALIGN=

"BOTTOM"></TD></TR>

<TR>

<TD><P>State Function</P>



<P>&nbsp;</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&nbsp; A Multiplier</H3>



<P><P CLASS="BodyAfterHead"><A NAME="pgfId=280364"></A>Table&nbsp;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&nbsp;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&nbsp;10.9&nbsp;&nbsp;&nbsp;&nbsp;A

4-bit by 4-bit multiplier.</TH></TR>

<TR>

<TD><P><P CLASS="Table"><A NAME="pgfId=281075"></A>&nbsp;</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 &lt;= Init <B>or</B> Reset; Result  &lt;= REGout;

SR1 : ShiftN&nbsp;<B>port</B> <B>map</B>(CLK=&gt;CLK,CLR=&gt;Reset,LD=&gt;Init,SH=&gt;Shift,DIR=&gt;Low&nbsp;,D=&gt;A,Q=&gt;SRA);

SR2 : ShiftN&nbsp;<B>port</B> <B>map</B>(CLK=&gt;CLK,CLR=&gt;Reset,LD=&gt;Init,SH=&gt;Shift,DIR=&gt;High,D=&gt;B,Q=&gt;SRB);

Z1 : AllZero&nbsp;<B>port</B> <B>map</B>(X=&gt;SRA,F=&gt;Zero);

A1 : Adder8&nbsp;&nbsp;<B>port</B> <B>map</B>(A=&gt;SRB,B=&gt;REGout,Cin=&gt;Low,Cout=&gt;OFL,Sum=&gt;ADDout);

M1 : Mux8&nbsp;&nbsp;&nbsp;&nbsp;<B>port</B> <B>map</B>(A=&gt;ADDout,B=&gt;REGout,Sel=&gt;Add,Y=&gt;MUXout);

R1 : Register8&nbsp;<B>port</B> <B>map</B>(D=&gt;MUXout,Q=&gt;REGout,Clk=&gt;CLK,Clr=&gt;REGclr);

F1 : SM_1&nbsp;&nbsp;&nbsp;&nbsp;<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&nbsp; 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

&quot;components list&quot; for the items in Table&nbsp;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 &quot;high&quot; time (<CODE> HT</CODE> ) and &quot;low&quot;

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&lt;='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 &lt;= Convert(Result);

Reset  &lt;= '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 &lt;= i; DB &lt;= j;

		A&lt;=Convert(i,A'Length);B&lt;=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 &lt;= '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 &lt;= i; DB &lt;= j;

		A&lt;=Convert(i,A'Length);B&lt;=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 &lt;= '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>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;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&nbsp;&nbsp;start</A>&nbsp;&nbsp;&nbsp;<A HREF="CH10.01.htm">Previous&nbsp;&nbsp;page</A>&nbsp;&nbsp;&nbsp;<A HREF="CH10.03.htm">Next&nbsp;&nbsp;page</A>

</BODY>



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

⌨️ 快捷键说明

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