Section 16.1

LRM-137

Change (changes in red and blue):

3) It provides a syntactic context that specifies execution scheduling in the Reactive region.

 

The program construct serves as a clear separator between design and testbench, and, more importantly, it specifies specialized execution semantics in the Reactive region for all elements declared within the program. Together with clocking domains blocks, the program construct provides for race-free interaction between the design and the testbench, and enables cycle and transaction level abstractions.

Section 16.4

LRM-137

Change (changes in red and blue):

To avoid the races inherent in the Verilog event scheduler, program statements are scheduled to execute in the Reactive region, after all clocks in the design have triggered and the design has settled to its steady state. Statements within a program block that are sensitive to changes (e.g., update events) in design signals (declared in modules, not program blocks) are scheduled in the Reactive region. Consider a program block that contains the statement @(clk) S1; where clk is a design signal in some module. Every transition of signal clk will cause the statement S1 to be scheduled into the Reactive region. Likewise, initial blocks within program blocks are scheduled in the Reactive region; in contrast, initial blocks in modules are scheduled in the Active region. In addition, design signals driven from within the program must be assigned using nonblocking assignments and are updated in the NBA region. Thus, even signals driven with no delay are propagated into the design as one event. With this behavior, correct cycle semantics can be modeled without races; thereby making program-based testbenches compatible with clocked assertions and formal tools.

 

Since the program executes schedules events in the Reactive region, the clocking domain block construct is very useful to automatically sample the steady-state values of previous time steps or clock cycles. Programs that read design values exclusively through clocking domain blocks with non-zero #0 input skews are insensitive to read-write races. It is important to note that simply sampling input signals (or setting non-zero #0 skews on clocking domain block inputs) does not eliminate the potential for races. Proper input sampling only addresses a single clocking domain block. With multiple clocks, the arbitrary order in which overlapping or simultaneous clocks are processed is still a potential source for races. The program construct addresses this issue by scheduling its execution in the Reactive region, after all design events have been processed, including clocks driven by nonblocking assignments.

Section 16.4.1

LRM-137

Change (changes in red and blue):

16.4.1 Zero-skew clocking domain block races

 

When a clocking domain block sets both input and output skews to #0 (see Section 15.3) then its inputs are sampled (in the observed region) at the same time as its outputs are driven (in the NBA region). This type of zero explicit #0-delay processing is a common source of non-determinism that can result in races. Nonetheless, even in this case, the program minimizes races by means of two mechanisms. First, by constraining program statements to execute be scheduled in the Reactive region, after all zero explicit #0-delay transitions have propagated through the design and the system has reached a quasi steady state. Second, by requiring design variables or nets to be modified only via nonblocking assignments. These two mechanisms reduce the likelihood of a race; nonetheless, a race is still possible when skews are set to zero explicit #0.

Section 16.5

LRM-137

Change (changes in red and blue):

Calling program tasks or functions from within design modules is illegal and shall result in an error. This is because the design must not be aware of the testbench. Programs are allowed to call tasks or functions in other programs or within design modules. Functions within design modules can be called from a program, and require no special handling. However, blocking tasks (a task that does not execute in 0 simulation time) within design modules that are called from a program do require explicit synchronization upon return from the task. That is, when blocking tasks return to the program code, the program block execution is automatically postponed until the Reactive region. The copy out of the parameters happens when the task returns.