ch11.06.htm
来自「介绍asci设计的一本书」· HTM 代码 · 共 462 行 · 第 1/2 页
HTM
462 行
<B>initial</B> <B>begin</B> D=1; Clock=0;Reset=1'b1; #15 Reset=1'b0; #20 D=0; <B>end</B>
<B>always</B> #10 Clock = !Clock;
<B>initial</B> <B>begin</B> $display("T Clk D Q Reset");
$monitor("%2g",$time,,Clock,,,,D,,Q,,Reset); #50 $finish; <B>end</B>
<B>endmodule</B>
<B>module</B> dff_wait(D, Q, Clock, Reset);
<B>output</B> Q; <B>input</B> D, Clock, Reset; <B>reg</B> Q; <B>wire</B> D;
<B>always</B> @(<B>posedge</B> Clock) <B>if</B> (Reset !== 1) Q = D;
<B>always</B> <B>begin</B> <B>wait</B> (Reset == 1) Q = 0; <B>wait</B> (Reset !== 1); <B>end</B>
<B>endmodule</B>
T Clk D Q Reset
0 0 1 0 1
10 1 1 0 1
15 1 1 0 0
20 0 1 0 0
30 1 1 1 0
35 1 0 1 0
40 0 0 1 0</PRE>
<P><P CLASS="Body"><A NAME="pgfId=83915"></A>We must include <CODE>wait</CODE>
statements in module <CODE>dff_wait</CODE> above to wait for both <CODE>Reset==1</CODE>
and <CODE>Reset==0</CODE> . If we were to omit the <CODE>wait</CODE> statement
for<CODE> Reset==0</CODE> , as in the following code:</P>
<PRE>
<B>module</B> dff_wait(D,Q,Clock,Reset);
<B>output</B> Q; <B>input</B> D,Clock,Reset; <B>reg</B> Q; <B>wire</B> D;
<B>always</B> @(<B>posedge</B> Clock) <B>if</B> (Reset !== 1) Q = D;
// We need another wait statement here or we shall spin forever.
<B>always</B> <B>begin</B> <B>wait</B> (Reset == 1) Q = 0; end
<B>endmodule</B></PRE>
<P><P CLASS="BodyAfterHead"><A NAME="pgfId=84023"></A>the simulator would
cycle endlessly, and we would need to press the <CODE>'Stop'</CODE> button
or <CODE>'CTRL-C'</CODE> to halt the simulator. Here is the console window
in VeriWell:</P>
<PRE>
C1> .
T Clk D Q Reset <- at this point nothing happens, so press CTRL-C
Interrupt at time 0
C1></PRE>
<H2><A NAME="pgfId=83894"></A>11.6.4 Blocking and Nonblocking
Assignments</H2>
<P><P CLASS="BodyAfterHead"><A NAME="pgfId=1038"></A>If a procedural assignment
in a sequential block contains a timing control, then the execution of the
following statement is delayed or <B>blocked</B>. For this reason a procedural
assignment statement is also known as a <B>blocking procedural assignment
statement</B> [Verilog LRM 9.2]. We covered this type of statement
in <A HREF="CH11.05.htm#pgfId=972">Section 11.5.3.</A> The <B>nonblocking
procedural assignment statement</B> allows execution in a sequential block
to continue and registers are all updated together at the end of the current
time step. Both types of procedural assignment may contain timing controls.
Here is an artificially complicated example that illustrates the different
types of assignment:</P>
<PRE>
<B>module</B> delay;
<B>reg</B> a,b,c,d,e,f,g,bds,bsd;
<B>initial</B> <B>begin</B>
a = 1; b = 0; // No delay control.
#1 b = 1; // Delayed assignment.
c = #1 1; // Intra-assignment delay.
#1; // Delay control.
d = 1; //
e <= #1 1; // Intra-assignment delay, nonblocking assignment
#1 f <= 1; // Delayed nonblocking assignment.
g <= 1; // Nonblocking assignment.
<B>end</B>
<B>initial</B> <B>begin</B> #1 bds = b; <B>end </B>// Delay then sample (ds).
<B>initial</B> <B>begin</B> bsd = #1 b; <B>end </B>// Sample then delay (sd).
<B>initial</B> <B>begin</B> $display("t a b c d e f g bds bsd");
$monitor("%g",$time,,a,,b,,c,,d,,e,,f,,g,,bds,,,,bsd); end
<B>endmodule</B>
t a b c d e f g bds bsd
0 1 0 x x x x x x x
1 1 1 x x x x x 1 0
2 1 1 1 x x x x 1 0
3 1 1 1 1 x x x 1 0
4 1 1 1 1 1 1 1 1 0</PRE>
<P><P CLASS="Body"><A NAME="pgfId=1054"></A>Many synthesis tools will not
allow us to use blocking and nonblocking procedural assignments to the same
<CODE>reg</CODE> within the same sequential block.</P>
<H2><A NAME="pgfId=6825"></A>11.6.5 Procedural Continuous
Assignment</H2>
<P><P CLASS="BodyAfterHead"><A NAME="pgfId=6827"></A>A <B>procedural continuous
assignment statement</B> [Verilog LRM 9.3] (sometimes called a quasicontinuous
assignment statement) is a special form of the <CODE>assign </CODE>statement
that we use within a sequential block. For example, the following flip-flop
model assigns to <CODE>q</CODE> depending on the clear, clr_, and preset,
pre_, inputs (in general it is considered very bad form to use a trailing
underscore to signify active-low signals as I have done to save space; you
might use "<CODE> _n</CODE> " instead).</P>
<PRE>
<B>module</B> dff_procedural_assign;
<B>reg</B> d,clr_,pre_,clk; <B>wire</B> q; dff_clr_pre dff_1(q,d,clr_,pre_,clk);
<B>always</B> #10 clk = ~clk;
<B>initial</B> <B>begin</B> clk = 0; clr_ = 1; pre_ = 1; d = 1;
#20; d = 0; #20; pre_ = 0; #20; pre_ = 1; #20; clr_ = 0;
#20; clr_ = 1; #20; d = 1; #20; $finish; <B>end</B>
<B>initial</B> <B>begin</B>
$display("T CLK PRE_ CLR_ D Q");
$monitor("%3g",$time,,,clk,,,,pre_,,,,clr_,,,,d,,q); <B>end</B>
<B>endmodule</B>
<B>module</B> dff_clr_pre(q,d,clear_,preset_,clock);
<B>output</B> q; <B>input</B> d,clear_,preset_,clock; <B>reg</B> q;
<B>always</B> @(clear_ <B>or</B> preset_)
<B>if</B> (!clear_) <B>assign</B> q = 0; // active-low clear
<B>else</B> <B>if</B>(!preset_) <B>assign</B> q = 1; // active-low preset
<B>else</B> <B>deassign</B> q;
<B>always</B> @(<B>posedge</B> clock) q = d;
<B>endmodule</B>
T CLK PRE_ CLR_ D Q
0 0 1 1 1 x
10 1 1 1 1 1
20 0 1 1 0 1
30 1 1 1 0 0
40 0 0 1 0 1
50 1 0 1 0 1
60 0 1 1 0 1
70 1 1 1 0 0
80 0 1 0 0 0
90 1 1 0 0 0
100 0 1 1 0 0
110 1 1 1 0 0
120 0 1 1 1 0
130 1 1 1 1 1</PRE>
<P><P CLASS="Body"><A NAME="pgfId=6832"></A>We have now seen all of the
different forms of Verilog assignment statements. The following skeleton
code shows where each type of statement belongs:</P>
<PRE>
<B>module</B> all_assignments
//... continuous assignments.
<B>always</B> // beginning of procedure
<B>begin</B> // beginning of sequential block
//... blocking procedural assignments.
//... nonblocking procedural assignments.
//... procedural continuous assignments.
<B>end</B>
<B>endmodule</B></PRE>
<P><P CLASS="Body"><A NAME="pgfId=6845"></A><A HREF="#pgfId=82965">Table 11.4</A>
summarizes the different types of assignments.</P>
<P><TABLE BORDER="1" CELLSPACING="2" CELLPADDING="2" HEIGHT="359">
<TR>
<TD COLSPAN="5"><P CLASS="TableTitle"><A NAME="pgfId=82965"></A>TABLE 11.4 Verilog
assignment statements.</TD></TR>
<TR>
<TD HEIGHT="80"><P CLASS="TableFirst"><A NAME="pgfId=6859"></A><B>Type of Verilog assignment</B></TD>
<TD><P CLASS="TableFirst"><A NAME="pgfId=6861"></A><B>Continuous assignment
statement</B></TD>
<TD><P CLASS="TableFirst"><A NAME="pgfId=6863"></A><B>Procedural assignment</B>
<B>statement</B></TD>
<TD><P CLASS="TableFirst"><A NAME="pgfId=6865"></A><B>Nonblocking procedural
assignment statement</B></TD>
<TD><P CLASS="TableFirst"><A NAME="pgfId=6867"></A><B>Procedural continuous
assignment statement</B></TD></TR>
<TR>
<TD HEIGHT="50"><P CLASS="TableLeft"><A NAME="pgfId=9941"></A>Where it can occur</TD>
<TD><P CLASS="TableLeft"><A NAME="pgfId=9943"></A>outside an always or initial
statement, task, or function</TD>
<TD><P CLASS="TableLeft"><A NAME="pgfId=9945"></A>inside an always or initial
statement, task, or function</TD>
<TD><P CLASS="TableLeft"><A NAME="pgfId=9947"></A>inside an always or initial
statement, task, or function</TD>
<TD><P CLASS="TableLeft"><A NAME="pgfId=9949"></A>always or initial statement,
task, or function</TD></TR>
<TR>
<TD HEIGHT="21"><P CLASS="TableLeft"><A NAME="pgfId=6869"></A>Example</TD>
<TD><B><TT>wire</TT></B><TT> [31:0] DataBus;<BR>
<B>assign</B> DataBus = Enable ? Data : 32'bz</TT></TD>
<TD><B><TT>reg</TT></B><TT> Y;<BR>
<B>always</B> @(posedge clock) Y = 1;</TT></TD>
<TD><B><TT>reg</TT></B><TT> Y;<BR>
<B>always</B> Y <= 1;</TT></TD>
<TD><B><TT>always</TT></B><TT> @(Enable)<BR>
<B>if</B>(Enable) <B>assign</B> Q = D;<BR>
<B>else</B> <B>deassign</B> Q;</TT></TD></TR>
<TR>
<TD HEIGHT="37"><P CLASS="TableLeft"><A NAME="pgfId=6887"></A>Valid LHS of assignment</TD>
<TD><P CLASS="TableLeft"><A NAME="pgfId=6889"></A>net</TD>
<TD><P CLASS="TableLeft"><A NAME="pgfId=6891"></A>register or memory element</TD>
<TD><P CLASS="TableLeft"><A NAME="pgfId=6893"></A>register or memory element</TD>
<TD><P CLASS="TableLeft"><A NAME="pgfId=6895"></A>net</TD></TR>
<TR>
<TD HEIGHT="65"><P CLASS="TableLeftEnd"><A NAME="pgfId=6897"></A>Valid RHS of assignment</TD>
<TD><P><P CLASS="TableLeftEnd"><A NAME="pgfId=6899"></A><expression></P>
<P><P CLASS="TableLeftEnd"><A NAME="pgfId=6900"></A>net, reg or memory element</TD>
<TD><P><P CLASS="TableLeftEnd"><A NAME="pgfId=6902"></A><expression></P>
<P><P CLASS="TableLeftEnd"><A NAME="pgfId=6903"></A>net, reg or memory element</TD>
<TD><P><P CLASS="TableLeftEnd"><A NAME="pgfId=6905"></A><expression></P>
<P><P CLASS="TableLeftEnd"><A NAME="pgfId=6906"></A>net, reg or memory element</TD>
<TD><P><P CLASS="TableLeftEnd"><A NAME="pgfId=6908"></A><expression></P>
<P><P CLASS="TableLeftEnd"><A NAME="pgfId=6909"></A>net, reg or memory element</TD></TR>
<TR>
<TD HEIGHT="24"><P CLASS="TableLeftEnd"><A NAME="pgfId=89992"></A>Book</TD>
<TD><P CLASS="TableLeftEnd"><A NAME="pgfId=89994"></A><A HREF="CH11.05.htm#pgfId=114445">11.5.1</A></TD>
<TD><P CLASS="TableLeftEnd"><A NAME="pgfId=89996"></A><A HREF="CH11.05.htm#pgfId=972">11.5.3</A></TD>
<TD><P CLASS="TableLeftEnd"><A NAME="pgfId=89998"></A><A HREF="#pgfId=83894">11.6.4</A></TD>
<TD><P CLASS="TableLeftEnd"><A NAME="pgfId=90000"></A><A HREF="#pgfId=6825">11.6.5</A></TD></TR>
<TR>
<TD HEIGHT="37"><P CLASS="TableLeftEnd"><A NAME="pgfId=7240"></A>Verilog LRM</TD>
<TD><P CLASS="TableLeftEnd"><A NAME="pgfId=7242"></A>6.1</TD>
<TD><P CLASS="TableLeftEnd"><A NAME="pgfId=7244"></A>9.2</TD>
<TD><P CLASS="TableLeftEnd"><A NAME="pgfId=7246"></A>9.2.2</TD>
<TD><P CLASS="TableLeftEnd"><A NAME="pgfId=7248"></A>9.3</TD></TR>
</TABLE>
<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>
</BODY>
<!--#include file="Copyright.html"--><!--#include file="footer.html"-->
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?