ch10.10.htm

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

HTM
490
字号
is the closest equivalent to the assignment statement in a computer programming

language. Variable assignment statements are always sequential statements

and the LHS of a variable assignment statement is always updated immediately.

Here is the definition and an example:</P>



<PRE>variable_assignment_statement ::=&nbsp;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <U>[label:]</U> name|aggregate := expression ;

<B>entity</B> Var_Assignment <B>is</B> <B>end</B>;

<B>architecture</B> Behave <B>of</B> Var_Assignment <B>is</B>

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <B>signal</B> s1 : INTEGER := 0;&nbsp;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <B>begin</B> <B>process variable</B> v1,v2 : INTEGER := 0; <B>begin</B>&nbsp;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <B>assert</B> (v1/=0) <B>report</B> &quot;v1 is 0&quot; <B>severity</B> note ; -- this prints

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; v1 := v1 + 1; -- after this statement v1 is 1

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <B>assert</B> (v1=0) <B>report</B> &quot;v1 isn't 0&quot; <B>severity</B> note ; -- this prints

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; v2 := v2 + s1; -- signal and variable types must match

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <B>wait</B>;

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

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



<P><A NAME="pgfId=115471"></A>This is the output from Cadence Leapfrog for

the preceding example:</P>



<PRE>ASSERT/NOTE (time 0 FS) from :$PROCESS_000 (design unit WORK.VAR_ASSIGNMENT:BEHAVE) v1 is 0

ASSERT/NOTE (time 0 FS) from :$PROCESS_000 (design unit WORK.VAR_ASSIGNMENT:BEHAVE) v1 isn't 0</PRE>



<P><A NAME="pgfId=10518"></A>A signal assignment statement schedules a future

assignment to a signal:</P>



<PRE>signal_assignment_statement::=&nbsp;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <U>[label:]</U> target &lt;=

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [<B>transport</B> <U>| [ reject time_expression ] inertial</U> ] waveform ;</PRE>



<P><A NAME="pgfId=238280"></A>The following example shows that, even with

no delay, a signal is updated at the end of a simulation cycle after all

the other assignments have been scheduled, just before simulation time is

advanced:</P>



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

<B>architecture</B> Behave <B>of</B> Sig_Assignment_1 <B>is</B>

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <B>signal</B> s1,s2,s3 : INTEGER := 0;&nbsp;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <B>begin</B> <B>process variable</B> v1 : INTEGER := 1; <B>begin</B>&nbsp;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <B>assert</B> (s1 /= 0) <B>report</B> &quot;s1 is 0&quot; <B>severity</B> note ; -- this prints.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; s1 &lt;= s1 + 1; -- after this statement s1 is still 0.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <B>assert</B> (s1 /= 0) <B>report</B> &quot;s1 still 0&quot; <B>severity</B> note ; -- this prints.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <B>wait</B>;

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

<B>end</B>;

ASSERT/NOTE (time 0 FS) from :$PROCESS_000 (design unit WORK.SIG_ASSIGNMENT_1:BEHAVE) s1 is 0

ASSERT/NOTE (time 0 FS) from :$PROCESS_000 (design unit WORK.SIG_ASSIGNMENT_1:BEHAVE) s1 still 0</PRE>



<P><A NAME="pgfId=116202"></A>Here is an another example to illustrate how

time is handled:</P>



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

<B>architecture</B> Behave <B>of</B> Sig_Assignment_2 <B>is</B>

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <B>signal</B> s1, s2, s3 : INTEGER := 0;&nbsp;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <B>begin</B> <B>process variable</B> v1 : INTEGER := 1; <B>begin</B>&nbsp;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -- s1, s2, s3 are initially 0; now consider the following:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; s1 &lt;= 1 ; -- schedules updates to s1 at end of 0 ns cycle.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; s2 &lt;= s1; -- s2 is 0, not 1.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <B>wait</B> <B>for</B> 1 ns;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; s3 &lt;= s1; -- now s3 will be 1 at 1 ns.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <B>wait</B>;

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

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



<P><A NAME="pgfId=116045"></A>The Compass simulator produces the following

trace file for this example:</P>



<PRE>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Time(fs) + Cycle&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; s1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; s2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; s3

----------------------&nbsp; ------------ ------------ ------------

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0+ 0:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0+ 1: *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1 *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0

...

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1000000+ 1:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0 *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1</PRE>



<P><A NAME="pgfId=116049"></A>Time is indicated in femtoseconds for each

simulation cycle plus the number of delta cycles (we call this delta time,

measured in units of delta) needed to calculate all transactions on signals.

A transaction consists of a new value for a signal (which may be the same

as the old value) and the time delay for the value to take effect. An asterisk

'*' before a value in the preceding trace indicates that a transaction has

occurred and the corresponding signal updated at that time. A transaction

that does result in a change in value is an event. In the preceding simulation

trace for Sig_Assignment_2:Behave</P>



