ch11.06.htm
来自「介绍asci设计的一本书」· HTM 代码 · 共 462 行 · 第 1/2 页
HTM
462 行
<HTML>
<HEAD>
<META NAME="GENERATOR" CONTENT="Adobe PageMill 2.0 Mac">
<TITLE> 11.6 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 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 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 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 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
| <B>posedge</B> expression | <B>negedge expression</B>
| 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;
$display("T Clk X Y");
$monitor("%2g",$time,,,Clk,,,,X,,Y);
$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 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 11.1 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"> </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) -> event_1; // Trigger event_1.
<B>always</B> @ event_1
<B>begin</B> $display("Strike 1!!"); -> event_2; end // Trigger event_2.
<B>always</B> @ event_2 <B>begin</B> $display("Strike 2!!");
$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 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("t Clk D Q1 Q2");
$monitor("%3g",$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 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 "infinite hold":</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 + -
显示快捷键?