Setup and hold with skew and uncertainty

Write the setup and hold checks with clock latency, skew and uncertainty, read each term in an OpenSTA report, and repair a hold violation that no clock period can fix.

Lesson
L2.4
Time
30 min
Runs on
OpenROAD
Check
6 questions

A two-flop shift register with no logic between the flops failed in silicon, after passing every RTL simulation. The capture flop's clock ran through five more buffers than the launch flop's and arrived 0.3818 ns late. The launch flop's clock-to-Q of 0.3119 ns was too short to keep D steady past that late edge.

Timing pathThe hold check of the shift registerFlop ff1 launches and flop ff2 captures on the same clock edge. The clock of ff2 passes through five clkbuf_1 cells.

ff1 → ff2hold check, earliest arrival1 cell

  • Clock latency
  • Cell delay
  • Hold time
The hold check of the shift register00.050.10.150.20.250.30.35time (ns)launch and capture clk ↑Data arrivesRequired afterff1/CLK → ff1/Q (dfxtp_1): 0.3119 ns1 dfxtp_1clock 0.3818 nshold −0.0300 nsslack −0.0399 ns · violatedarrival 0.3119required 0.3518The hold check of the shift register00.10.20.3time (ns)launch and capture clk ↑Data arrivesRequired afterff1/CLK → ff1/Q (dfxtp_1): 0.3119 ns1 dfxtp_1clock 0.3818 nshold −0.0300 nsslack −0.0399 ns · violatedarrival 0.3119required 0.3518
  1. New data leaves

    At the edge, ff1's Q changes after 0.3119 ns. Nothing slows it down on the way to ff2.

  2. The late edge

    The same edge reaches ff2 0.3818 ns late, and ff2 needs its old D until then. Its hold time is -0.0300 ns, so the window closes just before that late edge.

  3. Too early

    The new data arrives 0.0399 ns before ff2 stops sampling: hold slack -0.0399 ns.

Read the path as a table

Launch: clk rise edge at 0.0000 ns, clock latency 0.0000 ns. Capture: clk rise edge at 0.0000 ns, latency 0.3818 ns, library hold time −0.0300 ns.

Arrival 0.3119 ns, required 0.3518 ns, slack −0.0399 ns (violated).

CellArcThroughEdgeDelay (ns)Time (ns)Slew (ns)
1ff1/CLK → ff1/Qdfxtp_1rise0.31190.31190.0329
ff1/Q → ff2/Dwire q1rise0.00000.31190.0329
The report
Startpoint: ff1 (rising edge-triggered flip-flop clocked by clk)
Endpoint: ff2 (rising edge-triggered flip-flop clocked by clk)
Path Group: clk
Path Type: min

Fanout       Cap      Slew     Delay      Time   Description
-------------------------------------------------------------------------------------
                              0.0000    0.0000   clock clk (rise edge)
                              0.0000    0.0000   clock source latency
     2    0.0041    0.1000    0.0000    0.0000 ^ clk (in)
                                                 clk (net)
                    0.1000    0.0000    0.0000 ^ ff1/CLK (sky130_fd_sc_hd__dfxtp_1)
     1    0.0017    0.0329    0.3119    0.3119 ^ ff1/Q (sky130_fd_sc_hd__dfxtp_1)
                                                 q1 (net)
                    0.0329    0.0000    0.3119 ^ ff2/D (sky130_fd_sc_hd__dfxtp_1)
                                        0.3119   data arrival time

                              0.0000    0.0000   clock clk (rise edge)
                              0.0000    0.0000   clock source latency
     2    0.0041    0.1000    0.0000    0.0000 ^ clk (in)
                                                 clk (net)
                    0.1000    0.0000    0.0000 ^ cb1/A (sky130_fd_sc_hd__clkbuf_1)
     1    0.0022    0.0395    0.0906    0.0906 ^ cb1/X (sky130_fd_sc_hd__clkbuf_1)
                                                 ck1 (net)
                    0.0395    0.0000    0.0906 ^ cb2/A (sky130_fd_sc_hd__clkbuf_1)
     1    0.0022    0.0388    0.0736    0.1642 ^ cb2/X (sky130_fd_sc_hd__clkbuf_1)
                                                 ck2 (net)
                    0.0388    0.0000    0.1642 ^ cb3/A (sky130_fd_sc_hd__clkbuf_1)
     1    0.0022    0.0388    0.0734    0.2376 ^ cb3/X (sky130_fd_sc_hd__clkbuf_1)
                                                 ck3 (net)
                    0.0388    0.0000    0.2376 ^ cb4/A (sky130_fd_sc_hd__clkbuf_1)
     1    0.0022    0.0388    0.0734    0.3110 ^ cb4/X (sky130_fd_sc_hd__clkbuf_1)
                                                 ck4 (net)
                    0.0388    0.0000    0.3110 ^ cb5/A (sky130_fd_sc_hd__clkbuf_1)
     1    0.0019    0.0353    0.0708    0.3818 ^ cb5/X (sky130_fd_sc_hd__clkbuf_1)
                                                 ck5 (net)
                    0.0353    0.0000    0.3818 ^ ff2/CLK (sky130_fd_sc_hd__dfxtp_1)
                              0.0000    0.3818   clock reconvergence pessimism
                             -0.0300    0.3518   library hold time
                                        0.3518   data required time
-------------------------------------------------------------------------------------
                                        0.3518   data required time
                                       -0.3119   data arrival time
-------------------------------------------------------------------------------------
                                       -0.0399   slack (VIOLATED)

OpenSTA 3.1.0 on the sky130 tt library, propagated clock with a 0.1 ns input slew, no wires.

R4.1 said no clock period fixes hold. Here are the numbers, with the clock as it really arrives.

Latency, skew and uncertainty

R4.1 drew one clock edge reaching both flops at once. In silicon the edge reaches each flop at its own time, its latency L: the delay from the clock source to that flop's clock pin. Skew is the difference between two flops, Lcapture − Llaunch. Positive skew means the capture flop sees the edge later.

Uncertainty U is a margin you add in the constraints for what the analysis does not model. Clock jitter goes here. Before the clock tree exists, an estimate of the skew to come goes here too. set_clock_uncertainty with no -setup or -hold applies its value to both checks.

CheckData arrivalData requiredSlack (must be ≥ 0)
SetupLlaunch + tcq + tpathT + Lcapture − tsetup − Usetuprequired − arrival
HoldLlaunch + tcq + tpathLcapture + thold + Uholdarrival − required

One clock of period T, a single-cycle path. Setup takes the slowest arrival, hold the fastest.

Rearrange them and the trade is plain. Setup needs T ≥ tcq + tpath + tsetup + Usetup − skew. Hold needs tcq + tpath ≥ thold + Uhold + skew. Positive skew gives setup time and takes it from hold, and T appears only in setup.

Hold compares the launch and capture of the same edge, so most of the jitter cancels. That is why designers usually give hold a smaller uncertainty than setup, often only the expected skew.

Skew helps setup and hurts hold

The plot is one OpenSTA run of eight shift registers. Each capture clock passes through a different number of clkbuf_1 cells. Every buffer delays the capture edge by about 0.076 ns, and the two slacks move by nearly the same amount in opposite directions.

Measured sweepSetup and hold slack against the buffers in the capture clockA 1 ns clock, propagated, with a 0.1 ns slew at the clock port.
  • setup slack
  • hold slack
-0.4 ns-0.2 ns00.2 ns0.4 ns0.6 ns0.8 ns1.0 ns1.2 nsSlack01234567Capture-clock buffersslack 0-0.5 ns00.5 ns1.0 ns1.5 nsSlack0246Capture-clock buffersslack 0
  1. Capture-clock buffers 0setup slack = 606.7 ps · hold slack = 333.4 ps

    No skew: setup slack 0.6067 ns, hold slack 0.3334 ns. The flop's own clock-to-Q protects hold.

  2. Capture-clock buffers 4setup slack = 900 ps · hold slack = 33.5 ps

    4 buffers: hold slack 0.0335 ns, still met.

  3. Capture-clock buffers 5setup slack = 973.4 ps · hold slack = -39.9 ps

    5 buffers: hold slack -0.0399 ns. Setup has grown to 0.9734 ns, and a slower clock would add only to that.

