PrimeTime Guide · Chapter 3

Clocks: Defining, Shaping and Relating Every Clock in a Design

By the end of this chapter you will be able to define real, virtual and generated clocks. You will model latency, uncertainty, jitter and transition. You will relate clocks to each other and check pulse width, period and clock gating. You will also handle pulse clocks, phase-locked loops (PLLs) and clock meshes.

80 min read · Free, no login ·

Why this chapter matters in a real project

Every timing check in static timing analysis is measured against a clock edge. A setup check asks whether data arrives before the next capture edge. A hold check asks whether data stays stable after the current edge. If the clock is wrong, every one of those checks is wrong.

Clock mistakes are rarely loud. A missing generated clock leaves a whole block untimed, and the report still looks clean. A missing clock group makes the tool time paths between clocks that never talk. Thus, you get thousands of false violations and lose days chasing them.

Latency and uncertainty decide how much margin each path has. Too little margin before clock tree synthesis hides real problems until late in the project. Too much margin makes the design slower than it needs to be. This chapter shows how to describe clocks honestly, so the numbers you sign off are the numbers the silicon sees.

Prerequisites

  • Working With Design Data: reading and linking a design, and finding objects with get_ports, get_pins and get_clocks.
  • Constraining the Design: input and output delays, and design rule constraints such as maximum transition.
  • Basic digital logic: flip-flops, latches, multiplexers and the idea of setup and hold time.
  • You do not need to know timing exceptions, signal integrity analysis or variation yet. Where this chapter touches them, it explains the idea briefly.

In this chapter, times are in nanoseconds (ns) unless said otherwise.

Learning objectives

  1. Create real and virtual clocks with create_clock, and read a clock waveform.
  2. Explain source latency, network latency, ideal clocking and propagated clocking.
  3. Predict which early or late latency value the tool uses for setup and for hold.
  4. Apply clock uncertainty and jitter, and read their effect in a timing report.
  5. Check minimum pulse width, voltage swing and minimum period, and read the reports.
  6. Declare clocks as synchronous, asynchronous, logically exclusive or physically exclusive.
  7. Choose between false paths, case analysis, clock groups, active clocks and exclusivity points for multiplexed clocks.
  8. Control clock sense, and define pulse clocks and their width constraints.
  9. Define generated clocks with -⁠divide_by, -⁠multiply_by, -⁠edges and -⁠edge_shift, including PLL outputs.
  10. Set up clock-gating checks and describe the clock mesh simulation flow.

Figure 1 is a map of the whole chapter. Come back to it whenever you lose your place.

Clocks on one page
Define the clocks, shape them, relate them, then check them
Clocks on one page
Figure 1 The chapter as a map. Each panel is one group of sections. Come back to this figure as you read.What to notice: Panel 2 shapes an ideal clock into a realistic one. Panel 3 stops the tool from timing paths that cannot happen.

1  The beginner's mental model

Think of a school with one master bell. The bell schedule says it rings at 8:00, 8:50 and so on. That schedule is perfect on paper. However, the sound travels through wires and speakers before it reaches each classroom.

So a few real effects appear. Every room hears the bell a little late. Some rooms hear it earlier than others. Some speakers are old and give a short, weak ring. One wing runs its own bell at half the rate. A second school next door has its own bell, unrelated to ours. Figure 2 maps each effect to its PrimeTime name.

The school bell picture
A perfect schedule, real delays, and bells that may or may not be related
The school bell picture
Figure 2 An everyday picture of clocks. The schedule is the ideal waveform. Every real effect on the way to a classroom has a clock command.What to notice: The "next-door school" row is an asynchronous clock. Nothing we say about our own bell applies to it.
Where the analogy breaks — read this twice
  • A bell rings for people who can wait. A flip-flop captures data at one instant. A few picoseconds of clock error can turn a pass into a fail.
  • In the school, you can listen and measure. Before clock tree synthesis (CTS), there is no clock tree to measure. You must estimate latency and uncertainty yourself.
  • Two bells in one school are clearly related. In a chip, the tool assumes two clocks are related unless you say otherwise. Silence is not "unrelated".

Now the engineering model

PrimeTime analyzes the synchronous part of a design. That means paths between registers, or between registers and ports, that are timed by clock edges. When paths cross between clocks, the tool works out the phase relationship between the launch clock and the capture clock. The clocks can be single phase, multiple phase or multiple frequency.

The tool supports these kinds of clock information:

  • Multiple clocks. Clocks can have different waveforms and frequencies. A clock can have a real source, a port or a pin. It can also be virtual, with no source in the design.
  • Clock network delay and skew. Clock latency is the delay from the clock source to a register clock pin. Clock skew is the spread of arrival times at different registers. You can also give interclock skew between two clocks.
  • Ideal or computed delay. Before clock tree synthesis, you give an ideal delay. After it, the tool computes the delay from the real tree.
  • Minimum pulse width. The tool can check that the clock pulse does not shrink too far along the network.
  • Gated clocks. A gated clock is a clock controlled by gating logic, other than simple buffers or inverters. The tool runs setup and hold checks on the gating signal.
  • Generated clocks. A generated clock is made from another clock by a circuit inside the design, such as a clock divider.
  • Clock transition times. The transition time is how long a signal takes to change from one logic state to the other. You can set it at register clock pins.

So a complete clock description covers six items:

  1. period and waveform;
  2. latency, also called insertion delay;
  3. uncertainty, which covers skew;
  4. divided and other internally generated clocks;
  5. clock-gating checks;
  6. a fixed transition time while the clock network is incomplete.
TakeawayA clock starts as a perfect waveform. Everything else in this chapter makes it realistic, relates it to other clocks, or checks it.

2  Defining clocks

2.1  Creating a clock

Let us consider a block with a clock port C1. Its clock repeats every 10 ns. It rises at 2 ns and falls at 4 ns.

You must define every clock in the design with create_clock. The command creates a clock at the source you name. The source can be an input port or an internal pin. From there, the tool traces the clock network automatically. Thus, the clock reaches every register in the transitive fanout of the source. That is everything the source drives, directly or through other cells.

Creating a clock on two ports
pt_shell> create_clock -period 10 -waveform {2 4} {C1 CK2}  ;# one clock, two sources

Here is what this command does:

  • -⁠period 10 sets the clock period.
  • -⁠waveform {2 4} gives the edge times within one period: a rising edge at 2 and a falling edge at 4.
  • The clock gets the name C1, after the first source in the list.
  • The tool also creates a path group named C1. It holds all paths that end at points clocked by C1. Path groups are covered in the Timing Paths and Exceptions chapter.

The waveform is ideal. It ignores all delay in the clock network. After you create the clock, you still need to describe the network. The latency and uncertainty sections show how.

A single register can be reached by more than one clock. To define a second clock on the same port or pin, add -⁠add to create_clock.

2.2  Virtual clocks

Some signals come from, or go to, clocked chips outside our block. We need a clock to describe their timing, but that clock has no source in our design. This is a virtual clock. You use it as the reference for input and output delays.

Creating a virtual clock
pt_shell> create_clock -period 8 -name vclk -waveform {2 5}  ;# virtual: no source

Because there is no source object, we name the clock with -⁠name. Figure 3 shows both waveforms from this section.

Two clock waveforms
A real clock on ports C1 and CK2, and a virtual clock vclk
Two clock waveforms
Figure 3 The -waveform list places the rising and falling edges inside each period. The pattern then repeats every period.What to notice: C1 rises at 2 and 12. vclk rises at 2 and 10, because its period is 8.
Mentor's tip

Name virtual clocks clearly, for example vclk_ddr or vclk_spi. In a report, a path that starts at a virtual clock is an input or output path. A clear name tells you at once which interface it is.

2.3  Selecting, applying and removing clocks

A clock and a port can share a name, such as CLK. The get_clocks command makes sure a command works on the clock object, not the port. It also accepts patterns and filters.

Selecting clocks
pt_shell> report_clock [get_clocks -filter "period <= 5.0" PHI1*]   ;# fast PHI1 clocks

This reports the clocks whose names start with PHI1 and whose period is at most 5.0.

The all_clocks command is the same as get_clocks *. It returns a collection, a handle to a set of clock objects. The clock names are not printed.

Applying a command to every clock
pt_shell> set_max_time_borrow 0 [all_clocks]   ;# no time borrowing on any clock

Time borrowing lets a path through a transparent latch use time from the next cycle. Setting the limit to 0 on all clocks turns it off.

To remove clocks, use remove_clock. The reset_design command also removes clocks, together with other settings.

Removing clocks
pt_shell> remove_clock [get_clocks CLKB*]   ;# remove clocks whose names start with CLKB
pt_shell> remove_clock -all                 ;# remove every clock
TakeawayDefine every clock with create_clock. Use get_clocks to point at a clock object, and all_clocks to point at all of them.

3  Clock latency

3.1  Source latency and network latency

A clock edge does not appear at a flip-flop at time zero. It travels first from its true origin to the chip, then through the clock tree. Figure 4 splits this journey in two:

  • Source latency is the time from the ideal waveform origin to the clock definition point. That is the port or pin where you created the clock. For example, the board and an off-chip clock generator might add 1.0 ns.
  • Network latency is the time from the clock definition point to a register clock pin. That is the delay of the on-chip clock tree, rise or fall.

The total latency at a register clock pin is the sum of the two.

Two parts of clock latency
Source latency outside the definition point, network latency inside
Two parts of clock latency
Figure 4 Latency at FF1/CK is source latency plus network latency. The numbers are illustrative.What to notice: The clock is defined at port CLK. Everything to its left is source latency, even if it is on the board.

There are two ways to give network latency:

Table 1 Two ways to represent clock latency
Method How it works When to use it
Propagated The tool adds up the real cell and net delays along the clock network After clock tree synthesis, with annotated delays or parasitics
Ideal (estimated) You set an estimated latency with set_clock_latency Before clock tree synthesis

Ideal clocking is the default. With ideal clocking, you can set latency on a clock, a port or a pin. A value on a port or pin applies to every register clock pin in its transitive fanout. It overrides the value set on the clock object for those pins.

3.2  Propagated latency

After clock tree synthesis and layout, the clock tree exists. Its cell and net delays are back-annotated, or its net parasitics are calculated. Now the tool can compute latency itself. The edge times at each register are skewed by the real path delay from the clock source.

Propagating clock latency
pt_shell> set_propagated_clock [get_clocks CLK]   ;# compute latency from the real tree

You can set the propagated clock attribute on clocks, ports or pins. On a port or pin, it affects all register clock pins in the transitive fanout. To undo it on clocks, ports, pins or cells, use remove_propagated_clock.

Common beginner mistake

A beginner switches to propagated clocks on a pre-layout netlist. The parasitics are still unknown, so the computed latency is usually inaccurate. Propagated latency is accurate only when real clock trees and annotated delays or parasitics exist. Before that, use estimated latency.

3.3  Estimated latency with set_clock_latency

Before layout, the parasitics are unknown, so propagated latency is usually inaccurate. Instead, you estimate the latency and set it with set_clock_latency. The command sets latency on one or more clocks, ports or pins.

You can give different values for rising and falling edges:

Rise and fall latency
pt_shell> set_clock_latency -rise 1.2 [get_clocks CLK]  ;# rise edges 1.2 later
pt_shell> set_clock_latency -fall 0.9 [get_clocks CLK]  ;# fall edges 0.9 later

Source latency works for both ideal and propagated clocks. You set it with the -⁠source option. For a generated clock, the tool can compute source latency itself. This happens when its master clock is propagated and you have not set the generated clock's source latency.

To remove latency you have set on objects, network or source, use remove_clock_latency.

3.4  Early and late source latency

Now suppose the board delay to our CLK pin is not fixed. It can be anywhere from 1.5 to 2.5 ns. Figure 5 shows the setup. We describe this range with -⁠early and -⁠late:

