The elements that make up the SystemVerilog language can be used to describe electronic hardware’s behavior at varying levels of abstraction. SystemVerilog is a parallel programming language and the SystemVerilog Event Scheduler plays a vital role in it. The execution of certain language constructs is defined by the parallel execution of blocks or processes. It is important to understand what execution order is guaranteed to the user and what execution order is indeterminate. Although SystemVerilog is used for more than simulation, the semantics of the language is defined for simulation, and everything else is abstracted from.
Event Driven Simulation
The SystemVerilog language is defined in terms of a discrete event execution model. A SystemVerilog description consists of connected threads of execution or processes. Processes are objects that can be evaluated, have a state, and respond to changes in their inputs to produce outputs. Processes are concurrently scheduled elements, such as initial procedures. Examples of processes include, but are not limited to, primitives; initial, always, always_comb, always_latch, and always_ff procedures; continuous assignments; asynchronous tasks; and procedural assignment statements.
Every change in the state of a net or variable in the system description being simulated is considered an update event. Processes are sensitive to update events. When an update event is executed, all the processes that are sensitive to that event are considered for evaluation in an arbitrary order. The evaluation of a process is also an event, known as an evaluation event.
In addition to events, another key aspect of a simulator is time. The term simulation time is used to refer to the time value maintained by the simulator to model the actual time it would take for the system description to be simulated. The term time is used interchangeably with simulation time.
To fully support clear and predictable interactions, a single time slot is divided into multiple regions where events can be scheduled to order a particular type of execution. This allows properties and checkers to sample data when the design under test is in a stable state. Property expressions can be safely evaluated, and testbenches can react to both properties and checkers with zero delay, all in a predictable manner. This same mechanism also allows for nonzero delays in the design, clock propagation, and/or stimulus and response code to be mixed freely and consistently with cycle-accurate descriptions.
Stratified Event Scheduler
A compliant SystemVerilog simulator shall maintain some form of data structure, such as the SystemVerilog Event Scheduler, that allows events to be dynamically scheduled, executed, and removed as the simulator advances through time. The data structure is normally implemented as a time-ordered set of linked lists, which are divided and subdivided in a well-defined manner. The first division is by time. Every event has one and only one simulation execution time, which at any given point during the simulation can be the current time or some future time. All scheduled events at a specific time define a time slot. Simulation proceeds by executing and removing all events in the current simulation time slot before moving on to the next nonempty time slot, in time order. This procedure guarantees that the simulator never goes backward in time.
A time slot is divided into a set of ordered regions, as follows:
There are two important groupings of event regions that are used to help define the scheduling of SystemVerilog activity, the active region set, and the reactive region set. Events scheduled in the Active, Inactive, Pre-NBA, NBA, and Post-NBA regions are active region set events. Events scheduled in the Reactive, Re-Inactive, Pre- Re-NBA, Re-NBA, and Post-Re-NBA regions are reactive region set events.
The simulation regions of a time slot are the Preponed, Active, Inactive, NBA, Observed, Reactive, Re-Inactive, Re-NBA, and Postponed regions.
In addition to the simulation regions, where PLI callbacks can be scheduled, there are additional PLI-specific regions. The PLI regions of a time slot are the Preponed, Pre-Active, Pre-NBA, Post-NBA, Pre-Observed, Post-Observed, Pre-Re-NBA, Post-Re-NBA, and Pre-Postponed regions.
In this paper, we will discuss Simulation regions. To make sure there is no race between testbench & RTL, they both will work in different regions.
Regions that are designed to implement correct RTL functionality:
Active regions (Active, Inactive, and NBA regions – but avoid Inactive region events).
Regions that are designed to implement correct verification execution:
Preponed, Reactive regions (Reactive, Re-Inactive, Re-NBA), and Postponed regions.
Regions that are designed to implement concurrent assertion checking:
Preponed, Observed, and Reactive regions.
Region that should be avoided:
Preponed Region: Preponed region is for the verification environment. The assertion signals and the clocking block inputs with #1step delay are sampled in this region. Sampling in the Preponed region is equivalent to sampling in the previously postponed region.
Active Region: The Active region holds the current active region set events being evaluated and can be processed in any order. The events are,
- All the blocking assignments in the module block.
- Evaluate the Right-Hand-Side (RHS) of all nonblocking assignments in the module block and schedule updates into the NBA region.
- All module continuous assignments in the module block.
- Evaluate inputs and update outputs of Verilog primitives.
- Execute the $display and $finish commands.
Inactive Region: This region is where #0 blocking assignments in the module block are scheduled. It is not recommended to make #0 assignments in RTL.
NBA Region: In this region, the Left- Hand-side variables of non-blocking assignment statements in the module block get updated.
Observed Region: The concurrent assertions are evaluated in this region. Also, clocking block inputs with explicit #0 step delay are sampled in the Observed region.
Reactive Region: The following events take place in this region,
- Action blocks of the concurrent assertions.
- Blocking assignments in the program block.
- Evaluate the Right-Hand-Side (RHS) of all program nonblocking assignments in the program block and schedule updates into the Re-NBA region.
- All continuous assignments in the program block.
- Execute the $exit and implicit $exit commands.
Re-Inactive Region: #0 delays in the program block are executed in this region.
Re-NBA Region: In this region, the Left- Hand-side variables of non-blocking assignment statements in the program block get updated. Also, clocking block outputs with explicit #0 skew shall be driven at the same time as their specified clocking event, in the Re-NBA region.
Postponed Region: $monitor and $strobe are scheduled in the Postponed region.
Also read: How do I learn SystemVerilog in a week?
Due to the concurrent nature of Verilog and SystemVerilog language, multiple processes will be working at the same time. This may result in race conditions. The design and verification code should work in different regions to avoid race operation between the DUT & TB. Also, the SystemVerilog assertions should sample DUT data when the design is in a stable state so that the assertions can be safely evaluated. The SystemVerilog event scheduler will make sure there is proper interaction between different processes within the RTL, between the RTL & TB, and between RTL & assertions.
To learn SystemVerilog in detail, please explore our Advanced ASIC Verification Course