An interface
can specify the signals or nets through which a testbench test-bench communicates with a device under test. However, an interface does
not explicitly specify any timing disciplines, synchronization requirements, or
clocking paradigms.
SystemVerilog adds the clocking
construct that identifies clock signals,
and captures the timing and synchronization requirements of the blocks being
modeled. A clocking domain assembles signals that are synchronous to a
particular clock, and makes their timing explicit. The clocking domain is a key
element in a cycle-based methodology, which enables users to write testbenches test-benches 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 test-bench may
contain one or more clocking domains, each containing its own clock plus an
arbitrary number of signals.
The clocking domain
separates the timing and synchronization details from the structural,
functional, and procedural elements of a testbench test-bench. Thus, the timing for sampling and driving clocking
domain signals is implicit and relative to the clocking-domain’s clock. This
enables a set of key operations to be written very succinctly, without
explicitly using clocks or specifying timing. These operations are:
The clocking_event designates a particular event
to act as the clock for the clocking domain. 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 are
governed by the clocking event. All input or inout signals specified in the clocking domain
are sampled when the corresponding clock event occurs. Likewise, all output or inout signals in
the clocking domain are driven when the corresponding clock event occurs. Bi-directional Bidirectional signals (inout)
are sampled as well as driven.
The skew parameters 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).
Unless otherwise specified,
the default input skew is 1step and the default output skew is 0. A step is a special time unit whose value is defined in
Section 18.6. 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 time advances at
read-only-synchronize immediately before time advanced to the clock event). Unlike other time units, which represent physical
units, a step cannot be used to set or modify either the precision or the timeunit.
Any signal in a clocking
domain can be associated with an arbitrary hierarchical expression. As
described in section 15.2 above, a hierarchical expression is introduced by appending
an equal sign (=)
followed by the hierarchical expression:
15.7
Multiple clocking domains example
The test module program can be instantiated and connected to a device
under test (cpu and mem).
program test( input phi1, input [15:0] data, output logic write,
input phi2, inout [8:1] cmd, input enable
);
reg [8:1] cmd_reg;
clocking cd1 @(posedge phi1);
input data;
output write;
input state = top.cpu.state;
endclocking
clocking cd2 @(posedge phi2);
input #2 output
#4ps cmd;
input enable;
endclocking
initial
begin
// program begins here
...
// user can access cd1.data ,
cd2.cmd , etc…
end
assign cmd = enable ? cmd_reg: 'x;
endprogram
module
top;
logic
phi1, phi2;
wire [8:1] cmd; // cannot be
logic (two bidir drivers)
logic [15:0] data;
test main( phi1, data,
write, phi2, cmd, enable );
cpu cpu1(
phi1, data, write );
mem mem1(
phi2, cmd, enable );
endmodule
A clocking encapsulates a set of signals that share a common clock, therefore, specifying a clocking domain 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
within the testbench test-bench are with respect to the testbench
test-bench, and not the design under test, a modport
declaration can appropriately
describe either direction. A testbench test-bench program can be contained within a program, and
its ports can be interfaces that correspond to the signals declared in each clocking
domain. The interface’s wires will have the same direction as specified in the
clocking domain when viewed from the testbench test-bench side (i.e., modport
test), and reversed when viewed
from the device under test (i.e., modport
dut).
interface
bus_A (input
clk);
logic wire [15:0]
data;
logic wire write;
modport
test (input data, output
write);
modport
dut (output
data, input write);
endinterface
interface
bus_B (input
clk);
logic wire [8:1] cmd;
logic wire enable;
modport
test (input enable);
modport
dut (output
enable);
endinterface
Alternatively, in the program test above, the clocking domain can
be written using both interfaces and hierarchical expressions as:
A default clocking is valid
only within the scope containing the default clocking specification. This scope
includes the module, interface, or program that contains the declaration as
well as any nested modules or interfaces. It does not include other instantiated modules or interfaces.
Example
2. Assigning an existing clocking
to be the default:
clocking busA @(posedge clk1); ... endclocking
clocking busB @(negedge clk2); ... endclocking
module
processor ...
clocking busA @(posedge clk1); ... endclocking
clocking busB @(negedge clk2); ... endclocking
module
cpu( interface
y )
default
clocking busA ;
initial
begin
## 5; // use busA =>
(posedge clk1)
...
end
endmodule
endmodule
Swap Section 15.12 and 15.13
bus.data[3:0] <= 4’h5; // drive data in current cycle
##1 bus.data
<= 8’hz; //
wait 1 (bus) cycle and then drive data
##2; bus.data
<= 2; // wait 2 default clocking
cycles, then drive data
bus.data <= ##2 r; // sample remember the value of r, and then drive
// data 2 (bus) cycles later
When more than one
synchronous drive is applied to the same clocking domain output
(or inout) at the same simulation time, the driven values are
checked for conflicts. When conflicting drives are detected a runtime runt-ime error
is issued, and each conflicting bit is driven to X (or 0 for a 2-state port).
Clock-domain outputs
driving a net (i.e. through different ports) cause the net to be driven to its
resolved signal value. When a clock-domain 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 clock-domain that is
updated as a nonblocking non-blocking assignment.