A source latency range
pt_shell> create_clock -period 10 [get_ports CLK]                ;# the clock itself
pt_shell> set_clock_latency 1.5 -source -early [get_clocks CLK]  ;# earliest arrival
pt_shell> set_clock_latency 2.5 -source -late [get_clocks CLK]   ;# latest arrival

The tool then picks the more pessimistic value for each check:

  • Setup: the late value for the launch clock and the early value for the capture clock.
  • Hold: the early value for the launch clock and the late value for the capture clock.
Early and late source latency
The same clock arriving between 1.5 and 2.5 ns
Early and late source latency
Figure 5 For setup, launch is late and capture is early. For hold, the reverse. Both use the same clock here.What to notice: The setup window shrinks from 10.0 to 9.0. The hold check must cover an extra 1.0.

The same idea works with any values. For example, an early source latency of 0.8 and a late one of 0.9 on CLK1:

Another early and late pair
pt_shell> set_clock_latency 0.8 -source -early [get_clocks CLK1]  ;# early value
pt_shell> set_clock_latency 0.9 -source -late [get_clocks CLK1]  ;# late value
TakeawayLatency is source plus network. Before layout you estimate it; after layout you propagate it. An early and late range is always applied in the pessimistic direction.

3.5  Dynamic latency: modeling jitter in the source

A PLL produces a clock whose edges wander a little from cycle to cycle. This is jitter. It is a dynamic effect: it changes from one edge to the next.

You could model jitter with clock uncertainty, covered in the next section. However, uncertainty has two limits:

  • It does not affect the crosstalk arrival windows. These are the time ranges in which a net can switch, used in signal integrity analysis.
  • Clock reconvergence pessimism removal (CRPR) ignores it. CRPR removes the false pessimism on the clock path shared by launch and capture.

The -⁠dynamic option of set_clock_latency avoids both limits. It marks part of the source latency as dynamic. Arrival windows then include it. CRPR treats the dynamic part the same way it treats signal integrity delta delays.

Let us take a static source latency of 3.0 early and 5.0 late on CLK:

Static source latency only
pt_shell> set_clock_latency -early -source 3.0 [get_ports CLK]   ;# static, early
pt_shell> set_clock_latency -late -source 5.0 [get_ports CLK]    ;# static, late

Now add 0.5 of dynamic latency in each direction. The value you give is the new total, and -⁠dynamic gives the dynamic part of it:

Static plus dynamic source latency
pt_shell> set_clock_latency -early -source 2.5 \
            -dynamic -0.5 [get_clocks CLK]   ;# total 2.5 = static 3.0 + dynamic -0.5
pt_shell> set_clock_latency -source -late 5.5 \
            -dynamic 0.5 [get_clocks CLK]    ;# total 5.5 = static 5.0 + dynamic 0.5

When CLK is also propagated, delay calculation uses the total, static plus dynamic. However, look at a path that launches and captures on different clock edges. Up to the common point of the clock path, CRPR uses only the static latency. It removes the static pessimism from the result.

Two reports help here:

  • report_timing shows the static and dynamic parts of clock latency separately.
  • report_crpr shows the clock reconvergence pessimism (CRP) for static and dynamic conditions. It also shows which value was used for removal.

CRPR itself is covered in the Operating Conditions chapter.

TakeawayModel source jitter with set_clock_latency -⁠dynamic when crosstalk windows or CRPR matter. Plain uncertainty is ignored by both.

4  Clock uncertainty and jitter

4.1  What uncertainty does to a check

Before clock tree synthesis, we do not know the real skew. We still want margin for it. Clock uncertainty is that margin. It is the largest expected difference in clock arrival, within one clock or between clocks. You can also add extra margin to it on purpose, to tighten setup or hold.

Figure 6 shows its effect with a 10 ns clock:

  • Setup: the tool subtracts the setup uncertainty from the data required time. With 0.3, the capture edge at 10.0 becomes 9.7. Data must arrive 0.3 sooner.
  • Hold: the tool adds the hold uncertainty to the data required time. With 0.1, data must stay stable 0.1 longer.

If you give a single value, it applies to both setup and hold.

How uncertainty tightens setup and hold
A 10 ns clock with 0.3 setup and 0.1 hold uncertainty
How uncertainty tightens setup and hold
Figure 6 Setup uncertainty moves the required time earlier. Hold uncertainty moves it later. The numbers are illustrative.What to notice: Both arrows point toward the inside of the cycle. Uncertainty always makes a check harder, never easier.

4.2  Simple and interclock uncertainty

You set uncertainty with set_clock_uncertainty. It describes variation in successive edges of one clock, or between edges of different clocks. There are two kinds:

  • Simple uncertainty is the variation of one clock's edges from their ideal times. You give clocks, ports or pins. It applies to every capturing register clocked by that clock, or in the fanout of those ports or pins.
  • Interclock uncertainty is the skew between edges of two different clocks. It is more specific. You give a "from" clock with -⁠from, -⁠rise_from or -⁠fall_from. You give a "to" clock with -⁠to, -⁠rise_to or -⁠fall_to. It applies to paths that launch on the "from" clock and capture on the "to" clock.

You can also give uncertainty between two clock pins driven by the same clock. Interclock uncertainty matters most when launch and capture registers use different clocks.

Simple uncertainty examples
pt_shell> set_clock_uncertainty 0.45 [get_pins U1/FF*/CP]  ;# setup and hold
pt_shell> set_clock_uncertainty -setup 0.21 [get_clocks CLK1]    ;# setup only
pt_shell> set_clock_uncertainty -hold 0.33 [get_clocks CLK1]     ;# hold only

When a path has both kinds, interclock uncertainty wins:

Interclock uncertainty overrides simple uncertainty
pt_shell> set_clock_uncertainty 5 [get_clocks CLKA]   ;# simple: all paths into CLKA
pt_shell> set_clock_uncertainty 2 -from [get_clocks CLKB] \
            -to [get_clocks CLKA]                     ;# interclock: CLKB to CLKA only

A path from CLKB to CLKA uses 2. A path from CLKA to CLKA still uses 5.

Interclock uncertainty is one-way. If paths run in both directions, set both, even with the same value:

Interclock uncertainty in both directions
pt_shell> set_clock_uncertainty 2 -from [get_clocks CLKA] \
            -to [get_clocks CLKB]   ;# CLKA to CLKB
pt_shell> set_clock_uncertainty 2 -from [get_clocks CLKB] \
            -to [get_clocks CLKA]   ;# CLKB to CLKA
Common beginner mistake

A designer sets simple uncertainty on two clock ports that both feed a clock multiplexer (MUX). The worst of the two values then applies to the entire fanout of the MUX. This happens even when that clock is disabled at the MUX. Set uncertainty on the clock object instead, so each clock keeps its own value.

To remove uncertainty from clocks, ports, pins or cells, or between clocks, use remove_clock_uncertainty.

4.3  Clock jitter commands

The tool also has dedicated jitter commands:

  • set_clock_jitter sets jitter on a master clock. All clocks generated from that master get the same jitter. With no master clock named, it sets jitter on all clocks.
  • remove_clock_jitter removes jitter from a master clock and its generated clocks. With no master clock named, it removes jitter from all clocks.
  • report_clock_jitter shows the cycle jitter and duty-cycle jitter of each clock. It also shows the master clock whose jitter a generated clock uses.
Illustrative output — report_clock_jitter
pt_shell> report_clock_jitter
****************************************
Report : clock jitter
...
****************************************
Clock    cycle jitter   duty-cycle jitter    master clock with jitter
---------------------------------------------------------------------
mclk        2                   3                mclk
gclk        2                   3                mclk

Here gclk is generated from mclk, so it uses the jitter of mclk.

To see jitter in a path, use report_timing with the full clock path. In this example, CLK also has an estimated network latency of 1.0.

Jitter and uncertainty on one path
pt_shell> set_clock_uncertainty -setup 0.3 [get_clocks CLK]   ;# setup margin for skew
pt_shell> set_clock_jitter -cycle 0.4 CLK                     ;# cycle jitter on CLK
pt_shell> report_timing -from FF1 -to FF2 -path_type full_clock  ;# show clock lines
Illustrative output — capture side of report_timing
Point                                   Incr     Path
---------------------------------------------------------
clock CLK (rise edge)                  10.00    10.00
clock network delay (ideal)             1.00    11.00
clock uncertainty                      -⁠0.30    10.70
clock jitter                           -⁠0.40    10.30
FF2/CK (DFFX1)                                  10.30 r
library setup time                     -⁠0.05    10.25
data required time                              10.25
---------------------------------------------------------

The report lists uncertainty and jitter on separate lines. Each one moves the required time earlier.

TakeawayUncertainty is margin you add for unknown skew. Setup uncertainty is subtracted, hold uncertainty is added. Interclock values win over simple ones.

5  Clock transition time

Before clock tree synthesis, one buffer may drive 10,000 register clock pins. The computed transition on those pins is then very slow. A slow clock transition distorts the clock-to-output delays. It also distorts the setup and hold values taken from the library.

To avoid this, set an estimated transition for the whole clock network with set_clock_transition. It gives a nonzero transition time to an ideal clock.

Estimating clock transition
pt_shell> set_clock_transition 0.64 -fall [get_clocks CLK1]   ;# falling edges only

The value applies to all nets that directly feed sequential elements clocked by that clock. The useful options are:

  • -⁠rise or -⁠fall sets the value for only rising or only falling edges.
  • -⁠min or -⁠max sets the value for minimum or maximum operating conditions.

To remove the estimate, use remove_clock_transition.

In practice

Teams usually set clock latency, uncertainty and transition together in one pre-layout clock file. After clock tree synthesis, they switch to propagated clocks and remove the transition estimate. Keeping the two setups in separate files makes the switch a one-line change.

6  Pulse width, voltage swing and period checks

6.1  Minimum pulse width

Let us follow one clock pulse through a gate and a buffer. Each cell slows the rising and falling edges by different amounts. Thus, the high pulse can shrink at each stage. Figure 7 shows this. Two problems can follow:

  • If the pulse is too narrow at a register clock pin, the register might not capture data. Library cell pins can carry a minimum pulse width limit. report_constraint checks it.
  • The pulse might shrink so much inside the network that it does not pass any further. The tool can check the whole clock network against a threshold.
A pulse shrinking through the network
The same high pulse measured at three pins
A pulse shrinking through the network
Figure 7 Each stage can make the high pulse narrower. The check compares the width at each pin with the limit. Widths are illustrative.What to notice: At FF1/CP the pulse is 4.30 wide. A limit of 4.40 there would fail.

There is no default limit for clock tree pulse width checks. You set one with these commands:

Table 2 Commands that set pulse width limits
Command What it constrains
set_min_pulse_width Normal clock networks; set on clocks, cells, pins, ports or the current design
set_pulse_clock_min_width Minimum width in pulse generator networks
set_pulse_clock_max_width Maximum width in pulse generator networks
remove_min_pulse_width Removes minimum pulse width checks in a clock tree or at sequential cells

A minimum pulse width can also come from the library, on cell clock pins. The report_constraint command checks minimum pulse width at register clock pins and on clock networks. Pulse generator networks are covered in the pulse clock section.

By default, the uncertainty from set_clock_uncertainty also applies to pulse width checks. You can change this with a variable:

Uncertainty in pulse width checks
set_app_var timing_include_uncertainty_for_pulse_checks \
  none | setup_only | hold_only | setup_hold   ;# choose one value

The default is setup_hold, which applies both setup and hold uncertainty. The same variable controls pulse clock width checks.

6.2  Pulse width measurement thresholds

By default, the tool measures pulse width where the waveform crosses 50% of the supply voltage. For clock network pins, you can move this threshold to any fraction between 0.0 and 1.0.

A more conservative check measures a low pulse below 0.5 and a high pulse above 0.5. Figure 8 shows why: the pulse is narrower near its tip.

Conservative pulse width thresholds
set delay_calc_waveform_analysis full_design               ;# required for this analysis
set timing_enable_min_pulse_width_waveform_adjustment true ;# turn on the adjustment
set timing_min_pulse_width_low_pulse_threshold 0.12        ;# low pulse measured at 12%
set timing_min_pulse_width_high_pulse_threshold 0.88       ;# high pulse measured at 88%
report_min_pulse_width -path_type short                    ;# run the check

With nondefault thresholds, the report shows two extra adjustment lines. They are "open edge threshold voltage adjustment" and "close edge threshold voltage adjustment".

Thresholds for width and for swing
Measuring a pulse at 0.88 instead of 0.50, and checking how far it swings
Thresholds for width and for swing
Figure 8 Left: a higher threshold measures a narrower width. Right: a voltage swing check passes a pulse only if it reaches the threshold.What to notice: The weak pulse on the right never reaches 0.90 of the supply, so it fails, whatever its width.

6.3  Voltage swing checking

A weak driver may never pull a clock pulse fully to the supply rail. The voltage swing check finds this on clock network pins. It asks whether a high pulse gets close enough to the power rail. It also asks whether a low pulse gets close enough to the ground rail.

Voltage swing check
set delay_calc_waveform_analysis full_design         ;# required for this analysis
set timing_enable_voltage_swing true                 ;# turn on the swing check
set timing_voltage_swing_low_pulse_threshold 0.10    ;# low pulse must reach 10%
set timing_voltage_swing_high_pulse_threshold 0.90   ;# high pulse must reach 90%
report_min_pulse_width -voltage_swing                ;# run the check

The tool treats this as a special minimum pulse width check:

  • The minimum width is 0.0.
  • The width is measured at the chosen fraction of the supply voltage.
  • A pulse of any width that reaches or crosses the threshold passes.
  • A pulse that never crosses the threshold is a violation.
  • For a passing pulse, the positive slack is its width at the threshold.

Reading these reports in depth is covered in the Reporting and Debugging Analysis Results chapter.

6.4  Minimum period checking

Some cells have a min_period constraint on a pin, set in the library. It says that two successive clock edges of the same type must be at least that far apart. Same type means rising to rising, or falling to falling.

Three commands run the check:

  • report_min_period, with optional -⁠verbose for more detail;
  • report_constraint -⁠min_period, also with optional -⁠verbose;
  • report_analysis_coverage -⁠check_type min_period.

Let us read one result. The clock CLK has a period of 4.00. Pin FF2/CK has a min_period of 4.00 in the library.

Illustrative output — report_min_period -path_type full_clock FF2/CK
  Pin: FF2/CK
  Related clock: CLK
  Check: sequential_clock_min_period

  Point                                       Incr       Path
  ----------------------------------------------------------
  clock CLK (rise edge)                       0.00       0.00
  clock source latency                        0.20       0.20
  CLK (in)                                    0.00       0.20 r
  CB1/Y (BUFX4)                               0.90       1.10 r
  CB2/Y (BUFX2)                               0.10       1.20 r
  FF2/CK (DFFX1)                              0.00       1.20 r
  open edge clock latency                                1.20

  clock CLK (rise edge)                       4.00       4.00
  clock source latency                        0.20       4.20
  CLK (in)                                    0.00       4.20 r
  CB1/Y (BUFX4)                               0.80       5.00 r
  CB2/Y (BUFX2)                               0.08       5.08 r
  FF2/CK (DFFX1)                              0.00       5.08 r
  clock reconvergence pessimism               0.10       5.18
  clock uncertainty                          -⁠0.05       5.13
  close edge clock latency                               5.13
  ----------------------------------------------------------
  required min period                                    4.00
  actual period                                          3.93
  ----------------------------------------------------------
  slack (VIOLATED)                                      -⁠0.07

Here is how to read it, with Figure 9 alongside:

  • Open edge clock latency is the latest arrival of the first edge. It uses maximum delays through the clock cells: 1.20.
  • Close edge clock latency is the earliest arrival of the second edge. It uses minimum delays through the same cells: 5.08.
  • Clock reconvergence pessimism is added back, which reduces the violation: +0.10.
  • Clock uncertainty is subtracted, which adds to the violation: −0.05. The close edge is 5.13.
  • Actual period is close minus open: 5.13 − 1.20 = 3.93. It is less than 4.00, so the slack is −0.07.
Reading a minimum period check
The latest first edge against the earliest second edge
Reading a minimum period check
Figure 9 The first edge is taken late and the second edge early, so the measured period is the worst case. The numbers match the report above.What to notice: The ideal edges are 4.00 apart. Late-versus-early tree delays, CRP and uncertainty together give an actual spacing of 3.93.
TakeawayPulse width, voltage swing and minimum period are checks on the clock itself, not on data. They catch clocks that are too narrow, too weak or too fast for a cell.

7  How clocks relate to each other

7.1  Three kinds of relationship

With several clocks, the tool must know how they relate. Two clocks can be:

  • Synchronous: they share a common source and have a fixed phase relationship.
  • Asynchronous: they do not communicate in the design. Their edges can occur at any time relative to each other.
  • Exclusive: they do not interact, because only one of them is active at a time.

Figure 10 shows one small circuit for each case, with the commands that describe it. To analyze paths between clock domains correctly, you may need false paths between clocks. You may need to exclude some clocks from the analysis. Or you may need to declare the relationship directly.

Synchronous, asynchronous and exclusive
Three small circuits and the commands that describe them
Synchronous, asynchronous and exclusive
Figure 10 A divided clock is synchronous with its master. An on-chip oscillator is asynchronous with a clock from outside. Two clocks through a MUX are exclusive.What to notice: Only the synchronous case needs no extra command. The tool assumes it by default.

7.2  Synchronous clocks and the base period

Unless you say otherwise, the tool assumes two clocks are synchronous whenever a path launches on one and captures on the other. All clock waveforms are aligned at time zero, as create_clock defines them. Latency and uncertainty then shift the edges further.

Let us take three clocks:

Three synchronous clocks
pt_shell> create_clock -period 4 -name CK1 -waveform {0 2}   ;# rises 0, falls 2
pt_shell> create_clock -period 4 -name CK2 -waveform {1 3}   ;# rises 1, falls 3
pt_shell> create_clock -period 6 -name CK3 -waveform {2 3}   ;# rises 2, falls 3

Paths may cross between these clocks. To test every pair of edges, the tool expands the clocks internally. It repeats each clock up to the least common multiple of all synchronous periods. This is the base period. Here the periods are 4, 4 and 6, so the base period is 12.

The tool then checks paths between all edges in the expanded clocks. Figure 11 shows the result. Take paths from a falling edge of CK2 to a rising edge of CK3. The tightest setup check runs from 7 to 8.

Expanding synchronous clocks
CK1, CK2 and CK3 repeated over a base period of 12
Expanding synchronous clocks
Figure 11 The tool repeats each clock over the least common multiple of the periods, then checks every launch edge against every capture edge.What to notice: The red arrow from CK2 falling at 7 to CK3 rising at 8 is only 1 ns. That is the tightest CK2-fall to CK3-rise setup check.
Common beginner mistake

A beginner defines two unrelated clocks with periods 3.1 and 4.7 and leaves them synchronous. The tool now expands both clocks over a huge base period. It may find two edges very close together and report a false violation. Define clocks the way they really operate.

To declare clocks that are not synchronous, use case analysis, set_clock_groups or set_false_path.

7.3  Asynchronous clocks

A free-running on-chip oscillator is asynchronous to a system clock entering from outside. To declare this, use set_clock_groups -⁠asynchronous. The tool then:

  • does not check paths that launch on one clock and capture on the other, as if they were false paths;
  • in crosstalk analysis, gives infinite arrival windows to aggressor and victim nets between the two domains.

An aggressor is a net whose switching disturbs a nearby victim net. Infinite windows mean the tool assumes they can switch at any time relative to each other. The Signal Integrity Analysis chapter covers this in depth.

7.4  Exclusive clocks

A circuit might send a fast clock or a slow clock onto one clock line through a MUX. Only one is active at a time, so they never interact. Checking paths between them wastes runtime and creates false violations.

You can declare a false path between them. You can disable one with case analysis. Or you can declare them exclusive:

Declaring two exclusive clocks
pt_shell> set_clock_groups -logically_exclusive \
            -group {CK1} -group {CK2}   ;# no paths CK1->CK2 or CK2->CK1

This is like a false path in both directions. However, report_exceptions does not show clock groups. To see them, use report_clock -⁠groups. To limit that report to some clocks, give a list: report_clock -⁠groups clock_list.

The group rules are simple:

  • A group can hold several clocks: -⁠group {CK1 CK2} -⁠group {CK3 CK4}. Paths between the two groups are ignored.
  • With more than two groups, each group is exclusive to every other group.
  • With just one group, that group is exclusive to all other clocks.
  • -⁠name gives the declaration a name, so you can remove it later.
Named groups with several clocks
pt_shell> set_clock_groups -logically_exclusive -name EX1 \
            -group {CK1 CK2} -group {CK3 CK4}   ;# named, two groups of two
pt_shell> set_clock_groups -logically_exclusive \
            -group {CK1 CK2} -group {CK3 CK4} -group {CK5}   ;# three groups
pt_shell> set_clock_groups -logically_exclusive \
            -group {CK1 CK2}   ;# CK1, CK2 exclusive to every other clock
Mentor's tip

Do not add false paths between clocks that are already in exclusive groups. It is redundant, and set_clock_groups invalidates those false paths anyway. The same holds for -⁠asynchronous groups.

Some clocks are physically exclusive as well. They are never present in the chip together, for example because of multiplexing or physical separation. Then there can be no crosstalk between them either. Use -⁠physically_exclusive instead of -⁠logically_exclusive. The tool then skips crosstalk analysis between their nets.

Asynchronous groups and exclusive groups are kept separately, even though one command creates both. Table 3 sums up the three options.

Table 3 The three kinds of clock group
Option Timing paths between groups Crosstalk between groups
-⁠asynchronous Not checked Analyzed with infinite arrival windows
-⁠logically_exclusive Not checked Still analyzed
-⁠physically_exclusive Not checked Not analyzed

Three more commands help:

Querying and removing clock groups
pt_shell> get_clock_relationship {CK1 CK2}  ;# how do they relate?
pt_shell> remove_clock_groups -logically_exclusive -name EX1   ;# remove one declaration
pt_shell> remove_clock_groups -logically_exclusive -all  ;# remove all exclusive
TakeawayClocks are synchronous by default. Declare asynchronous and exclusive relationships yourself, and pick physically exclusive when the clocks can never couple.

7.5  Choosing a method for multiplexed clocks

Figure 12 shows four clocks and one select signal. With SEL at 0, CK1 and CK3 run. With SEL at 1, CK2 and CK4 run. By default, the tool checks all combinations, including the impossible ones.

Four clocks and one select signal
Two clock MUXes share SEL, so only two clocks run at a time
Four clocks and one select signal
Figure 12 Valid pairs are CK1 with CK3, and CK2 with CK4. Every other pair can never happen.What to notice: One SEL line drives both MUXes. That is why CK1 can never meet CK4.

There are four ways to describe this:

1. False paths between every invalid pair. One run covers all valid combinations.

Method 1 — false paths
pt_shell> set_false_path -from CK1 -to CK2   ;# repeat for each invalid pair:
pt_shell> set_false_path -from CK2 -to CK1   ;#   CK3<->CK4, CK1<->CK4, CK2<->CK3

