03 · Program, clocking, and scheduler regions
Race freedom comes from explicit sampling and driving contracts.
Program blocks and clocking blocks were designed to separate testbench activity from RTL updates. Modern environments still need to understand the event regions even when they use interfaces, classes, and UVM instead.
One simulation time slot
Observe first, update deliberately
- →
- →
- →
- 01Preponedsample
Concurrent assertions capture values before current-slot design updates.
- 02Active / Inactiveblocking / #0
Design evaluation and zero-delay rescheduling; order within a region can race.
- 03NBAcommit
Deferred nonblocking LHS updates apply.
- 04Observed / Reactivecheck / react
Assertions evaluate and program/testbench reactions can follow stabilized design state.
Concurrent assertions capture values before current-slot design updates.
- #0
- Inactive
- It runs before NBA and is not a substitute for nonblocking assignment.
- Program
- Reactive domain
- Useful historical construct, but uncommon in current UVM architectures.
- Completion
- Explicit
- A program does not automatically solve end-of-test coordination.
Source order is not a synchronization primitive. The event region and edge-relative skew are the actual temporal contract.
Observe
Trace each read and write through Preponed, Active, Inactive, NBA, Observed, Reactive, and postponed behavior at the same simulation time.
Decide
Put RTL in design regions, assertions in their sampling/reactive flow, and testbench access behind a clocking or synchronization boundary.
Failure
Two blocks that read and write the same signal in the Active region can race even when source order looks deterministic.
Prove
Use sampled-value functions, scheduler-aware assertions, randomized compilation order, and tests that drive exactly on a clock edge.
Program blocks are one tool, not a magic partition
A program executes testbench activity in Reactive regions after design and assertion work for the slot. It restricts some design constructs and was intended to reduce DUT/testbench races. Modern UVM usually uses modules, interfaces, clocking blocks, and explicit objections instead.
- A program may instantiate classes and call tasks, but should not be used to model synthesizable hardware.
- Reactive scheduling does not fix two testbench threads racing with each other.
- End-of-simulation still needs an explicit completion protocol.
- Use one disciplined interface boundary rather than mixing direct signal access and clocking-block access.
Clocking blocks define sampling and drive skew
A clocking block names a clocking event and direction for each signal. Input skew chooses when values are sampled relative to the event; output skew chooses when drives occur. Assignments to clocking outputs follow clocking-drive semantics, so a universal rule such as “always use =” is incomplete.
interface bus_if(input logic clk);
logic valid, ready;
logic [31:0] data;
clocking drv_cb @(posedge clk);
default input #1step output #0;
input ready;
output valid, data;
endclocking
clocking mon_cb @(posedge clk);
default input #1step;
input valid, ready, data;
endclocking
endinterfaceExplain it out loud
Interview reasoning checkpoints
No. They schedule program activity in Reactive regions relative to design activity, but they do not resolve races among testbench threads or replace a clear clocking, ownership, and completion protocol.
- Identify which competing operations live in which regions.
- Separate DUT-versus-testbench races from testbench-versus-testbench races.
- Use clocking blocks and explicit synchronization for the remaining boundaries.
A nuanced answer acknowledges the feature without presenting it as the modern UVM default.
Claiming program automatically makes any testbench deterministic.
It defines a named edge-relative sampling and driving contract, including input and output skew, so monitors and drivers do not depend on same-region execution order.
- Choose the clocking event.
- Set input sampling before or at the edge as the protocol requires.
- Set output drive timing and access signals only through that contract.
Look for sampling versus driving skew and the reason it removes ambiguity.
Treating a clocking block as only a namespace for interface signals.
