The most common type of digital simulator is an event-driven simulator . When a circuit node changes in value the time, the node, and the new value are collectively known as an event . The event is scheduled by putting it in an event queue or event list . 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 evaluated , which may add more events to the event list. The simulator keeps track of the current time, the current time step , 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.
An interpreted-code simulator 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 compiled-code simulator 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 native-code simulator converts the HDL directly to an executable and offers the shortest execution time.
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:
An event occurs when one of the circuit nodes a2 or b3 changes, and the function defined in the primitive model is called. For example, when a2 changes, it affects the port a of the model. The function will be called to set zn to the logical NAND of a and b . The implementation of the primitive functions is unique to each simulator and carefully coded to reduce execution time.
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:
The event list keeps track of logic cells whose outputs are changing and the new values for each output. The evaluation list 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 simulation cycle , or an event–evaluation cycle (or event–eval cycle for short).
Delays are tracked using a time wheel 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.
We shall use VHDL as an example to illustrate the steps in a simulation cycle (which is precisely defined in the LRM). In VHDL, before simulation begins, the design hierarchy is first elaborated . 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:
- The current time, t c is set equal to t n .
- Each active signal in the model is updated and events may occur as a result.
- 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.
- Each resumed process is executed until it suspends.
- The time of the next simulation cycle, t n , is set to the earliest of:
Simulation is complete when we run out of time ( t n = TIME'HIGH ) and there are no active drivers or process resumptions at t n (there are some slight modifications to these rules involving postponed processes—which we rarely use in ASIC design).
Time in an event-driven simulator has two dimensions. A delta cycle takes delta time , which does not result in a change in real time. Each event that occurs at the same time step executes in delta time. Only when all events have been completed and signals updated does real time advance to the next time step.
In VHDL you may assign a delay mechanism to an assignment statement. Transport delay is characteristic of wires and transmission lines that exhibit nearly infinite frequency response and will transmit any pulse, no matter how short. Inertial delay 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 pulse-rejection limit . 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: