ch10.13.htm
来自「介绍asci设计的一本书」· HTM 代码 · 共 427 行 · 第 1/2 页
HTM
427 行
, or <CODE>buffer</CODE> , see Section 10.7).</P>
<H3><A NAME="pgfId=362380"></A>10.13.3 Concurrent Procedure Call</H3>
<P><P CLASS="BodyAfterHead"><A NAME="pgfId=10534"></A>A concurrent procedure
call appears outside a <CODE>process</CODE> statement [<A HREF="../../VHDL/LRM/HTML/1076_9.HTM#9.3">VHDL
LRM9.3</A>]. The concurrent procedure call is a shorthand way of writing
an equivalent <CODE>process</CODE> statement that contains a procedure call
(Section 10.10.4):</P>
<PRE><B>package</B> And_Pkg <B>is procedure</B> V_And(a,b:BIT; <B>signal</B> c:<B>out</B> BIT); <B>end</B>;
<B>package body</B> And_Pkg <B>is procedure</B> V_And(a,b:BIT; <B>signal</B> c:<B>out</B> BIT) <B>is </B>
<B> begin</B> c <= a <B>and </B>b; <B>end</B>; <B>end</B> And_Pkg;
<B>use</B> work.And_Pkg.<B>all</B>;<B> entity</B> Proc_Call_2 <B>is</B> <B>end</B>;
<B>architecture</B> Behave <B>of</B> Proc_Call_2 <B>is signal</B> A, B, Y : BIT := '0';
<B>begin</B> V_And (A, B, Y); -- Concurrent procedure call.
<B>process</B> <B>begin wait</B>; <B>end</B> <B>process</B>; -- Extra process to stop.
<B>end</B>;</PRE>
<H3><A NAME="pgfId=2066"></A>10.13.4 Concurrent Signal Assignment</H3>
<P><P CLASS="BodyAfterHead"><A NAME="pgfId=536268"></A>There are two forms
of concurrent signal assignment statement. A selected signal assignment
statement is equivalent to a <CODE>case</CODE> statement inside a <CODE>process</CODE>
statement [<A HREF="../../VHDL/LRM/HTML/1076_9.HTM#9.5.2">VHDL LRM9.5.2</A>]:</P>
<PRE>selected_signal_assignment ::=
<B>with</B> expression <B>select</B>
name|aggregate <= [<B>guarded</B>]
[<B>transport</B><U>|[<B>reject</B> <I>time_</I>expression] <B>inertial</B></U>]
waveform <B>when</B> choice {| choice}
{, waveform <B>when</B> choice {| choice} } ;</PRE>
<P><P CLASS="Body"><A NAME="pgfId=22841"></A>The following design unit,
Selected_1, uses a selected signal assignment. The equivalent unit, Selected_2,
uses a <CODE>case</CODE> statement inside a <CODE>process</CODE> statement.</P>
<PRE><B>entity</B> Selected_1 <B>is</B> <B>end</B>; <B>architecture</B> Behave <B>of</B> Selected_1 <B>is</B>
<B>signal </B>y,i1,i2 : INTEGER; <B>signal</B> sel : INTEGER <B>range</B> 0 <B>to</B> 1;
<B>begin with</B> sel <B>select</B> y <= i1 <B>when</B> 0, i2 <B>when</B> 1; <B>end</B>;
<B>entity</B> Selected_2 <B>is</B> <B>end</B>; <B>architecture</B> Behave <B>of</B> Selected_2 <B>is</B>
<B>signal</B> i1,i2,y : INTEGER; <B>signal</B> sel : INTEGER <B>range</B> 0 <B>to</B> 1;
<B>begin process begin</B>
<B>case</B> sel <B>is</B> <B>when</B> 0 => y <= i1; <B>when</B> 1 => y <= i2; <B>end</B> <B>case</B>;
<B>wait</B> <B>on</B> i1, i2;
<B>end</B> <B>process</B>; <B>end</B>;</PRE>
<P><P CLASS="Body"><A NAME="pgfId=10538"></A>The other form of concurrent
signal assignment is a conditional signal assignment statement that, in
its most general form, is equivalent to an <CODE>if</CODE> statement inside
a <CODE>process</CODE> statement [<A HREF="../../VHDL/LRM/HTML/1076_9.HTM#9.5.1">VHDL
LRM9.5.1</A>]:</P>
<PRE>conditional_signal_assignment ::=
name|aggregate <= [<B>guarded</B>]
[<B>transport</B><U>|[<B>reject</B> <I>time_</I>expression] <B>inertial</B></U>]
{waveform <B>when</B> <I>boolean_</I>expression <B>else</B>}
waveform <U>[<B>when</B> <I>boolean_</I>expression]</U>;</PRE>
<P><P CLASS="Body"><A NAME="pgfId=22972"></A>Notice that in VHDL-93 the
<CODE>else</CODE> clause is optional. Here is an example of a conditional
signal assignment, followed by a model using the equivalent process with
an <CODE>if</CODE> statement:</P>
<PRE><B>entity</B> Conditional_1 <B>is</B> <B>end</B>; <B>architecture</B> Behave <B>of</B> Conditional_1 <B>is</B>
<B>signal</B> y,i,j : INTEGER; <B>signal</B> clk : BIT;
<B>begin </B>y <= i <B>when</B> clk = '1' <B>else</B> j; -- conditional signal assignment
<B>end</B>;
<B>entity</B> Conditional_2 <B>is</B> <B>end</B>; <B>architecture</B> Behave <B>of</B> Conditional_2 <B>is</B>
<B>signal</B> y,i : INTEGER; <B>signal</B> clk : BIT;
<B>begin process begin</B>
<B>if</B> clk = '1' <B>then</B> y <= i; <B>else</B> y <= y ; <B>end</B> <B>if</B>; <B>wait</B> <B>on</B> clk;
<B>end</B> <B>process</B>; <B>end</B>;</PRE>
<P><P CLASS="Body"><A NAME="pgfId=5651"></A>A concurrent signal assignment
statement can look just like a sequential signal assignment statement, as
in the following example:</P>
<PRE><B>entity</B> Assign_1 <B>is</B> <B>end</B>; <B>architecture</B> Behave <B>of</B> Assign_1 <B>is</B>
<B>signal</B> Target, Source : INTEGER;
<B>begin </B>Target <= Source <B>after</B> 1 ns; -- looks like signal assignment
<B>end</B>;</PRE>
<P><P CLASS="Body"><A NAME="pgfId=5652"></A>However, outside a <CODE>process</CODE>
statement, this statement is a concurrent signal assignment and has its
own equivalent <CODE>process</CODE> statement. Here is the equivalent process
for the example:</P>
<PRE><B>entity</B> Assign_2 <B>is</B> <B>end</B>; <B>architecture</B> Behave <B>of</B> Assign_2 <B>is</B>
<B>signal</B> Target, Source : INTEGER;
<B>begin</B> <B>process</B> <B>begin</B>
Target <= Source <B>after</B> 1 ns; <B>wait</B> <B>on</B> Source;
<B>end</B> <B>process</B>; <B>end</B>;</PRE>
<P><P CLASS="Body"><A NAME="pgfId=2126"></A>Every process is executed once
during initialization. In the previous example, an initial value will be
scheduled to be assigned to <CODE>Target</CODE> even though there is no
event on <CODE>Source</CODE> . If, for some reason, you do not want this
to happen, you need to rewrite the concurrent assignment statement as a
<CODE>process</CODE> statement with a <CODE>wait</CODE> statement before
the assignment statement:</P>
<PRE><B>entity</B> Assign_3 <B>is</B> <B>end</B>; <B>architecture</B> Behave <B>of</B> Assign_3 <B>is</B>
<B>signal</B> Target, Source : INTEGER; <B>begin process</B> <B>begin</B>
<B>wait</B> <B>on</B> Source; Target <= Source <B>after</B> 1 ns;
<B>end</B> <B>process</B>; <B>end</B>;</PRE>
<H3><A NAME="pgfId=5703"></A>10.13.5 Concurrent Assertion Statement</H3>
<P><P CLASS="BodyAfterHead"><A NAME="pgfId=536330"></A>A concurrent assertion
statement is equivalent to a passive <CODE>process</CODE> statement (without
a sensitivity list) that contains an <CODE>assertion</CODE> statement followed
by a <CODE>wait</CODE> statement [<A HREF="../../VHDL/LRM/HTML/1076_9.HTM#9.4">VHDL
LRM9.4</A>].</P>
<PRE>concurrent_assertion_statement
::= [ label : ] <U>[ <B>postponed</B> ]</U> assertion ;</PRE>
<P><P CLASS="Body"><A NAME="pgfId=540011"></A>If the assertion condition
contains a signal, then the equivalent <CODE>process</CODE> statement will
include a final <CODE>wait</CODE> statement with a sensitivity clause. A
concurrent assertion statement with a condition that is static expression
is equivalent to a <CODE>process</CODE> statement that ends in a <CODE>wait</CODE>
statement that has no sensitivity clause. The equivalent process will execute
once, at the beginning of simulation, and then wait indefinitely.</P>
<H3><A NAME="pgfId=536299"></A>10.13.6 Component Instantiation</H3>
<P><P CLASS="BodyAfterHead"><A NAME="pgfId=10539"></A>A component instantiation
statement in VHDL is similar to placement of a component in a schematic--an
instantiated component is somewhere between a copy of the component and
a reference to the component. Here is the definition [<A HREF="../../VHDL/LRM/HTML/1076_9.HTM#9.6">VHDL
LRM9.6</A>]:</P>
<PRE>component_instantiation_statement ::=
<I>instantiation_</I>label:
<U>[<B>component</B>]</U> <I>component_</I>name
<U>|<B>entity</B> <I>entity_</I>name [(<I>architecture_</I>identifier)]</U>
<U>|<B>configuration</B> <I>configuration_</I>name</U>
[<B>generic</B> <B>map</B> (<I>generic_</I>association_list)]
[<B>port</B> <B>map</B> (<I>port_</I>association_list)] ;</PRE>
<P><P CLASS="Body"><A NAME="pgfId=537592"></A>We examined component instantiation
using a component_name in Section 10.5. If we instantiate a component
in this way we must declare the component (see BNF [10.9]). To bind a component
to an entity-architecture pair we can use a configuration, as illustrated
in Figure 10.1, or we can use the default binding as described in Section 10.7.
In VHDL-93 we have another alternative--we can directly instantiate an entity
or configuration. For example:</P>
<PRE><B>entity</B> And_2 <B>is</B> <B>port</B> (i1, i2 : <B>in</B> BIT; y : <B>out</B> BIT); <B>end</B>;
<B>architecture</B> Behave <B>of</B> And_2 <B>is begin</B> y <= i1 <B>and</B> i2; <B>end</B>;
<B>entity</B> Xor_2 <B>is port</B> (i1, i2 : <B>in</B> BIT; y : <B>out</B> BIT); <B>end</B>;
<B>architecture</B> Behave <B>of</B> Xor_2 <B>is begin</B> y <= i1 <B>xor </B>i2; <B>end</B>;
<B>entity</B> Half_Adder_2 <B>is port</B> (a,b : BIT := '0'; sum, cry : <B>out</B> BIT); <B>end</B>;
<B>architecture</B> Netlist_2 <B>of</B> Half_Adder_2 <B>is</B>
<B>use</B> work.<B>all</B>; -- need this to see the entities Xor_2 and And_2
<B>begin</B>
X1 : <B>entity</B> Xor_2(Behave) <B>port</B> <B>map</B> (a, b, sum); -- VHDL-93 only
A1 : <B>entity</B> And_2(Behave) <B>port</B> <B>map</B> (a, b, cry); -- VHDL-93 only
<B>end</B>;</PRE>
<H3><A NAME="pgfId=2136"></A>10.13.7 Generate Statement</H3>
<P><P CLASS="BodyAfterHead"><A NAME="pgfId=10540"></A>A generate statement
[<A HREF="../../VHDL/LRM/HTML/1076_9.HTM#9.7">VHDL LRM9.7</A>] simplifies repetitive
code:</P>
<PRE>generate_statement ::=
<I>generate_</I>label: <B>for </B><I>generate_</I>parameter_specification
|<B>if</B> <I>boolean_</I>expression
<B>generate</B> <U>[{block_declarative_item} <B>begin</B>]</U>
{concurrent_statement}
<B>end</B> <B>generate</B> [<I>generate_</I>label] ;</PRE>
<P><P CLASS="Body"><A NAME="pgfId=240575"></A>Here is an example (notice
the labels are required):</P>
<PRE><B>entity</B> Full_Adder <B>is</B> <B>port</B> (X, Y, Cin : BIT; Cout, Sum: <B>out</B> BIT); <B>end</B>;
<B>architecture</B> Behave <B>of</B> Full_Adder <B>is begin</B> Sum <= X <B>xor</B> Y <B>xor</B> Cin;
Cout <= (X <B>and</B> Y) <B>or</B> (X <B>and</B> Cin) <B>or</B> (Y <B>and</B> Cin); <B>end</B>;
<B>entity</B> Adder_1 <B>is</B>
<B>port</B> (A, B : <B>in</B> BIT_VECTOR (7 <B>downto</B> 0) := (<B>others</B> => '0');
Cin : <B>in</B> BIT := '0'; Sum : <B>out</B> BIT_VECTOR (7 <B>downto</B> 0);
Cout : <B>out</B> BIT); <B>end</B>;
<B>architecture</B> Structure <B>of</B> Adder_1 <B>is use</B> work.<B>all</B>;
<B>component</B> Full_Adder <B>port</B> (X, Y, Cin: BIT; Cout, Sum: <B>out</B> BIT);
<B>end</B> <B>component</B>;
<B>signal</B> C : BIT_VECTOR(7 <B>downto</B> 0);
<B>begin</B> AllBits : <B>for</B> i <B>in</B> 7 <B>downto</B> 0 <B>generate</B>
LowBit : <B>if</B> i = 0 <B>generate</B>
FA : Full_Adder <B>port</B> <B>map</B> (A(0), B(0), Cin, C(0), Sum(0));
<B>end</B> <B>generate</B>;
OtherBits : <B>if</B> i /= 0 <B>generate</B>
FA : Full_Adder <B>port</B> <B>map</B> (A(i), B(i), C(i-1), C(i), Sum(i));
<B> end</B> <B>generate</B>;
<B>end</B> <B>generate</B>;
Cout <= C(7);
<B>end</B>;</PRE>
<P><P CLASS="Body"><A NAME="pgfId=238344"></A>The instance names within
a <CODE>generate</CODE> loop include the <CODE>generate</CODE> parameter.
For example for <CODE>i=6</CODE> , <CODE>FA'INSTANCE_NAME</CODE> <CODE>is</CODE></P>
<PRE>:adder_1(structure):allbits(6):otherbits:fa:</PRE>
<P><HR ALIGN="LEFT"></P>
<P><A HREF="CH10.htm">Chapter start</A> <A HREF="CH10.12.htm">Previous page</A> <A HREF="CH10.14.htm">Next page</A>
</BODY>
<!--#include file="Copyright.html"--><!--#include file="footer.html"-->
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?