ch11.08.htm

来自「介绍asci设计的一本书」· HTM 代码 · 共 154 行

HTM
154
字号
<HTML>

<HEAD>

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

  

  <TITLE> 11.8&nbsp;&nbsp;&nbsp;Control Statements</TITLE>

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



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

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

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

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

<H1>11.8&nbsp;&nbsp;&nbsp;Control Statements</H1>

<P><P CLASS="BodyAfterHead"><A NAME="pgfId=84723"></A>In this section we

shall discuss the Verilog <CODE>if</CODE> , <CODE>case</CODE> , <CODE>loop</CODE>

, <CODE>disable</CODE> , <CODE>fork</CODE> , and <CODE>join</CODE> statements

that control the flow of code execution.</P>

<H2><A NAME="pgfId=1117"></A>11.8.1&nbsp;&nbsp;&nbsp;Case and If Statement</H2>

<P><P CLASS="BodyAfterHead"><A NAME="pgfId=1121"></A>An <B>if statement</B>

[Verilog LRM&nbsp;9.4] represents a two-way branch. In the following example,<CODE>

switch </CODE>has to be true to execute <CODE>'Y = 1'</CODE> ; otherwise

<CODE>'Y = 0'</CODE> is executed:</P>

<PRE>

<B>if</B>(switch) Y = 1; <B>else</B> Y = 0;</PRE>

<P><P CLASS="Body"><A NAME="pgfId=84983"></A>The <B>case statement</B> [Verilog

LRM&nbsp;9.5] represents a multiway branch. A controlling expression is

matched with case <B>expressions</B> in each of the <B>case items</B> (or

arms) to determine a match,</P>

<PRE>

<B>module</B> test_mux; <B>reg</B> a, b, select; <B>wire</B> out;

mux mux_1(a, b, out, select);

<B>initial</B> <B>begin</B> #2; select = 0; a = 0; b = 1;

&nbsp;&nbsp;#2; select = 1'bx; #2; select = 1'bz; #2; select = 1; <B>end</B> 

<B>initial</B> $monitor(&quot;T=%2g&quot;,$time,&quot;  Select=&quot;,select,&quot;  Out=&quot;,out);

<B>initial</B> #10 $finish;

<B>endmodule</B> 

<B>module</B> mux(a, b, mux_output, mux_select); <B>input</B> a, b, mux_select;

<B>output</B> mux_output; <B>reg</B> mux_output;

<B>always</B> <B>begin</B> 

<B>case</B>(mux_select)

&nbsp;&nbsp;0: mux_output = a;

&nbsp;&nbsp;1: mux_output = b;

&nbsp;&nbsp;<B>default</B> mux_output = 1'bx; // If select = x or z set output to x.

<B>endcase</B> 

#1; // Need some delay, otherwise we'll spin forever.

<B>end</B> 

<B>endmodule</B>

T= 0  Select=x  Out=x

T= 2  Select=0  Out=x

T= 3  Select=0  Out=0

T= 4  Select=x  Out=0

T= 5  Select=x  Out=x

T= 6  Select=z  Out=x

T= 8  Select=1  Out=x

T= 9  Select=1  Out=1</PRE>

<P><P CLASS="Body"><A NAME="pgfId=16037"></A>Notice that the <CODE>case</CODE>

statement must be inside a sequential block (inside an <CODE>always</CODE>

statement). Because the <CODE>case</CODE> statement is inside an <CODE>always</CODE>

statement, it needs some delay; otherwise the simulation runs forever without

advancing simulation time. The <B>casex statement</B> handles both <CODE>'z'</CODE>

and <CODE>'x'</CODE> as don't care (so that they match any bit value), the

<B>casez statement</B> handles <CODE>'z'</CODE> bits, and only <CODE>'z'</CODE>

bits, as don't care. Bits in case expressions may be set to <CODE>'?'</CODE>

representing don't care values, as follows:</P>

<PRE>

<B>casex</B> (instruction_register[31:29])

&nbsp;&nbsp;3b'??1 : add;

&nbsp;&nbsp;3b'?1? : subtract;

&nbsp;&nbsp;3b'1?? : branch;

<B>endcase</B></PRE>

<H2><A NAME="pgfId=1161"></A>11.8.2&nbsp;&nbsp;&nbsp;Loop Statement</H2>

<P><P CLASS="BodyAfterHead"><A NAME="pgfId=119901"></A>A <B>loop statement</B>

[Verilog LRM&nbsp;9.6] is a <B>for</B>, <B>while</B>, <B>repeat</B>, or

<B>forever</B> statement. Here are four examples, one for each different