The full set has eight commands: both directions of CK1–CK2, CK3–CK4, CK1–CK4 and CK2–CK3.

2. Case analysis. Set a constant on the select line. Only one mode is timed per run.

Method 2 — case analysis
pt_shell> set_case_analysis 0 [get_ports SEL]   ;# only CK1 and CK3 are active

To cover both modes you need two runs, one with SEL=0 and one with SEL=1.

3. Disable timing from some clock inputs.

Method 3 — disable timing
pt_shell> set_disable_timing [get_ports {CKP2 CKP4}]   ;# no paths from these clock pins

4. Clock groups with active clocks.

Method 4 — groups plus active clocks
pt_shell> set_clock_groups -logically_exclusive -name E1 \
            -group {CK1 CK3} -group {CK2 CK4}   ;# the two valid sets
pt_shell> set_active_clocks [all_clocks]        ;# analyze both sets in one run

The tool checks all valid paths in one run. To time only the SEL=0 mode, change the last line to set_active_clocks {CK1 CK3}. That makes CK2 and CK4 inactive, just like case analysis.

Now give each MUX its own select, S1 and S2. Only CK1–CK2 and CK3–CK4 are invalid now. Every other pair is possible.

Two select signals — groups per MUX
pt_shell> set_clock_groups -logically_exclusive -name mux1 \
            -group {CK1} -group {CK2}   ;# first MUX
pt_shell> set_clock_groups -logically_exclusive -name mux2 \
            -group {CK3} -group {CK4}   ;# second MUX
pt_shell> set_active_clocks {CK1 CK2 CK3 CK4}   ;# all four, one run

The tool times CK1 and CK2 against CK3 and CK4, in both directions if paths exist. It skips CK1–CK2 and CK3–CK4. With false paths, you would need four commands here. With case analysis, you would need four runs: S1 S2 = 00, 01, 10 and 11. To time only 00, use set_active_clocks {CK1 CK3}.

One more case is common. CK1 launches a path and CK2 captures it. The same two clocks also meet at a MUX further on. Here the path between the clocks is real, but paths after the MUX are not. Case analysis on the select line is the best method, because it removes only the downstream combinations.

In practice

For complex clock MUX trees, exclusivity points, covered next, usually work best. Clock groups with set_active_clocks also keep one run and document intent in one place. Case analysis stays useful when you sign off one mode at a time.

7.6  Clock exclusivity points

Modern chips often pick a clock through MUX cells. A fast clock runs under heavy load, and a slow clock saves power. Figure 13 shows two cascaded MUXes, U15 and U23.

By default, CK1, CK2 and CK3 all reach the flops below U23 together. The tool checks every launch and capture pair, such as launch on CK1 and capture on CK2. In silicon, only one clock is there at a time, as long as the MUX controls stay static between launch and capture.

An exclusivity point marks a pin where only one clock at a time can pass. For complex clock MUX trees, this usually gives better simplicity, accuracy, completeness and turnaround time than the other methods.

Clock exclusivity points
Marking MUX outputs so only one clock passes at a time
Clock exclusivity points
Figure 13 Exclusivity points at U15/Z and U23/Z make CK1, CK2 and CK3 physically exclusive below them. Paths above the MUXes are not affected.What to notice: Without the points, the flops see all three clocks at once and the tool times every pair.

The exclusivity setting applies to delay checks, minimum pulse width checks and minimum period checks. There are two ways to place the points.

Explicitly, with set_clock_exclusivity:

Setting exclusivity points
pt_shell> set_clock_exclusivity -type mux -output "U15/Z"   ;# one clock at a time here
pt_shell> set_clock_exclusivity -type mux -output "U23/Z"   ;# and here

This enforces a physically exclusive relationship among the clocks in the transitive fanout of the pin. It works whatever the value of the automatic variable below.

Automatically, with a variable:

Inferring exclusivity points at MUX outputs
pt_shell> set_app_var timing_enable_auto_mux_clock_exclusivity true  ;# auto-detect
pt_shell> set_disable_auto_mux_clock_exclusivity MUX32/Z   ;# but not at this MUX

With the variable true, the tool finds MUX cells with several clocks at their inputs. It places exclusivity points at their outputs. Clock interactions in the fanin of the MUX are not affected. set_disable_auto_mux_clock_exclusivity turns off the inference at chosen MUX cells.

Automatic detection works only for real MUX cells, as marked by the is_mux_cell cell attribute. A MUX built from random logic is not detected. For such logic, set the point by hand and name the clock inputs as well:

Exclusivity point on a non-MUX cell
pt_shell> set_clock_exclusivity -type user_defined \
            -inputs "OR1/A OR1/B" -output OR1/Z   ;# clock inputs and output pin

To report all points, inferred or explicit, use report_clock -⁠exclusivity. To query one pin, read its is_clock_exclusivity attribute.

Illustrative output — exclusivity reports
pt_shell> report_clock -exclusivity
...
clock exclusivity points:

     -type mux
     -output U23/Z
pt_shell> get_attribute -class pin [get_pins U23/Z] is_clock_exclusivity
true

Table 4 compares exclusivity points with the other methods. Each has strengths in simplicity, flexibility, turnaround time and completeness.

Table 4 Ways to stop analysis of impossible clock pairs
Method Command Note
Exclusivity points set_clock_exclusivity or the auto MUX variable Exclusive below the MUX only; one run
False paths set_false_path One run; many commands for many clocks
Exclusive clock groups set_clock_groups -⁠logically_exclusive One run; applies everywhere, not just below the MUX
Case analysis set_case_analysis One mode per run
Disable timing set_disable_timing Cuts all paths from the chosen clock input pins
New clocks at MUX outputs Define new clocks on the MUX output pins Exclusive downstream, not upstream

7.7  Removing clocks from analysis

By default, the tool analyzes all clocks and all interactions between them. Often you want only some clocks, for one operating mode. For example, a device may use a fast clock normally and a slow clock in power-down mode.

The first way is case analysis on the select port:

Restricting analysis with case analysis
pt_shell> set_case_analysis 0 [get_ports SEL]   ;# analyze only the SEL=0 mode

The second way is set_active_clocks. Clocks not listed are inactive and ignored.

Choosing the active clocks
pt_shell> set_active_clocks {CK1 CK2}    ;# only CK1 and CK2 are analyzed
pt_shell> set_active_clocks [all_clocks]  ;# back to the default: all clocks active

Keep these rules in mind:

  • A generated clock based on an inactive clock is also inactive.
  • Each use of the command replaces the previous list.
  • The command triggers a full timing update.
  • It works for standard timing analysis only. It does not work for context characterization, model extraction or write_sdc.
TakeawayFor MUXed clocks, exclusivity points or clock groups keep one run and stay accurate. Case analysis and active clocks pick one mode at a time.

8  Clock sense

8.1  Positive, negative and non-unate clocks

The tool tracks inverters and buffers in clock trees. It knows whether each register sees the clock true or inverted. This is the clock sense. For a tree of only buffers and inverters, you need not set anything. The clock at each register is unate.

  • Positive unate: a rising edge at the source gives a rising edge at the register. A falling edge gives a falling edge. Buffers, two inverters and an AND gate used for gating all keep positive sense.
  • Negative unate: a rising edge at the source gives a falling edge at the register, and the reverse. One inverter does this.
  • Non-unate: the sense is ambiguous, because of non-unate timing arcs in the clock path. Through an XOR gate, the sense depends on the other input. With that input at 0 the sense is positive; at 1 it is negative.

A pulse generator is also non-unate. It has a direct path through an AND gate and an inverting path through an inverter. Figure 14 shows all of these cases.

Clock sense through common cells
Unate cells keep a known sense; XOR and pulse generators do not
Clock sense through common cells
Figure 14 Buffers and inverters give a known sense. An XOR or a pulse generator gives both senses at once, so the tool cannot choose.What to notice: The gated clock through the AND gate is still positive unate. Gating does not make a clock non-unate.

8.2  Resolving a non-unate clock with set_sense

To resolve the ambiguity, set a sense to propagate forward from a pin in the non-unate part of the network:

set_sense syntax for clock sense
set_sense -⁠type clock
  -⁠positive | -⁠negative
  object_list
Forcing positive sense after an XOR
pt_shell> set_sense -type clock -positive [get_pins UX1/Z]   ;# keep only positive paths

This propagates only the positive unate paths through UX1/Z, relative to the original clock source. After that point, the tool tracks sense through any further buffers and inverters as usual.

Two rules apply:

  • The command affects only the non-unate part of a clock network. Suppose you set it on a pin in a unate part, and the sense disagrees with the real one. The tool then reports an error and ignores the command.
  • The setting applies to every clock through the pin. To limit it to some clocks, add -⁠clocks.
Limiting the sense to one clock
pt_shell> set_sense -type clock -positive \
            -clocks [get_clocks CLK] [get_pins UMUX1/Z]   ;# only CLK at this pin

set_sense -⁠type clock also has options for pulse clocks. They are covered in the next major section.

8.3  Stopping clock propagation

Sometimes a clock physically never passes a point. In Figure 15, the control logic lets UMUX2 select CLK2, but never TESTCLK. So TESTCLK never exists after UMUX2.

Stopping a clock at a pin
pt_shell> set_sense -type clock -stop_propagation -clocks TESTCLK UMUX2/Z  ;# stop here

This says the signal is not used as a clock at that pin. It also prevents clock-gating checks on the clock network leading up to the pin.

A leaf pin is the last pin of a clock network, where the clock is used. To stop a clock at a leaf pin, use -⁠clock_leaf instead:

Ending a clock at a leaf pin
pt_shell> set_sense -type clock -clock_leaf -clocks CLK3 UMUX3/Z  ;# leaf here

Here the signal is a clock at the pin, but it does not propagate past it. Clock-gating checks on the network leading up to the pin are still performed.

Two ways to stop a clock
-stop_propagation versus -clock_leaf
Two ways to stop a clock
Figure 15 Both stop the clock at the MUX output. They differ in whether the pin still counts as a clock pin.What to notice: Only -clock_leaf keeps the clock-gating checks before the pin.

To remove a sense set with set_sense -⁠type clock, use remove_sense -⁠type clock.

TakeawayClock sense is automatic through buffers and inverters. Use set_sense -⁠type clock only where the sense is ambiguous or where a clock really stops.

9  Pulse clocks

9.1  What a pulse clock is

A pulse clock is a train of short pulses. Both edges of each pulse come from the same edge of another clock. Pulse clocks can improve performance and reduce power.

Figure 16 shows a simple pulse generator. CLK and a delayed, inverted copy CLKB feed an AND gate. Each rising edge of CLK makes a short high pulse on CLKP. The pulse ends when CLKB falls, so its width is the delay of the inverter.

A pulse generator and its pulse clock
One rising edge of CLK makes both edges of the pulse
A pulse generator and its pulse clock
Figure 16 CLKP is high only while CLK is already high and CLKB is still high. The 0.5 ns inverter delay sets the pulse width. Times are illustrative.What to notice: Edge 1 of CLK at 1.0 starts the pulse and also, through the inverter, ends it at 1.5.

9.2  Three ways to describe a pulse clock

The tool needs the timing behavior of the pulse. There are three ways to give it:

  1. A characterized pulse generator cell. The library describes the cell with pulse generator attributes. This is the best method. You need to do nothing more in PrimeTime.
  2. create_generated_clock. You describe the pulse timing relative to the source clock. This creates a new clock domain at the pulse generator output.
  3. set_sense -⁠type clock. You give the sense of the pulses relative to the source clock. This does not create a new clock. It sets the sense of the existing clock downstream of the pin.

Without characterized cells, you must use method 2 or 3 at each pulse generation point.

9.3  Method 2: a generated pulse clock

For the circuit in Figure 16, the pulse clock is defined like this:

A pulse clock as a generated clock
pt_shell> create_generated_clock -name CLKP -source CLK \
            -edges {1 1 3} [get_pins UAND/Z]   ;# rise and fall both on edge 1

The -⁠edges list names edges of the master clock. Edge 1 is the first rising edge, edge 2 the first falling edge, edge 3 the next rising edge. The three numbers give the generated clock's rising edge, falling edge and next rising edge.

A repeated edge number marks a pulse. It is better to use repeated edge numbers than explicit pulse times. This keeps the delay checks between source and pulse clock correct. The general rule:

  • The position of the repeated number decides a high or low pulse.
  • The repeated number decides which master edge triggers the pulse.
Table 5 Edge lists for the four pulse types
Edge list Pulse type
{1 1 3} Rising edge of the source triggers a high pulse
{2 2 4} Falling edge of the source triggers a high pulse
{1 3 3} Rising edge of the source triggers a low pulse
{2 4 4} Falling edge of the source triggers a low pulse

9.4  Method 3: a pulse clock sense

Instead of a new clock, you can tell the tool that the existing clock becomes a pulse after a pin:

A pulse clock as a clock sense
pt_shell> set_sense -type clock -pulse rise_triggered_high_pulse \
            [get_pins UAND/Z]   ;# same clock, now a rise-triggered high pulse

The general syntax is:

set_sense syntax for pulse clocks
set_sense
  -⁠type clock
  -⁠pulse rise_triggered_high_pulse | rise_triggered_low_pulse |
         fall_triggered_high_pulse | fall_triggered_low_pulse
  object_list

Figure 17 shows the four pulse senses next to the master clock. It also shows the matching -⁠edges list for each.

The four pulse clock senses
Each sense next to its -edges equivalent
The four pulse clock senses
Figure 17 A rise-triggered pulse starts at each rising master edge; a fall-triggered pulse at each falling edge. High or low tells which way the pulse goes.What to notice: All four pulse types keep the master's frequency. Only the trigger edge and the polarity change.

9.5  Why method 3 scales

A design may need thousands of pulse generators for clock gating, skew control and pulse integrity. A generated clock at each one does not scale. You must find and define each one, and the clock groups multiply.

For pulse generators that do not change frequency, set the pulse_clock attribute to one of the four senses instead. They cover all four types without any generated clock. Points to remember:

  • The sense can be set on internal, bidirectional or output pins. On a bidirectional pin, it affects only clock paths through the output side.
  • If the requested sense does not exist, the tool issues a warning. For example, rise_triggered_high_pulse needs a path where a source rise gives a fall at the pin. With only a positive unate path, there is none, so the command is not applied.
  • With both a positive and a negative unate path to the pin, the command works. The rise latency comes from the positive path and the fall latency from the negative path.
  • The tool reports an error if a pulse clock merges with another sense of the same clock. Where senses merge, set the one you want with set_sense -⁠type clock -⁠pulse.
  • For pulse generators that change frequency, such as frequency doublers, use create_generated_clock.

9.6  Pulse width comes from latency

The nominal width of every pulse clock is zero, whichever method you use. The tool computes the real width from the rise and fall latency at the pulse generator output:

  • high pulse width = fall network latency − rise network latency
  • low pulse width = rise network latency − fall network latency

The tool can compute these latencies from the circuit. Or you can set them with set_clock_latency, which fixes the pulse width. You can set it on any pin in the clock network. It then affects all registers in the fanout. For an ideal high pulse width of 0.5, with an overall latency of 0.6:

Setting the ideal pulse width with latency
pt_shell> set_clock_latency -rise 0.6 UAND/Z   ;# pulse starts 0.6 after the source edge
pt_shell> set_clock_latency -fall 1.1 UAND/Z   ;# ends 1.1 after: width 1.1 - 0.6 = 0.5

A clock driven by a pulse generator may need a waveform whose edge times do not strictly increase. In the example below, the rise and fall edges are both at 0.0, so the ideal pulse has zero width. The source latencies then set the real pulse. It rises 0.23 and falls 0.65 after the edge, so its high width is 0.65 − 0.23 = 0.42. To define such a clock, use create_clock -⁠waveform:

A zero-width ideal waveform shaped by source latency
pt_shell> create_clock -waveform {0.0 0.0} -period 10 [get_ports BCK]  ;# zero width
pt_shell> set_clock_latency -source -rise 0.23 -fall 0.65 \
            [get_ports BCK]  ;# rise and fall
TakeawayDescribe pulse clocks with a characterized cell if you can. Otherwise use -⁠edges with a repeated number, or a pulse sense. The pulse width always comes from fall minus rise latency.

9.7  Constraining pulse width in a pulse clock network

The transitive fanout of a pulse generator is a pulse clock network. The clock traveling through it is the pulse clock. If the pulse generator has sequential arcs, its output is not a clock unless you define a generated clock there.

Two commands constrain pulse width in these networks:

Pulse width constraint syntax
set_pulse_clock_min_width -⁠transitive_fanout value object_list
set_pulse_clock_max_width -⁠transitive_fanout value object_list
  • You can name pulse generator instances or pulse generator library cells.
  • On a clock, the constraint covers the fanout of every pulse generator driven by that clock.
  • On the design, it covers all pulse clock networks.
  • If constraints conflict, the most restrictive one is used.
  • The library minimum pulse width also applies in the pulse clock network.

When CRPR is enabled, the clock reconvergence pessimism is a credit to the pulse width. It is added for the minimum width check and subtracted for the maximum width check.

The tool infers whether the high or the low pulse is constrained from the clock sense. Before an inverter, the high pulse minimum width is checked. After the inverter, the low pulse is checked, as Figure 18 shows.

Sense decides which pulse is checked
A high pulse becomes a low pulse after an inverter
Sense decides which pulse is checked
Figure 18 The constraint follows the sense of the clock. The same minimum width is checked on the high pulse before the inverter and on the low pulse after it.What to notice: The pulse has the same width on both sides of U1. Only its polarity changes.

To remove these constraints, use remove_pulse_clock_min_width or remove_pulse_clock_max_width. You must name every source of the constraint you want removed. To report them, use:

  • report_pulse_clock_min_width or report_constraint -⁠pulse_clock_min_width;
  • report_pulse_clock_max_width or report_constraint -⁠pulse_clock_max_width.

By default, the general minimum pulse width constraints apply everywhere except pulse clock networks. The more specific pulse clock constraints apply inside them. The variable timing_enable_pulse_clock_constraints controls this. Setting it to true enables pulse clock constraint checking. Setting it to false makes the tool ignore pulse clock constraints and use the general constraints everywhere.

During report_analysis_coverage, the tool sets this variable to false for a moment, to collect design data correctly. It prints an information message when it does.

9.8  Constraining transitions at pulse generators

A pulse generator needs a sharp enough input edge, and its output network needs controlled slopes. Two commands set these limits.

Minimum transition, at the pulse generator input only:

Minimum transition syntax
set_pulse_clock_min_transition [-rise | -⁠fall] value object_list

You can apply it by pulse generator instance, pulse generator library cell, clock or design. On a clock, it covers the inputs of all pulse generators in that clock network. On a design, it covers all pulse generator inputs.

Maximum transition, at the input or in the fanout:

  • set_pulse_clock_max_transition without -⁠transitive_fanout constrains only the pulse generator inputs.
  • With -⁠transitive_fanout, it constrains the fanout of the pulse generators.
  • You can apply it by instance, library cell, clock or design. On a design, all pulse networks are covered.
  • A set_max_transition limit on the design also applies to pulse networks. So do maximum transition limits on library pins.

For both commands, the most restrictive constraint wins on a conflict. -⁠rise and -⁠fall constrain the two edges separately.

Table 6 lists the remove and report commands.

Table 6 Removing and reporting pulse transition constraints
Task Command
Remove minimum transition at inputs remove_pulse_clock_min_transition
Remove maximum transition at inputs remove_pulse_clock_max_transition, without -⁠transitive_fanout
Remove maximum transition in fanout remove_pulse_clock_max_transition -⁠transitive_fanout
Report maximum transition report_pulse_clock_max_transition or report_constraint -⁠pulse_clock_max_transition
Report minimum transition at inputs report_pulse_clock_min_transition or report_constraint -⁠pulse_clock_min_transition

To report the maximum transition at pulse generator inputs, leave out -⁠transitive_fanout. As with width, timing_enable_pulse_clock_constraints must be true for pulse clock constraint checking.

10  PLL-based designs

10.1  What a PLL does for timing

A phase-locked loop (PLL) aligns the phase of its feedback pin with the phase of its reference clock. If the feedback is taken from the end of the clock tree, the tree delay is nearly canceled. This reduces skew between launch and capture flops. It also allows much faster chip-to-chip communication.

Effects such as on-chip variation (OCV) and signal integrity need a complete and accurate analysis that includes the PLL. OCV is the small spread of delays across one die; the Variation chapter covers it.

The PLL library model marks the reference, output and feedback pins with attributes. The tool uses them for extra error checks when you define the PLL output clocks. During the timing update, the tool computes the feedback path timing. It applies that as a phase correction on the PLL cell. This keeps runtime low and scripts short. The approach supports:

  • multiple PLLs, and PLLs with multiple outputs;
  • PLL jitter and long-term drift;
  • CRPR for PLL paths, and PrimeTime SI (signal integrity) analysis;
  • sequential cells in the feedback path;
  • PLL adjustment during path-based analysis.

10.2  Defining PLL output clocks

You create each PLL output clock with create_generated_clock, plus two PLL options:

  • -⁠pll_feedback names the PLL feedback pin used for the phase correction.
  • -⁠pll_output names the PLL output pin whose clock reaches the feedback pin.

For a single-output PLL, -⁠pll_output is the same pin as the generated clock source. For a multiple-output PLL with one shared feedback path, it can be a different output.

With these options, only some options are allowed, and four pins are involved:

Table 7 The four pins in a PLL clock definition
Pin Given by What it is
Source object the pin the clock is created on A single pin: the PLL clock output being described
Master pin -⁠source The reference clock input of the PLL
Feedback pin -⁠pll_feedback The feedback input of the PLL
Output pin -⁠pll_output The output where the feedback path starts; can differ from the source object

All four pins must belong to the same cell. For the PLL adjustment to work, both clocks must be propagated. That means the PLL output clock and the reference clock at the reference pin.

10.3  A sequential cell in the feedback path

If the feedback path has sequential cells, define a generated clock at the output of the last one. Its master pin can be any pin that lies on the feedback path and whose fanout reaches the feedback pin.

In Figure 19, the PLL output CLKO runs at twice the reference frequency at REFC. The flop FFdiv divides it back down before the feedback pin FDBK.

A PLL with a divider in its feedback path
Two generated clocks: the PLL output and the feedback divider
A PLL with a divider in its feedback path
Figure 19 CLK_pll is defined at the PLL output with the PLL options. pll_FDBK_clk is defined at the divider output. With both, the tool can apply the PLL phase correction.What to notice: The feedback path starts at CLKO, the pin named by -pll_output, and ends at FDBK.
Defining the PLL output clock
pt_shell> create_generated_clock -name CLK_pll \
            -source [get_pins UPLL/REFC] \
            -pll_output [get_pins UPLL/CLKO] \
            -pll_feedback [get_pins UPLL/FDBK] \
            -multiply_by 2 [get_pins UPLL/CLKO]   ;# twice the reference frequency
pt_shell> create_generated_clock -name pll_FDBK_clk \
            -source [get_pins UPLL/CLKO] \
            -divide_by 2 [get_pins FFdiv/Q]       ;# the divider in the feedback path

10.4  PLL drift and jitter