Read the plot as a table
Capture-clock bufferssetup slackhold slack
0606.7 ps333.4 ps
1679.8 ps253.8 ps
2753.3 ps180.2 ps
3826.6 ps106.9 ps
4900 ps33.5 ps
5973.4 ps-39.9 ps
61.047 ns-113.3 ps
71.12 ns-186.6 ps

OpenSTA 3.1.0, dfxtp_1 and clkbuf_1 from the sky130_fd_sc_hd tt library, no wires.

set_propagated_clock tells OpenSTA to time the clock through the buffers in the netlist. Without it the clock is ideal: every flop sees the edge at its latency from the constraints, zero by default. That is how timing runs before clock tree synthesis, in L5.

Uncertainty and the critical transition

Back to the two-flop path, with set_clock_uncertainty -setup 0.05. The report lists the uncertainty on the required side, where it shortens the time available. The data can arrive with D rising or D falling, and the two are checked separately.

Timing pathSetup of the two-flop path, D fallingThe worst setup path: ff1 → u1 (inv_1) → u2 (nand2_1) → ff2, with 0.05 ns of setup uncertainty.

ff1 → ff2setup check, latest arrival3 cells

  • Clock latency
  • Cell delay
  • Uncertainty
  • Setup time
Setup of the two-flop path, D falling00.10.20.30.40.50.60.70.80.91time (ns)launch clk ↑capture clk ↑Data arrivesRequired byff1/CLK → ff1/Q (dfxtp_1): 0.3082 ns1 dfxtp_1u1/A → u1/Y (inv_1): 0.0376 ns2u2/A → u2/Y (nand2_1): 0.0330 ns3uncertainty −0.0500 nssetup −0.0882 nsslack +0.4829 ns · metarrival 0.3789required 0.8618Setup of the two-flop path, D falling00.20.40.60.81time (ns)launch clk ↑capture clk ↑Data arrivesRequired byff1/CLK → ff1/Q (dfxtp_1): 0.3082 ns1 dfxtp_1u1/A → u1/Y (inv_1): 0.0376 nsu2/A → u2/Y (nand2_1): 0.0330 nsuncertainty −0.0500 nssetup −0.0882 nsslack +0.4829 ns · metarrival 0.3789required 0.8618
  1. Arrival

    Clock-to-Q and two gates: D falls at 0.3789 ns.

  2. Required

    The next edge at 1 ns, minus 0.05 ns of uncertainty and a setup time of 0.0882 ns: required at 0.8618 ns.

  3. Slack

    0.4829 ns. So the smallest period that passes for this transition is 1 − 0.4829 = 0.5171 ns.

Read the path as a table

Launch: clk rise edge at 0.0000 ns, clock latency 0.0000 ns (ideal). Capture: clk rise edge at 1.0000 ns, latency 0.0000 ns, uncertainty −0.0500 ns, library setup time −0.0882 ns.

Arrival 0.3789 ns, required 0.8618 ns, slack 0.4829 ns (met).

CellArcThroughEdgeDelay (ns)Time (ns)Slew (ns)
1ff1/CLK → ff1/Qdfxtp_1fall0.30820.30820.0249
ff1/Q → u1/Awire q1fall0.00000.30820.0249
2u1/A → u1/Yinv_1rise0.03760.34590.0299
u1/Y → u2/Awire n1rise0.00000.34590.0299
3u2/A → u2/Ynand2_1fall0.03300.37890.0233
u2/Y → ff2/Dwire n2fall0.00000.37890.0233
The report
Startpoint: ff1 (rising edge-triggered flip-flop clocked by clk)
Endpoint: ff2 (rising edge-triggered flip-flop clocked by clk)
Path Group: clk
Path Type: max

Fanout       Cap      Slew     Delay      Time   Description
-------------------------------------------------------------------------------------
                    0.1000    0.0000    0.0000   clock clk (rise edge)
                              0.0000    0.0000   clock network delay (ideal)
                    0.1000    0.0000    0.0000 ^ ff1/CLK (sky130_fd_sc_hd__dfxtp_1)
     1    0.0022    0.0249    0.3082    0.3082 v ff1/Q (sky130_fd_sc_hd__dfxtp_1)
                                                 q1 (net)
                    0.0249    0.0000    0.3082 v u1/A (sky130_fd_sc_hd__inv_1)
     1    0.0024    0.0299    0.0376    0.3459 ^ u1/Y (sky130_fd_sc_hd__inv_1)
                                                 n1 (net)
                    0.0299    0.0000    0.3459 ^ u2/A (sky130_fd_sc_hd__nand2_1)
     1    0.0017    0.0233    0.0330    0.3789 v u2/Y (sky130_fd_sc_hd__nand2_1)
                                                 n2 (net)
                    0.0233    0.0000    0.3789 v ff2/D (sky130_fd_sc_hd__dfxtp_1)
                                        0.3789   data arrival time

                    0.1000    1.0000    1.0000   clock clk (rise edge)
                              0.0000    1.0000   clock network delay (ideal)
                             -0.0500    0.9500   clock uncertainty
                              0.0000    0.9500   clock reconvergence pessimism
                                        0.9500 ^ ff2/CLK (sky130_fd_sc_hd__dfxtp_1)
                             -0.0882    0.8618   library setup time
                                        0.8618   data required time
-------------------------------------------------------------------------------------
                                        0.8618   data required time
                                       -0.3789   data arrival time
-------------------------------------------------------------------------------------
                                        0.4829   slack (MET)

OpenSTA 3.1.0, ideal clock with a 0.1 ns clock slew.

The same path with D rising
Timing pathSetup of the two-flop path, D rising

ff1 → ff2setup check, latest arrival3 cells

  • Clock latency
  • Cell delay
  • Uncertainty
  • Setup time
Setup of the two-flop path, D rising00.10.20.30.40.50.60.70.80.91time (ns)launch clk ↑capture clk ↑Data arrivesRequired byff1/CLK → ff1/Q (dfxtp_1): 0.3171 ns1 dfxtp_1u1/A → u1/Y (inv_1): 0.0303 ns2u2/A → u2/Y (nand2_1): 0.0354 ns3uncertainty −0.0500 nssetup −0.0437 nsslack +0.5234 ns · metarrival 0.3828required 0.9063Setup of the two-flop path, D rising00.20.40.60.81time (ns)launch clk ↑capture clk ↑Data arrivesRequired byff1/CLK → ff1/Q (dfxtp_1): 0.3171 ns1 dfxtp_1u1/A → u1/Y (inv_1): 0.0303 nsu2/A → u2/Y (nand2_1): 0.0354 nsuncertainty −0.0500 nssetup −0.0437 nsslack +0.5234 ns · metarrival 0.3828required 0.9063
Read the path as a table

Launch: clk rise edge at 0.0000 ns, clock latency 0.0000 ns (ideal). Capture: clk rise edge at 1.0000 ns, latency 0.0000 ns, uncertainty −0.0500 ns, library setup time −0.0437 ns.

Arrival 0.3828 ns, required 0.9063 ns, slack 0.5234 ns (met).

CellArcThroughEdgeDelay (ns)Time (ns)Slew (ns)
1ff1/CLK → ff1/Qdfxtp_1rise0.31710.31710.0388
ff1/Q → u1/Awire q1rise0.00000.31710.0388
2u1/A → u1/Yinv_1fall0.03030.34740.0188
u1/Y → u2/Awire n1fall0.00000.34740.0188
3u2/A → u2/Ynand2_1rise0.03540.38280.0345
u2/Y → ff2/Dwire n2rise0.00000.38280.0345
The report
Startpoint: ff1 (rising edge-triggered flip-flop clocked by clk)
Endpoint: ff2 (rising edge-triggered flip-flop clocked by clk)
Path Group: clk
Path Type: max

Fanout       Cap      Slew     Delay      Time   Description
-------------------------------------------------------------------------------------
                    0.1000    0.0000    0.0000   clock clk (rise edge)
                              0.0000    0.0000   clock network delay (ideal)
                    0.1000    0.0000    0.0000 ^ ff1/CLK (sky130_fd_sc_hd__dfxtp_1)
     1    0.0024    0.0388    0.3171    0.3171 ^ ff1/Q (sky130_fd_sc_hd__dfxtp_1)
                                                 q1 (net)
                    0.0388    0.0000    0.3171 ^ u1/A (sky130_fd_sc_hd__inv_1)
     1    0.0023    0.0188    0.0303    0.3474 v u1/Y (sky130_fd_sc_hd__inv_1)
                                                 n1 (net)
                    0.0188    0.0000    0.3474 v u2/A (sky130_fd_sc_hd__nand2_1)
     1    0.0017    0.0345    0.0354    0.3828 ^ u2/Y (sky130_fd_sc_hd__nand2_1)
                                                 n2 (net)
                    0.0345    0.0000    0.3828 ^ ff2/D (sky130_fd_sc_hd__dfxtp_1)
                                        0.3828   data arrival time

                    0.1000    1.0000    1.0000   clock clk (rise edge)
                              0.0000    1.0000   clock network delay (ideal)
                             -0.0500    0.9500   clock uncertainty
                              0.0000    0.9500   clock reconvergence pessimism
                                        0.9500 ^ ff2/CLK (sky130_fd_sc_hd__dfxtp_1)
                             -0.0437    0.9063   library setup time
                                        0.9063   data required time
-------------------------------------------------------------------------------------
                                        0.9063   data required time
                                       -0.3828   data arrival time
-------------------------------------------------------------------------------------
                                        0.5234   slack (MET)

The second path of the same run.

With D rising the data arrives later, at 0.3828 ns against 0.3789 ns, yet it needs less period: 0.4766 ns against 0.5171 ns. The flop's setup time for a falling D is 0.0882 ns, more than twice the 0.0437 ns for a rising one. The critical transition is not always the latest arrival.

dfxtp_1, 0.01 ns slewsD risingD falling
setup time0.0508 ns0.1033 ns
hold time-0.0285 ns-0.0468 ns
window, setup + hold0.0223 ns0.0565 ns

From the setup_rising and hold_rising tables of the pinned Liberty, at their first index: 0.01 ns on the clock and on D.

Setup and hold times are tables too, indexed by the clock slew and the data slew. Hold times here are negative: D may change slightly before the clock edge, and the flop still keeps the old value. The window in which D must hold still is setup plus hold, and it stays positive.

Repair hold in the data path

A hold violation is fixed by making the short path slower, where it ends. Insert a delay cell between the flops: dlygate4sd3_1 is a buffer built to be slow, 0.5205 ns here. Hold slack becomes 0.4835 ns. The delay cell sits on the setup path too: setup slack falls from 0.9734 to 0.4336 ns. It still meets the 1 ns clock, because the late capture edge gave setup room.

Timing pathThe shift register with a delay cellThe same five-buffer capture clock; hd1 (dlygate4sd3_1) sits between ff1 and ff2.

ff1 → ff2hold check, earliest arrival2 cells

  • Clock latency
  • Cell delay
  • Hold time
The shift register with a delay cell00.10.20.30.40.50.60.70.8time (ns)launch and capture clk ↑Data arrivesRequired afterff1/CLK → ff1/Q (dfxtp_1): 0.3123 ns1 dfxtp_1hd1/A → hd1/X (dlygate4sd3_1): 0.5205 ns2 dlygate4sd3_1clock 0.3818 nshold −0.0326 nsslack +0.4835 ns · metarrival 0.8327required 0.3492The shift register with a delay cell00.20.40.60.8time (ns)launch and capture clk ↑Data arrivesRequired afterff1/CLK → ff1/Q (dfxtp_1): 0.3123 ns1 dfxtp_1hd1/A → hd1/X (dlygate4sd3_1): 0.5205 ns2 dlygate4sd3_1clock 0.3818 nshold −0.0326 nsslack +0.4835 ns · metarrival 0.8327required 0.3492
  1. The delay cell

    hd1 adds 0.5205 ns to the fastest path.

  2. Hold met

    Hold slack 0.4835 ns.

Read the path as a table

Launch: clk rise edge at 0.0000 ns, clock latency 0.0000 ns. Capture: clk rise edge at 0.0000 ns, latency 0.3818 ns, library hold time −0.0326 ns.

Arrival 0.8327 ns, required 0.3492 ns, slack 0.4835 ns (met).

