ch11.08.htm
来自「介绍asci设计的一本书」· HTM 代码 · 共 154 行
HTM
154 行
<HTML>
<HEAD>
<META NAME="GENERATOR" CONTENT="Adobe PageMill 2.0 Mac">
<TITLE> 11.8 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 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 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 Case and If Statement</H2>
<P><P CLASS="BodyAfterHead"><A NAME="pgfId=1121"></A>An <B>if statement</B>
[Verilog LRM 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 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;
#2; select = 1'bx; #2; select = 1'bz; #2; select = 1; <B>end</B>
<B>initial</B> $monitor("T=%2g",$time," Select=",select," Out=",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)
0: mux_output = a;
1: mux_output = b;
<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])
3b'??1 : add;
3b'?1? : subtract;
3b'1?? : branch;
<B>endcase</B></PRE>
<H2><A NAME="pgfId=1161"></A>11.8.2 Loop Statement</H2>
<P><P CLASS="BodyAfterHead"><A NAME="pgfId=119901"></A>A <B>loop statement</B>
[Verilog LRM 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 <= 15; i = i+1) DataBus[i] = 1;
/*************** Insert loop code before here. ****************/
<B>end</B>
<B>initial</B> <B>begin</B>
$display("DataBus = %b",DataBus);
#2; $display("DataBus = %b",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 <= 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
DataBus[i] = 1;
<B>if</B> (i == 15) #1 <B>disable</B> my_loop; // Need to let time advance to exit.
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 Disable</H2>
<P><P CLASS="BodyAfterHead"><A NAME="pgfId=1189"></A>The <B>disable statement</B>
[Verilog LRM 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.
@(<B>posedge</B> clock)
<B>if</B> (reset) <B>disable</B> microprocessor_block; // Skip to end of block.
<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 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 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> fork </B>
@eat_breakfast; @read_paper;
<B> 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 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 + -
显示快捷键?