Drift is a slow, long-term phase error of the PLL output. Jitter is the fast, edge-to-edge error. You set both with set_clock_latency on the PLL output clock, using -⁠pll_shift:

  • With -⁠pll_shift, the value is added to the base early or late latency of the PLL clock. Normally, set_clock_latency replaces the latency instead.
  • The value given with -⁠pll_shift alone is the drift.
  • Jitter uses both -⁠pll_shift and -⁠dynamic.
  • Set it on the generated clock at the PLL output that feeds the feedback pin. The tool applies the same shift to every PLL output.
PLL drift and jitter
set drift 0.100                                   ;# long-term drift
set jitter 0.020                                  ;# edge-to-edge jitter
create_clock -period 5 [get_ports CLK]            ;# reference clock
create_generated_clock -name CLK_pll -divide_by 1 \
   -source UPLL/CLKIN \
   -pll_feedback UPLL/FDBK \
   -pll_output UPLL/CLKOUT \
   [get_pins UPLL/CLKOUT]                         ;# PLL output clock
set_clock_latency -source -pll_shift [get_clocks CLK_pll] \
   -early -${drift} -dynamic -${jitter}           ;# early: drift and jitter
set_clock_latency -source -pll_shift [get_clocks CLK_pll] \
   -late +${drift} -dynamic +${jitter}            ;# late: drift and jitter
set_propagated_clock {CLK CLK_pll}                ;# both clocks propagated

10.5  CRPR, checks and reports for PLLs

The tool treats all outputs of a PLL as having the same phase. So, for CRPR, the outputs are interchangeable. Take a path launched by OUTCLK1 and captured by OUTCLK2. The last physical common pin is the PLL reference pin. Still, the tool removes clock reconvergence pessimism up to the PLL outputs. This is essential, because the outputs must be in phase. report_crpr shows this by listing one PLL output as the common pin.

Two more checks help:

  • check_timing confirms that a PLL clock reaches each feedback pin. update_timing runs the same check.
  • report_timing shows the PLL adjustment on the line for the PLL output.
Illustrative output — PLL adjustment in report_timing
clock CLK (rise edge)                          0.00       0.00
clock source latency                           0.00       0.00
clk_in (in)                                    0.00       0.00 r
inst_my_pll/REFCLK (my_pll)                    0.00       0.00 r
inst_my_pll/OUTCLK (my_pll) (gclock source)  -⁠798.03 *  -⁠798.03 r
b1/A (buf1a1)                                  0.00    -⁠798.03 r
...

The large negative value is the phase correction. It cancels the delay of the clock tree that the feedback loop measures.

10.6  What the PLL library cell needs

The PLL library cell needs a single positive unate timing arc from the reference pin to each output. Four attributes identify it:

  • is_pll_cell marks the cell as a PLL.
  • is_pll_reference_pin, is_pll_output_pin and is_pll_feedback_pin mark the three kinds of pin.
A PLL cell in the library (one output shown)
cell(my_pll) {
  is_pll_cell : true;
  pin( REFCLK ) { direction : input;  is_pll_reference_pin : true; }
  pin( FBKCLK ) { direction : input;  is_pll_feedback_pin : true; }
  pin( OUTCLK1 ) {
    direction : output;
    is_pll_output_pin : true;
    timing() {                       /* the required timing arc */
      related_pin : "REFCLK";
      timing_sense : positive_unate;
      cell_fall(scalar) { values("0.0"); }
    }
  }
}

A second output, OUTCLK2, would repeat the OUTCLK1 block with its own name.

TakeawayDefine a PLL output with create_generated_clock -⁠pll_feedback -⁠pll_output, propagate the clocks, and let the tool apply the phase correction. Add drift and jitter with -⁠pll_shift.

11  Clock-gating checks

11.1  What the tool checks

A gated clock appears when the clock network holds logic other than buffers and inverters. For example, the clock feeds one input of an AND gate and an enable signal feeds the other. The output is a gated clock.

The tool checks setup and hold on the gating input automatically. The goal is that the gate never cuts or clips the clock. The check runs only on combinational gates. One input must be a clock that can pass through, and the gating input must not be a clock.

  • Clock-gating setup check. The enable must settle before the clock becomes active. The leading clock edge is checked against both edges of the enable. A violation gives a glitch at the start of the pulse, or a clipped pulse.
  • Clock-gating hold check. The enable must stay stable while the clock is active. The trailing clock edge is checked against both edges of the enable. A violation gives a glitch at the end of the pulse, or a clipped pulse.

For an AND gate, the clock is active while high. So the enable must change only while the clock is low. Figure 20 shows a good case and both kinds of violation.

Clock-gating setup and hold
An AND gate: the enable must not change while CK is high
Clock-gating setup and hold
Figure 20 GATE changes while CK is low: clean pulses. GATE rises while CK is high: the pulse is clipped at its start. GATE falls while CK is high: the pulse is clipped at its end.What to notice: The red stretches of GCLK are the damaged parts of each pulse.

A gating check must reach a clock pin to take effect. Such pins include reference pins of sequential timing constraints and the from-pins of sequential arcs.

11.2  Setting and reporting gating checks

By default, the setup and hold values are 0.0. The exception is a library cell with its own gating setup or hold arcs. To set nonzero values, use set_clock_gating_check. It affects only gating checks at the cells or pins you name. To cover a whole clock network, name a clock.

Setting clock-gating margins
pt_shell> set_clock_gating_check -setup 0.2 -hold 0.4 \
            [get_clocks CLK1]  ;# all CLK1 gates
pt_shell> set_clock_gating_check -setup 0.5 [get_cells and1]  ;# one gate only

To run the checks and find violations, use report_clock_gating_check:

Reporting clock-gating checks
pt_shell> report_clock_gating_check [get_cells and1]  ;# run the checks at and1
pt_shell> report_clock_gating_check -auto_inferred_only  ;# tool-inferred gates only

With -⁠auto_inferred_only, the report shows only gates the tool inferred itself. It leaves out checks inserted by the Power Compiler tool or defined by clock-gating library cells. To remove values set with set_clock_gating_check, use remove_clock_gating_check.

11.3  Disabling and restoring gating checks

You can disable or restore gating checks on any pin or cell in the design or its subdesigns:

Disabling and restoring gating checks
pt_shell> set_disable_clock_gating_check U44/Z      ;# no gating check at this pin
pt_shell> remove_disable_clock_gating_check U44     ;# restore the checks on cell U44

With no objects given, set_disable_clock_gating_check disables all clock-gating checks. That is the same as setting the variable timing_disable_clock_gating_checks to true.

Common beginner mistake

A designer disables all gating checks to silence a noisy report. Real glitch risks on enable paths then go unchecked. It is better to find why the checks fail. Disable a check only on a named pin, with a written reason.

TakeawayClock-gating checks protect the clock pulse from its enable. The enable must be stable through the whole active phase of the clock.

12  Generated clocks

12.1  Why generated clocks need their own definition

Many designs make a new clock from a master clock with on-chip logic, such as a divider. The tool does not look at the circuit logic of a clock generator. So you must describe the generated clock yourself. You define it relative to the master, so it follows any change to the master clock.

create_generated_clock defines an internally generated clock:

  • Running it on an existing generated clock overwrites that clock.
  • Generated clocks become real clocks during analysis. This expansion happens inside report_timing, or explicitly with update_timing.
Table 8 Ways to describe a generated clock
Option Meaning
-⁠divide_by 2 A frequency-divided clock (here, half the master frequency)
-⁠multiply_by 2 A frequency-multiplied clock (here, twice the master frequency)
-⁠edges {1 5 7} A clock built from numbered edges of the master
-⁠edge_shift {2.2 2.2 2.2} Shifts each edge by a time; only with -⁠edges
-⁠combinational Used with -⁠divide_by, -⁠multiply_by or -⁠edges; source latency follows only the logic the master clock passes through
-⁠master_clock Picks the master when several clocks reach the source pin

With -⁠combinational, there must be a valid path for the master clock's rise and fall edges to the generated clock source pin. The source latency of this clock includes only the logic the master clock passes through.

12.2  A divide-by-2 clock

Figure 21 shows a flop FF1 with its QN fed back to D. Each rising edge of SYSCLK toggles Q. So FF1/Q runs at half the frequency. The figure calls this clock DIV2A.

A divide-by-2 generated clock
pt_shell> create_generated_clock -name DIV2A \
            -source [get_ports SYSCLK] -divide_by 2 [get_pins FF1/Q]   ;# half of SYSCLK
  • -⁠source names a port or a pin, not a clock name. It is the master source.
  • The last argument is the pin where the new clock is created.
  • -⁠divide_by counts rising edges at the master source pin. For a clock based on falling edges, use -⁠edges instead.

12.3  Clocks built from edges

The -⁠edges option lists master edges by number. They are the new clock's rising edge, falling edge and next rising edge. Figure 21 numbers the edges of SYSCLK: odd numbers are rising edges, even numbers falling edges.

DIV2A toggles on rising edges, so either form works:

DIV2A two ways
pt_shell> create_generated_clock -name DIV2A \
            -source [get_ports SYSCLK] -divide_by 2 [get_pins FF1/Q]    ;# by division
pt_shell> create_generated_clock -name DIV2A \
            -source [get_ports SYSCLK] -edges { 1 3 5 } [get_pins FF1/Q] ;# by edges
Divided clocks from rising and falling edges
DIV2A follows rising edges; DIV2B follows falling edges
Divided clocks from rising and falling edges
Figure 21 Edges of SYSCLK are numbered 1, 2, 3 and so on. Odd numbers are rising edges and even numbers are falling edges.What to notice: DIV2B changes on even-numbered edges, so -divide_by cannot describe it. Only -edges can.

DIV2B toggles on falling edges, so -⁠divide_by cannot describe it:

DIV2B from falling edges
pt_shell> create_generated_clock -name DIV2B \
            -source [get_ports SYSCLK] -edges { 2 4 6 } [get_pins FF2/Q]  ;# fall edges

Another way is to use the inverted clock at U1/Z as the source. Its edges 1, 3 and 5 are the falling edges of SYSCLK:

DIV2B from an inverted source pin
pt_shell> create_generated_clock -name DIV2B \
            -source [get_pins U1/Z] -edges { 1 3 5 } [get_pins FF2/Q]  ;# U1/Z rises

Edges also describe uneven waveforms. A divide-by-3 circuit can make DIV3A, high for two master periods and low for one. Let SYSCLK have period 2. Then DIV3A rises at edge 1 (time 0), falls at edge 5 (time 4) and rises at edge 7 (time 6).

An asymmetric divide-by-3
pt_shell> create_clock -period 2 -name SYSCLK [get_ports SYSCLK]   ;# master
pt_shell> create_generated_clock -edges { 1 5 7 } \
            -name DIV3A -source [get_ports SYSCLK] [get_pins U2/Q]   ;# period 6

12.4  Shifting the edges of a generated clock

You can shift each edge of a generated clock by a fixed time with -⁠edge_shift. The shift is not clock latency. It is part of the waveform. -⁠edge_shift works only together with -⁠edges.

In Figure 22, a period-2.2 master drives two flops in series. DIV3B comes from U3/Q. DIV3C is the same waveform, one master period later, at U4/QN.

Building clocks from numbered edges
DIV3A from edges 1 5 7; DIV3B and a shifted DIV3C from edges 3 5 9
Building clocks from numbered edges
Figure 22 Top: SYSCLK at period 2 and DIV3A. Bottom: CLK at period 2.2, DIV3B, and DIV3C shifted by 2.2.What to notice: DIV3C has exactly the shape of DIV3B. -edge_shift moved every edge 2.2 later.
Two divide-by-3 clocks, one shifted
pt_shell> create_clock -period 2.2 -name CLK [get_ports SYSCLK]  ;# master
pt_shell> create_generated_clock -edges { 3 5 9 } \
            -name DIV3B -source [get_ports SYSCLK] [get_pins U3/Q]  ;# {2.2 4.4}
