ch12.6.htm
来自「介绍asci设计的一本书」· HTM 代码 · 共 2,688 行 · 第 1/5 页
HTM
2,688 行
output</B>
[3:0] po;</P>
<P CLASS="ComputerLabelV">
<A NAME="pgfId=293280">
</A>
<B CLASS="Keyword">
supply1</B>
VDD; <B CLASS="Keyword">
supply0</B>
VSS;</P>
<P CLASS="ComputerLabelV">
<A NAME="pgfId=293281">
</A>
dfntnb po_ff_b0 (.D(po[1]),.CP(clk),.Q(po[0]),.QN(\po_ff_b0.QN));</P>
<P CLASS="ComputerLabelV">
<A NAME="pgfId=293282">
</A>
dfntnb po_ff_b1 (.D(po[2]),.CP(clk),.Q(po[1]),.QN(\po_ff_b1.QN));</P>
<P CLASS="ComputerLabelV">
<A NAME="pgfId=293283">
</A>
dfntnb po_ff_b2 (.D(po[3]),.CP(clk),.Q(po[2]),.QN(\po_ff_b2.QN));</P>
<P CLASS="ComputerLabelV">
<A NAME="pgfId=293284">
</A>
dfntnb po_ff_b3 (.D(si),.CP(clk),.Q(po[3]),.QN(\po_ff_b3.QN ));</P>
<P CLASS="ComputerLastLabelV">
<A NAME="pgfId=293285">
</A>
<B CLASS="Keyword">
endmodule</B>
</P>
<P CLASS="Body">
<A NAME="pgfId=293289">
</A>
The synthesized design consists of four flip-flops. Notice that (line 6 in the VHDL input) signal <SPAN CLASS="BodyComputer">
PO</SPAN>
is of mode <SPAN CLASS="BodyComputer">
buffer</SPAN>
because we cannot read a signal of mode <SPAN CLASS="BodyComputer">
out</SPAN>
inside a process. This is acceptable for synthesis but not usually a good idea for simulation models. We can modify the code to eliminate the <SPAN CLASS="BodyComputer">
buffer</SPAN>
port and at the same time we shall include a reset signal, as follows:</P>
<P CLASS="ComputerFirstLabel">
<A NAME="pgfId=293290">
</A>
<B CLASS="Keyword">
library</B>
IEEE; </P>
<P CLASS="ComputerLastLabel">
<A NAME="pgfId=293291">
</A>
<B CLASS="Keyword">
use</B>
IEEE.STD_LOGIC_1164.<B CLASS="Keyword">
all</B>
; <B CLASS="Keyword">
use</B>
IEEE.NUMERIC_STD.<B CLASS="Keyword">
all</B>
;</P>
<P CLASS="ComputerLabel">
<A NAME="pgfId=293292">
</A>
<B CLASS="Keyword">
entity</B>
SIPO_R <B CLASS="Keyword">
is port</B>
(</P>
<P CLASS="ComputerLabel">
<A NAME="pgfId=293293">
</A>
clk : <B CLASS="Keyword">
in</B>
STD_LOGIC ; res : <B CLASS="Keyword">
in</B>
STD_LOGIC ;</P>
<P CLASS="ComputerLabel">
<A NAME="pgfId=293295">
</A>
<A NAME="26948">
</A>
SI : <B CLASS="Keyword">
in</B>
STD_LOGIC ; PO : <B CLASS="Keyword">
out </B>
STD_LOGIC_VECTOR(3 <B CLASS="Keyword">
downto</B>
0));</P>
<P CLASS="ComputerLastLabel">
<A NAME="pgfId=293296">
</A>
<B CLASS="Keyword">
end</B>
;</P>
<P CLASS="ComputerLabel">
<A NAME="pgfId=293297">
</A>
<B CLASS="Keyword">
architecture</B>
Synthesis_1 <B CLASS="Keyword">
of</B>
SIPO_R <B CLASS="Keyword">
is</B>
</P>
<P CLASS="ComputerLabel">
<A NAME="pgfId=293298">
</A>
<B CLASS="Keyword">
signal</B>
PO_t : STD_LOGIC_VECTOR(3 <B CLASS="Keyword">
downto</B>
0); </P>
<P CLASS="ComputerLabel">
<A NAME="pgfId=293299">
</A>
<B CLASS="Keyword">
begin</B>
</P>
<P CLASS="ComputerLabel">
<A NAME="pgfId=293301">
</A>
<A NAME="29773">
</A>
<B CLASS="Keyword">
process</B>
(PO_t) <B CLASS="Keyword">
begin</B>
PO <= PO_t; <B CLASS="Keyword">
end</B>
<B CLASS="Keyword">
process</B>
;</P>
<P CLASS="ComputerLabel">
<A NAME="pgfId=293303">
</A>
<B CLASS="Keyword">
process</B>
<A NAME="23705">
</A>
(clk, res) <B CLASS="Keyword">
begin</B>
</P>
<P CLASS="ComputerLabel">
<A NAME="pgfId=293304">
</A>
<B CLASS="Keyword">
if</B>
(res = '0') <B CLASS="Keyword">
then</B>
PO_t <= (<B CLASS="Keyword">
others</B>
=> '0');</P>
<P CLASS="ComputerLabel">
<A NAME="pgfId=293306">
</A>
<B CLASS="Keyword">
elsif</B>
<A NAME="15173">
</A>
(rising_edge(clk)) <B CLASS="Keyword">
then</B>
PO_t <= SI & PO_t(3 <B CLASS="Keyword">
downto</B>
1);</P>
<P CLASS="ComputerLabel">
<A NAME="pgfId=293307">
</A>
<B CLASS="Keyword">
end</B>
<B CLASS="Keyword">
if</B>
;</P>
<P CLASS="ComputerLabel">
<A NAME="pgfId=293308">
</A>
<B CLASS="Keyword">
end</B>
<B CLASS="Keyword">
process</B>
;</P>
<P CLASS="ComputerLastLabel">
<A NAME="pgfId=293309">
</A>
<B CLASS="Keyword">
end</B>
Synthesis_1;</P>
<P CLASS="Body">
<A NAME="pgfId=293318">
</A>
Notice the following:</P>
<UL>
<LI CLASS="BulletList">
<A NAME="pgfId=293322">
</A>
Line <A HREF="#29773" CLASS="XRef">
10</A>
uses a temporary signal, <SPAN CLASS="BodyComputer">
PO_t</SPAN>
, to avoid using a port of mode <SPAN CLASS="BodyComputer">
buffer</SPAN>
for the output signal <SPAN CLASS="BodyComputer">
PO</SPAN>
. We could have used a variable instead of a signal and the variable would consume less overhead during simulation. However, we must complete an assignment to a variable inside the clocked process (not in a separate process as we can for the signal). Assignment between a variable and a signal inside a single process creates its own set of problems.</LI>
<LI CLASS="BulletList">
<A NAME="pgfId=293326">
</A>
Line <A HREF="#23705" CLASS="XRef">
11</A>
is sensitive to the clock, <SPAN CLASS="BodyComputer">
clk</SPAN>
, and the reset, <SPAN CLASS="BodyComputer">
res</SPAN>
. It is not sensitive to <SPAN CLASS="BodyComputer">
PO_t</SPAN>
or <SPAN CLASS="BodyComputer">
SI</SPAN>
and this is what indicates the sequential logic.</LI>
<LI CLASS="BulletList">
<A NAME="pgfId=293330">
</A>
Line <A HREF="#15173" CLASS="XRef">
13</A>
uses the <SPAN CLASS="BodyComputer">
rising_edge</SPAN>
<A NAME="marker=395358">
</A>
function from the <SPAN CLASS="BodyComputer">
STD_LOGIC_1164</SPAN>
package. </LI>
</UL>
<P CLASS="Body">
<A NAME="pgfId=293331">
</A>
The software synthesizes four positive-edge–triggered D flip-flops for design entity <SPAN CLASS="BodyComputer">
SIPO_R(Synthesis_1)</SPAN>
as it did for design entity <SPAN CLASS="BodyComputer">
SIPO_1(Synthesis_1)</SPAN>
. The difference is that the synthesized flip-flops in <SPAN CLASS="BodyComputer">
SIPO_R</SPAN>
have active-low resets. However, the simulation behavior of these two design entities will be different. In <SPAN CLASS="BodyComputer">
SIPO_R</SPAN>
, the function <SPAN CLASS="BodyComputer">
rising_edge</SPAN>
only evaluates to <SPAN CLASS="BodyComputer">
TRUE</SPAN>
for a transition from<SPAN CLASS="BodyComputer">
'0'</SPAN>
or <SPAN CLASS="BodyComputer">
'L'</SPAN>
to <SPAN CLASS="BodyComputer">
'1'</SPAN>
or <SPAN CLASS="BodyComputer">
'H'</SPAN>
. In <SPAN CLASS="BodyComputer">
SIPO_1</SPAN>
we only tested for <SPAN CLASS="BodyComputer">
Clk = '1'</SPAN>
. Since nearly all synthesis tools now accept <SPAN CLASS="BodyComputer">
rising_edge</SPAN>
and <SPAN CLASS="BodyComputer">
falling_edge</SPAN>
, it is probably wiser to use these functions consistently.</P>
</DIV>
<DIV>
<H2 CLASS="Heading2">
<A NAME="pgfId=293333">
</A>
12.6.9 Adders and Arithmetic Functions</H2>
<P CLASS="BodyAfterHead">
<A NAME="pgfId=393076">
</A>
If you wish to perform <SPAN CLASS="BodyComputer">
BIT_VECTOR</SPAN>
or <SPAN CLASS="BodyComputer">
STD_LOGIC_VECTOR</SPAN>
arithmetic you have three choices:</P>
<UL>
<LI CLASS="BulletFirst">
<A NAME="pgfId=393096">
</A>
Use a vendor-supplied package (there are no standard vendor packages—even if a company puts its own package in the IEEE library).</LI>
<LI CLASS="BulletList">
<A NAME="pgfId=393099">
</A>
Convert to <SPAN CLASS="BodyComputer">
SIGNED</SPAN>
(or <SPAN CLASS="BodyComputer">
UNSIGNED</SPAN>
) and use the IEEE standard synthesis packages (IEEE Std 1076.3-1997).</LI>
<LI CLASS="BulletLast">
<A NAME="pgfId=393100">
</A>
Use overloaded functions in packages or functions that you define yourself.</LI>
</UL>
<P CLASS="Body">
<A NAME="pgfId=393104">
</A>
Here is an example of addition using a ripple-carry architecture:</P>
<P CLASS="ComputerFirstLabel">
<A NAME="pgfId=293335">
</A>
<B CLASS="Keyword">
library</B>
IEEE; </P>
<P CLASS="ComputerLastLabel">
<A NAME="pgfId=293336">
</A>
<B CLASS="Keyword">
use</B>
IEEE.STD_LOGIC_1164.<B CLASS="Keyword">
all</B>
; <B CLASS="Keyword">
use</B>
IEEE.NUMERIC_STD.<B CLASS="Keyword">
all</B>
;</P>
<P CLASS="ComputerLabel">
<A NAME="pgfId=293337">
</A>
<B CLASS="Keyword">
entity</B>
Adder4 <B CLASS="Keyword">
is port</B>
(</P>
<P CLASS="ComputerLabel">
<A NAME="pgfId=293338">
</A>
in1, in2 : <B CLASS="Keyword">
in</B>
BIT_VECTOR(3 <B CLASS="Keyword">
downto</B>
0) ;</P>
<P CLASS="ComputerLabel">
<A NAME="pgfId=293339">
</A>
mySum : <B CLASS="Keyword">
out</B>
BIT_VECTOR(3 <B CLASS="Keyword">
downto</B>
0) ) ;</P>
<P CLASS="ComputerLastLabel">
<A NAME="pgfId=293340">
</A>
<B CLASS="Keyword">
end</B>
Adder4;</P>
<P CLASS="ComputerLabel">
<A NAME="pgfId=293341">
</A>
<B CLASS="Keyword">
architecture</B>
Behave_A <B CLASS="Keyword">
of</B>
Adder4 <B CLASS="Keyword">
is</B>
</P>
<P CLASS="ComputerLabel">
<A NAME="pgfId=293342">
</A>
<B CLASS="Keyword">
function</B>
DIY(L,R: BIT_VECTOR(3 <B CLASS="Keyword">
downto</B>
0)) <B CLASS="Keyword">
return</B>
BIT_VECTOR <B CLASS="Keyword">
is</B>
</P>
<P CLASS="ComputerLabel">
<A NAME="pgfId=293343">
</A>
<B CLASS="Keyword">
variable</B>
sum:BIT_VECTOR(3 <B CLASS="Keyword">
downto</B>
0);<B CLASS="Keyword">
variable</B>
lt,rt,st,cry: BIT;</P>
<P CLASS="ComputerLabel">
<A NAME="pgfId=293344">
</A>
<B CLASS="Keyword">
begin </B>
cry := '0';</P>
<P CLASS="ComputerLabel">
<A NAME="pgfId=293345">
</A>
<B CLASS="Keyword">
for</B>
i <B CLASS="Keyword">
in</B>
L'REVERSE_RANGE <B CLASS="Keyword">
loop</B>
</P>
<P CLASS="ComputerLabel">
<A NAME="pgfId=293346">
</A>
lt := L(i); rt := R(i); st := lt <B CLASS="Keyword">
xor</B>
rt;</P>
<P CLASS="ComputerLabel">
<A NAME="pgfId=293347">
</A>
sum(i):= st <B CLASS="Keyword">
xor</B>
cry; cry:= (lt <B CLASS="Keyword">
and</B>
rt) <B CLASS="Keyword">
or</B>
(st <B CLASS="Keyword">
and</B>
cry);</P>
<P CLASS="ComputerLabel">
<A NAME="pgfId=293348">
</A>
<B CLASS="Keyword">
end</B>
<B CLASS="Keyword">
loop</B>
;</P>
<P CLASS="ComputerLabel">
<A NAME="pgfId=293349">
</A>
<B CLASS="Keyword">
return</B>
sum;</P>
<P CLASS="ComputerLabel">
<A NAME="pgfId=293350">
</A>
<B CLASS="Keyword">
end</B>
;</P>
<P CLASS="ComputerLabel">
<A NAME="pgfId=293351">
</A>
<B CLASS="Keyword">
begin </B>
mySum <= DIY (in1, in2); -- do it yourself (DIY) add </P>
<P CLASS="ComputerLastLabel">
<A NAME="pgfId=293352">
</A>
<B CLASS="Keyword">
end</B>
Behave_A;</P>
<P CLASS="BodyAfterHead">
<A NAME="pgfId=293353">
</A>
This model results in random logic. </P>
<P CLASS="Body">
<A NAME="pgfId=293354">
</A>
An alternative is to use <SPAN CLASS="BodyComputer">
UNSIGNED</SPAN>
or <SPAN CLASS="BodyComputer">
UNSIGNED</SPAN>
from the IEEE <SPAN CLASS="BodyComputer">
NUMERIC_STD</SPAN>
or <SPAN CLASS="BodyComputer">
NUMERIC_BIT</SPAN>
packages as in the following example:</P>
<P CLASS="ComputerFirstLabel">
<A NAME="pgfId=293355">
</A>
<B CLASS="Keyword">
library</B>
IEEE; </P>
<P CLASS="ComputerLastLabel">
<A NAME="pgfId=293356">
</A>
<B CLASS="Keyword">
use</B>
IEEE.STD_LOGIC_1164.<B CLASS="Keyword">
all</B>
; <B CLASS="Keyword">
use</B>
IEEE.NUMERIC_STD.<B CLASS="Keyword">
all</B>
;</P>
<P CLASS="ComputerLabel">
<A NAME="pgfId=293357">
</A>
<B CLASS="Keyword">
entity</B>
Adder4 <B CLASS="Keyword">
is port</B>
(</P>
<P CLASS="ComputerLabel">
<A NAME="pgfId=293358">
</A>
in1, in2 : <B CLASS="Keyword">
in</B>
UNSIGNED(3 <B CLASS="Keyword">
downto</B>
0) ;</P>
<P CLASS="ComputerLabel">
<A NAME="pgfId=293359">
</A>
mySum : <B CLASS="Keyword">
out</B>
UNSIGNED(3 <B CLASS="Keyword">
downto</B>
0) ) ;</P>
<P CLASS="ComputerLastLabel">
<A NAME="pgfId=293360">
</A>
<B CLASS="Keyword">
end</B>
Adder4;</P>
<P CLASS="ComputerLabel">
<A NAME="pgfId=293361">
</A>
<B CLASS="Keyword">
architecture</B>
Behave_B <B CLASS="Keyword">
of</B>
Adder4 <B CLASS="Keyword">
is</B>
</P>
<P CLASS="ComputerLabel">
<A NAME="pgfId=293362">
</A>
<B CLASS="Keyword">
begin </B>
mySum <= in1 + in2; -- This uses an overloaded '+'.</P>
<P CLASS="ComputerLastLabel">
<A NAME="pgfId=293363">
</A>
<B CLASS="Keyword">
end</B>
Behave_B;</P>
<P CLASS="BodyAfterHead">
<A NAME="pgfId=293364">
</A>
In this case, the synthesized logic will depend on the logic synthesizer. </P
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?