ch12.5.htm

来自「介绍asci设计的一本书」· HTM 代码 · 共 2,288 行 · 第 1/5 页

HTM
2,288
字号
 </A>

<B CLASS="Keyword">

endmodule</B>

 </P>

<P CLASS="BodyAfterHead">

<A NAME="pgfId=258225">

 </A>

It is important to understand why this code implies a sequential latch and not a combinational MUX. Think like the hardware and you will see the problem. When <SPAN CLASS="BodyComputer">

sel</SPAN>

 is zero, you can pass through the <SPAN CLASS="BodyComputer">

always</SPAN>

 statement whenever a change occurs on the input <SPAN CLASS="BodyComputer">

a</SPAN>

 without updating the value of the output <SPAN CLASS="BodyComputer">

z</SPAN>

. In this situation you need to &#8220;remember&#8221; the value of <SPAN CLASS="BodyComputer">

z</SPAN>

 when <SPAN CLASS="BodyComputer">

a</SPAN>

 changes. This implies sequential logic using <SPAN CLASS="BodyComputer">

a</SPAN>

 as the latch input, <SPAN CLASS="BodyComputer">

sel</SPAN>

 as the active-high latch enable, and <SPAN CLASS="BodyComputer">

z</SPAN>

 as the latch output.</P>

<P CLASS="Body">

<A NAME="pgfId=258286">

 </A>

The following code implies an 8:1 MUX with a three-state output:</P>

<P CLASS="ComputerFirstLabelV">

<A NAME="pgfId=173232">

 </A>

<B CLASS="Keyword">

module</B>

 Mux_81(InBus, sel, OE, OutBit);</P>

<P CLASS="ComputerLabelV">

<A NAME="pgfId=173233">

 </A>

<B CLASS="Keyword">

input</B>

 [7:0] InBus; <B CLASS="Keyword">

input</B>

 [2:0] Sel;</P>

<P CLASS="ComputerLabelV">

<A NAME="pgfId=173234">

 </A>

<B CLASS="Keyword">

input</B>

 OE; <B CLASS="Keyword">

output</B>

 OutBit; <B CLASS="Keyword">

reg</B>

 OutBit;</P>

<P CLASS="ComputerLabelV">

<A NAME="pgfId=173235">

 </A>

<B CLASS="Keyword">

always</B>

 @(OE <B CLASS="Keyword">

or</B>

 sel <B CLASS="Keyword">

or</B>

 InBus)</P>

<P CLASS="ComputerLabelV">

<A NAME="pgfId=173236">

 </A>

<B CLASS="Keyword">

	begin </B>

</P>

<P CLASS="ComputerLabelV">

<A NAME="pgfId=292670">

 </A>

<B CLASS="Keyword">

		if</B>

 (OE == 1) OutBit = InBus[sel]; <B CLASS="Keyword">

else</B>

 OutBit = 1'bz; </P>

<P CLASS="ComputerLabelV">

<A NAME="pgfId=292671">

 </A>

<B CLASS="Keyword">

	end </B>

</P>

<P CLASS="ComputerLastLabelV">

<A NAME="pgfId=173239">

 </A>

<B CLASS="Keyword">

endmodule</B>

 </P>

<P CLASS="Body">

<A NAME="pgfId=173252">

 </A>

When you synthesize a large MUX the required speed and area, the output load, as well as the cells that are available in the cell library will determine whether the synthesizer uses a large MUX cell, several smaller MUX cells, or equivalent random logic cells. The synthesized logic may also use different logic cells depending on whether you want the fastest path from the select input to the MUX output or from the data inputs to the MUX output. </P>

</DIV>

<DIV>

<H2 CLASS="Heading2">

<A NAME="pgfId=258311">

 </A>

12.5.6&nbsp;The Verilog Case Statement</H2>

<P CLASS="BodyAfterHead">

<A NAME="pgfId=259172">

 </A>

Consider the following model:</P>

<P CLASS="ComputerFirstLabelV">

<A NAME="pgfId=258937">

 </A>

<B CLASS="Keyword">

module</B>

 case8_oneHot(oneHot, a, b, c, z); </P>

<P CLASS="ComputerLabelV">

<A NAME="pgfId=258938">

 </A>