pt_shell> create_generated_clock -edges { 3 5 9 } \
            -edge_shift { 2.2 2.2 2.2 } \
            -name DIV3C -source [get_ports SYSCLK] [get_pins U4/QN]  ;# 2.2 later

report_clock lists both the clocks and the generated clock details:

Illustrative output — report_clock
  p - propagated_clock
  G - Generated clock

Clock          Period   Waveform        Attrs     Sources
----------------------------------------------------------
CLK              2.20   {0 1.1}                   {SYSCLK}
DIV3B            6.60   {2.2 4.4}       G         {U3/Q}
DIV3C            6.60   {4.4 6.6}       G         {U4/QN}

Generated     Master       Generated    Waveform
Clock         Source       Source       Modification
----------------------------------------------------------
DIV3B         SYSCLK       U3/Q         edges( 3 5 9 )
DIV3C         SYSCLK       U4/QN        edges( 3 5 9 )
                                        shifts( 2.2 2.2 2.2 )

12.5  Several clocks at the source pin

The generated clock depends on the clock that reaches its -⁠source pin. That pin may receive more than one clock. Then you pick the master with -⁠master_clock, together with -⁠source. report_clock shows the master clock, the master source pin and the generated clock pin.

12.6  Selecting, reporting and removing generated clocks

get_clocks selects clocks by name pattern or by filter. If all generated clocks share a pattern, use it:

Selecting generated clocks by name
pt_shell> set_false_path -from [get_clocks CLK_DIV*] \
            -to [get_clocks CLKB]   ;# all CLK_DIV clocks to CLKB

If the names follow no pattern, filter on the is_generated attribute:

Selecting generated clocks by attribute
pt_shell> set_false_path -from [get_clocks CLK* -filter "is_generated==true"] \
            -to [get_clocks CLKB]   ;# generated clocks only

For reports and clean-up:

  • report_clock reports clocks and generated clocks in the current design.
  • report_clock_timing gives a detailed report of a clock network. The Reporting and Debugging Analysis Results chapter covers it.
  • report_transitive_fanout -⁠clock_tree shows the clock networks in the design.
  • remove_generated_clock removes a generated clock and its clock object.
Removing a generated clock
pt_shell> remove_generated_clock CLK_DIV2   ;# remove CLK_DIV2

12.7  Edge-specific source latency for generated clocks

The source latency of a generated clock depends on which master edge makes each of its edges. The tool takes this into account. It finds the worst-case path that produces the required edge type, starting from the master clock source.

Sometimes paths exist, but none gives the needed edge relationship. The tool then reports error UITE-461. It says that no path is found for the generated clock source latency, and it uses zero source latency:

Illustrative output — an unsatisfiable generated clock
Error: Generated clock 'clk_div2' 'rise_edge' is not
satisfiable; zero source latency will be used. (UITE-461)
Error: Generated clock 'clk_div2' 'fall_edge' is not
satisfiable; zero source latency will be used. (UITE-461)

Path Type: min

Point                                    Incr       Path
----------------------------------------------------------
clock clk_div2 (rise edge)              0.000      0.000
clock source latency                    0.000      0.000
Udiv/Q (FD1)                            0.000      0.000 r
...
Common beginner mistake

A beginner ignores UITE-461 because it is "only latency". However, zero source latency hides the whole master clock path. Every path on that clock is then timed with wrong clock arrival times. Fix the -⁠edges list or the source pin until the error disappears.

TakeawayDefine each generated clock relative to its master pin. Use -⁠divide_by for rising-edge dividers, -⁠edges for anything else, and treat UITE-461 as a real error.

13  Clock mesh analysis

13.1  What a clock mesh is and why it is special

A clock mesh is a grid of metal wires driven by many buffers in parallel. Each load is driven by several drivers at once. Thus, the mesh is a good candidate for circuit-level simulation.

PrimeTime SI offers a simple way to analyze a mesh with transistor-level accuracy, using SPICE simulation. SPICE is a circuit simulator that solves the transistor equations directly. If the clock network does not change, you can reuse the results in later timing and signoff runs.

13.2  How the analysis works

  1. You give the root node of the clock network.
  2. From there, the tool traces the whole network, including the mesh and the sequential loads.
  3. It runs an external HSPICE-compatible simulator on the network. This gives the exact timing of each cell arc and net arc.
  4. It back-annotates the measured delays onto the design.
  5. It reduces the timing arcs of the mesh, as Figure 23 shows.

In the reduction, the tool keeps a single mesh driver. It disables timing through the other drivers. Arcs from the disabled drivers are replaced by equal arcs from the retained driver.

Why reduce? With n drivers and m loads, the full mesh has n × m driver-to-load arcs. After the reduction there are only m. The driver-to-load timing stays accurate.

Reducing a clock mesh for timing
Three drivers become one, and the shortest mesh delay moves into the driver
Reducing a clock mesh for timing
Figure 23 Left: the simulated mesh with three drivers. Right: one retained driver, with the shortest mesh delay moved into the driver. All delays are illustrative.What to notice: Every load keeps the same total delay: 0.42 + 0.03 = 0.30 + 0.15.

13.3  CRPR through the mesh

The delays from the single driver to the loads differ. The shortest one, to the nearest load, is shared by every path through the mesh. To get the most CRPR benefit, this shared part should sit before the CRPR common point. So the tool makes this adjustment:

  • The output of the retained driver becomes the CRPR common point.
  • The tool finds the shortest net delay through the mesh, for example 0.12.
  • It adds that value to the driver cell delay: 0.30 becomes 0.42.
  • It subtracts the same value from every net delay through the mesh: 0.15 becomes 0.03.

report_timing through the mesh shows the timing through the single retained driver. The numbers reflect the SPICE results.

13.4  Running the flow

The flow has two parts. You generate the clock mesh model once. Then you reuse it in as many runs as you need. Figure 24 shows both.

Generating and reusing a clock mesh model
Simulate once, then source the result in every run
Generating and reusing a clock mesh model
Figure 24 The left column runs once. The right column repeats for every mode, as long as the clock network is unchanged.What to notice: The validation step loops back to fixing the setup until the SPICE setup is valid.

The model can be reused while the clock network stays the same. Typical reuse cases are timing analysis, ECO (engineering change order) netlist editing and constraint clean-up.

Clock mesh model generation
# set up the simulator, working directory and options
sim_setup_simulator -simulator /usr/bin/hspice -simulator_type hspice \
  -work_dir ./tmp_dir -sim_options ".option ingold=2 numdgt=6 statfl=1"  ;# SPICE setup

foreach_in_collection lib [get_libs *] {
  sim_setup_library -library $lib \
    -sub_circuit /u/xtalk/si_lib_gen/unit/gem/hspice \
    -header /u/xtalk/si_lib_gen/unit/gem/model_hspice \
    -file_name_pattern {my_%s.spc}                  ;# map cells to SPICE files
}

sim_validate_setup -from A -to Y -lib_cell [get_lib_cells */IV170BQ] \
  -capacitance 48 -transition_time 0.2              ;# optional: check one arc

sim_setup_spice_deck -enable_clock_mesh             ;# turn on mesh model output

read_verilog top.v                                  ;# read the design
link                                                ;# link the design
read_parasitics top.spef                            ;# clock net parasitics
create_clock -period 10 [get_ports CLK1]            ;# clock constraints

sim_analyze_clock_network -from [get_ports CLK1] \
  -output ./clock_mesh_model.tcl                    ;# simulate and annotate

The simulation results are written to a Tcl script. In later runs, source that script instead of repeating the generation steps, then update timing.

Reusing the model in a later run
# ... read the design and clock constraints for this mode ...
source clock_mesh_model.tcl   ;# load the clock simulation results
update_timing                 ;# then continue with the SI analysis

13.5  The five simulation commands

Table 9 Clock network simulation commands
Command What it does
sim_setup_simulator Sets the simulator location, simulator type and working directory
sim_setup_library Library setup, such as mapping transistor models to gate-level cells
sim_setup_spice_deck Sets options for writing the SPICE deck; -⁠enable_clock_mesh turns on mesh model generation
sim_validate_setup Checks that the SPICE setup matches the library characterization
sim_analyze_clock_network Extracts the network from a root, simulates it and back-annotates the results
Simulation setup commands
pt_shell> sim_setup_simulator -simulator /usr/bin/hspice \
            -simulator_type hspice -work_dir ./tmp_dir \
            -sim_options ".option ingold=2 numdgt=6 statfl=1"  ;# simulator setup
Library and SPICE deck setup
pt_shell> sim_setup_library -library $lib_name \
            -sub_circuit /u/xtalk/si_lib_gen/unit/gem/hspice \
            -header /u/xtalk/si_lib_gen/unit/gem/model_hspice \
            -file_name_pattern {my_%s.spc}                      ;# SPICE files per cell
pt_shell> sim_setup_spice_deck -enable_clock_mesh               ;# mesh model flow on

sim_validate_setup deserves care, because a wrong SPICE setup spoils everything after it:

  • It runs the simulator from sim_setup_simulator on the timing arcs of one library cell.
  • It checks that the library characterization settings match the SPICE setup.
  • It looks for the SPICE executable, SPICE netlists, model files and licenses.
  • It checks SPICE options and data such as I/O rail settings and unit sizes.
  • It checks the model license and the SPICE version against the model.
  • If no errors are found, it shows the delay and slew from SPICE and from PrimeTime side by side.

It supports only combinational cells. It assumes the library is already fully validated, so any mismatch points at the simulator setup. It runs only when no design is loaded.

Validating the simulator setup
pt_shell> sim_validate_setup -from A -to Y \
            -lib_cell [get_lib_cells $lib_name/IV170BQ] \
            -capacitance 48 -transition_time 0.2  ;# one arc

Finally, sim_analyze_clock_network extracts the network from the root you give. It writes a SPICE deck, runs the simulator and back-annotates the results.

Simulating the clock network
pt_shell> sim_analyze_clock_network -from [get_ports CLK1] \
            -output ./clock_mesh_model.tcl   ;# results saved as a Tcl script
TakeawayA clock mesh is simulated once in SPICE and reduced to one driver. Reuse the saved Tcl model while the clock network stays the same.

14  Worked example: clocking a small block before and after CTS

Let us clock a small block named top. Figure 25 shows its clock network.

  • Port CLK drives FF1 and FF2 through buffer U0.
  • CLK also drives AND gate UG, enabled by EN. UG clocks FF3.
  • Flop FFD divides CLK by 2. Its output clocks FF4.
  • Port TCK is a slow test clock from outside. It clocks FF5 and never talks to CLK.
The worked example: block top
One system clock, one gated branch, one divided branch and an unrelated test clock
The worked example: block top
Figure 25 The clock network of block top. Data paths are left out.What to notice: FF3 is behind a clock gate, FF4 is on a generated clock, and FF5 is on a separate clock domain.

Step 1 — Create the master clocks

Step 1 — real clocks
pt_shell> create_clock -period 10 -waveform {0 5} [get_ports CLK]  ;# system clock
pt_shell> create_clock -period 100 -waveform {0 50} [get_ports TCK] ;# slow test clock

Check: report_clock lists CLK and TCK with the right periods.

Step 2 — Create the generated clock

Step 2 — the divided clock
pt_shell> create_generated_clock -name CLKDIV -source [get_ports CLK] \
            -divide_by 2 [get_pins FFD/Q]   ;# half of CLK, at FFD/Q

Check: report_clock shows CLKDIV with a G and a period of 20. No UITE-461 error appears at the next timing update.

Step 3 — Add a virtual clock for the interface

Step 3 — virtual clock for I/O delays
pt_shell> create_clock -period 10 -name vclk -waveform {0 5}   ;# off-chip partner clock