<UL>

  <P><A NAME="pgfId=116070"></A>At <TT>0 ns + 0</TT> delta: all signals are

  <TT>0</TT> .

  <P><A NAME="pgfId=116073"></A>At <TT>0 ns + 1</TT> delta: <TT>s1</TT> is

  updated to <TT>1</TT> , <TT>s2</TT> is updated to <TT>0</TT> (not to <TT>1</TT>

  ).

  <P><A NAME="pgfId=116091"></A>At <TT>1 ns + 1</TT> delta: <TT>s3</TT> is

  updated to a <TT>1</TT> .

</UL>



<P><A NAME="pgfId=108835"></A>The following example shows the behavior of

the different delay models: transport and inertial (the default):</P>



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

<B>architecture</B> Behave <B>of</B> Transport_1 <B>is</B>

<B>signal</B> s1, SLOW, FAST, WIRE : BIT := '0';&nbsp;

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

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; s1 &lt;= '1' <B>after</B> 1 ns, '0' <B>after</B> 2 ns, '1' <B>after</B> 3 ns ;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -- schedules s1 to be '1' at t+1 ns, '0' at t+2 ns,'1' at t+3 ns

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

-- inertial delay: SLOW rejects pulsewidths less than 5ns:

<B>process</B> (s1) <B>begin</B> SLOW &lt;= s1 <B>after</B> 5 ns ; <B>end</B> <B>process</B>;

-- inertial delay: FAST rejects pulsewidths less than 0.5ns:

<B>process</B> (s1) <B>begin</B> FAST &lt;= s1 <B>after</B> 0.5 ns ; <B>end</B> <B>process</B>;

-- transport delay: WIRE passes all pulsewidths...

<B>process</B> (s1) <B>begin</B> WIRE &lt;= <B>transport</B> s1 <B>after</B> 5 ns ; <B>end</B> <B>process</B>;

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



<P><A NAME="pgfId=189300"></A>Here is the trace file from the Compass simulator:</P>



<PRE><A NAME="pgfId=189301"></A> &nbsp;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Time(fs) + Cycle&nbsp;&nbsp;&nbsp; s1 slow fast wire

----------------------&nbsp; ---- ---- ---- ----

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0+ 0:&nbsp; '0'&nbsp; '0'&nbsp; '0'&nbsp; '0'

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 500000+ 0:&nbsp; '0'&nbsp; '0' *'0'&nbsp; '0'

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1000000+ 0: *'1'&nbsp; '0'&nbsp; '0'&nbsp; '0'

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1500000+ 0:&nbsp; '1'&nbsp; '0' *'1'&nbsp; '0'

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2000000+ 0: *'0'&nbsp; '0'&nbsp; '1'&nbsp; '0'

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2500000+ 0:&nbsp; '0'&nbsp; '0' *'0'&nbsp; '0'

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3000000+ 0: *'1'&nbsp; '0'&nbsp; '0'&nbsp; '0'

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3500000+ 0:&nbsp; '1'&nbsp; '0' *'1'&nbsp; '0'

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 5000000+ 0:&nbsp; '1'&nbsp; '0'&nbsp; '1' *'0'

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 6000000+ 0:&nbsp; '1'&nbsp; '0'&nbsp; '1' *'1'

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 7000000+ 0:&nbsp; '1'&nbsp; '0'&nbsp; '1' *'0'

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 8000000+ 0:&nbsp; '1' *'1'&nbsp; '1' *'1'</PRE>



<P><A NAME="pgfId=116304"></A>Inertial delay mimics the behavior of real

logic gates, whereas transport delay more closely models the behavior of

wires. In VHDL-93 you can also add a separate&nbsp;<DFN CLASS="Definition">pulse

rejection limit</DFN> for the inertial delay model as in the following example:</P>



<PRE><B>process</B> (s1) <B>begin</B> RJCT &lt;= <B>reject</B> 2 ns s1 <B>after</B> 5 ns ; <B>end</B> <B>process</B>;</PRE>



<H3><A NAME="pgfId=4858"></A>10.10.4&nbsp; Procedure Call</H3>



<P><A NAME="pgfId=10519"></A>A procedure call in VHDL corresponds to calling

a subroutine in a conventional programming language [<A HREF="../../VHDL/LRM/HTML/1076_8.HTM#8.6">VHDL

LRM8.6</A>]. The parameters in a procedure call statement are the actual

procedure parameters (or actuals); the parameters in the procedure definition

are the formal procedure parameters (or formals). The two are linked using

an association list, which may use either positional or named association

(association works just as it does for ports--see Section&nbsp;10.7.1):</P>



<PRE>procedure_call_statement ::=

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <U>[label:]</U> procedure_name [(parameter_association_list)];</PRE>



<P><A NAME="pgfId=32499"></A>Here is an example:</P>



<PRE><B>package</B> And_Pkg <B>is&nbsp;</B>

<B>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; procedure</B> V_And(a, b : BIT; <B>signal</B> c : <B>out</B> BIT);&nbsp;

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

<B>end</B>;

<B>package body</B> And_Pkg <B>is&nbsp;</B>

<B>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; procedure</B> V_And(a, b : BIT; <B>signal</B> c: <B>out</B> BIT) <B>is&nbsp;</B>

<B>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; begin</B> c &lt;= a <B>and </B>b; <B>end</B>;

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

<B>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&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;

⌨️ 快捷键说明

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