📄 ch13.4.htm
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML EXPERIMENTAL 970324//EN">
<HTML>
<HEAD>
<META NAME="GENERATOR" CONTENT="Adobe FrameMaker 5.5/HTML Export Filter">
<TITLE> 13.4 How Logic Simulation Works</TITLE></HEAD><!--#include file="top.html"--><!--#include file="header.html"-->
<DIV>
<P>[ <A HREF="CH13.htm">Chapter start</A> ] [ <A HREF="CH13.3.htm">Previous page</A> ] [ <A HREF="CH13.5.htm">Next page</A> ]</P><!--#include file="AmazonAsic.html"--><HR></DIV>
<H1 CLASS="Heading1">
<A NAME="pgfId=2850">
</A>
13.4 <A NAME="20315">
</A>
How Logic Simulation Works</H1>
<P CLASS="BodyAfterHead">
<A NAME="pgfId=29399">
</A>
The most common type of digital simulator is an <A NAME="marker=2872">
</A>
<SPAN CLASS="Definition">
event-driven simulator</SPAN>
. When a circuit node changes in value the time, the node, and the new value are collectively known as an <A NAME="marker=2884">
</A>
<SPAN CLASS="Definition">
event</SPAN>
. The event is scheduled by putting it in an <A NAME="marker=2887">
</A>
<SPAN CLASS="Definition">
event queue</SPAN>
or <SPAN CLASS="Definition">
event list</SPAN>
<A NAME="marker=20759">
</A>
. When the specified time is reached, the logic value of the node is changed. The change affects logic cells that have this node as an input. All of the affected logic cells must be <SPAN CLASS="Definition">
evaluated</SPAN>
<A NAME="marker=20688">
</A>
, which may add more events to the event list. The simulator keeps track of the current time, the current <A NAME="marker=2915">
</A>
<SPAN CLASS="Definition">
time step</SPAN>
, and the event list that holds future events. For each circuit node the simulator keeps a record of the logic state and the strength of the source or sources driving the node. When a node changes logic state, whether as an input or as an output of a logic cell, this causes an event. </P>
<P CLASS="Body">
<A NAME="pgfId=67138">
</A>
An <A NAME="marker=67137">
</A>
<SPAN CLASS="Definition">
interpreted-code simulator</SPAN>
uses the HDL model as data, compiling an executable model as part of the simulator structure, and then executes the model. This type of simulator usually has a short compile time but a longer execution time compared to other types of simulator. An example is Verilog-XL. A <A NAME="marker=67139">
</A>
<SPAN CLASS="Definition">
compiled-code simulator</SPAN>
converts the HDL model to an intermediate form (usually C) and then uses a separate compiler to create executable binary code (an executable). This results in a longer compile time but shorter execution time than an interpreted-code simulator. A <A NAME="marker=67140">
</A>
<SPAN CLASS="Definition">
native-code simulator</SPAN>
converts the HDL directly to an executable and offers the shortest execution time.</P>
<P CLASS="Body">
<A NAME="pgfId=20770">
</A>
The logic cells for each of these types of event-driven simulator are modeled using a primitive modeling language (primitive in the sense of “fundamental”). There are no standards for this primitive modeling language. For example, the following code is a primitive model of a two-input NAND logic cell:</P>
<P CLASS="ComputerFirst">
<A NAME="pgfId=2927">
</A>
model nd01d1 (a, b, zn)</P>
<P CLASS="Computer">
<A NAME="pgfId=2929">
</A>
function (a, b) !(a & b); function end</P>
<P CLASS="ComputerLast">
<A NAME="pgfId=2935">
</A>
model end</P>
<P CLASS="Body">
<A NAME="pgfId=2939">
</A>
The model has three ports: <SPAN CLASS="BodyComputer">
a</SPAN>
,<SPAN CLASS="BodyComputer">
b</SPAN>
, and <SPAN CLASS="BodyComputer">
zn</SPAN>
. These ports are connected to nodes when a NAND gate is instantiated in an input structural netlist,</P>
<P CLASS="ComputerOneLine">
<A NAME="pgfId=2941">
</A>
nand nd01d1(a2, b3, r7)</P>
<P CLASS="Body">
<A NAME="pgfId=2945">
</A>
An event occurs when one of the circuit nodes <SPAN CLASS="BodyComputer">
a2</SPAN>
or <SPAN CLASS="BodyComputer">
b3</SPAN>
changes, and the function defined in the primitive model is called. For example, when <SPAN CLASS="BodyComputer">
a2</SPAN>
changes, it affects the port <SPAN CLASS="BodyComputer">
a</SPAN>
of the model. The function will be called to set <SPAN CLASS="BodyComputer">
zn </SPAN>
to the logical NAND of <SPAN CLASS="BodyComputer">
a</SPAN>
and <SPAN CLASS="BodyComputer">
b</SPAN>
. The implementation of the primitive functions is unique to each simulator and carefully coded to reduce execution time.</P>
<P CLASS="Body">
<A NAME="pgfId=2949">
</A>
The data associated with an event consists of the affected node, a new logic value for the node, a time for the change to take effect, and the node that caused the event. Written in C, the data structure for an event might look like the following:</P>
<P CLASS="ComputerFirst">
<A NAME="pgfId=2951">
</A>
struct Event {</P>
<P CLASS="Computer">
<A NAME="pgfId=2953">
</A>
event_ptr fwd_link, back_link; /* event list */</P>
<P CLASS="Computer">
<A NAME="pgfId=2955">
</A>
event_ptr node_link; /* list of node events */</P>
<P CLASS="Computer">
<A NAME="pgfId=2957">
</A>
node_ptr event_node; /* node for the event */</P>
<P CLASS="Computer">
<A NAME="pgfId=2959">
</A>
node_ptr cause; /* node causing event */</P>
<P CLASS="Computer">
<A NAME="pgfId=2961">
</A>
port_ptr port; /* port which caused this event */</P>
<P CLASS="Computer">
<A NAME="pgfId=2963">
</A>
long event_time; /* event time, in units of delta */</P>
<P CLASS="Computer">
<A NAME="pgfId=2967">
</A>
char new_value; /* new value: '1' '0' etc. */</P>
<P CLASS="ComputerLast">
<A NAME="pgfId=65122">
</A>
};</P>
<P CLASS="Body">
<A NAME="pgfId=65130">
</A>
The event list keeps track of logic cells whose outputs are changing and the new values for each output. The <SPAN CLASS="Definition">
evaluation list</SPAN>
<A NAME="marker=65131">
</A>
keeps track of logic cells whose inputs have changed. Using separate event and evaluation lists avoids any dependence on the order in which events are processed, since the evaluations occur only after all nodes have been updated. The sequence of event-list processing followed by the evaluation-list processing is called a <SPAN CLASS="Definition">
simulation cycle</SPAN>
<A NAME="marker=65171">
</A>
, or an <SPAN CLASS="Definition">
event–evaluation cycle</SPAN>
<A NAME="marker=65172">
</A>
(or event–eval cycle for short). </P>
<P CLASS="Body">
<A NAME="pgfId=20731">
</A>
Delays are tracked using a <SPAN CLASS="Definition">
time wheel</SPAN>
<A NAME="marker=20757">
</A>
divided into ticks or slots, with each slot representing a unit of time. A software pointer marks the current time on the timing wheel. As simulation progresses, the pointer moves forward by one slot for each time step. The event list tracks the events pending and, as the pointer moves, the simulator processes the event list for the current time. </P>
<DIV>
<H2 CLASS="Heading2">
<A NAME="pgfId=3007">
</A>
13.4.1 <A NAME="27867">
</A>
VHDL Simulation Cycle</H2>
<P CLASS="BodyAfterHead">
<A NAME="pgfId=11270">
</A>
We shall use VHDL as an example to illustrate the steps in a <A NAME="marker=85257">
</A>
<SPAN CLASS="Definition">
simulation cycle</SPAN>
(which is precisely defined in the LRM). In VHDL, before simulation begins, the design hierarchy is first <SPAN CLASS="Definition">
elaborated</SPAN>
<A NAME="marker=85256">
</A>
. This means all the pieces of the model code (entities, architectures, and configurations) are put together. Then the nets in the model are initialized just before simulation starts. The simulation cycle is then continuously repeated during which processes are executed and signals are updated. A VHDL simulation cycle consists of the following steps:</P>
<OL>
<LI CLASS="NumberFirst">
<A NAME="pgfId=11280">
</A>
The current time, <SPAN CLASS="EquationVariables">
t</SPAN>
<SUB CLASS="SubscriptVariable">
c</SUB>
is set equal to <SPAN CLASS="EquationVariables">
t</SPAN>
<SUB CLASS="SubscriptVariable">
n</SUB>
. </LI>
<LI CLASS="NumberList">
<A NAME="pgfId=11281">
</A>
Each active signal in the model is updated and events may occur as a result.</LI>
<LI CLASS="NumberList">
<A NAME="pgfId=31346">
</A>
For each process P, if P is currently sensitive to a signal S, and an event has occurred on signal S in this simulation cycle, then process P resumes.</LI>
<LI CLASS="NumberList">
<A NAME="pgfId=11284">
</A>
Each resumed process is executed until it suspends.</LI>
<LI CLASS="NumberList">
<A NAME="pgfId=11285">
</A>
The time of the next simulation cycle, <SPAN CLASS="EquationVariables">
t</SPAN>
<SUB CLASS="SubscriptVariable">
n</SUB>
, is set to the earliest of:</LI>
</OL>
<P CLASS="Body">
<A NAME="pgfId=11287">
</A>
a. the next time at which a driver becomes active or</P>
<P CLASS="Body">
<A NAME="pgfId=11288">
</A>
b. the next time at which a process resumes</P>
<OL>
<LI CLASS="NumberList">
<A NAME="pgfId=11289">
</A>
If <SPAN CLASS="EquationVariables">
t</SPAN>
<SUB CLASS="SubscriptVariable">
n</SUB>
= <SPAN CLASS="EquationVariables">
t</SPAN>
<SUB CLASS="SubscriptVariable">
c</SUB>
, then the next simulation cycle is a <SPAN CLASS="Definition">
delta cycle</SPAN>
<A NAME="marker=11315">
</A>
.</LI>
</OL>
<P CLASS="Body">
<A NAME="pgfId=31330">
</A>
Simulation is complete when we run out of time (<SPAN CLASS="EquationVariables">
t</SPAN>
<SUB CLASS="SubscriptVariable">
n</SUB>
= <SPAN CLASS="BodyComputer">
TIME'HIGH</SPAN>
<A NAME="marker=117686">
</A>
) and there are no active drivers or process resumptions at <SPAN CLASS="EquationVariables">
t</SPAN>
<SUB CLASS="SubscriptVariable">
n</SUB>
(there are some slight modifications to these rules involving <A NAME="marker=85258">
</A>
<A NAME="marker=117687">
</A>
postponed processes—which we rarely use in ASIC design).</P>
<P CLASS="Body">
<A NAME="pgfId=3013">
</A>
Time in an event-driven simulator has two dimensions. A <SPAN CLASS="Definition">
delta cycle</SPAN>
<A NAME="marker=85259">
</A>
takes <A NAME="marker=3009">
</A>
<SPAN CLASS="Definition">
delta time</SPAN>
, which does not result in a change in real time. Each event that occurs at the same <A NAME="marker=3012">
</A>
<SPAN CLASS="Definition">
time step</SPAN>
executes in delta time. Only when all events have been completed and signals updated does real time advance to the next time step.</P>
</DIV>
<DIV>
<H2 CLASS="Heading2">
<A NAME="pgfId=3017">
</A>
13.4.2 Delay</H2>
<P CLASS="BodyAfterHead">
<A NAME="pgfId=67934">
</A>
In VHDL you may assign a <SPAN CLASS="Definition">
delay mechanism</SPAN>
<A NAME="marker=85260">
</A>
to an assignment statement. <SPAN CLASS="Definition">
Transport delay</SPAN>
<A NAME="marker=67933">
</A>
is characteristic of wires and transmission lines that exhibit nearly infinite frequency response and will transmit any pulse, no matter how short. <SPAN CLASS="Definition">
Inertial delay</SPAN>
<A NAME="marker=67935">
</A>
more closely models the real behavior of logic cells. Typically, a logic cell will not transmit a pulse that is shorter than the switching time of the circuit, and this is the default <SPAN CLASS="Definition">
pulse-rejection limit</SPAN>
<A NAME="marker=67936">
</A>
. If we explicitly specify a pulse-rejection limit, the assignment will not transmit a pulse shorter than the limit. As an example, the following three assignments are equivalent to each other:</P>
<P CLASS="ComputerFirstLabel">
<A NAME="pgfId=11358">
</A>
Op <= Ip after 10 ns;</P>
<P CLASS="ComputerLabel">
<A NAME="pgfId=11359">
</A>
Op <= inertial Ip after 10 ns;</P>
<P CLASS="ComputerLastLabel">
<A NAME="pgfId=11360">
</A>
Op <= reject 10 ns inertial Ip after 10 ns;</P>
<P CLASS="Body">
<A NAME="pgfId=67913">
</A>
Every assignment that uses transport delay can be written using inertial delay with a pulse-rejection limit, as the following examples illustrate.</P>
<P CLASS="ComputerFirstLabel">
<A NAME="pgfId=11341">
</A>
-- Assignments using transport delay:</P>
<P CLASS="ComputerLabel">
<A NAME="pgfId=11366">
</A>
Op <= transport Ip after 10 ns;</P>
<P CLASS="ComputerLabel">
<A NAME="pgfId=11367">
</A>
Op <= transport Ip after 10 ns, not Ip after 20 ns;</P>
<P CLASS="ComputerLabel">
<A NAME="pgfId=11342">
</A>
-- Their equivalent assignments:</P>
<P CLASS="ComputerLabel">
<A NAME="pgfId=11368">
</A>
Op <= reject 0 ns inertial Ip after 10 ns;</P>
<P CLASS="ComputerLastLabel">
<A NAME="pgfId=11369">
</A>
Op <= reject 0 ns inertial Ip after 10 ns, not Ip after 10 ns;</P>
</DIV>
<HR><P>[ <A HREF="CH13.htm">Chapter start</A> ] [ <A HREF="CH13.3.htm">Previous page</A> ] [ <A HREF="CH13.5.htm">Next page</A> ]</P></BODY>
<!--#include file="Copyright.html"--><!--#include file="footer.html"-->
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -