ch10.10.htm

来自「介绍asci设计的一本书」· HTM 代码 · 共 490 行 · 第 1/3 页

HTM
490
字号
<B>use</B> work.And_Pkg.<B>all</B>;<B> entity</B> Proc_Call_1 <B>is</B> <B>end</B>;&nbsp;

<B>architecture</B> Behave <B>of</B> Proc_Call_1 <B>is signal</B> A, B, Y: BIT := '0';

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <B>begin</B> <B>process begin</B> V_And (A, B, Y); <B>wait</B>; <B>end</B> <B>process</B>;

<B>end</B>;</PRE>



<P><A NAME="pgfId=17144"></A>Table&nbsp;10.13 on page 416 explains the rules

for formal procedure parameters. There is one other way to call procedures,

which we shall cover in Section&nbsp;10.13.3.</P>



<H3><A NAME="pgfId=1824"></A>10.10.5&nbsp; If Statement</H3>



<P><A NAME="pgfId=10520"></A>An if statement evaluates one or more Boolean

expressions and conditionally executes a corresponding sequence of statements

[<A HREF="../../VHDL/LRM/HTML/1076_8.HTM#8.7">VHDL LRM8.7</A>].</P>



<PRE>if_statement ::=

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <U>[if_label:]</U> <B>if</B> boolean_expression <B>then</B> {sequential_statement}

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<B>elsif</B> boolean_expression <B>then</B> {sequential_statement}}

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [<B>else</B> {sequential_statement}]

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <B>end</B> <B>if</B> <U>[if_label]</U>;</PRE>



<P><A NAME="pgfId=1838"></A>The simplest form of an<TT> if </TT>statement

is thus:</P>



<PRE><B>if</B> boolean_expression <B>then</B> {sequential_statement} <B>end</B> <B>if</B>;</PRE>



<P><A NAME="pgfId=114124"></A>Here are some examples of the <TT>if</TT>

statement:</P>



<PRE><B>entity</B> If_Then_Else_1 <B>is</B> <B>end</B>;&nbsp;

<B>architecture</B> Behave <B>of</B> If_Then_Else_1 <B>is signal</B> a, b, c: BIT :='1';&nbsp;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <B>begin</B> <B>process begin</B>

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <B>if</B> c = '1' <B>then</B> c &lt;= a ; <B>else</B> c &lt;= b; <B>end</B> <B>if</B>; <B>wait</B>;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <B>end</B> <B>process</B>;

<B>end</B>;

<B>entity</B> If_Then_1 <B>is</B> <B>end</B>;&nbsp;

<B>architecture</B> Behave <B>of</B> If_Then_1 <B>is signal</B> A, B, Y : BIT :='1';

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <B>begin</B> <B>process begin</B>

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <B>if</B> A = B <B>then</B> Y &lt;= A; <B>end</B> <B>if</B>; <B>wait</B>;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <B>end</B> <B>process</B>;

<B>end</B>;</PRE>



<H3><A NAME="pgfId=1846"></A>10.10.6&nbsp; Case Statement</H3>



<P><A NAME="pgfId=10521"></A>A case statement [<A HREF="../../VHDL/LRM/HTML/1076_8.HTM#8.8">VHDL

LRM8.8</A>] is a multiway decision statement that selects a sequence of

statements by matching an expression with a list of (locally static [<A HREF="../../VHDL/LRM/HTML/1076_7.HTM#7.4.1">VHDL LRM7.4.1</A>]) choices.</P>



<PRE>case_statement ::=

<U>[case_label:]</U> <B>case</B> expression <B>is</B>

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<B>when</B> choice {| choice} =&gt; {sequential_statement}

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<B>when</B> choice {| choice} =&gt; {sequential_statement}}

<B>end</B> <B>case</B> <U>[case_label]</U>;</PRE>



<P><A NAME="pgfId=364518"></A>Case statements are useful to model state

machines. Here is an example of a Mealy state machine with an asynchronous

reset:</P>



<PRE><B>library</B> IEEE; <B>use</B> IEEE.STD_LOGIC_1164.<B>all</B>;&nbsp;

<B>entity</B> sm_mealy <B>is</B>

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <B>port</B> (reset, clock, i1, i2 : STD_LOGIC; o1, o2 : <B>out</B> STD_LOGIC);

<B>end</B> sm_mealy;

<B>architecture</B> Behave <B>of</B> sm_mealy <B>is</B>&nbsp;

<B>type</B> STATES <B>is</B> (s0, s1, s2, s3); <B>signal</B> current, new : STATES;

<B>begin</B>

synchronous : <B>process </B>(clock, reset) <B>begin</B>

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <B>if</B> To_X01(reset) = '0' <B>then</B> current &lt;= s0;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <B>elsif</B> rising_edge(clock) <B>then</B> current &lt;= new; <B>end</B> <B>if</B>;

<B>end</B> <B>process</B>;

combinational : <B>process </B>(current, i1, i2) <B>begin</B>&nbsp;

<B>case</B> current <B>is</B>

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <B>when</B> s0 =&gt;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <B>if</B> To_X01(i1) = '1' <B>then</B> o2 &lt;='0'; o1 &lt;='0'; new &lt;= s2;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <B>else</B> o2 &lt;= '1'; o1 &lt;= '1'; new &lt;= s1; <B>end</B> <B>if</B>;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <B>when</B> s1 =&gt;&nbsp;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <B>if</B> To_X01(i2) = '1' <B>then</B> o2 &lt;='1'; o1 &lt;='0'; new &lt;= s1;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <B>else</B> o2 &lt;='0'; o1 &lt;='1'; new &lt;= s3; <B>end</B> <B>if</B>;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <B>when</B> s2 =&gt;&nbsp;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <B>if</B> To_X01(i2) = '1' <B>then</B> o2 &lt;='0'; o1 &lt;='1'; new &lt;= s2;&nbsp;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <B>else</B> o2 &lt;= '1'; o1 &lt;= '0'; new &lt;= s0; <B>end</B> <B>if</B>;&nbsp;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <B>when</B> s3 =&gt; o2 &lt;= '0'; o1 &lt;= '0'; new &lt;= s0;&nbsp;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <B>when</B> <B>others</B> =&gt; o2 &lt;= '0'; o1 &lt;= '0'; new &lt;= s0;

