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(&quot;T  Clk D Q Reset&quot;);

&nbsp;&nbsp;$monitor(&quot;%2g&quot;,$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&gt; .

T  Clk D Q Reset &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;- at this point nothing happens, so press CTRL-C

Interrupt at time 0

C1&gt;</PRE>



<H2><A NAME="pgfId=83894"></A>11.6.4&nbsp;&nbsp;&nbsp;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&nbsp;9.2]. We covered this type of statement

in <A HREF="CH11.05.htm#pgfId=972">Section&nbsp;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 &lt;= #1 1;    // Intra-assignment delay, nonblocking assignment

#1 f &lt;= 1;    // Delayed nonblocking assignment.

g &lt;= 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(&quot;t a b c d e f g bds bsd&quot;);

$monitor(&quot;%g&quot;,$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&nbsp;&nbsp;&nbsp;Procedural Continuous

Assignment</H2>



<P><P CLASS="BodyAfterHead"><A NAME="pgfId=6827"></A>A <B>procedural continuous

assignment statement</B> [Verilog LRM&nbsp;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 &quot;<CODE> _n</CODE> &quot; 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;

&nbsp;&nbsp;#20; d = 0; #20; pre_ = 0; #20; pre_ = 1; #20; clr_ = 0;

&nbsp;&nbsp;#20; clr_ = 1; #20; d = 1; #20; $finish; <B>end</B> 

<B>initial</B> <B>begin</B> 

&nbsp;&nbsp;$display(&quot;T  CLK PRE_ CLR_ D Q&quot;);

&nbsp;&nbsp;$monitor(&quot;%3g&quot;,$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_)

&nbsp;&nbsp;<B>if</B> (!clear_) <B>assign</B> q = 0; // active-low clear

&nbsp;&nbsp;<B>else</B> <B>if</B>(!preset_) <B>assign</B> q = 1; // active-low preset

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

&nbsp;&nbsp;<B>begin</B> // beginning of sequential block

&nbsp;&nbsp;//... blocking procedural assignments.

&nbsp;&nbsp;//... nonblocking procedural assignments.

&nbsp;&nbsp;//... procedural continuous assignments.

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

<B>endmodule</B></PRE>



<P><P CLASS="Body"><A NAME="pgfId=6845"></A><A HREF="#pgfId=82965">Table&nbsp;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&nbsp;11.4&nbsp;&nbsp;&nbsp;&nbsp;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>&nbsp;DataBus&nbsp;= &nbsp;Enable&nbsp;?&nbsp;Data : &nbsp;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 &lt;= 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>&lt;expression&gt;</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>&lt;expression&gt;</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>&lt;expression&gt;</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>&lt;expression&gt;</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&nbsp;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 + -
显示快捷键?