<B CLASS="Keyword">

input</B>

 a, b, c;<B CLASS="Keyword">

 input</B>

 [2:0] oneHot; <B CLASS="Keyword">

output</B>

 z; <B CLASS="Keyword">

reg</B>

 z;</P>

<P CLASS="ComputerLabelV">

<A NAME="pgfId=258939">

 </A>

<B CLASS="Keyword">

always</B>

 @(oneHot <B CLASS="Keyword">

or</B>

 a <B CLASS="Keyword">

or</B>

 b <B CLASS="Keyword">

or</B>

 c)</P>

<P CLASS="ComputerLabelV">

<A NAME="pgfId=258940">

 </A>

<B CLASS="Keyword">

begin case</B>

(oneHot) //synopsys full_case</P>

<P CLASS="ComputerLabelV">

<A NAME="pgfId=258941">

 </A>

	3'b001: z &lt;= a; 3'b010: z &lt;= b; 3'b100: z &lt;= c; </P>

<P CLASS="ComputerLabelV">

<A NAME="pgfId=258944">

 </A>

	default: z &lt;= 1'bx; <B CLASS="Keyword">

endcase </B>

</P>

<P CLASS="ComputerLabelV">

<A NAME="pgfId=258945">

 </A>

<B CLASS="Keyword">

end </B>

</P>

<P CLASS="ComputerLastLabelV">

<A NAME="pgfId=258946">

 </A>

<B CLASS="Keyword">

endmodule</B>

 </P>

<P CLASS="BodyAfterHead">

<A NAME="pgfId=259834">

 </A>

By including the <SPAN CLASS="BodyComputer">

default</SPAN>

 choice, the <SPAN CLASS="BodyComputer">

case</SPAN>

 statement is <SPAN CLASS="Definition">

exhaustive</SPAN>

<A NAME="marker=259833">

 </A>

. This means that every possible value of the select variable (<SPAN CLASS="BodyComputer">

oneHot</SPAN>

) is accounted for in the arms of the <SPAN CLASS="BodyComputer">

case</SPAN>

 statement. In some synthesizers (Synopsys, for example) you may indicate the arms are exhaustive and imply a MUX by using a <SPAN CLASS="Definition">

compiler directive</SPAN>

<A NAME="marker=267896">

 </A>

 or <SPAN CLASS="Definition">

synthesis directive</SPAN>

<A NAME="marker=267897">

 </A>

. A compiler directive is also called a <SPAN CLASS="Definition">

pseudocomment</SPAN>

<A NAME="marker=259836">

 </A>

 if it uses the comment format (such as <SPAN CLASS="BodyComputer">

//synopsys full_case</SPAN>

). The format of pseudocomments is very specific. Thus, for example, <SPAN CLASS="BodyComputer">

//synopys</SPAN>

 may be recognized but <SPAN CLASS="BodyComputer">

//&nbsp;synopys</SPAN>

 (with an extra space) or <SPAN CLASS="BodyComputer">

//SynopSys</SPAN>

 (uppercase) may not. The use of pseudocomments shows the problems of using an HDL for a purpose for which it was not intended. When we start &#8220;extending&#8221; the language we lose the advantages of a standard and sacrifice portability. A compiler directive in module <SPAN CLASS="BodyComputer">

case8_oneHot</SPAN>

 is unnecessary if the <SPAN CLASS="BodyComputer">

default</SPAN>

 choice is included. If you omit the <SPAN CLASS="BodyComputer">

default</SPAN>

 choice and you do not have the ability to use the <SPAN CLASS="BodyComputer">

full_case</SPAN>

 directive (or you use a different tool), the synthesizer will infer latches for the output <SPAN CLASS="BodyComputer">

z</SPAN>

.</P>

<P CLASS="Body">

<A NAME="pgfId=259508">

 </A>

If the default in a <SPAN CLASS="BodyComputer">

case</SPAN>

 statement is <SPAN CLASS="BodyComputer">

'x'</SPAN>

 (signifying a <SPAN CLASS="Definition">

synthesis don&#8217;t care value</SPAN>

<A NAME="marker=260273">

 </A>

), this gives the synthesizer flexibility in optimizing the logic. It does not mean that the synthesized logic output will be unknown when the default applies. The combinational logic that results from a <SPAN CLASS="BodyComputer">