<B>end</B> <B>case</B>;

<B>end</B> <B>process</B>;

<B>end</B> Behave;</PRE>



<P><A NAME="pgfId=178861"></A>Each possible value of the case expression

must be present once, and once only, in the list of choices (or arms) of

the case statement (the list must be exhaustive). You can use '|' (that

means 'or') or <TT>'to'</TT> to denote a range in the expression for <TT>choice</TT>

. You may also use the keyword <TT>others</TT> as the last, default <TT>choice</TT>

(even if the list is already exhaustive, as in the preceding example).</P>



<H3><A NAME="pgfId=1878"></A>10.10.7&nbsp; Other Sequential Control Statements</H3>



<P><A NAME="pgfId=10522"></A>A loop statement repeats execution of a series

of sequential statements [<A HREF="../../VHDL/LRM/HTML/1076_8.HTM#8.9">VHDL LRM8.9</A>]:</P>



<PRE>loop_statement ::=

[loop_label:]&nbsp;

[<B>while</B> boolean_expression|<B>for</B> identifier <B>in</B> discrete_range]

<B>loop</B>

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {sequential_statement}

e<B>nd</B> <B>loop</B> [loop_label];</PRE>



<P><A NAME="pgfId=10523"></A>If the loop variable (after the keyword <TT>for</TT>

) is used, it is only visible inside the loop. A <TT>while</TT> loop evaluates

the Boolean expression before each execution of the sequence of statements;

if the expression is <TT>TRUE</TT> , the statements are executed. In a <TT>for</TT>

loop the sequence of statements is executed once for each value of the discrete

range.</P>



<PRE><B>package</B> And_Pkg <B>is </B>function V_And(a, b : BIT) <B>return</B> BIT; <B>end</B>;

<B>package body</B> And_Pkg <B>is </B>function V_And(a, b : BIT) <B>return</B> BIT <B>is&nbsp;</B>

<B>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; begin</B> <B>return</B> a <B>and </B>b; <B>end</B>; <B>end</B> And_Pkg;

<B>entity</B> Loop_1 <B>is</B> <B>port</B> (x, y : <B>in </B>BIT := '1'; s : <B>out</B> BIT := '0'); <B>end</B>;

<B>use</B> work.And_Pkg.<B>all</B>;&nbsp;

<B>architecture</B> Behave <B>of</B> Loop_1 <B>is&nbsp;</B>

<B>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; begin</B> <B>loop</B>

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; s &lt;= V_And(x, y); <B>wait on</B> x, y;&nbsp;

<B>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; end</B> <B>loop</B>;&nbsp;

<B>end</B>;</PRE>



<P><A NAME="pgfId=240351"></A>The next statement [<A HREF="../../VHDL/LRM/HTML/1076_8.HTM#8.10">VHDL

LRM8.10</A>] forces completion of the current iteration of a loop (the containing

loop unless another loop label is specified). Completion is forced if the

condition following the keyword <TT>then</TT> is <TT>TRUE</TT> (or if there

is no condition).</P>



<PRE>next_statement ::=

<U>[label:]</U> <B>next</B> [loop_label] [<B>when</B> boolean_expression];</PRE>



<P><A NAME="pgfId=10524"></A>An exit statement [<A HREF="../../VHDL/LRM/HTML/1076_8.HTM#8.11">VHDL

LRM8.11</A>] forces an exit from a loop.</P>



<PRE>exit_statement ::=&nbsp;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <U>[label:]</U> <B>exit</B> [loop_label] [<B>when</B> condition] ;</PRE>



<P><A NAME="pgfId=231686"></A>As an example:</P>



<PRE><B>loop</B> <B>wait</B> <B>on</B> Clk; <B>exit</B> <B>when</B> Clk = '0'; <B>end</B> <B>loop</B>;

-- equivalent to: wait until Clk = '0';</PRE>



<P><A NAME="pgfId=1908"></A>The return statement [<A HREF="../../VHDL/LRM/HTML/1076_8.HTM#8.12">VHDL

LRM8.12</A>] completes execution of a procedure or function.</P>



<PRE>return_statement ::= <U>[label:]</U> <B>return</B> [expression];</PRE>



<P><A NAME="pgfId=1916"></A>A null statement [<A HREF="../../VHDL/LRM/HTML/1076_8.HTM#8.13">VHDL

LRM8.13</A>] does nothing (but is useful in a <TT>case</TT> statement where

all choices must be covered, but for some of the choices you do not want

to do anything).</P>



<PRE>null_statement ::= <U>[label:]</U> <B>null</B>;</PRE>



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



<P><A HREF="CH10.htm">Chapter&nbsp;&nbsp;start</A>&nbsp;&nbsp;&nbsp;<A HREF="CH10.09.htm">Previous&nbsp;&nbsp;page</A>&nbsp;&nbsp;&nbsp;<A HREF="CH10.11.htm">Next&nbsp;&nbsp;page</A>

</BODY>



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

⌨️ 快捷键说明

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