Section 15

LRM-137

Change (changes in red and blue):

Section 15

Clocking Domains Blocks

Section 15.1

LRM-137

Change (changes in red and blue):

SystemVerilog adds the clocking construct block that identifies clock signals, and captures the timing and synchronization requirements of the blocks being modeled. A clocking domain block assembles signals that are synchronous to a particular clock, and makes their timing explicit. The clocking domain block is a key element in a cycle-based methodology, which enables users to write testbenches at a higher level of abstraction. Rather than focusing on signals and transitions in time, the test can be defined in terms of cycles and transactions. Depending on the environment, a testbench can contain one or more clocking domains blocks, each containing its own clock plus an arbitrary number of signals.

 

The clocking domain block separates the timing and synchronization details from the structural, functional, and procedural elements of a testbench. Thus, the timing for sampling and driving clocking domain block signals is implicit and relative to the clocking domain block’s clock. This enables a set of key operations to be written very succinctly, without explicitly using clocks or specifying timing. These operations are:

Section 15.2

LRM-137

Change (changes in red and blue):

15.2 Clocking domain block declaration

 

The syntax for the clocking construct block is:

LRM-137

Change (changes in red and blue):

The clocking_identifier specifies the name of the clocking domain block being declared.

 

The signal_identfier identifies a signal in the scope enclosing the clocking domain block declaration, and declares the name of a signal in the clocking domain block. Unless a hierarchical_expression is used, both the signal and the clocking_item names shall be the same.

 

The clocking_event designates a particular event to act as the clock for the clocking domain block. Typically, this expression is either the posedge or negedge of a clocking signal. The timing of all the other signals specified in a given clocking domain block are is governed by the clocking event. All input or inout signals specified in the clocking domain block are sampled when the corresponding clock event occurs. Likewise, all output or inout signals in the clocking domain block are driven when the corresponding clock event occurs. Bidirectional signals (inout) are sampled as well as driven.

 

The clocking_skew determines how many time units away from the clock event a signal is to be sampled or driven. Input skews are implicitly negative, that is, they always refer to a time before the clock, whereas output skews always refer to a time after the clock (see Section 15.3). When the clocking event specifies a simple edge, instead of a number, the skew can be specified as the opposite specific edge of the signal. A single skew can be specified for the entire domain block by using a default clocking item.

 

clocking ck1 (posedge clk);

default input #1step output negedge; // legal

// outputs driven on the negedge clk

input  ... ;

output ... ;

endclocking

 

clocking ck2 (clk); // no edge specified!

default input #1step output negedge; // legal

input  ... ;

output ... ;

endclocking

 

The hierarchical_identifier specifies that, instead of a local port, the signal to be associated with the clocking domain block is specified by its hierarchical name (cross-module reference).

LRM-137

Change (changes in red and blue):

In the above example, the first line declares a clocking domain block called bus that is to be clocked on the positive edge of the signal clock1. The second line specifies that by default all signals in the domain shall use a 10ns input skew and a 2ns output skew. The next line adds three input signals to the domain: data, ready, and enable; the last signal refers to the hierarchical signal top.mem1.enable. The fourth line adds the signal ack to the domain, and overrides the default output skew so that ack is driven on the negative edge of the clock. The last line adds the signal addr and overrides the default input skew so that addr is sampled one step before the positive edge of the clock.

 

Unless otherwise specified, the default input skew is 1step and the default output skew is 0 (in the NBA region). A step is a special time unit whose value is defined in Section 18.9. A 1step input skew allows input signals to sample their steady-state values in the time step immediately before the clock event (i.e., in the preceding Postponed region). Unlike other time units, which represent physical units, a step cannot be used to set or modify either the precision or the timeunit.

Section 15.3

LRM-137

Change (changes in red and blue):

An input skew of #0 forces a skew of zero. Inputs with zero explicit #0 skew are sampled at the same time as their corresponding clocking event, but to avoid races, they are sampled in the Observed region. Likewise, clocking block outputs with zero no skew (or explicit #0 skew) are driven at the same time as their specified clocking event, as nonblocking assignments (in the NBA region).

 

Skews are declarative constructs, thus, they are semantically very different from the syntactically similar procedural delay statement. In particular, an explicit #0 skew, does not suspend any process nor does it execute or sample values in the Inactive region.

Section 15.4

LRM-137

Change (changes in red and blue):

Any signal in a clocking domain block can be associated with an arbitrary hierarchical expression. As described in Section 15.2, a hierarchical expression is introduced by appending an equal sign (=) followed by the hierarchical expression:

Section 15.5

LRM-137

Change (changes in red and blue):

15.5 Signals in multiple clocking domains blocks

 

The same signals—clock, inputs, inouts, or outputs—can appear in more than one domain block. Clocking domains blocks that use the same clock (or clocking expression) shall share the same synchronization event, in the same manner as several latches can be controlled by the same clock. Input semantics are described in Section 15.12, and output semantics are described in Section 15.14.

Section 15.6

LRM-137

Change (changes in red and blue):

A clocking construct block is both a declaration and an instance of that declaration. A separate instantiation step is not necessary. Instead, one copy is created for each instance of the block containing the declaration (like an always block). Once declared, the clocking signals are available via the clocking-domain block name and the dot (.) operator:

 

dom.sig // signal sig in clocking dom

 

Clocking domains blocks cannot be nested. They cannot be declared inside functions, tasks, packages, or outside all declarations in a compilation unit. Clocking domains blocks can only be declared inside a module, interface or program (see Section 16).

 

