CLOCKING BLOCKS
SV for Verification
Topics Covered
Introduction
Syntax
Input & Output Skews
Hierarchical Expressions
Signals in Multiple Clocking Blocks
Clocking Block Scope & Lifetime
Multiple Clocking Blocks Example
Interfaces & Clocking Blocks
Topics Covered
Clocking Block Events
Cycle Delay : ##
Default Clocking
Input Sampling
Synchronous Events
Synchronous Drives
Drives & Nonblocking Assignments
Drive Value Resolution
INTRODUCTION
• SV adds clocking block that
- Identifies clock signals
- Captures timing and synchronization requirements of blocks being modified
- Assembles signals that are synchronous to a particular clock, and make them timing
explicit
• A testbench can contain one or more clocking blocks, each containing its own
clock plus an arbitrary number of signals.
• A clocking block separated timing and synchronization details from structural,
functional, and procedural elements of a testbench.
INTRODUCTION
• Timing for sampling and driving clocking block signals is implicit and
relative to the clocking block’s clock.
• This enables a set of key operations :
- Synchronous events
- Input sampling
- Synchronous drives
to be written without explicitly using clocks or specifying timing.
SYNTAX
[default] clocking [clocking_identifier] clocking_event;
{clocking_item} @identifier |
Name of clocking block
endclocking
@event_expression
default default_skew;
clocking_direction edge_identifier [delay_control]
list_of_clocking_decl_assign or
delay_control #delay_value
input [clocking_skew] or
output [clocking_skew] or
input [clocking_skew] output [clocking_skew] posedge or negedge
SYNTAX -
-
-
Acts as clock for clocking block.
Governs the timing of all signals specified in the clocking block
All input/inout signals in the clocking block are sampled when corresponding
clocking event occurs.
- All output/inout signals in the clocking block are driven when corresponding
clocking ck1 @(posedge clk); clocking event occurs.
default input #1step output negedge;
input …;
Skew can be specified as specific edge of the signals
output …;
endclocking
clocking ck2 @(clk);
default input #1step output negedge;
- Determines how many units away from the
clock event a signal is to be sampled/driven.
input …;
- Input skew refers to a time before clock
output …;
event when a signal is to be sampled.
endclocking
- Output skew refers to a time after clock
event when a signal is to be driven.
SYNTAX
Default input and output skew
clocking bus @(posedge clock1);
default input #10ns output #2ns;
input data, ready, enable = [Link];
output negedge ack;
Instead of local port, hierarchical name(cross-
input #1step addr; module reference) is associated with the clocking
block
endclocking
Overrides default output skew
Overrides default input skew
SYNTAX
• Default values of skews:
- Input skew : 1step
- Output skew: 0
• A step is a special time unit.
1step input skew allows input signals to sample their steady values in
the time step immediately before clock event (i.e., in the preceding
Postponed region).
INPUT & OUTPUT SKEWS
Signal sampled here Signal driven here
clock
Input skew
Output skew
INPUT & OUTPUT SKEWS
• Skew must be a constant expression.
• Skew can be specified as a parameter.
• If skew does not specify a time unit, current time unit is used.
clocking dram @(clk);
input #1ps address;
input #5 output #6 data;
endclocking
INPUT & OUTPUT SKEWS
• Input with explicit #0 skew are sampled at the same time as their
corresponding clocking event.
• To avoid races, they are sampled in Observed region.
• Clocking block output with no skew(or explicit #0 skew) are driven at
the same time as their specified clocking event, as non-blocking
assignments (in the NBA region).
HIERARCHICAL EXPRESSIONS
clocking cd1 @(posedge phi1);
input #1step state = [Link];
endclocking
clocking mem @(clock);
input instruction = {opcode, regA, regB[3:1]};
endclocking
SIGNALS IN MULTIPLE CLOCKING
BLOCKS
• Same signals
- Clock
- Inputs
- Inouts
- Outputs
can appear in more than one clocking block.
CLOCKING BLOCK SCOPE &
LIFETIME
• A clocking block is both a declaration and an instance of that declaration.
• No separate instantiation step is necessary.
• One copy is created for each instance of the block containing the declaration.
• Clocking signals are available via clocking block name and the dot(.)
respectively.
[Link] // signal sig in clocking dom
CLOCKING BLOCK SCOPE &
LIFETIME
• Clocking blocks cannot be nested.
• Clocking blocks CANNOT be declared inside functions, tasks, packages, or
outside all declarations in a compilation unit.
• Clocking blocks CAN ONLY be declared inside a module, interface or program.
• Clocking blocks have static lifetime and scope local to their enclosing module,
interface or program.
MULTIPLE CLOCKING BLOCKS
EXAMPLE
program test(input ph1, input [15:0] data, output initial begin
logic write, input phi2, inout [8:1] cmd, input
// program begins here
enable);
…
// user can access [Link], [Link], etc…
reg [8:1] cmd_reg;
end
assign cmd = enable ? cmd_reg : ‘x;
clocking cd1 @(posedge phi1);
endprogram
input data;
output write;
module top;
input state = [Link];
logic phi1, phi2;
endclocking wire [8:1] cmd;
logic [15:0] data;
clocking cd2 @(posedge phi2)l test main(phi1, data, write, phi2, cmd, enable);
input #2 output #4ps cmd; cpu cpu1(phi1, data, write);
input enable; mem mem1(phi2, cmd, enable);
endclocking endmodule
INTERFACES & CLOCKING
BLOCKS
• Clocking block encapsulates a set of signals that share a common
clock.
• Specifying a clocking block using SV interface reduces amount of code
needed to connect testbench.
• Signal directions in clocking block within testbench are w.r.t the
testbench and not DUT.
- modport declaration can appropriately describe either direction.
INTERFACES & CLOCKING
BLOCKS
interface bus_A(input clk); program test(bus_A.test a, bus_B.test b);
logic [15:0] data; clocking cd1 @(posedge [Link]);
logic write; input [Link];
output [Link];
modport test(input data, output write);
inout state = [Link];
modport dut(output data, input write);
endclocking
endinterface
clocking cd2 @(posedge [Link]);
interface bus_B(input clk);
input #2 output #4ps [Link];
logic [8:1] cmd;
input [Link];
logic enable; endclocking
modport test(input enable); endprogram
modport dut(output enable);
endinterface initial begin … end
INTERFACES & CLOCKING
BLOCKS
interface bus_A(input clk); program test(bus_A.test a, bus_B.test b);
logic [15:0] data; clocking cd1 @(posedge [Link]);
logic write; input data = [Link];
output write = [Link];
modport test(input data, output write);
inout state = [Link];
modport dut(output data, input write); Can now be
endclocking refrerenced with
endinterface shorter names
([Link]) instead
of
clocking cd2 @(posedge [Link]); [Link]
interface bus_B(input clk);
input #2 output #4ps [Link];
logic [8:1] cmd;
input enable = [Link];
logic enable; endclocking
modport test(input enable); endprogram
modport dut(output enable);
endinterface initial begin … end
CLOCKING BLOCK EVENTS
Clocking event of a clocking block is available directly by using the clocking block
name.
clocking dram @(posedge phi1);
inout data;
output negedge #1 data;
endclocking
Clocking event of dram clocking block can be used to wait for that particular
event:
@(dram); equivalent to @(posedge phi1)
CYCLE DELAY: ##
• ## can be used to delay execution by a specified number of clocking
events/clock cycles.
• What constitutes a cycle is determined by default clocking in effect.
• If no default clocking is specified for current module/interface/program,
then compiler shall issue an ERROR.
## 5; // wait 5 cycles(clocking events) using default clocking
## (j+1); // wait j+1 cycles(clocking events) using default clocking
DEFAULT CLOCKING
• One clocking can be specified as default for all cycle delay operations within a given
module/interface/program.
• Only one clocking can be specified in a program/module/interface, otherwise ERROR.
• A default clocking is valid only within the scope containing default clocking
specification.
• Scope includes module/interface/program that contains the declaration as well as any
nested modules/interfaces.
- Does not include instantiated modules/interfaces.
DEFAULT CLOCKING
Declaring a clocking as the default Assigning an existing clock to be default
program test(input bit clk, input reg [15:0] data); module processor …
default clocking bus @(posedge clk);
clocking busA @(posedge clk1); … endclocking
inout data;
clocking busB @(posedge clk2); … endclocking
endclocking
module cpu1 (interface y);
endprogram
default clocking busA;
initial begin
initial begin
## 5; ## 5; …
if([Link] == 10) ## 1; end
else … endmodule
end endmodule
endprogram
INPUT SAMPLING
• All clocking block inputs are sampled at corresponding clocking event.
• If input skew is not an explicit #0, value sampled corresponds to signal value
at the POSTPONED region of time step skew-time units prior to clocking
event.
• If input skew is an explicit #0, value sampled corresponds to signal value in
OBSERVED region.
• Samples happen immediately (calling process does not block).
INPUT SAMPLING
• When a signal appears in an expression it is replaces by signal’s
sampled value, i.e., value that was sampled at the last sampling point.
• When same signal is an input to multiple clocking blocks, each
clocking block sample corresponding signal with its own clocking
signal
SYNCHRONOUS EVENTS
• Wait for next change of signal ack_1 of clocking block ram_bus
@(ram_bus.ack_1);
• Wait for next clocking event in clocking block ram_bus
@(ram_bus);
• Wait for positive edge of signal ram_bus.enable
@(posedge ram_bus.enable);
SYNCHRONOUS EVENTS
• Wait for falling edge of specified 1-bit slice [Link][a]
@(negedge [Link][a]);
• Wait for next positive edge of dom.sig1 or next change of dom.sig2,
whichever happens first
@(posedge dom.sig1 or dom.sig2);
• Wait for either negative edge of dom.sig1 or positive edge of dom.sig2,
whichever happens first
@(negedge dom.sig1 or posedge dom.sig2);
SYNCHRONOUS DRIVES
DRIVES & NONBLOCKING
ASSIGNMENTS
• Synchronous signal drives are processed as nonblocking assignments.
• Key features of inout clocking block variables and synchronous drives
is that a drive does not change the clocking block input.
- This is because reading the input always yields last sampled value, and not the
driven value.
DRIVEN VALUE RESOLUTION
• When more than one synchronous drive is applied to same clocking block output(or
inout) at the same simulation time, driven values are checked for conflicts.
• When conflicting drives are detected a run-time error is issued, and each conflicting bit
is driven to X (or 0 for a 2-state port).
clocking pe @(posedge clk);
output nibble;
endclocking
[Link] <= 4’b0101;
[Link] <= 4’b0011; // Driven value of nibble is 4’b0xx1
DRIVEN VALUE RESOLUTION
• When same variable is an output from multiple clocking blocks, last drive
determines value of the variable.
reg j;
clocking pe @(posedge clk);
output j;
endclocking
j is output of 2 clocking blocks using different clocking events
(posedge vs negedge)
clocking ne @(negedge clk);
output j; Variable j shall take value most recently assigned by either
endclocking clocking block.