ch12.5.htm
来自「介绍asci设计的一本书」· HTM 代码 · 共 2,288 行 · 第 1/5 页
HTM
2,288 行
reg</B>
j; <B CLASS="Keyword">
reg</B>
[4:0]OutBus;</P>
<P CLASS="ComputerLabelV">
<A NAME="pgfId=172995">
</A>
<B CLASS="Keyword">
always</B>
@(<B CLASS="Keyword">
posedge</B>
Clk) </P>
<P CLASS="ComputerLabelV">
<A NAME="pgfId=259295">
</A>
<B CLASS="Keyword">
begin </B>
</P>
<P CLASS="ComputerLabelV">
<A NAME="pgfId=172997">
</A>
<A NAME="33663">
</A>
<B CLASS="Keyword">
if</B>
(OE == 0) OutBus = 5'bz ; </P>
<P CLASS="ComputerLabelV">
<A NAME="pgfId=259291">
</A>
<B CLASS="Keyword">
else </B>
</P>
<P CLASS="ComputerLabelV">
<A NAME="pgfId=259294">
</A>
<B CLASS="Keyword">
begin </B>
OutBus = 0;</P>
<P CLASS="ComputerLabelV">
<A NAME="pgfId=173001">
</A>
<A NAME="16539">
</A>
<B CLASS="Keyword">
for</B>
(j = 31; j >= 0; j = j - 1)</P>
<P CLASS="ComputerLabelV">
<A NAME="pgfId=173002">
</A>
<A NAME="39488">
</A>
<B CLASS="Keyword">
begin if</B>
(InBus[j] == 1) OutBus = j; <B CLASS="Keyword">
end</B>
</P>
<P CLASS="ComputerLabelV">
<A NAME="pgfId=259297">
</A>
<B CLASS="Keyword">
end </B>
<A NAME="37846">
</A>
</P>
<P CLASS="ComputerLabelV">
<A NAME="pgfId=173009">
</A>
<B CLASS="Keyword">
end</B>
</P>
<P CLASS="ComputerLastLabelV">
<A NAME="pgfId=173010">
</A>
<B CLASS="Keyword">
endmodule </B>
</P>
<P CLASS="BodyAfterHead">
<A NAME="pgfId=284978">
</A>
In lines <A HREF="#16539" CLASS="XRef">
9</A>
–<A HREF="#37846" CLASS="XRef">
11</A>
the binary-encoded output is set to the position of the lowest-indexed <SPAN CLASS="BodyComputer">
'1'</SPAN>
in the input bus. The logic synthesizer must be able to unroll the loop in a <SPAN CLASS="BodyComputer">
for</SPAN>
statement. Normally the synthesizer will check for fixed (or <A NAME="marker=395327">
</A>
static) bounds on the loop limits, as in line <A HREF="#16539" CLASS="XRef">
9</A>
above.</P>
</DIV>
<DIV>
<H2 CLASS="Heading2">
<A NAME="pgfId=2637">
</A>
12.5.9 <A NAME="19781">
</A>
Arithmetic in Verilog</H2>
<P CLASS="BodyAfterHead">
<A NAME="pgfId=71094">
</A>
You need to make room for the carry bit when you add two numbers in Verilog. You may do this using concatenation on the LHS of an assignment as follows:</P>
<P CLASS="ComputerFirstLabelV">
<A NAME="pgfId=260080">
</A>
<B CLASS="Keyword">
module</B>
Adder_8 (A, B, Z, Cin, Cout);</P>
<P CLASS="ComputerLabelV">
<A NAME="pgfId=260081">
</A>
<B CLASS="Keyword">
input</B>
[7:0] A, B; <B CLASS="Keyword">
input</B>
Cin; <B CLASS="Keyword">
output</B>
[7:0] Z; <B CLASS="Keyword">
output</B>
Cout;</P>
<P CLASS="ComputerLabelV">
<A NAME="pgfId=260084">
</A>
<B CLASS="Keyword">
assign </B>
{Cout, Z} = A + B + Cin;</P>
<P CLASS="ComputerLastLabelV">
<A NAME="pgfId=299813">
</A>
<B CLASS="Keyword">
endmodule</B>
</P>
<P CLASS="Body">
<A NAME="pgfId=260078">
</A>
In the following example, the synthesizer should recognize <SPAN CLASS="BodyComputer">
'1'</SPAN>
as a carry-in bit of an adder and should synthesize one adder and not two: </P>
<P CLASS="ComputerFirstLabelV">
<A NAME="pgfId=2643">
</A>
<B CLASS="Keyword">
module</B>
Adder_16 (A, B, Sum, Cout);</P>
<P CLASS="ComputerLabelV">
<A NAME="pgfId=2645">
</A>
<B CLASS="Keyword">
input</B>
[15:0] A, B; <B CLASS="Keyword">
output</B>
[15:0] Sum; <B CLASS="Keyword">
output</B>
Cout;</P>
<P CLASS="ComputerLabelV">
<A NAME="pgfId=2649">
</A>
<B CLASS="Keyword">
reg</B>
[15:0] Sum; <B CLASS="Keyword">
reg</B>
Cout;</P>
<P CLASS="ComputerLabelV">
<A NAME="pgfId=2651">
</A>
<B CLASS="Keyword">
always</B>
@(A <B CLASS="Keyword">
or</B>
B) {Cout, Sum} = A + B + 1;</P>
<P CLASS="ComputerLastLabelV">
<A NAME="pgfId=299832">
</A>
<B CLASS="Keyword">
endmodule</B>
</P>
<P CLASS="Body">
<A NAME="pgfId=2657">
</A>
It is always possible to synthesize adders (and other arithmetic functions) using random logic, but they may not be as efficient as using datapath synthesis (see <A HREF="#25859" CLASS="XRef">
Section 12.5.12</A>
).</P>
<P CLASS="Body">
<A NAME="pgfId=260145">
</A>
A logic sythesizer may infer two adders from the following description rather than shaping a single adder. </P>
<P CLASS="ComputerFirstLabelV">
<A NAME="pgfId=18300">
</A>
<B CLASS="Keyword">
module</B>
Add_A (sel, a, b, c, d, y); </P>
<P CLASS="ComputerLabelV">
<A NAME="pgfId=292672">
</A>
<B CLASS="Keyword">
input</B>
a, b, c, d, sel; <B CLASS="Keyword">
output</B>
y; <B CLASS="Keyword">
reg</B>
y;</P>
<P CLASS="ComputerLabelV">
<A NAME="pgfId=18303">
</A>
<B CLASS="Keyword">
always</B>
@(sel <B CLASS="Keyword">
or</B>
a <B CLASS="Keyword">
or</B>
b <B CLASS="Keyword">
or</B>
c <B CLASS="Keyword">
or</B>
d)</P>
<P CLASS="ComputerLabelV">
<A NAME="pgfId=18304">
</A>
<B CLASS="Keyword">
begin</B>
<B CLASS="Keyword">
if</B>
(sel == 0) y <= a + b; <B CLASS="Keyword">
else</B>
y <= c + d; <B CLASS="Keyword">
end</B>
</P>
<P CLASS="ComputerLastLabelV">
<A NAME="pgfId=18309">
</A>
<B CLASS="Keyword">
endmodule</B>
</P>
<P CLASS="Body">
<A NAME="pgfId=70609">
</A>
To imply the presence of a MUX before a single adder we can use temporary variables. For example, the synthesizer should use only one adder for the following code:</P>
<P CLASS="ComputerFirstLabelV">
<A NAME="pgfId=18392">
</A>
<B CLASS="Keyword">
module</B>
Add_B (sel, a, b, c, d, y); </P>
<P CLASS="ComputerLabelV">
<A NAME="pgfId=292673">
</A>
<B CLASS="Keyword">
input</B>
a, b, c, d, sel; <B CLASS="Keyword">
output</B>
y; <B CLASS="Keyword">
reg</B>
t1, t2, y;</P>
<P CLASS="ComputerLabelV">
<A NAME="pgfId=18395">
</A>
<B CLASS="Keyword">
always</B>
@(sel <B CLASS="Keyword">
or</B>
a <B CLASS="Keyword">
or</B>
b <B CLASS="Keyword">
or</B>
c <B CLASS="Keyword">
or</B>
d) <B CLASS="Keyword">
begin</B>
</P>
<P CLASS="ComputerLabelV">
<A NAME="pgfId=2665">
</A>
<B CLASS="Keyword">
if</B>
(sel == 0) <B CLASS="Keyword">
begin</B>
t1 = a; t2 = b; <B CLASS="Keyword">
end</B>
// Temporary </P>
<P CLASS="ComputerLabelV">
<A NAME="pgfId=2669">
</A>
<B CLASS="Keyword">
else</B>
<B CLASS="Keyword">
begin</B>
t1 = c; t2 = d; <B CLASS="Keyword">
end</B>
// variables.</P>
<P CLASS="ComputerLabelV">
<A NAME="pgfId=2673">
</A>
<B CLASS="Keyword">
</B>
y = t1 + t2; <B CLASS="Keyword">
end</B>
</P>
<P CLASS="ComputerLastLabelV">
<A NAME="pgfId=299870">
</A>
<B CLASS="Keyword">
endmodule</B>
</P>
<P CLASS="Body">
<A NAME="pgfId=71082">
</A>
If a synthesis tool is capable of performing <SPAN CLASS="Definition">
resource allocation</SPAN>
<A NAME="marker=70665">
</A>
and <SPAN CLASS="Definition">
resource sharing</SPAN>
<A NAME="marker=70653">
</A>
in these situations, the coding style may not matter. However we may want to use a different tool, which may not be as advanced, at a later date—so it is better to use <SPAN CLASS="BodyComputer">
Add_B</SPAN>
rather than <SPAN CLASS="BodyComputer">
Add_A</SPAN>
if we wish to conserve area. This example shows that the simplest code (<SPAN CLASS="BodyComputer">
Add_A</SPAN>
) does not always result in the simplest logic (<SPAN CLASS="BodyComputer">
Add_B</SPAN>
).</P>
<P CLASS="Body">
<A NAME="pgfId=260163">
</A>
Multiplication in Verilog assumes nets are unsigned numbers:</P>
<P CLASS="ComputerFirstLabelV">
<A NAME="pgfId=260166">
</A>
<B CLASS="Keyword">
module</B>
Multiply_unsigned (A, B, Z); </P>
<P CLASS="ComputerLabelV">
<A NAME="pgfId=292682">
</A>
<B CLASS="Keyword">
input</B>
[1:0] A, B; <B CLASS="Keyword">
output</B>
[3:0] Z; </P>
<P CLASS="ComputerLabelV">
<A NAME="pgfId=260168">
</A>
<B CLASS="Keyword">
assign </B>
Z <= A * B;</P>
<P CLASS="ComputerLastLabelV">
<A NAME="pgfId=260169">
</A>
<B CLASS="Keyword">
endmodule</B>
</P>
<P CLASS="Body">
<A NAME="pgfId=260197">
</A>
To multiply signed numbers we need to extend the multiplicands with their sign bits as follows (some simulators have trouble with the concatenation <SPAN CLASS="BodyComputer">
'{}'</SPAN>
structures, in which case we have to write them out “long hand”):</P>
<P CLASS="ComputerFirstLabelV">
<A NAME="pgfId=260198">
</A>
<B CLASS="Keyword">
module</B>
Multiply_signed (A, B, Z); </P>
<P CLASS="ComputerLabelV">
<A NAME="pgfId=292683">
</A>
<B CLASS="Keyword">
input</B>
[1:0] A, B; <B CLASS="Keyword">
output</B>
[3:0] Z; </P>
<P CLASS="ComputerLabelV">
<A NAME="pgfId=260220">
</A>
// 00 -> 00_00 01 -> 00_01 10 -> 11_10 11 -> 11_11</P>
<P CLASS="ComputerLabelV">
<A NAME="pgfId=260200">
</A>
<B CLASS="Keyword">
assign </B>
Z = { { 2{A[1]} }, A} * { { 2{B[1]} }, B};</P>
<P CLASS="ComputerLastLabelV">
<A NAME="pgfId=260201">
</A>
<B CLASS="Keyword">
endmodule</B>
</P>
<P CLASS="BodyAfterHead">
<A NAME="pgfId=260238">
</A>
How the logic synthesizer implements the multiplication depends on the software.</P>
</DIV>
<DIV>
<H2 CLASS="Heading2">
<A NAME="pgfId=18370">
</A>
12.5.10 <A NAME="41490">
</A>
Sequential Logic in Verilog</H2>
<P CLASS="BodyAfterHead">
<A NAME="pgfId=171938">
</A>
The following statement implies a positive-edge–triggered D flip-flop:</P>
<P CLASS="ComputerOneLine">
<A NAME="pgfId=2771">
</A>
<B CLASS="Keyword">
always</B>
@(<B CLASS="Keyword">
posedge</B>
clock) Q_flipflop = D; // A flip-flop.</P>
<P CLASS="BodyAfterHead">
<A NAME="pgfId=2775">
</A>
When you use edges (<SPAN CLASS="BodyComputer">
posedge</SPAN>
or <SPAN CLASS="BodyComputer">
negedge</SPAN>
) in the sensitivity list of an <SPAN CLASS="BodyComputer">
always</SPAN>
statement, you imply a clocked storage element. However, an <SPAN CLASS="BodyComputer">
always</SPAN>
statement does not have to be edge-sensitive to imply sequential logic. As another example of sequential logic, the following statement implies a level-sensitive transparent latch:</P>
<P CLASS="ComputerOneLine">
<A NAME="pgfId=171974">
</A>
<B CLASS="Keyword">
always</B>
@(clock <B CLASS="Keyword">
or</B>
D) <B CLASS="Keyword">
if</B>
(clock) Q_latch = D; // A latch.</P>
<P CLASS="BodyAfterHead">
<A NAME="pgfId=171975">
</A>
On the negative edge of the clock the <SPAN CLASS="BodyComputer">
always</SPAN>
statement is executed, but no assignment is made to <SPAN CLASS="BodyComputer">
Q_latch</SPAN>
. These last two code examples concisely illustrate the difference between a flip-flop and a latch. </P>
<P CLASS="Body">
<A NAME="pgfId=16320">
</A>
Any sequential logic cell or memory element must be initialized. Although you could use an <SPAN CLASS="BodyComputer">
initial</SPAN>
statement to simulate power-up, generating logic to mimic an <SPAN CLASS="BodyComputer">
initial</SPAN>
statement is hard. Instead use a reset as follows:</P>
<P CLASS="ComputerOneLine">
<A NAME="pgfId=16242">
</A>
<B CLASS="Keyword">
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?