ch12.6.htm
来自「介绍asci设计的一本书」· HTM 代码 · 共 2,688 行 · 第 1/5 页
HTM
2,688 行
</A>
Depending on how the expression is parsed, the first adder may perform <SPAN CLASS="BodyComputer">
x = a + b</SPAN>
, a second adder <SPAN CLASS="BodyComputer">
y = x + c</SPAN>
, and a third adder <SPAN CLASS="BodyComputer">
z = y + d</SPAN>
. The following code should generate faster logic with three adders stacked only two deep:</P>
<P CLASS="ComputerOneLine">
<A NAME="pgfId=3966">
</A>
z <= (a + b) + (c + d);</P>
</DIV>
<DIV>
<H2 CLASS="Heading2">
<A NAME="pgfId=4004">
</A>
12.6.6 Sequential Logic in VHDL</H2>
<P CLASS="BodyAfterHead">
<A NAME="pgfId=4108">
</A>
Sensitivity to an edge implies sequential logic in VHDL. A synthesis tool can locate edges in VHDL by finding a <SPAN CLASS="BodyComputer">
process</SPAN>
<A NAME="marker=395354">
</A>
statement that has either:</P>
<UL>
<LI CLASS="BulletFirst">
<A NAME="pgfId=4112">
</A>
no sensitivity list with a <SPAN CLASS="BodyComputer">
wait until </SPAN>
statement </LI>
<LI CLASS="BulletLast">
<A NAME="pgfId=4114">
</A>
a sensitivity list and test for<SPAN CLASS="BodyComputer">
'EVENT </SPAN>
plus a specific level</LI>
</UL>
<P CLASS="Body">
<A NAME="pgfId=4122">
</A>
Any signal assigned in an edge-sensitive <SPAN CLASS="BodyComputer">
process</SPAN>
statement should also be reset—but be careful to distinguish between asynchronous and synchronous resets. The following example illustrates these points:</P>
<P CLASS="ComputerFirst">
<A NAME="pgfId=4128">
</A>
<B CLASS="Keyword">
library</B>
IEEE; <B CLASS="Keyword">
use</B>
IEEE.STD_LOGIC_1164.<B CLASS="Keyword">
all</B>
; <B CLASS="Keyword">
entity</B>
DFF_With_Reset <B CLASS="Keyword">
is</B>
</P>
<P CLASS="Computer">
<A NAME="pgfId=4130">
</A>
<B CLASS="Keyword">
port</B>
(D, Clk, Reset : <B CLASS="Keyword">
in</B>
STD_LOGIC; Q : <B CLASS="Keyword">
out</B>
STD_LOGIC);</P>
<P CLASS="ComputerLast">
<A NAME="pgfId=4132">
</A>
<B CLASS="Keyword">
end</B>
DFF_With_Reset;</P>
<P CLASS="ComputerFirst">
<A NAME="pgfId=4134">
</A>
<B CLASS="Keyword">
architecture</B>
Synthesis_1 <B CLASS="Keyword">
of</B>
DFF_With_Reset <B CLASS="Keyword">
is</B>
</P>
<P CLASS="Computer">
<A NAME="pgfId=4138">
</A>
<B CLASS="Keyword">
begin</B>
<B CLASS="Keyword">
process</B>
(Clk, Reset) <B CLASS="Keyword">
begin</B>
</P>
<P CLASS="Computer">
<A NAME="pgfId=4140">
</A>
<B CLASS="Keyword">
if</B>
(Reset = '0') <B CLASS="Keyword">
then</B>
Q <= '0'; -- asynchronous reset </P>
<P CLASS="Computer">
<A NAME="pgfId=173535">
</A>
<B CLASS="Keyword">
elsif</B>
rising_edge(Clk) <B CLASS="Keyword">
then</B>
Q <= D;</P>
<P CLASS="Computer">
<A NAME="pgfId=4148">
</A>
<B CLASS="Keyword">
end</B>
<B CLASS="Keyword">
if</B>
;</P>
<P CLASS="Computer">
<A NAME="pgfId=4150">
</A>
<B CLASS="Keyword">
end</B>
<B CLASS="Keyword">
process</B>
;</P>
<P CLASS="ComputerLast">
<A NAME="pgfId=4152">
</A>
<B CLASS="Keyword">
end</B>
Synthesis_1;</P>
<P CLASS="ComputerFirst">
<A NAME="pgfId=4156">
</A>
<B CLASS="Keyword">
architecture</B>
Synthesis_2 <B CLASS="Keyword">
of</B>
DFF_With_Reset <B CLASS="Keyword">
is</B>
</P>
<P CLASS="Computer">
<A NAME="pgfId=4158">
</A>
<B CLASS="Keyword">
begin</B>
<B CLASS="Keyword">
process</B>
<B CLASS="Keyword">
begin</B>
</P>
<P CLASS="Computer">
<A NAME="pgfId=4160">
</A>
<B CLASS="Keyword">
wait</B>
<B CLASS="Keyword">
until</B>
rising_edge(Clk);</P>
<P CLASS="Computer">
<A NAME="pgfId=4162">
</A>
-- This reset is gated with the clock and is synchronous:</P>
<P CLASS="Computer">
<A NAME="pgfId=173528">
</A>
<B CLASS="Keyword">
if</B>
(Reset = '0') <B CLASS="Keyword">
then</B>
Q <= '0'; <B CLASS="Keyword">
else</B>
Q <= D; <B CLASS="Keyword">
end</B>
<B CLASS="Keyword">
if</B>
;</P>
<P CLASS="Computer">
<A NAME="pgfId=4170">
</A>
<B CLASS="Keyword">
end</B>
<B CLASS="Keyword">
process</B>
;</P>
<P CLASS="ComputerLast">
<A NAME="pgfId=4172">
</A>
<B CLASS="Keyword">
end</B>
Synthesis_2;</P>
<P CLASS="Body">
<A NAME="pgfId=286971">
</A>
Sequential logic results when we have to “remember” something between successive executions of a <SPAN CLASS="BodyComputer">
process</SPAN>
statement. This occurs when a <SPAN CLASS="BodyComputer">
process</SPAN>
statement contains one or more of the following situations:</P>
<UL>
<LI CLASS="BulletFirst">
<A NAME="pgfId=221950">
</A>
A signal is read but is not in the sensitivity list of a <SPAN CLASS="BodyComputer">
process</SPAN>
statement.</LI>
<LI CLASS="BulletList">
<A NAME="pgfId=221916">
</A>
A signal or variable is read before it is updated.</LI>
<LI CLASS="BulletList">
<A NAME="pgfId=221920">
</A>
A signal is not always updated.</LI>
<LI CLASS="BulletLast">
<A NAME="pgfId=221957">
</A>
There are multiple <SPAN CLASS="BodyComputer">
wait</SPAN>
statements.</LI>
</UL>
<P CLASS="BodyAfterHead">
<A NAME="pgfId=264046">
</A>
Not all of the models that we could write using the above constructs will be synthesizable. Any models that do use one or more of these constructs and that are synthesizable will result in sequential logic.</P>
</DIV>
<DIV>
<H2 CLASS="Heading2">
<A NAME="pgfId=173349">
</A>
12.6.7 Instantiation in VHDL</H2>
<P CLASS="BodyAfterHead">
<A NAME="pgfId=4176">
</A>
The easiest way to find out how to <A NAME="marker=395355">
</A>
hand instantiate a component is to generate a structural netlist from a simple HDL input—for example, the following Verilog behavioral description (VHDL could have been used, but the Verilog is shorter):</P>
<P CLASS="ComputerFirstLabelV">
<A NAME="pgfId=287227">
</A>
`timescale 1ns/1ns</P>
<P CLASS="ComputerLabelV">
<A NAME="pgfId=287228">
</A>
<B CLASS="Keyword">
module</B>
halfgate (myInput, myOutput);</P>
<P CLASS="ComputerLabelV">
<A NAME="pgfId=287229">
</A>
<B CLASS="Keyword">
input</B>
myInput; <B CLASS="Keyword">
output</B>
myOutput; <B CLASS="Keyword">
wire</B>
myOutput; </P>
<P CLASS="ComputerLabelV">
<A NAME="pgfId=287245">
</A>
<B CLASS="Keyword">
assign</B>
myOutput = ~myInput;</P>
<P CLASS="ComputerLastLabelV">
<A NAME="pgfId=287225">
</A>
<B CLASS="Keyword">
endmodule</B>
</P>
<P CLASS="Body">
<A NAME="pgfId=287234">
</A>
We synthesize this module and generate the following VHDL structural netlist:</P>
<P CLASS="ComputerFirstLabel">
<A NAME="pgfId=287253">
</A>
<B CLASS="Keyword">
library</B>
IEEE; <B CLASS="Keyword">
use</B>
IEEE.STD_LOGIC_1164.<B CLASS="Keyword">
all</B>
;</P>
<P CLASS="ComputerLabel">
<A NAME="pgfId=287256">
</A>
<B CLASS="Keyword">
library</B>
COMPASS_LIB; <B CLASS="Keyword">
use</B>
COMPASS_LIB.COMPASS.<B CLASS="Keyword">
all</B>
;</P>
<P CLASS="ComputerLabel">
<A NAME="pgfId=287258">
</A>
--compass compile_off -- synopsys etc.</P>
<P CLASS="ComputerLabel">
<A NAME="pgfId=287259">
</A>
<B CLASS="Keyword">
use</B>
COMPASS_LIB.COMPASS_ETC.<B CLASS="Keyword">
all</B>
;</P>
<P CLASS="ComputerLabel">
<A NAME="pgfId=287260">
</A>
--compass compile_on -- synopsys etc.</P>
<P CLASS="ComputerLabel">
<A NAME="pgfId=287262">
</A>
<B CLASS="Keyword">
entity</B>
halfgate_u <B CLASS="Keyword">
is</B>
</P>
<P CLASS="ComputerLabel">
<A NAME="pgfId=287264">
</A>
--compass compile_off -- synopsys etc.</P>
<P CLASS="ComputerLabel">
<A NAME="pgfId=287265">
</A>
<B CLASS="Keyword">
generic</B>
( </P>
<P CLASS="ComputerLabel">
<A NAME="pgfId=292774">
</A>
myOutput_cap : Real := 0.01; </P>
<P CLASS="ComputerLabel">
<A NAME="pgfId=292775">
</A>
INSTANCE_NAME : string := "halfgate_u" );</P>
<P CLASS="ComputerLabel">
<A NAME="pgfId=287946">
</A>
--compass compile_on -- synopsys etc.</P>
<P CLASS="ComputerLabel">
<A NAME="pgfId=287270">
</A>
<B CLASS="Keyword">
port</B>
( myInput : <B CLASS="Keyword">
in</B>
Std_Logic := 'U';</P>
<P CLASS="ComputerLabel">
<A NAME="pgfId=287272">
</A>
myOutput : <B CLASS="Keyword">
out</B>
Std_Logic := 'U' );</P>
<P CLASS="ComputerLastLabel">
<A NAME="pgfId=287274">
</A>
<B CLASS="Keyword">
end</B>
halfgate_u;</P>
<P CLASS="ComputerLabel">
<A NAME="pgfId=287278">
</A>
<B CLASS="Keyword">
architecture</B>
halfgate_u <B CLASS="Keyword">
of</B>
halfgate_u <B CLASS="Keyword">
is</B>
</P>
<P CLASS="ComputerLabel">
<A NAME="pgfId=287280">
</A>
<B CLASS="Keyword">
component</B>
in01d0</P>
<P CLASS="ComputerLabel">
<A NAME="pgfId=287281">
</A>
<B CLASS="Keyword">
port</B>
( I : <B CLASS="Keyword">
in</B>
Std_Logic; ZN : <B CLASS="Keyword">
out</B>
Std_Logic ); <B CLASS="Keyword">
end</B>
<B CLASS="Keyword">
component</B>
;</P>
<P CLASS="ComputerLabel">
<A NAME="pgfId=287287">
</A>
<B CLASS="Keyword">
begin</B>
</P>
<P CLASS="ComputerLabel">
<A NAME="pgfId=287290">
</A>
u2: in01d0 <B CLASS="Keyword">
port</B>
<B CLASS="Keyword">
map</B>
( I => myInput, ZN => myOutput );</P>
<P CLASS="ComputerLastLabel">
<A NAME="pgfId=287293">
</A>
<B CLASS="Keyword">
end</B>
halfgate_u;</P>
<P CLASS="ComputerLabel">
<A NAME="pgfId=287296">
</A>
--compass compile_off -- synopsys etc.</P>
<P CLASS="ComputerLabel">
<A NAME="pgfId=287299">
</A>
<B CLASS="Keyword">
library</B>
cb60hd230d;</P>
<P CLASS="ComputerLabel">
<A NAME="pgfId=287301">
</A>
<B CLASS="Keyword">
configuration</B>
halfgate_u_CON <B CLASS="Keyword">
of</B>
halfgate_u <B CLASS="Keyword">
is</B>
</P>
<P CLASS="ComputerLabel">
<A NAME="pgfId=287302">
</A>
<B CLASS="Keyword">
for</B>
halfgate_u</P>
<P CLASS="ComputerLabel">
<A NAME="pgfId=287303">
</A>
<B CLASS="Keyword">
for</B>
u2 : in01d0 <B CLASS="Keyword">
use</B>
<B CLASS="Keyword">
configuration</B>
cb60hd230d.in01d0_CON</P>
<P CLASS="ComputerLabel">
<A NAME="pgfId=287305">
</A>
<B CLASS="Keyword">
generic</B>
<B CLASS="Keyword">
map</B>
( </P>
<P CLASS="ComputerLabel">
<A NAME="pgfId=292776">
</A>
ZN_cap => 0.0100 + myOutput_cap, </P>
<P CLASS="ComputerLabel">
<A NAME="pgfId=292777">
</A>
INSTANCE_NAME => INSTANCE_NAME&"/u2" )</P>
<P CLASS="ComputerLabel">
<A NAME="pgfId=287308">
</A>
<B CLASS="Keyword">
port</B>
<B CLASS="Keyword">
map</B>
( I => I, ZN => ZN);</P>
<P CLASS="ComputerLabel">
<A NAME="pgfId=287309">
</A>
<B CLASS="Keyword">
end</B>
<B CLASS="Keyword">
for</B>
;</P>
<P CLASS="ComputerLabel">
<A NAME="pgfId=287311">
</A>
<B CLASS="Keyword">
end</B>
<B CLASS="Keyword">
for</B>
;</P>
<P CLASS="ComputerLabel">
<A NAME="pgfId=287312">
</A>
<B CLASS="Keyword">
end</B>
halfgate_u_CON;</P>
<P CLASS="ComputerLastLabel">
<A NAME="pgfId=287313">
</A>
--compass compile_on -- synopsys etc.</P>
<P CLASS="BodyAfterHead">
<A NAME="pgfId=287224">
</A>
This gives a template to follow when hand instantiating logic cells. Instantiating a standard component requires the name of the component and its parameters:</P>
<P CLASS="ComputerFirst">
<A NAME="pgfId=287505">
</A>
<B CLASS="Keyword">
component</B>
ASDFF</P>
<P CLASS="Computer">
<A NAME="pgfId=287506">
</A>
<B CLASS="Keyword">
generic</B>
(WIDTH : POSITIVE := 1;</P>
<P CLASS="Computer">
<A NAME="pgfId=287507">
</A>
RESET_VALUE : STD_LOGIC_VECTOR := "0" );</P>
<P CLASS="Computer">
<A NAME="pgfId=287509">
</A>
<B CLASS="Keyword">
port</B>
(Q : <B CLASS="Keyword">
out</B>
STD_LOGIC_VECTOR (WIDTH-1 downto 0);</P>
<P CLASS="Computer">
<A NAME="pgfId=287510">
</A>
D : <B CLASS="Keyword">
in</B>
STD_LOGIC_VECTOR (WIDTH-1 downto 0);</P>
<P CLASS="Computer">
<A NAME="pgfId=287511">
</A>
CLK : <B CLASS="Keyword">
in</B>
STD_LOGIC;</P>
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?