type of loop statement, each of which performs the same function. The comments

with each type of loop statement illustrate how the controls work:</P>

<PRE>

<B>module</B> loop_1;

<B>integer</B> i; <B>reg</B> [31:0] DataBus; <B>initial</B> DataBus = 0;

<B>initial begin </B>

/************** Insert loop code after here. ******************/

/* for(Execute this assignment once before starting loop; exit loop if this expression is false; execute this assignment at end of loop before the check for end of loop.) */

<B>for</B>(i = 0; i &lt;= 15; i = i+1) DataBus[i] = 1;

/*************** Insert loop code before here. ****************/

<B>end</B> 

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

$display(&quot;DataBus = %b&quot;,DataBus);

#2; $display(&quot;DataBus = %b&quot;,DataBus); $finish;

<B>end</B> 

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

<P><P CLASS="Body"><A NAME="pgfId=65337"></A>Here is the <CODE>while</CODE>

statement code (to replace line 4 in module<CODE> loop_1</CODE> ):</P>

<PRE>

i = 0;

/* while(Execute next statement while this expression is true.) */

<B>while</B>(i &lt;= 15) <B>begin</B> DataBus[i] = 1; i = i+1; <B>end</B></PRE>

<P><P CLASS="Body"><A NAME="pgfId=65339"></A>Here is the <CODE>repeat</CODE>

statement code (to replace line 4 in module<CODE> loop_1</CODE> ):</P>

<PRE>

i = 0;

/* repeat(Execute next statement the number of times corresponding to the evaluation of this expression at the beginning of the loop.) */

<B>repeat</B>(16) <B>begin</B> DataBus[i] = 1; i = i+1; <B>end </B></PRE>

<P><P CLASS="Body"><A NAME="pgfId=65346"></A>Here is the <CODE>forever</CODE>

statement code (to replace line 4 in module<CODE> loop_1</CODE> ):</P>

<PRE>

i = 0;

/* A forever statement loops continuously. */

<B>forever</B> <B>begin</B> : my_loop

&nbsp;&nbsp;DataBus[i] = 1;

&nbsp;&nbsp;<B>if</B> (i == 15) #1 <B>disable</B> my_loop; // Need to let time advance to exit.

&nbsp;&nbsp;i = i+1; 

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

<P><P CLASS="Body"><A NAME="pgfId=201018"></A>The output for all four forms

of looping statement is the same:</P>

<PRE>

DataBus = 00000000000000000000000000000000

DataBus = 00000000000000001111111111111111</PRE>

<H2><A NAME="pgfId=1185"></A>11.8.3&nbsp;&nbsp;&nbsp;Disable</H2>

<P><P CLASS="BodyAfterHead"><A NAME="pgfId=1189"></A>The <B>disable statement</B>

[Verilog LRM&nbsp;11] stops the execution of a labeled sequential block

and skips to the end of the block:</P>

<PRE>

<B>forever</B>

<B>begin</B>: microprocessor_block // Labeled sequential block.

&nbsp;&nbsp;@(<B>posedge</B> clock)

&nbsp;&nbsp;<B>if</B> (reset) <B>disable</B> microprocessor_block; // Skip to end of block.

&nbsp;&nbsp;<B>else</B> Execute_code;

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

<P><P CLASS="Body"><A NAME="pgfId=11811"></A>Use the <CODE>disable</CODE>

statement with caution in ASIC design. It is difficult to implement directly

in hardware.</P>

<H2><A NAME="pgfId=1205"></A>11.8.4&nbsp;&nbsp;&nbsp;Fork and Join</H2>

<P><P CLASS="BodyAfterHead"><A NAME="pgfId=1211"></A>The <B>fork statement</B>

and <B>join statement</B> [Verilog LRM&nbsp;9.8.2] allows the execution

of two or more parallel threads in a <B>parallel block</B>:</P>

<PRE>

<B>module</B> fork_1

<B>event</B> eat_breakfast, read_paper;

<B>initial begin</B>

<B>&nbsp;&nbsp;fork </B>

&nbsp;&nbsp;@eat_breakfast; @read_paper;

<B>&nbsp;&nbsp;join </B>

<B>end </B>

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

<P><P CLASS="BodyAfterHead"><A NAME="pgfId=11276"></A>This is another Verilog

language feature that should be used with care in ASIC design, because it

is difficult to implement in hardware.</P>

<P><HR ALIGN="LEFT"></P>

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

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

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

</BODY>



<!--#include file="Copyright.html"--><!--#include file="footer.html"-->

⌨️ 快捷键说明

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