CellArcThroughEdgeDelay (ns)Time (ns)Slew (ns)
1ff1/CLK → ff1/Qdfxtp_1rise0.31230.31230.0333
ff1/Q → hd1/Awire q1rise0.00000.31230.0333
2hd1/A → hd1/Xdlygate4sd3_1rise0.52050.83270.0451
hd1/X → ff2/Dwire q1drise0.00000.83270.0451
The report
Startpoint: ff1 (rising edge-triggered flip-flop clocked by clk)
Endpoint: ff2 (rising edge-triggered flip-flop clocked by clk)
Path Group: clk
Path Type: min

Fanout       Cap      Slew     Delay      Time   Description
-------------------------------------------------------------------------------------
                              0.0000    0.0000   clock clk (rise edge)
                              0.0000    0.0000   clock source latency
     2    0.0041    0.1000    0.0000    0.0000 ^ clk (in)
                                                 clk (net)
                    0.1000    0.0000    0.0000 ^ ff1/CLK (sky130_fd_sc_hd__dfxtp_1)
     1    0.0017    0.0333    0.3123    0.3123 ^ ff1/Q (sky130_fd_sc_hd__dfxtp_1)
                                                 q1 (net)
                    0.0333    0.0000    0.3123 ^ hd1/A (sky130_fd_sc_hd__dlygate4sd3_1)
     1    0.0017    0.0451    0.5205    0.8327 ^ hd1/X (sky130_fd_sc_hd__dlygate4sd3_1)
                                                 q1d (net)
                    0.0451    0.0000    0.8327 ^ ff2/D (sky130_fd_sc_hd__dfxtp_1)
                                        0.8327   data arrival time

                              0.0000    0.0000   clock clk (rise edge)
                              0.0000    0.0000   clock source latency
     2    0.0041    0.1000    0.0000    0.0000 ^ clk (in)
                                                 clk (net)
                    0.1000    0.0000    0.0000 ^ cb1/A (sky130_fd_sc_hd__clkbuf_1)
     1    0.0022    0.0395    0.0906    0.0906 ^ cb1/X (sky130_fd_sc_hd__clkbuf_1)
                                                 ck1 (net)
                    0.0395    0.0000    0.0906 ^ cb2/A (sky130_fd_sc_hd__clkbuf_1)
     1    0.0022    0.0388    0.0736    0.1642 ^ cb2/X (sky130_fd_sc_hd__clkbuf_1)
                                                 ck2 (net)
                    0.0388    0.0000    0.1642 ^ cb3/A (sky130_fd_sc_hd__clkbuf_1)
     1    0.0022    0.0388    0.0734    0.2376 ^ cb3/X (sky130_fd_sc_hd__clkbuf_1)
                                                 ck3 (net)
                    0.0388    0.0000    0.2376 ^ cb4/A (sky130_fd_sc_hd__clkbuf_1)
     1    0.0022    0.0388    0.0734    0.3110 ^ cb4/X (sky130_fd_sc_hd__clkbuf_1)
                                                 ck4 (net)
                    0.0388    0.0000    0.3110 ^ cb5/A (sky130_fd_sc_hd__clkbuf_1)
     1    0.0019    0.0353    0.0708    0.3818 ^ cb5/X (sky130_fd_sc_hd__clkbuf_1)
                                                 ck5 (net)
                    0.0353    0.0000    0.3818 ^ ff2/CLK (sky130_fd_sc_hd__dfxtp_1)
                              0.0000    0.3818   clock reconvergence pessimism
                             -0.0326    0.3492   library hold time
                                        0.3492   data required time
-------------------------------------------------------------------------------------
                                        0.3492   data required time
                                       -0.8327   data arrival time
-------------------------------------------------------------------------------------
                                        0.4835   slack (MET)

OpenSTA 3.1.0, propagated clock.

The setup path after the repair
Timing pathSetup of the repaired shift register

ff1 → ff2setup check, latest arrival2 cells

  • Clock latency
  • Cell delay
  • Setup time
Setup of the repaired shift register00.20.40.60.811.21.4time (ns)launch clk ↑capture clk ↑Data arrivesRequired byff1/CLK → ff1/Q (dfxtp_1): 0.3048 ns1 dfxtp_1hd1/A → hd1/X (dlygate4sd3_1): 0.5291 ns2 dlygate4sd3_1clock 0.3818 nssetup −0.1143 nsslack +0.4336 ns · metarrival 0.8340required 1.2675Setup of the repaired shift register00.51time (ns)launch clk ↑capture clk ↑Data arrivesRequired byff1/CLK → ff1/Q (dfxtp_1): 0.3048 ns1 dfxtp_1hd1/A → hd1/X (dlygate4sd3_1): 0.5291 ns2 dlygate4sd3_1clock 0.3818 nssetup −0.1143 nsslack +0.4336 ns · metarrival 0.8340required 1.2675
Read the path as a table

Launch: clk rise edge at 0.0000 ns, clock latency 0.0000 ns. Capture: clk rise edge at 1.0000 ns, latency 0.3818 ns, library setup time −0.1143 ns.

Arrival 0.8340 ns, required 1.2675 ns, slack 0.4336 ns (met).

CellArcThroughEdgeDelay (ns)Time (ns)Slew (ns)
1ff1/CLK → ff1/Qdfxtp_1fall0.30480.30480.0220
ff1/Q → hd1/Awire q1fall0.00000.30480.0220
2hd1/A → hd1/Xdlygate4sd3_1fall0.52910.83400.0484
hd1/X → ff2/Dwire q1dfall0.00000.83400.0484
The report
Startpoint: ff1 (rising edge-triggered flip-flop clocked by clk)
Endpoint: ff2 (rising edge-triggered flip-flop clocked by clk)
Path Group: clk
Path Type: max

Fanout       Cap      Slew     Delay      Time   Description
-------------------------------------------------------------------------------------
                              0.0000    0.0000   clock clk (rise edge)
                              0.0000    0.0000   clock source latency
     2    0.0041    0.1000    0.0000    0.0000 ^ clk (in)
                                                 clk (net)
                    0.1000    0.0000    0.0000 ^ ff1/CLK (sky130_fd_sc_hd__dfxtp_1)
     1    0.0016    0.0220    0.3048    0.3048 v ff1/Q (sky130_fd_sc_hd__dfxtp_1)
                                                 q1 (net)
                    0.0220    0.0000    0.3048 v hd1/A (sky130_fd_sc_hd__dlygate4sd3_1)
     1    0.0017    0.0484    0.5291    0.8340 v hd1/X (sky130_fd_sc_hd__dlygate4sd3_1)
                                                 q1d (net)
                    0.0484    0.0000    0.8340 v ff2/D (sky130_fd_sc_hd__dfxtp_1)
                                        0.8340   data arrival time

                              1.0000    1.0000   clock clk (rise edge)
                              0.0000    1.0000   clock source latency
     2    0.0041    0.1000    0.0000    1.0000 ^ clk (in)
                                                 clk (net)
                    0.1000    0.0000    1.0000 ^ cb1/A (sky130_fd_sc_hd__clkbuf_1)
     1    0.0022    0.0395    0.0906    1.0906 ^ cb1/X (sky130_fd_sc_hd__clkbuf_1)
                                                 ck1 (net)
                    0.0395    0.0000    1.0906 ^ cb2/A (sky130_fd_sc_hd__clkbuf_1)
     1    0.0022    0.0388    0.0736    1.1642 ^ cb2/X (sky130_fd_sc_hd__clkbuf_1)
                                                 ck2 (net)
                    0.0388    0.0000    1.1642 ^ cb3/A (sky130_fd_sc_hd__clkbuf_1)
     1    0.0022    0.0388    0.0734    1.2376 ^ cb3/X (sky130_fd_sc_hd__clkbuf_1)
                                                 ck3 (net)
                    0.0388    0.0000    1.2376 ^ cb4/A (sky130_fd_sc_hd__clkbuf_1)
     1    0.0022    0.0388    0.0734    1.3110 ^ cb4/X (sky130_fd_sc_hd__clkbuf_1)
                                                 ck4 (net)
                    0.0388    0.0000    1.3110 ^ cb5/A (sky130_fd_sc_hd__clkbuf_1)
     1    0.0019    0.0353    0.0708    1.3818 ^ cb5/X (sky130_fd_sc_hd__clkbuf_1)
                                                 ck5 (net)
                    0.0353    0.0000    1.3818 ^ ff2/CLK (sky130_fd_sc_hd__dfxtp_1)
                              0.0000    1.3818   clock reconvergence pessimism
                             -0.1143    1.2675   library setup time
                                        1.2675   data required time
-------------------------------------------------------------------------------------
                                        1.2675   data required time
                                       -0.8340   data arrival time
-------------------------------------------------------------------------------------
                                        0.4336   slack (MET)

The same run, max path.

This cell is far more than the 0.0399 ns that hold lacked, and setup paid for all of it. A repair tool adds only about as much delay as hold needs, and by default it skips a fix that would break setup. Removing the extra clock buffers would also work, and that is what clock tree synthesis tries to do. The flow repairs what remains with buffers and delay cells after the tree is built.

Asked in interviews
  1. Write the setup and hold equations with skew.

    Setup: T + L_capture − t_setup − U_setup ≥ L_launch + t_cq + t_path,max. Hold: L_launch + t_cq + t_path,min ≥ L_capture + t_hold + U_hold. Positive skew, L_capture − L_launch, helps setup and hurts hold.

  2. Is clock skew good or bad?

    Neither by itself. Positive skew gives a path more time for setup and takes the same time from its hold margin. Skew used on purpose is called useful skew; skew nobody planned breaks hold on short paths.

  3. Can a flop have a negative hold time?

    Yes. It means D may change slightly before the clock edge without disturbing the capture. The setup plus hold window is still positive.

  4. How do you fix a hold violation?

    Add delay to the short data path, usually with delay or buffer cells near the capture flop, or reduce the skew. Changing the clock period does not help, because the period is not in the hold check.

Try it

The netlist is the shift register of the hook, with five clkbuf_1 cells in ff2's clock. Run it: hold slack -0.0399 ns, setup slack 0.9734 ns. Open Paths to see both checks drawn.

Now repair it. In the netlist tab, declare wire q1d;, add sky130_fd_sc_hd__dlygate4sd3_1 hd1 (.A(q1), .X(q1d)); and connect ff2's D to q1d. Run again and read both slacks. Then try removing buffers instead, or change the period in the SDC and watch which slack moves.

STAOpenSTA in OpenROAD 26Q2 · sky130hd tt_025C_1v80 Liberty · simulator service
Edit the constraints or the netlist, then run

          
Expected: worst minimum slack -0.0399 ns WNS 0.9734 ns

Check yourself

Predict the outputThe two-flop path with the same 0.05 ns of setup uncertainty, now at a 0.6 ns period. What worst setup slack (WNS) does OpenSTA report, in ns?
create_clock -name clk -period 0.6 [get_ports clk]
set_clock_transition 0.1 [all_clocks]
set_clock_uncertainty -setup 0.05 [all_clocks]
ConceptThe capture flop's clock arrives 0.2 ns after the launch flop's. What does that do to the two checks of the path between them?
ConceptWith 5 buffers in ff2's clock, the shift register fails hold by 0.0399 ns. Which single change makes hold pass?
ConceptAt 0.01 ns slews, dfxtp_1's setup time for a rising D is 0.0508 ns and its hold time -0.0285 ns. D rises 0.01 ns before the clock edge. What does the flop capture at that edge?
ConceptA path has Llaunch = 0.10, Lcapture = 0.35, tcq = 0.30, tpath = 0.02, thold = −0.03 and Uhold = 0.05, all in ns. What is its hold slack?
ConceptBefore CTS, a designer writes set_clock_uncertainty 0.2 [all_clocks] for 0.15 ns of jitter and 0.05 ns of expected skew. What is wrong with it?

Remember

  • Latency is when the clock edge reaches a flop; skew is the capture latency minus the launch latency.
  • Setup: T + L_capture − t_setup − U_setup ≥ L_launch + t_cq + t_path. Hold: L_launch + t_cq + t_path ≥ L_capture + t_hold + U_hold.
  • Positive skew helps setup and hurts hold by the same amount, and the period appears only in setup.
  • Fix hold by slowing the short path or reducing skew; library setup and hold times are tables and may be negative.