case</SPAN>

 statement when a don&#8217;t care (<SPAN CLASS="BodyComputer">

'x'</SPAN>

) is included as a default may or may not include a MUX, depending on how the logic is optimized.</P>

<P CLASS="Body">

<A NAME="pgfId=259137">

 </A>

In <SPAN CLASS="BodyComputer">

case8_oneHot</SPAN>

 the choices in the arms of the <SPAN CLASS="BodyComputer">

case</SPAN>

 statement are exhaustive and also <A NAME="marker=259149">

 </A>

<SPAN CLASS="Emphasis">

mutually exclusive</SPAN>

. Consider the following alternative model:</P>

<P CLASS="ComputerFirstLabelV">

<A NAME="pgfId=258740">

 </A>

<B CLASS="Keyword">

module</B>

 case8_priority(oneHot, a, b, c, z); </P>

<P CLASS="ComputerLabelV">

<A NAME="pgfId=258828">

 </A>

<B CLASS="Keyword">

input</B>

 a, b, c;<B CLASS="Keyword">

 input</B>

 [2:0] oneHot; <B CLASS="Keyword">

output</B>

 z; <B CLASS="Keyword">

reg</B>

 z;</P>

<P CLASS="ComputerLabelV">

<A NAME="pgfId=258829">

 </A>

<B CLASS="Keyword">

always</B>

 @(oneHot <B CLASS="Keyword">

or</B>

 a <B CLASS="Keyword">

or</B>

 b <B CLASS="Keyword">

or</B>

 c) <B CLASS="Keyword">

begin</B>

</P>

<P CLASS="ComputerLabelV">

<A NAME="pgfId=258957">

 </A>

<B CLASS="Keyword">

case</B>