Clocking domains blocks have static lifetime and scope local to their enclosing module, interface or program.

Section 15.7

LRM-137

Change (changes in red and blue):

15.7 Multiple clocking domains blocks example

 

In this example, a simple test program includes two clocking domains blocks. The program construct used in this example is discussed in Section 16.

Section 15.8

LRM-137

Change (changes in red and blue):

15.8 Interfaces and clocking domains blocks

 

A clocking encapsulates a set of signals that share a common clock, therefore, specifying a clocking domain block using a SystemVerilog interface can significantly reduce the amount of code needed to connect the testbench. Furthermore, since the signal directions in the clocking domain block within the testbench are with respect to the testbench, and not the design under test, a modport declaration can appropriately describe either direction. A testbench program can be contained within a program and its ports can be interfaces that correspond to the signals declared in each clocking domain block. The interface’s wires shall have the same direction as specified in the clocking domain block when viewed from the testbench side (i.e., modport test), and reversed when viewed from the device under test (i.e., modport dut).

LRM-137

Change (changes in red and blue):

Alternatively, in the program test above, the clocking domain block can be written using both interfaces and hierarchical expressions as:

Section 15.9

LRM-137

Change (changes in red and blue):

15.9 Clocking domain block events

 

The clocking event of a clocking domain block is available directly by using the clocking domain block name, regardless of the actual clocking event used to declare the clocking domain block.

Section 15.10

LRM-139

Change Syntax 15-2 (changes in red and blue):

cycle_delay_range ::=                                                                                         // from Annex A.2.10

  ## constant_expression

| ## [ cycle_delay_const_range_expression ]

cycle_delay_const_range_expression ::=

  constant_expression : constant_expression

| constant_expression : $

procedural_timing_control_statement ::=                                                        // from Annex A.6.5

procedural_timing_control statement_or_null

procedural_timing_control ::=

| cycle_delay

 

cycle_delay ::= ## expression                                                                            // from Annex A.6.11

LRM-139

Change (changes in red and blue):

The constant_expression expression can be any SystemVerilog expression that evaluates to a positive integer value.

Section 15.11

LRM-137

Change (changes in red and blue):

The clocking_identifier must be the name of a clocking domain block.

Section 15.12

LRM-137

Change (changes in red and blue):

All clocking domain block inputs (input or inout) are sampled at the corresponding clocking event. If the input skew is non-zero not an explicit #0, then the value sampled corresponds to the signal value at the Postponed region of the time step skew time-units prior to the clocking event (see Figure 15-1 in Section 15.3). If the input skew is zero an explicit #0, then the value sampled corresponds to the signal value in the Observed region.

 

Samples happen immediately (the calling process does not block). When a signal appears in an expression, it is replaced by the signal’s sampled value, that is, the value that was sampled at the last sampling point.

 

When the same signal is an input to multiple clocking domain blocks, the semantics are straightforward; each clocking domain block samples the corresponding signal with its own clocking event.

Section 15.13

LRM-137

Change (changes in red and blue):

The expression used with the event control can denote clocking-domain block input (input or inout), or a slice thereof. Slices can include dynamic indices, which are evaluated once, when the @ expression executes.

Section 15.14

LRM-137

Change (changes in red and blue):

Clocking domain block outputs (output or inout) are used to drive values onto their corresponding signals, but at a specified time. That is, the corresponding signal changes value at the indicated clocking event as modified by the output skew.

LRM-137

Change (changes in red and blue):

The clockvar_expression is either a bit-select, slice, or the entire clocking domain block output whose corresponding signal is to be driven (concatenation is not allowed):

LRM-137

Change (changes in red and blue):

The event_count is an integral expression that optionally specifies the number of clocking events (i.e. cycles) that must pass before the statement executes. Specifying a non-zero event_count blocks the current process until the specified number of clocking events have elapsed, otherwise the statement executes at the current time. The event_count uses syntax similar to the cycle-delay operator (see Section 15.10), however, the synchronous drive uses the clocking domain block of the signal being driven and not the default clocking.

LRM-137

Change (changes in red and blue):

bus.data[3:0] <= 4’h5; // drive data in the NBA region of the current cycle

Section 15.14.1

LRM-137

Change (changes in red and blue):

A key feature of inout clocking domain block variables and synchronous drives is that a drive does not change the clock domain input. This is because reading the input always yields the last sampled value, and not the driven value.

Section 15.14.2

LRM-137

Change (changes in red and blue):

When more than one synchronous drive is applied to the same clocking domain block output (or inout) at the same simulation time, the driven values are checked for conflicts. When conflicting drives are detected a runtime error is issued, and each conflicting bit is driven to X (or 0 for a 2-state port).

LRM-137

Change (changes in red and blue):

When the same variable is an output from multiple clocking domain blocks, the last drive determines the value of the variable. This allows a single module to model multi-rate devices, such as a DDR memory, using a different clocking domain block to model each active edge. For example:

LRM-137

Change (changes in red and blue):

The variable j is an output to two clocking domain blocks using different clocking events (posedge vs. negedge). When driven, the variable j shall take on the value most recently assigned by either clocking domain block.

 

Clocking- domain block outputs driving a net (i.e. through different ports) cause the net to be driven to its resolved signal value. When a Clocking- domain block output corresponds to a wire, a driver for that wire is created that is updated as if by a continuous assignment from a register inside the Clocking- domain block that is updated as a nonblocking assignment.