Input and output delays then refer to vclk, as the Constraining the Design chapter shows.

Step 4 — Pre-CTS latency, uncertainty and transition

Step 4 — estimates before the clock tree exists
pt_shell> set_clock_latency 1.0 -source -early [get_clocks CLK]   ;# board delay, early
pt_shell> set_clock_latency 1.4 -source -late [get_clocks CLK]    ;# board delay, late
pt_shell> set_clock_latency 0.8 [get_clocks CLK]  ;# tree estimate
pt_shell> set_clock_uncertainty -setup 0.3 [get_clocks CLK]       ;# skew plus margin
pt_shell> set_clock_uncertainty -hold 0.1 [get_clocks CLK]        ;# hold margin
pt_shell> set_clock_transition 0.15 [get_clocks CLK]              ;# estimated slope

Check: a setup report for FF1 to FF2 shows source latency 1.4 at launch and 1.0 at capture.

Step 5 — Clock-gating check on UG

Step 5 — gating margins and report
pt_shell> set_clock_gating_check -setup 0.2 -hold 0.1 [get_clocks CLK]  ;# all CLK gates
pt_shell> report_clock_gating_check [get_cells UG]                     ;# check EN at UG

Check: no clock-gating violation at UG. A violation means EN changes while CLK is high.

Step 6 — Declare the unrelated test clock

Step 6 — asynchronous groups
pt_shell> set_clock_groups -asynchronous -name sys_vs_test \
            -group {CLK CLKDIV vclk} -group {TCK}   ;# never time CLK against TCK
pt_shell> report_clock -groups                    ;# confirm the groups
pt_shell> get_clock_relationship {CLK TCK}        ;# report how CLK and TCK relate

Check: the timing report has no path between TCK and the system clocks.

Illustrative output — report_clock after Step 6
Clock          Period   Waveform        Attrs     Sources
----------------------------------------------------------
CLK             10.00   {0 5}                     {CLK}
CLKDIV          20.00   {0 10}          G         {FFD/Q}
TCK            100.00   {0 50}                    {TCK}
vclk            10.00   {0 5}                     {}

Step 7 — Check pulse width and period

Step 7 — clock checks
pt_shell> report_constraint -min_period              ;# library min_period limits
pt_shell> report_min_pulse_width -path_type short    ;# pulse width on clock pins

Check: no minimum period or pulse width violation. Before CTS, these mainly catch waveform and library limit problems.

Step 8 — After CTS: switch to the real tree

Step 8 — post-CTS clocks
pt_shell> set_propagated_clock [all_clocks]     ;# real tree delays from now on
pt_shell> remove_clock_transition [get_clocks CLK]   ;# real slopes replace the estimate

Check: report_timing -⁠path_type full_clock now lists each clock buffer on the clock path. Rerun Step 7, because real tree delays can shrink pulses.

Mentor's tip

Keep the source latency from Step 4 after CTS. It describes the board, which clock tree synthesis does not change. Only the on-chip parts become propagated.

15  Common mistakes and how to catch them

Table 10 Symptoms, causes and fixes
Symptom Likely cause Fix
Flops on a divider output are untimed No generated clock at the divider Add create_generated_clock at the divider pin
Thousands of violations between two clocks Unrelated clocks left synchronous Declare set_clock_groups -⁠asynchronous
False paths between clocks have no effect The clocks are already in a clock group, which invalidates them Remove the redundant false paths
Setup slack looks too good before CTS No clock uncertainty set Add setup and hold uncertainty
Pre-layout clock latency looks wrong Propagated clock used before a clock tree exists Use set_clock_latency estimates until after CTS
Large clock-to-output delays before CTS One buffer drives every clock pin, so slopes are slow Set set_clock_transition
One MUX input clock gets another clock's uncertainty Uncertainty set on ports feeding a clock MUX Set uncertainty on the clock objects
UITE-461 at timing update Edge list or source pin does not match the circuit Fix -⁠edges or -⁠source; never ignore it
Every pair of MUXed clocks is timed No exclusivity declared Use exclusivity points, clock groups or case analysis
Pulse clock width reported as zero No rise and fall latency at the pulse generator Let latency propagate, or set -⁠rise and -⁠fall latency
Error that a pulse clock merges with another sense Two senses of one clock meet Set the wanted sense with set_sense -⁠type clock -⁠pulse

16  Interview preparation

Beginner
Q1. What does create_clock -⁠period 10 -⁠waveform {2 4} [get_ports C1] define?

A clock on port C1 with a 10 ns period, rising at 2 and falling at 4 in each period.

  • The clock is named C1, after its first source.
  • A path group named C1 is also created.
  • The waveform is ideal until you add latency.
What is being tested:whether you can read a waveform and know the side effects of the command.
Beginner
Q2. What is a virtual clock, and why use one?

A clock with no source in the design, used as the reference for input and output delays.

  • It models a clocked device outside the block.
  • You create it with create_clock and -⁠name, and no source object.
What is being tested:whether you understand how interface timing is referenced.
Beginner
Q3. What is the difference between source latency and network latency?

Source latency runs from the ideal origin to the clock definition point; network latency runs on to the register clock pin.

  • Total latency is the sum.
  • Board and off-chip delay are source latency.
  • After CTS, network latency is usually propagated.
What is being tested:the two-part model of clock arrival.
Beginner
Q4. How do setup and hold uncertainty change the required time?

Setup uncertainty is subtracted from the required time; hold uncertainty is added to it.

  • Both make the check harder.
  • A single value applies to both setup and hold.
What is being tested:basic arithmetic of a timing check.
Intermediate
Q5. With source latency of 1.5 early and 2.5 late, which values are used for setup and hold?

Setup uses late launch and early capture; hold uses early launch and late capture.

  • This picks the pessimistic value for each check.
  • Same clock, 10 ns period: the setup window shrinks to 9.0.
What is being tested:whether you can predict the pessimistic corner of a range.
Intermediate
Q6. A path has simple uncertainty 5 on CLKA and interclock uncertainty 2 from CLKB to CLKA. What is used on a CLKB to CLKA path?

2, because interclock uncertainty overrides simple uncertainty.

  • Interclock uncertainty is one-way; set both directions if needed.
  • A CLKA to CLKA path still uses 5.
What is being tested:precedence between uncertainty settings.
Intermediate
Q7. Why might you model PLL jitter with set_clock_latency -⁠dynamic instead of set_clock_uncertainty?

Uncertainty is ignored by crosstalk arrival windows and by CRPR; dynamic latency is handled correctly by both.

  • CRPR uses only the static part up to the common point for paths with different launch and capture edges.
  • report_timing shows static and dynamic latency separately.
What is being tested:understanding of how margin interacts with SI and CRPR.
Intermediate
Q8. What is the difference between -⁠logically_exclusive, -⁠physically_exclusive and -⁠asynchronous?

All three stop timing checks between groups; they differ in crosstalk handling.

  • Asynchronous: crosstalk analyzed with infinite arrival windows.
  • Logically exclusive: crosstalk still analyzed normally.
  • Physically exclusive: no crosstalk analysis between the clocks.
What is being tested:choosing the right relationship for the physical situation.
Intermediate
Q9. Two clocks have periods 4 and 6. How does the tool find the worst setup check between them?

It expands both clocks over the base period, the least common multiple 12, and checks every launch edge against every capture edge.

  • This assumes the clocks are synchronous, which is the default.
  • Unrelated clocks with odd periods can give huge base periods and false violations.
What is being tested:understanding of synchronous clock expansion.
Advanced
Q10. When would you choose clock exclusivity points over set_clock_groups -⁠logically_exclusive?

When clocks are exclusive only below a MUX, but may still interact above it.

  • Exclusivity points make clocks physically exclusive in the MUX fanout only.
  • They can be inferred at MUX cells with timing_enable_auto_mux_clock_exclusivity.
  • Random-logic MUXes need set_clock_exclusivity -⁠type user_defined.
What is being tested:precise scoping of clock exclusivity.
Advanced
Q11. How is the width of a pulse clock determined?

The nominal width is zero; the real width is fall network latency minus rise network latency for a high pulse.

  • Latency can be propagated or set with set_clock_latency -⁠rise and -⁠fall.
  • A low pulse uses rise minus fall.
What is being tested:understanding of how pulse clocks are modeled.
Advanced
Q12. How do you define a pulse clock that rises and falls on the rising edge of its source?

create_generated_clock -⁠edges {1 1 3}, or set_sense -⁠type clock -⁠pulse rise_triggered_high_pulse at the generator output.

  • The generated clock creates a new domain; the sense does not.
  • A characterized pulse generator cell in the library needs neither.
What is being tested:knowledge of the three pulse clock methods.
Advanced
Q13. A minimum period report shows open edge latency 1.20 and close edge latency 5.13 against a 4.00 limit. What is the slack, and why is it negative?

Slack is −0.07, because the actual period 5.13 − 1.20 = 3.93 is below 4.00.

  • The first edge uses maximum delays and the second uses minimum delays.
  • CRP is added back to the close edge; uncertainty is subtracted.
What is being tested:reading a clock-only check from a report.
Advanced
Q14. Why does the tool reduce a clock mesh to one driver, and how does CRPR stay accurate?

It cuts n × m driver-to-load arcs to m; the shortest mesh delay moves into the retained driver, the CRPR common point.

  • That shared delay is then before the common point, so CRPR removes it.
  • Each load keeps the same total delay.
What is being tested:understanding of mesh modeling for signoff.

17  Chapter close

Compact glossary

Table 11 Clocks glossary
Term Meaning
Ideal waveform The clock's edge times from create_clock, with no network delay
Virtual clock A clock with no source in the design, used for I/O delays
Clock definition point The port or pin where a clock is created
Source latency Delay from the ideal origin to the clock definition point
Network latency Delay from the clock definition point to a register clock pin
Ideal clocking Estimated latency set with set_clock_latency; the default
Propagated clock Latency computed from the real clock tree
Clock uncertainty Margin for skew and jitter; tightens setup and hold
Interclock uncertainty Uncertainty between a "from" clock and a "to" clock
Dynamic latency The jitter part of source latency, seen by SI and CRPR
CRPR Clock reconvergence pessimism removal on shared clock paths
Base period Least common multiple of synchronous clock periods
Synchronous clocks Clocks with a common source and fixed phase; the default
Asynchronous clocks Clocks that do not communicate; edges at any time
Exclusive clocks Clocks never active together, logically or physically
Exclusivity point A pin where only one clock at a time can pass
Clock sense Whether a register sees the clock true, inverted or ambiguous
Non-unate A clock path whose sense is ambiguous, such as through an XOR
Pulse clock A train of short pulses whose two edges come from one source edge
Generated clock A clock derived from a master clock by on-chip logic
Edge numbers Master edges counted 1, 2, 3 …; odd are rising
Clock-gating check Setup and hold of an enable against the clock it gates
Minimum period check Spacing of same-type clock edges against a library limit
PLL Phase-locked loop; aligns feedback phase to the reference
Clock mesh A grid of wires driven by many parallel clock buffers

Clocks on one page

Figure 26 is the summary to redraw from memory.

Clocks on one page
Six boxes you should be able to redraw
Clocks on one page
Figure 26 The whole chapter in six boxes: define, shape, relate, check, special clocks and meshes.What to notice: Each box ends with the one rule people most often forget.

Where the next chapter goes, and why

You can now describe every clock in a design, give it realistic latency and margin, and tell the tool which clocks meet. However, a correct clock is only half of a timing check. The other half is the path that data takes between two clock edges.

The Timing Paths and Exceptions chapter covers those paths. It explains startpoints, endpoints and path groups, including the groups create_clock makes. It also covers exceptions such as false paths and multicycle paths. Thus, the clock relationships you set here become the base that every exception changes.