📄 ch09.7.htm
字号:
<A NAME="pgfId=708"> </A>it can be made to occur at any particular time </LI><LI CLASS="DashedList"><A NAME="pgfId=709"> </A>it has no time duration</LI><LI CLASS="DashedList"><A NAME="pgfId=710"> </A>its occurrence can be recognized by using the event control syntax described in <A HREF="ch09.7.htm#78422" CLASS="XRef">See Event control</A></LI></UL><P CLASS="Body"><A NAME="pgfId=576"> </A>A declared event is made to occur by the activation of an <A NAME="marker=214"> </A>event triggering statement of the following <A NAME="marker=215"> </A>syntax:</P><P CLASS="Body"><A NAME="pgfId=388"> </A></P><DIV><IMG SRC="ch09-34.gif"></DIV><P CLASS="BNFCapBody"><A NAME="pgfId=711"> </A>Syntax 9-10: Syntax for event trigger</P><P CLASS="Body"><A NAME="pgfId=556"> </A>An event controlled statement (for example, <CODE CLASS="code">@trig rega = regb;</CODE>) shall cause simulation of its containing procedure to wait until some other procedure executes the appropriate event triggering statement (for example, <BR><CODE CLASS="code">-> trig</CODE>).</P><P CLASS="Body"><A NAME="pgfId=422"> </A>Named events and event control give a powerful and efficient means of describing the communication between, and synchronization of, two or more concurrently active processes. A basic example of this is a small waveform clock generator that synchronizes control of a synchronous circuit by signalling the occurrence of an explicit event periodically while the circuit waits for the event to occur. <CODE CLASS="code"></CODE><A NAME="marker=124"> </A> <A NAME="marker=125"> </A></P><P CLASS="SubSection"><A NAME="pgfId=583"> </A><A NAME="marker=216"> </A>Event OR operator </P><P CLASS="Body"><A NAME="pgfId=715"> </A>The ORing of any number of events can be expressed such that the occurrence of any one of the events trigger the execution of the procedural statement that follows it. The keyword <B CLASS="Keyword">or</B> is used as an event OR operator.</P></DIV><DIV><H2 CLASS="Example"><A NAME="pgfId=579"> </A></H2><P CLASS="Body"><A NAME="pgfId=582"> </A>The next two <A NAME="marker=220"> </A>examples show the ORing of two and three events respectively.</P><PRE CLASS="CodeIndent"><A NAME="pgfId=717"> </A>@(trig or enable) rega = regb; // controlled by trig or enable@(<B CLASS="Keyword">posedge</B> clk_a or <B CLASS="Keyword">posedge</B> clk_b or trig) rega = regb;</PRE><P CLASS="SubSection"><A NAME="pgfId=719"> </A><A NAME="60223"> </A><A NAME="marker=222"> </A><A NAME="marker=223"> </A>Level-sensitive event control </P><P CLASS="Body"><A NAME="pgfId=721"> </A>The execution of a procedural statement can also be delayed until a condition becomes true. This is accomplished using the <I CLASS="Emphasis">wait</I><A NAME="marker=224"> </A> statement, which is a special form of event control. The nature of the wait statement is level-sensitive, as opposed to basic event control (specified by the <CODE CLASS="code">@</CODE> character), which is edge-sensitive. </P><P CLASS="Body"><A NAME="pgfId=584"> </A>The <A NAME="marker=225"> </A><A NAME="marker=226"> </A>wait statement shall evaluate a condition, and, if it is false, the procedural statements following the wait statement shall remain blocked until that condition becomes true before continuing. The wait statement has the following form:</P><P CLASS="Body"><A NAME="pgfId=867"> </A></P><DIV><IMG SRC="ch09-35.gif"></DIV><P CLASS="BNFCapBody"><A NAME="pgfId=631"> </A>Syntax 9-11: Syntax for wait statement</P></DIV><DIV><H2 CLASS="Example"><A NAME="pgfId=723"> </A></H2><P CLASS="Body"><A NAME="pgfId=498"> </A>The example below shows the use of the wait statement to accomplish level-sensitive event control.</P><P CLASS="Body"><A NAME="pgfId=724"> </A></P><DIV><IMG SRC="ch09-36.gif"></DIV><P CLASS="Body"><A NAME="pgfId=725"> </A>If the value of <CODE CLASS="code">enable</CODE><A NAME="marker=228"> </A> is <CODE CLASS="code">1</CODE> when the block is entered, the wait statement will delay the evaluation of the next statement (<CODE CLASS="code">#10 a = b;</CODE>) until the value of <CODE CLASS="code">enable</CODE> changes to <CODE CLASS="code">0</CODE>. If <CODE CLASS="code">enable</CODE> is already <CODE CLASS="code">0</CODE> when the <CODE CLASS="code">begin-end </CODE>block is entered, then the next statement is evaluated immediately and no delay occurs.</P><P CLASS="SubSection"><A NAME="pgfId=726"> </A><A NAME="26871"> </A><A NAME="marker=230"> </A><A NAME="marker=231"> </A>Intra-assignment timing controls </P><P CLASS="Body"><A NAME="pgfId=574"> </A>The delay and event control constructs previously described precede a statement and delay its execution. In contrast, the <I CLASS="Emphasis">intra-assignment delay</I> <I CLASS="Emphasis">and event controls</I> are contained within an assignment statement and modify the flow of activity in a different way. This section describes the purpose of intra-assignment timing controls and the repeat timing control that can be used in intra-assignment delays.</P><P CLASS="Body"><A NAME="pgfId=727"> </A>An intra-assignment delay or event control shall delay the assignment of the new value to the left-hand side, but the right-hand-side expression shall be evaluated before the delay, instead of after the delay. The syntax for intra-assignment delay and event control is shown below:</P><P CLASS="Body"><A NAME="pgfId=633"> </A></P><DIV><IMG SRC="ch09-37.gif"></DIV><P CLASS="BNFCapBody"><A NAME="pgfId=639"> </A>Syntax 9-12<A NAME="33037"> </A>: Syntax for intra-assignment delay and event control</P><P CLASS="Body"><A NAME="pgfId=642"> </A>The intra-assignment delay and event control can be applied to both blocking assignments and non-blocking assignments. The event expression shall be resolved to a one bit value. T<A NAME="marker=132"> </A>he <I CLASS="Emphasis">repe</I><A NAME="marker=133"> </A><I CLASS="Emphasis">at</I> event control shall specify an intra-assignment delay of a specified number of occurrences of an event. This construct is convenient when events must be synchronized with counts of clock signals.</P></DIV><DIV><H2 CLASS="Example"><A NAME="pgfId=611"> </A></H2><P CLASS="Body"><A NAME="pgfId=612"> </A><A HREF="ch09.7.htm#82943" CLASS="XRef">See : Intra-assignment timing control equivalence</A> illustrates the philosophy of intra-assignment timing controls by showing the code that could accomplish the same timing effect without using intra-assignment.</P><TABLE BORDER="1"><CAPTION><P CLASS="TableTitle"><A NAME="pgfId=499"> </A>Table 9-2<A NAME="82943"> </A>: Intra-assignment timing control equivalence</P></CAPTION><TR><TH ROWSPAN="1" COLSPAN="2"><P CLASS="CellHeading"><A NAME="pgfId=586"> </A><I CLASS="Emphasis">Intra-assignment timing control</I></P></TH></TR><TR><TD ROWSPAN="1" COLSPAN="1"><P CLASS="CellHeading"><A NAME="pgfId=588"> </A>with intra-assignment construct</P></TD><TD ROWSPAN="1" COLSPAN="1"><P CLASS="CellHeading"><A NAME="pgfId=589"> </A>without intra-assignment construct</P></TD></TR><TR><TD ROWSPAN="1" COLSPAN="1"><P CLASS="CellBody"><A NAME="pgfId=590"> </A><BR>a = #5 b;</P></TD><TD ROWSPAN="1" COLSPAN="1"><P CLASS="CellBody"><A NAME="pgfId=592"> </A><B CLASS="Keyword">begin<BR></B> temp = b;<BR> #5 a = temp;<BR><B CLASS="Keyword">end</B></P></TD></TR><TR><TD ROWSPAN="1" COLSPAN="1"><P CLASS="CellBody"><A NAME="pgfId=602"> </A><BR>a = @(<B CLASS="Keyword">posedge</B> clk) b;</P></TD><TD ROWSPAN="1" COLSPAN="1"><P CLASS="CellBody"><A NAME="pgfId=605"> </A><B CLASS="Keyword">begin<BR></B> temp = b;<BR> @(<B CLASS="Keyword">posedge</B> clk) a = temp; <BR><B CLASS="Keyword">end</B></P></TD></TR><TR><TD ROWSPAN="1" COLSPAN="1"><PRE CLASS="CodeText"><A NAME="pgfId=606"> </A>a = <B CLASS="Keyword">repeat</B>(3)</PRE><P CLASS="CellBody"><A NAME="pgfId=607"> </A> @(<B CLASS="Keyword">posedge</B> clk) b;</P></TD><TD ROWSPAN="1" COLSPAN="1"><P CLASS="CellBody"><A NAME="pgfId=608"> </A><B CLASS="Keyword">begin<BR></B> temp = b;<BR> @(<B CLASS="Keyword">posedge</B> clk);<BR> @(<B CLASS="Keyword">posedge</B> clk);<BR> @(<B CLASS="Keyword">posedge</B> clk) a = temp; <BR><B CLASS="Keyword">end</B></P></TD></TR></TABLE><P CLASS="Body"><A NAME="pgfId=610"> </A>The next three examples use the fork-join behavioral construct. All statements between the keywords <B CLASS="Keyword">fork</B> and <B CLASS="Keyword">join</B> execute concurrently. The <A HREF="ch09.8.htm#47887" CLASS="XRef">See Parallel blocks</A> describes this construct in more detail.</P><P CLASS="Body"><A NAME="pgfId=728"> </A>The following example shows a race condition that could be prevented by using intra-assignment timing control: <A NAME="marker=233"> </A></P><PRE CLASS="CodeIndent"><A NAME="pgfId=729"> </A><B CLASS="Keyword">fork</B> <A NAME="marker=234"> </A> #5 a = b; #5 b = a;<B CLASS="Keyword">join</B></PRE><P CLASS="Body"><A NAME="pgfId=730"> </A>The code in the example above samples and sets the values of both <CODE CLASS="code">a</CODE> and <CODE CLASS="code">b</CODE> at the same simulation time, thereby creating a race condition. The intra-assignment form of timing control used in the example below prevents this race condition:</P><PRE CLASS="CodeIndent"><A NAME="pgfId=731"> </A><B CLASS="Keyword">fork</B><A NAME="marker=235"> </A> // data swap a = #5 b; b = #5 a; <B CLASS="Keyword">join</B></PRE><P CLASS="Body"><A NAME="pgfId=732"> </A>Intra-assignment timing control works because the intra-assignment delay causes the values of <CODE CLASS="code">a</CODE> and <CODE CLASS="code">b</CODE> to be evaluated before the delay, and the assignments to be made after the delay. Some existing tools that implement intra-assignment timing control use temporary storage in evaluating each expression on the right-hand side.</P><P CLASS="Body"><A NAME="pgfId=733"> </A>Intra-assignment waiting for events is also effective. In the example below, the right-hand-side expressions are evaluated when the assignment statements are encountered, but the assignments are delayed until the rising edge of the clock signal.</P><PRE CLASS="CodeIndent"><A NAME="pgfId=734"> </A><B CLASS="Keyword">fork</B> // data shift a = @(<B CLASS="Keyword">posedge</B> clk) b; b = @(<B CLASS="Keyword">posedge</B> clk) c;<B CLASS="Keyword">join</B></PRE><P CLASS="Body"><A NAME="pgfId=735"> </A>The following is an example of a repeat event control as the intra-assignment delay of a non-blocking assignment:</P><PRE CLASS="CodeIndent"><A NAME="pgfId=736"> </A>a <= <B CLASS="Keyword">repeat</B>(5) @(<B CLASS="Keyword">posedge</B> clk) data;</PRE><P CLASS="Body"><A NAME="pgfId=737"> </A><A HREF="ch09.7.htm#99476" CLASS="XRef">See : Repeat event control utilizing a clock edge</A> illustrates the activities that result from this <CODE CLASS="code">repeat </CODE>event control:</P><P CLASS="Body"><A NAME="pgfId=620"> </A></P><DIV><IMG SRC="ch09-38.gif"></DIV><P CLASS="FigCapBody"><A NAME="pgfId=739"> </A>Figure 9-1<A NAME="99476"> </A>: Repeat event control utilizing a clock edge<A NAME="marker=241"> </A></P><P CLASS="Body"><A NAME="pgfId=740"> </A>In this example, the value of <CODE CLASS="code">data</CODE> is evaluated when the assignment is encountered. After five occurrences of<CODE CLASS="code"> </CODE><B CLASS="Keyword">posedge</B><CODE CLASS="code"> clk</CODE>, <CODE CLASS="code">a </CODE>is assigned the value of <CODE CLASS="code">data</CODE>.</P><P CLASS="Body"><A NAME="pgfId=741"> </A>The following is an example of a repeat event control as the intra-assignment delay of a procedural assignment:</P><PRE CLASS="CodeIndent"><A NAME="pgfId=742"> </A>a = <B CLASS="Keyword">repeat</B>(num) @(clk) data;</PRE><P CLASS="Body"><A NAME="pgfId=743"> </A>In this example, the value of <CODE CLASS="code">data</CODE> is evaluated when the assignment is encountered. After the number of transitions of <CODE CLASS="code">clk</CODE> equals the value of <CODE CLASS="code">num</CODE>, <CODE CLASS="code">a</CODE> is assigned the value of <CODE CLASS="code">data</CODE>.</P><P CLASS="Body"><A NAME="pgfId=744"> </A>The following is an example of a repeat event control with expressions containing operations to specify both the number of event occurrences and the event that is counted:</P><PRE CLASS="CodeIndent"><A NAME="pgfId=745"> </A>a <= <B CLASS="Keyword">repeat</B>(a+b) @(<B CLASS="Keyword">posedge</B> phi1 or <B CLASS="Keyword">negedge</B> phi2) data;</PRE><P CLASS="Body"><A NAME="pgfId=746"> </A>In the example above, the value of <CODE CLASS="code">data</CODE> is evaluated when the assignment is encountered. After the sum of the positive edges of<CODE CLASS="code"> phi1</CODE> and the negative edges of<CODE CLASS="code"> phi2</CODE> equals the sum of <CODE CLASS="code">a</CODE> and <CODE CLASS="code">b</CODE>, <CODE CLASS="code">a</CODE> is assigned the value of <CODE CLASS="code">data</CODE>. Even if <B CLASS="Keyword">posedge</B><CODE CLASS="code"> phi1</CODE> and <B CLASS="Keyword">negedge</B><CODE CLASS="code"> phi2</CODE> occurred at the same simulation time, each will be detected separately. <A NAME="marker=242"> </A><A NAME="marker=243"> </A><A NAME="marker=244"> </A><A NAME="marker=245"> </A></P></DIV><HR><P><A HREF="ch09.htm">Chapter start</A> <A HREF="ch09.6.htm">Previous page</A> <A HREF="ch09.8.htm">Next page</A></P></BODY></HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -