ch11.06.htm

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

HTM
462
字号
<HTML>

<HEAD>

  <META NAME="GENERATOR" CONTENT="Adobe PageMill 2.0 Mac">

  

  <TITLE> 11.6&nbsp;&nbsp;&nbsp;Timing Controls and Delay</TITLE>

</HEAD><!--#include file="top.html"--><!--#include file="header.html"--><br><!--#include file="AmazonAsic.html"-->





<P><A NAME="pgfId=990"></A><HR ALIGN="LEFT"></P>



<P><A HREF="CH11.htm">Chapter&nbsp;start</A></P>



<P><A HREF="CH11.05.htm">Previous page</A></P>



<P><A HREF="CH11.07.htm">Next page</A></P>



<H1>11.6&nbsp;&nbsp;&nbsp;Timing Controls and Delay</H1>



<P><P CLASS="BodyAfterHead"><A NAME="pgfId=100556"></A>The statements within

a sequential block are executed in order, but, in the absence of any delay,

they all execute at the same simulation time--the current <B>time step</B>.

In reality there are delays that are modeled using a timing control.</P>



<H2><A NAME="pgfId=100559"></A>11.6.1&nbsp;&nbsp;&nbsp;Timing Control</H2>



<P><P CLASS="BodyAfterHead"><A NAME="pgfId=67187"></A>A <B>timing control</B>

is either a delay control or an event control [Verilog LRM&nbsp;9.7]. A

<B>delay control</B> delays an assignment by a specified amount of time.

A <B>timescale compiler directive</B> is used to specify the units of time

followed by the precision used to calculate time expressions,</P>



<PRE>`timescale 1ns/10ps // Units of time are ns. Round times to 10 ps.</PRE>



<P><P CLASS="Body"><A NAME="pgfId=106588"></A>Time units may only be <CODE>s</CODE>

, <CODE>ns</CODE> , <CODE>ps</CODE> , or <CODE>fs</CODE> and the multiplier

must be 1, 10, or 100. We can delay an assignment in two different ways:</P>



<UL>

  <LI><A NAME="pgfId=66529"></A>Sample the RHS immediately and then delay

  the assignment to the LHS.

  <LI><A NAME="pgfId=66530"></A>Wait for a specified time and then assign

  the value of the LHS to the RHS.

</UL>



<P><P CLASS="Body"><A NAME="pgfId=66533"></A>Here is an example of the first

alternative (an <B>intra-assignment delay</B>):</P>



<PRE>x = #1 y; // intra-assignment delay</PRE>



<P><P CLASS="Body"><A NAME="pgfId=66321"></A>The second alternative is <B>delayed

assignment</B>:</P>



<PRE>#1 x = y; // delayed assignment</PRE>



<P><P CLASS="Body"><A NAME="pgfId=66611"></A>These two alternatives are

not the same. The intra-assignment delay is equivalent to the following

code:</P>



<PRE>

<B>begin</B> // Equivalent to intra-assignment delay.

hold = y; // Sample and hold y immediately.

#1; // Delay.

x = hold; // Assignment to x. Overall same as x = #1 y.

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



<P><P CLASS="BodyAfterHead"><A NAME="pgfId=66582"></A>In contrast, the delayed

assignment is equivalent to a delay followed by an assignment as follows:</P>



<PRE><B>begin</B> // Equivalent to delayed assignment.

#1; // Delay.

x = y; // Assign y to x. Overall same as #1 x = y.

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



<P><P CLASS="Body"><A NAME="pgfId=67188"></A>The other type of timing control,

an <B>event control</B>, delays an assignment until a specified event occurs.

Here is the formal definition:</P>



<PRE>

event_control ::= @ event_identifier | @ (event_expression)

event_expression ::= expression | event_identifier

&nbsp;&nbsp;| <B>posedge</B> expression | <B>negedge expression</B>

&nbsp;&nbsp;| event_expression <B>or</B> event_expression</PRE>



<P><P CLASS="BodyAfterHead"><A NAME="pgfId=66653"></A>(Notice there are

two different uses of <CODE>'or'</CODE> in this simplified BNF definition--the

last one, in bold, is part of the Verilog language, a keyword.) A positive

edge<CODE> </CODE>(denoted by the keyword <CODE>posedge</CODE> ) is a transition

from <CODE>'0'</CODE> to <CODE>'1'</CODE> or <CODE>'x'</CODE> , or a transition

from <CODE>'x'</CODE> to <CODE>'1</CODE> '. A negative edge (<CODE> negedge</CODE>

) is a transition from <CODE>'1'</CODE> to <CODE>'0'</CODE> or <CODE>'x'</CODE>

, or a transition from<CODE> 'x'</CODE> to <CODE>'0'</CODE>. Transitions

to or from <CODE>'z'</CODE> do not count. Here are examples of event controls:</P>



<PRE>

<B>module</B> delay_controls; <B>reg</B> X, Y, Clk, Dummy;

<B>always</B> #1 Dummy=!Dummy; // Dummy clock, just for graphics.

// Examples of delay controls:

<B>always</B> <B>begin</B> #25 X=1;#10 X=0;#5; <B>end</B>

// An event control:

<B>always</B> @(<B>posedge</B> Clk) Y=X; // Wait for +ve clock edge.

<B>always</B> #10 Clk = !Clk; // The real clock.

<B>initial</B> <B>begin</B> Clk = 0;

&nbsp;&nbsp;$display(&quot;T   Clk X Y&quot;);

&nbsp;&nbsp;$monitor(&quot;%2g&quot;,$time,,,Clk,,,,X,,Y);

&nbsp;&nbsp;$dumpvars;#100 $finish; <B>end</B>

<B>endmodule</B>

T   Clk X Y

 0  0   x x

10  1   x x

20  0   x x

25  0   1 x

30  1   1 1

35  1   0 1

40  0   0 1

50  1   0 0

60  0   0 0

65  0   1 0

70  1   1 1

75  1   0 1

80  0   0 1

90  1   0 0</PRE>



<P><P CLASS="Body"><A NAME="pgfId=83337"></A>The dummy clock in delay_controls

helps in the graphical waveform display of the results (it provides a one-time-tick

timing grid when we zoom in, for example). <A HREF="#pgfId=83466">Figure&nbsp;11.1</A>

shows the graphical output from the Waves viewer in VeriWell (white is used

to represent the initial unknown values). The assignment statements to <CODE>'X'</CODE>

in the <CODE>always</CODE> statement repeat (every 25 + 10 + 5 = 40 time

ticks).</P>



<P><TABLE BORDER="1" CELLSPACING="2" CELLPADDING="2">

<TR>

<TD><P CLASS="TableFigTitleSide"><A NAME="pgfId=83466"></A>FIGURE&nbsp;11.1&nbsp;&nbsp;Output

from the module <CODE>delay_controls</CODE> .</TD>

<TD><P CLASS="TableFigure"><A NAME="pgfId=83471"></A><IMG SRC="CH11-1.gif" ALIGN="BASELINE" WIDTH="335" HEIGHT="72" NATURALSIZEFLAG="3"> &nbsp;</TD></TR>

</TABLE>

<P CLASS="Body"><A NAME="pgfId=83657"></A>Events can be declared (as named

events), triggered, and detected as follows:</P>



<PRE>

<B>module</B> show_event;

<B>reg</B> clock;

<B>event</B> event_1, event_2; // Declare two named events.

<B>always</B> @(<B>posedge</B> clock) -&gt; event_1; // Trigger event_1.

<B>always</B> @ event_1 

<B>begin</B> $display(&quot;Strike 1!!&quot;); -&gt; event_2; end // Trigger event_2.

<B>always</B> @ event_2 <B>begin</B> $display(&quot;Strike 2!!&quot;);

$finish; <B>end</B> // Stop on detection of event_2.

<B>always</B> #10 clock = ~ clock; // We need a clock.

<B>initial</B> clock = 0;

<B>endmodule</B> 

Strike 1!!

Strike 2!!</PRE>



<H2><A NAME="pgfId=5752"></A>11.6.2&nbsp;&nbsp;&nbsp;Data Slip</H2>



<P><P CLASS="BodyAfterHead"><A NAME="pgfId=67190"></A>Consider this model

for a shift register and the simulation output that follows:</P>



<PRE>

<B>module</B> data_slip_1 (); <B>reg</B> Clk, D, Q1, Q2;

/************* bad sequential logic below ***************/

<B>always</B> @(<B>posedge</B> Clk)  Q1 = D;

<B>always</B> @(<B>posedge</B> Clk)  Q2 = Q1; // Data slips here!

/************* bad sequential logic above ***************/

<B>initial</B> <B>begin</B> Clk = 0; D = 1; <B>end</B> <B>always</B> #50 Clk = ~Clk;

<B>initial</B> <B>begin</B> $display(&quot;t   Clk D Q1 Q2&quot;);

$monitor(&quot;%3g&quot;,$time,,Clk,,,,D,,Q1,,,Q2); <B>end</B>

<B>initial</B> #400 $finish; // Run for 8 cycles.

<B>initial</B> $dumpvars;

<B>endmodule</B> 

t   Clk D Q1 Q2

  0 0   1 x  x

 50 1   1 1  1

100 0   1 1  1

150 1   1 1  1

200 0   1 1  1

250 1   1 1  1

300 0   1 1  1

350 1   1 1  1</PRE>



<P><P CLASS="Body"><A NAME="pgfId=83750"></A>The first clock edge at <CODE>t</CODE>

<CODE>=</CODE> <CODE>50</CODE> causes <CODE>Q1</CODE> to be updated to the

value of <CODE>D</CODE> at the clock edge (a <CODE>'1'</CODE> ), and at

the same time<CODE> Q2 </CODE>is updated to this new value of <CODE>Q1</CODE>

. The data, <CODE>D</CODE> , has passed through both <CODE>always</CODE>

statements. We call this problem <B>data slip</B>.</P>



<P><P CLASS="Body"><A NAME="pgfId=67329"></A>If we include delays in the

<CODE>always</CODE> statements (labeled 3 and 4) in the preceding example,

like this--</P>



<PRE>

<B>always</B> @(<B>posedge</B> Clk)  Q1 = #1 D;  // The delays in the assignments

<B>always</B> @(<B>posedge</B> Clk)  Q2 = #1 Q1; // fix the data slip.</PRE>



<P><P CLASS="BodyAfterHead"><A NAME="pgfId=67419"></A>--we obtain the correct

output:</P>



<PRE>

t   Clk D Q1 Q2

  0 0   1 x  x

 50 1   1 x  x

 51 1   1 1  x

100 0   1 1  x

150 1   1 1  x

151 1   1 1  1

200 0   1 1  1

250 1   1 1  1

300 0   1 1  1

350 1   1 1  1</PRE>



<H2><A NAME="pgfId=2896"></A>11.6.3&nbsp;&nbsp;&nbsp;Wait Statement</H2>



<P><P CLASS="BodyAfterHead"><A NAME="pgfId=2897"></A>The <B>wait statement</B>

[Verilog LRM9.7.5] suspends a procedure until a condition becomes true.

There must be another concurrent procedure that alters the condition (in

this case the variable <CODE>Done</CODE> --in general the condition is an

expression) in the following <CODE>wait</CODE> statement; otherwise we are

placed on &quot;infinite hold&quot;:</P>



<PRE>

<B>wait</B> (Done) $stop; // Wait until Done = 1 then stop.</PRE>



<P><P CLASS="Body"><A NAME="pgfId=83887"></A>Notice that the Verilog <CODE>wait</CODE>

statement does not look for an event or a change in the condition; instead

it is level-sensitive--it only cares that the condition is true.</P>



<PRE>

<B>module</B> test_dff_wait;

<B>reg</B> D, Clock, Reset; dff_wait u1(D, Q, Clock, Reset);

⌨️ 快捷键说明

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