(1'b1) //synopsys parallel_case</P>

<P CLASS="ComputerLabelV">

<A NAME="pgfId=258745">

 </A>

	oneHot[0]: z &lt;= a; </P>

<P CLASS="ComputerLabelV">

<A NAME="pgfId=258746">

 </A>

	oneHot[1]: z &lt;= b; </P>

<P CLASS="ComputerLabelV">

<A NAME="pgfId=258839">

 </A>

	oneHot[2]: z &lt;= c; </P>

<P CLASS="ComputerLabelV">

<A NAME="pgfId=258747">

 </A>

	default: z &lt;= 1'bx; <B CLASS="Keyword">

endcase</B>

</P>

<P CLASS="ComputerLabelV">

<A NAME="pgfId=258748">

 </A>

<B CLASS="Keyword">

end </B>

</P>

<P CLASS="ComputerLastLabelV">

<A NAME="pgfId=258749">

 </A>

<B CLASS="Keyword">

endmodule</B>

 </P>

<P CLASS="BodyAfterHead">

<A NAME="pgfId=258738">

 </A>

In this version of the <SPAN CLASS="BodyComputer">

case</SPAN>

 statement the choices are not necessarily mutually exclusive (<SPAN CLASS="BodyComputer">

oneHot[0]</SPAN>

 and <SPAN CLASS="BodyComputer">

oneHot[2]</SPAN>

 may both be equal to <SPAN CLASS="BodyComputer">

1'b1</SPAN>

, for example). Thus the code implies a priority encoder. This may not be what you intended. Some logic synthesizers allow you to indicate mutually exclusive choices by using a directive (<SPAN CLASS="BodyComputer">

//synopsys parallel_case</SPAN>

, for example). It is probably wiser not to use these &#8220;outside-the-language&#8221; directives if they can be avoided.</P>

</DIV>

<DIV>

<H2 CLASS="Heading2">

<A NAME="pgfId=172817">

 </A>

12.5.7&nbsp;<A NAME="16058">

 </A>

Decoders In Verilog</H2>

<P CLASS="BodyAfterHead">

<A NAME="pgfId=172818">

 </A>

The following code models a 4:16 decoder with enable and three-state output:</P>

<P CLASS="ComputerFirstLabelV">

<A NAME="pgfId=70093">

 </A>

<B CLASS="Keyword">

module</B>

 Decoder_4To16(enable, In_4, Out_16); // 4-to-16 decoder</P>

<P CLASS="ComputerLabelV">

<A NAME="pgfId=70094">

 </A>

<B CLASS="Keyword">

input</B>

 enable; <B CLASS="Keyword">

input</B>

 [3:0] In_4; <B CLASS="Keyword">

output</B>

 [15:0] Out_16;</P>

<P CLASS="ComputerLabelV">

<A NAME="pgfId=70097">

 </A>

<B CLASS="Keyword">

reg</B>

 [15:0] Out_16;</P>

<P CLASS="ComputerLabelV">

<A NAME="pgfId=70098">

 </A>

<B CLASS="Keyword">

always</B>

 @(enable <B CLASS="Keyword">

or</B>

 In_4)</P>

<P CLASS="ComputerLabelV">

<A NAME="pgfId=70099">

 </A>

<A NAME="26215">

 </A>

	<B CLASS="Keyword">

begin </B>

Out_16 = 16'hzzzz;</P>

<P CLASS="ComputerLabelV">

<A NAME="pgfId=70101">

 </A>

<A NAME="32688">

 </A>

	<B CLASS="Keyword">

if</B>

 (enable == 1) </P>

<P CLASS="ComputerLabelV">

<A NAME="pgfId=292650">

 </A>

<B CLASS="Keyword">

		begin </B>

<A NAME="34637">

 </A>

Out_16 = 16'h0000; Out_16[In_4] = 1; <B CLASS="Keyword">

end</B>

</P>

<P CLASS="ComputerLabelV">

<A NAME="pgfId=70106">

 </A>

	<B CLASS="Keyword">

end</B>

</P>

<P CLASS="ComputerLastLabelV">

<A NAME="pgfId=70107">

 </A>

<B CLASS="Keyword">

endmodule</B>

 </P>

<P CLASS="BodyAfterHead">

<A NAME="pgfId=12382">

 </A>

In line <A HREF="#34637" CLASS="XRef">

7</A>

 the binary-encoded 4-bit input sets the corresponding bit of the 16-bit output to <SPAN CLASS="BodyComputer">

'1'</SPAN>

.<SPAN CLASS="BodyComputer">

 </SPAN>

The synthesizer infers a three-state buffer from the assignment in line <A HREF="#26215" CLASS="XRef">

5</A>

. Using the equality operator, <SPAN CLASS="BodyComputer">

'=='</SPAN>

, rather than the case equality operator, <SPAN CLASS="BodyComputer">

'==='</SPAN>

, makes sense in line <A HREF="#32688" CLASS="XRef">

6</A>

, because the synthesizer cannot generate logic that will check for <SPAN CLASS="BodyComputer">

enable</SPAN>

 being <SPAN CLASS="BodyComputer">

'x'</SPAN>

 or <SPAN CLASS="BodyComputer">

'z'</SPAN>

. So, for example, do not write the following (though some synthesis tools will still accept it):</P>

<P CLASS="ComputerOneLine">

<A NAME="pgfId=12390">

 </A>

<B CLASS="Keyword">

if</B>

 (enable === 1) // can't make logic to check for enable = x or z</P>

</DIV>

<DIV>

<H2 CLASS="Heading2">

<A NAME="pgfId=172984">

 </A>

12.5.8&nbsp;Priority Encoder in Verilog</H2>

<P CLASS="BodyAfterHead">

<A NAME="pgfId=172985">

 </A>

The following Verilog code models a priority encoder with three-state output:</P>

<P CLASS="ComputerFirstLabelV">

<A NAME="pgfId=172990">

 </A>

<B CLASS="Keyword">

module</B>

 Pri_Encoder32 (InBus, Clk, OE, OutBus);</P>

<P CLASS="ComputerLabelV">

<A NAME="pgfId=172991">

 </A>

<B CLASS="Keyword">

input</B>

 [31:0]InBus; <B CLASS="Keyword">

input</B>

 OE, Clk; <B CLASS="Keyword">

output</B>

 [4:0]OutBus; </P>

<P CLASS="ComputerLabelV">

<A NAME="pgfId=259282">

 </A>

<B CLASS="Keyword">

⌨️ 快捷键说明

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