ch10.09.htm
来自「介绍asci设计的一本书」· HTM 代码 · 共 744 行 · 第 1/3 页
HTM
744 行
<P><P CLASS="TableLeft"><A NAME="pgfId=254275"></A> 'QUIET</P>
<P><P CLASS="TableLeft"><A NAME="pgfId=254276"></A> 'DELAYED</P>
<P><P CLASS="TableLeft"><A NAME="pgfId=254277"></A> 'TRANSACTION</P>
<P><P CLASS="TableLeft"><A NAME="pgfId=254278"></A>of a signal</TD>
<TD><P CLASS="TableLeft"><A NAME="pgfId=254280"></A> </TD></TR>
</TABLE>
<P CLASS="Body"><A NAME="pgfId=178490"></A>A subprogram declaration is optional,
but a subprogram specification must be included in the subprogram body (and
must be identical in syntax to the subprogram declaration--see BNF [10.19]):</P>
<PRE>subprogram_body ::=
subprogram_specification is
{subprogram_declaration|subprogram_body
|type_declaration|subtype_declaration
|constant_declaration|variable_declaration|file_declaration
|alias_declaration|attribute_declaration|attribute_specification
|use_clause<U>|group_template_declaration|group_declaration</U>}
begin
{sequential_statement}
end <U>[procedure|function]</U> [identifier|string_literal] ;</PRE>
<P><P CLASS="Body"><A NAME="pgfId=178325"></A>You can include a subprogram
declaration or subprogram body in a package or package body (see Section 10.6)
or in the declarative region of an entity or <CODE>process</CODE> statement.
The following is an example of a function declaration and its body:</P>
<PRE><B>function</B> subset0(sout0 : <B>in</B> BIT) <B>return</B> BIT_VECTOR -- declaration
-- Declaration can be separate from the body.
<B>function</B> subset0(sout0 : <B>in</B> BIT) <B>return</B> BIT_VECTOR <B>is</B> -- body
<B>variable</B> y : BIT_VECTOR(2 <B>downto</B> 0);
<B>begin</B>
<B>if</B> (sout0 = '0') <B>then</B> y := "000"; <B>else</B> y := "100"; <B>end</B> <B>if</B>;
<B>return</B> result;
<B>end</B>;
<B>procedure </B>clockGen (clk : <B>out </B>BIT) -- Declaration
<B>procedure </B>clockGen (clk : <B>out </B>BIT) <B>is </B> -- Specification
<B>begin</B> -- Careful this process runs forever:
<B> process</B> <B>begin wait</B> <B>for</B> 10 ns; clk <= <B>not</B> clk; <B>end</B> <B>process</B>;
<B>end</B>;</PRE>
<P><P CLASS="Body"><A NAME="pgfId=178540"></A>One reason for having the
optional (and seemingly redundant) subprogram declaration is to allow companies
to show the subprogram declarations (to document the interface) in a package
declaration, but to hide the subprogram bodies (the actual code) in the
package body. If a separate subprogram declaration is present, it must conform
to the specification in the subprogram body [<A HREF="../../VHDL/LRM/HTML/1076_2.HTM#2.7">VHDL
93LRM2.7</A>]. This means the specification and declaration must be almost
identical; the safest method is to copy and paste. If you define common
procedures and functions in packages (instead of in each entity or architecture,
for example), it will be easier to reuse subprograms. In order to make a
subprogram included in a package body visible outside the package, you must
declare the subprogram in the package declaration (otherwise the subprogram
is private).</P>
<P><P CLASS="Body"><A NAME="pgfId=220552"></A>You may call a function from
any expression, as follows:</P>
<PRE><B>entity</B> F_1 <B>is</B> <B>port</B> (s : <B>out</B> BIT_VECTOR(3 <B>downto</B> 0) := "0000"); <B>end</B>;
<B>architecture</B> Behave <B>of</B> F_1 <B>is begin</B> <B>process</B>
<B>function </B>add(a, b, c : BIT_VECTOR(3 <B>downto</B> 0)) <B>return</B> BIT_VECTOR <B>is</B>
<B>begin</B> <B>return</B> a <B>xor</B> b <B>xor</B> c; <B>end</B>;
<B>begin</B> s <= add("0001", "0010", "1000"); <B>wait</B>; <B>end</B> <B>process</B>; <B>end</B>;
<B>package</B> And_Pkg <B>is </B>
<B> procedure</B> V_And(a, b : BIT; <B>signal</B> c : <B>out</B> BIT);
<B> </B>function V_And(a, b : BIT) <B>return</B> BIT;
<B>end</B>;
<B>package body</B> And_Pkg <B>is </B>
<B> 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> </B>function V_And(a,b : BIT) <B>return</B> BIT <B>is </B>
<B> begin</B> <B>return</B> a <B>and </B>b; <B>end</B>;
<B>end</B> And_Pkg;
<B>entity</B> F_2 <B>is</B> <B>port</B> (s: <B>out</B> BIT := '0'); <B>end</B>;
<B>use</B> work.And_Pkg.<B>all</B>; -- use package already analyzed
<B>architecture</B> Behave <B>of</B> F_2 <B>is begin</B> <B>process begin</B>
s <= V_And('1', '1'); <B>wait</B>; <B>end</B> <B>process</B>; <B>end</B>;</PRE>
<P><P CLASS="Body"><A NAME="pgfId=220498"></A>I shall discuss the two different
ways to call a procedure in Sections 10.10.4 and 10.13.3.</P>
<H3><A NAME="pgfId=178524"></A>10.9.3 Alias and Attribute Declarations</H3>
<P><P CLASS="BodyAfterHead"><A NAME="pgfId=539643"></A>An alias declaration
[VHDL 87LRM4.3.4, <A HREF="../../VHDL/LRM/HTML/1076_4.HTM#4.3.3">93LRM4.3.3</A>]
names parts of a type:</P>
<PRE>alias_declaration ::=
<B>alias</B>
identifier<U>|character_literal|operator_symbol </U> <U>[</U> :subtype_indication<U>]</U>
<B>is</B> name <U>[signature]</U> ;</PRE>
<P><P CLASS="BodyAfterHead"><A NAME="pgfId=539649"></A>(the subtype indication
is required in VHDL-87, but not in VHDL-93).</P>
<P><P CLASS="Body"><A NAME="pgfId=231594"></A>Here is an example of alias
declarations for parts of a floating-point number:</P>
<PRE><B>entity</B> Alias_1 <B>is</B> <B>end</B>; <B>architecture</B> Behave <B>of</B> Alias_1 <B>is</B>
<B>begin</B> <B>process variable</B> Nmbr: BIT_VECTOR (31 <B>downto</B> 0);
-- alias declarations to split Nmbr into 3 pieces :
<B>alias</B> Sign : BIT <B>is</B> Nmbr(31);
<B>alias</B> Mantissa : BIT_VECTOR (23 <B>downto</B> 0) <B>is</B> Nmbr (30 <B>downto</B> 7);
<B>alias</B> Exponent : BIT_VECTOR ( 6 <B>downto</B> 0) <B>is</B> Nmbr ( 6 <B>downto</B> 0);
<B>begin</B> <B>wait</B>; <B>end</B> <B>process</B>; <B>end</B>; -- the wait prevents an endless cycle</PRE>
<P><P CLASS="Body"><A NAME="pgfId=539668"></A>An attribute declaration [<A HREF="../../VHDL/LRM/HTML/1076_4.HTM#4.4">VHDL LRM4.4</A>] defines attribute properties:</P>
<PRE>attribute_declaration ::=
<B> attribute</B> identifier:<I>type_</I>name ; | <B>attribute</B> identifier:<I>subtype_</I>name ;</PRE>
<P><P CLASS="BodyAfterHead"><A NAME="pgfId=539672"></A>Here is an example:</P>
<PRE><B>entity</B> Attribute_1 <B>is</B> <B>end</B>; <B>architecture</B> Behave <B>of</B> Attribute_1 <B>is</B>
<B>begin</B> <B>process</B> <B>type</B> COORD <B>is</B> <B>record</B> X, Y : INTEGER; <B>end</B> <B>record</B>;
<B>attribute </B>LOCATION : COORD; -- the attribute declaration
<B>begin</B> <B>wait </B>; -- the wait prevents an endless cycle
<B>end</B> <B>process</B>; <B>end</B>;</PRE>
<P><P CLASS="Body"><A NAME="pgfId=178910"></A>You define the attribute properties
in an attribute specification (the following example specifies an attribute
of a component label). You probably will not need to use your own attributes
very much in ASIC design.</P>
<PRE><B>attribute</B> LOCATION <B>of</B> adder1 : <B>label</B> <B>is</B> (10,15);</PRE>
<P><P CLASS="BodyAfterHead"><A NAME="pgfId=21125"></A>You can then refer
to your attribute as follows:</P>
<PRE>positionOfComponent := adder1'LOCATION;</PRE>
<H3><A NAME="pgfId=231597"></A>10.9.4 Predefined Attributes</H3>
<P><P CLASS="BodyAfterHead"><A NAME="pgfId=570568"></A>The predefined attributes
for scalar and array types in VHDL-93 are shown in Table 10.14 [<A HREF="../../VHDL/LRM/HTML/1076_14.HTM#14.1">VHDL 93LRM14.1</A>]. There are two attributes,
<CODE>'STRUCTURE</CODE> and <CODE>'BEHAVIOR</CODE> , that are present in
VHDL-87, but removed in VHDL-93. Both of these attributes apply to architecture
bodies. The attribute name <CODE>A'BEHAVIOR</CODE> is <CODE>TRUE</CODE>
if the architecture <CODE>A</CODE> does not contain component instantiations.
The attribute name <CODE>A'STRUCTURE</CODE> is <CODE>TRUE</CODE> if the
architecture <CODE>A</CODE> contains only passive processes (those with
no assignments to signals) and component instantiations. These two attributes
were not widely used. The attributes shown in Table 10.14, however,
are used extensively to create packages and functions for type conversion
and overloading operators, but should not be needed by an ASIC designer.
Many of the attributes do not correspond to "real" hardware and
cannot be implemented by a synthesis tool.</P>
<P><TABLE BORDER="1" CELLSPACING="2" CELLPADDING="2">
<TR>
<TH COLSPAN="6"><P CLASS="TableTitle"><A NAME="pgfId=570581"></A>TABLE 10.14 Predefined
attributes for scalar and array types.</TH></TR>
<TR>
<TH><P CLASS="Table"><A NAME="pgfId=570593"></A><P CLASS="TableHeads">Attribute</TH>
<TH><P CLASS="Table"><A NAME="pgfId=570598"></A><P CLASS="TableHeads">Kind <A HREF="#pgfId=570597" CLASS="footnote">1</A></TH>
<TH><P CLASS="Table"><A NAME="pgfId=570600"></A><P CLASS="TableHeads">Prefix
<P CLASS="Table"><A NAME="pgfId=570604"></A>T, A, E <A HREF="#pgfId=570603" CLASS="footnote">2</A></TH>
<TH><P CLASS="Table"><A NAME="pgfId=570606"></A><P CLASS="TableHeads">Parameter
X or N <A HREF="#pgfId=570615" CLASS="footnote">3</A></TH>
<TH><P CLASS="Table"><A NAME="pgfId=570611"></A><P CLASS="TableHeads">Result
type <A HREF="#pgfId=570615" CLASS="footnote">3</A></TH>
<TH><P CLASS="Table"><A NAME="pgfId=570617"></A><P CLASS="TableHeads">Result</TH></TR>
<TR>
<TD><P CLASS="TableLeft"><A NAME="pgfId=570620"></A><CODE>T'BASE</CODE></TD>
<TD><P CLASS="Table"><A NAME="pgfId=570622"></A>T</TD>
<TD><P CLASS="Table"><A NAME="pgfId=570624"></A>any</TD>
<TD><P CLASS="Table"><A NAME="pgfId=570626"></A> </TD>
<TD><P CLASS="Table"><A NAME="pgfId=570628"></A>base(T)</TD>
<TD><P CLASS="TableLeft"><A NAME="pgfId=570630"></A>base(T), use only with other
attribute</TD></TR>
<TR>
<TD><P CLASS="TableLeft"><A NAME="pgfId=570633"></A><CODE>T'LEFT</CODE></TD>
<TD><P CLASS="Table"><A NAME="pgfId=570635"></A>V</TD>
<TD><P CLASS="Table"><A NAME="pgfId=570637"></A>scalar</TD>
<TD><P CLASS="Table"><A NAME="pgfId=570639"></A> </TD>
<TD><P CLASS="Table"><A NAME="pgfId=570641"></A>T</TD>
<TD><P CLASS="TableLeft"><A NAME="pgfId=570643"></A>Left bound of T</TD></TR>
<TR>
<TD><P CLASS="TableLeft"><A NAME="pgfId=570646"></A><CODE>T'RIGHT</CODE></TD>
<TD><P CLASS="Table"><A NAME="pgfId=570648"></A>V</TD>
<TD><P CLASS="Table"><A NAME="pgfId=570650"></A>scalar</TD>
<TD><P CLASS="Table"><A NAME="pgfId=570652"></A> </TD>
<TD><P CLASS="Table"><A NAME="pgfId=570654"></A>T</TD>
<TD><P CLASS="TableLeft"><A NAME="pgfId=570656"></A>Right bound of T</TD></TR>
<TR>
<TD><P CLASS="TableLeft"><A NAME="pgfId=570659"></A><CODE>T'HIGH</CODE></TD>
<TD><P CLASS="Table"><A NAME="pgfId=570661"></A>V</TD>
<TD><P CLASS="Table"><A NAME="pgfId=570663"></A>scalar</TD>
<TD><P CLASS="Table"><A NAME="pgfId=570665"></A> </TD>
<TD><P CLASS="Table"><A NAME="pgfId=570667"></A>T</TD>
<TD><P CLASS="TableLeft"><A NAME="pgfId=570669"></A>Upper bound of T</TD></TR>
<TR>
<TD><P CLASS="TableLeft"><A NAME="pgfId=570672"></A><CODE>T'LOW</CODE></TD>
<TD><P CLASS="Table"><A NAME="pgfId=570674"></A>V</TD>
<TD><P CLASS="Table"><A NAME="pgfId=570676"></A>scalar</TD>
<TD><P CLASS="Table"><A NAME="pgfId=570678"></A> </TD>
<TD><P CLASS="Table"><A NAME="pgfId=570680"></A>T</TD>
<TD><P CLASS="TableLeft"><A NAME="pgfId=570682"></A>Lower bound of T</TD></TR>
<TR>
<TD><P CLASS="TableLeft"><A NAME="pgfId=570685"></A><CODE>T'ASCENDING</CODE></TD>
<TD><P CLASS="Table"><A NAME="pgfId=570687"></A>V</TD>
<TD><P CLASS="Table"><A NAME="pgfId=570689"></A>scalar</TD>
<TD><P CLASS="Table"><A NAME="pgfId=570691"></A> </TD>
<TD><P CLASS="Table"><A NAME="pgfId=570693"></A><CODE>BOOLEAN</CODE></TD>
<TD><P CLASS="TableLeft"><A NAME="pgfId=570699"></A>True if range of T is ascending
<A HREF="#pgfId=570698" CLASS="footnote">4</A></TD></TR>
<TR>
<TD><P CLASS="TableLeft"><A NAME="pgfId=570702"></A><CODE>T'IMAGE(X)</CODE></TD>
<TD><P CLASS="Table"><A NAME="pgfId=570704"></A>F</TD>
<TD><P CLASS="Table"><A NAME="pgfId=570706"></A>scalar</TD>
<TD><P CLASS="Table"><A NAME="pgfId=570708"></A>base(T)</TD>
<TD><P CLASS="Table"><A NAME="pgfId=570710"></A><CODE>STRING</CODE></TD>
<TD><P CLASS="TableLeft"><A NAME="pgfId=570712"></A>String representation of
X in T <A HREF="#pgfId=570698" CLASS="footnote">4</A></TD></TR>
<TR>
<TD><P CLASS="TableLeft"><A NAME="pgfId=570715"></A><CODE>T'VALUE(X)</CODE></TD>
<TD><P CLASS="Table"><A NAME="pgfId=570717"></A>F</TD>
<TD><P CLASS="Table"><A NAME="pgfId=570719"></A>scalar</TD>
<TD><P CLASS="Table"><A NAME="pgfId=570721"></A><CODE>STRING</CODE></TD>
<TD><P CLASS="Table"><A NAME="pgfId=570723"></A>base(T)</TD>
<TD><P CLASS="TableLeft"><A NAME="pgfId=570725"></A>Value in T with representation
X <A HREF="#pgfId=570698" CLASS="footnote">4</A></TD></TR>
<TR>
<TD><P CLASS="TableLeft"><A NAME="pgfId=570728"></A><CODE>T'POS(X)</CODE></TD>
<TD><P CLASS="Table"><A NAME="pgfId=570730"></A>F</TD>
<TD><P CLASS="Table"><A NAME="pgfId=570732"></A>discrete</TD>
<TD><P CLASS="Table"><A NAME="pgfId=570734"></A>base(T)</TD>
<TD><P CLASS="Table"><A NAME="pgfId=570736"></A>UI</TD>
<TD><P CLASS="TableLeft"><A NAME="pgfId=570738"></A>Position number of X in
T (starts at 0)</TD></TR>
<TR>
<TD><P CLASS="TableLeft"><A NAME="pgfId=570741"></A><CODE>T'VAL(X)</CODE></TD>
<TD><P CLASS="Table"><A NAME="pgfId=570743"></A>F</TD>
<TD><P CLASS="Table"><A NAME="pgfId=570745"></A>discrete</TD>
<TD><P CLASS="Table"><A NAME="pgfId=570747"></A>UI</TD>
<TD><P CLASS="Table"><A NAME="pgfId=570749"></A>base(T)</TD>
<TD><P CLASS="TableLeft"><A NAME="pgfId=570751"></A>Value of position X in T</TD></TR>
<TR>
<TD><P CLASS="TableLeft"><A NAME="pgfId=570754"></A><CODE>T'SUCC(X)</CODE></TD>
<TD><P CLASS="Table"><A NAME="pgfId=570756"></A>F</TD>
<TD><P CLASS="Table"><A NAME="pgfId=570758"></A>discrete</TD>
<TD><P CLASS="Table"><A NAME="pgfId=570760"></A>base(T)</TD>
<TD><P CLASS="Table"><A NAME="pgfId=570762"></A>base(T)</TD>
<TD><P CLASS="TableLeft"><A NAME="pgfId=570764"></A>Value of position X in T
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?