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.
clkbuf_1 cells.ff1 → ff2hold check, earliest arrival1 cell
- Clock latency
- Cell delay
- Hold time
- New data leaves
At the edge, ff1's Q changes after 0.3119 ns. Nothing slows it down on the way to ff2.
- 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.
- 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).
| Cell | Arc | Through | Edge | Delay (ns) | Time (ns) | Slew (ns) |
|---|---|---|---|---|---|---|
| 1 | ff1/CLK → ff1/Q | dfxtp_1 | rise | 0.3119 | 0.3119 | 0.0329 |
ff1/Q → ff2/D | wire q1 | rise | 0.0000 | 0.3119 | 0.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.
| Check | Data arrival | Data required | Slack (must be ≥ 0) |
|---|---|---|---|
| Setup | Llaunch + tcq + tpath | T + Lcapture − tsetup − Usetup | required − arrival |
| Hold | Llaunch + tcq + tpath | Lcapture + thold + Uhold | arrival − 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.
- setup slack
- hold slack
- 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.
- Capture-clock buffers 4setup slack = 900 ps · hold slack = 33.5 ps
4 buffers: hold slack 0.0335 ns, still met.
- 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 buffers | setup slack | hold slack |
|---|---|---|
| 0 | 606.7 ps | 333.4 ps |
| 1 | 679.8 ps | 253.8 ps |
| 2 | 753.3 ps | 180.2 ps |
| 3 | 826.6 ps | 106.9 ps |
| 4 | 900 ps | 33.5 ps |
| 5 | 973.4 ps | -39.9 ps |
| 6 | 1.047 ns | -113.3 ps |
| 7 | 1.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.
ff1 → ff2setup check, latest arrival3 cells
- Clock latency
- Cell delay
- Uncertainty
- Setup time
- Arrival
Clock-to-Q and two gates: D falls at 0.3789 ns.
- 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.
- 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).
| Cell | Arc | Through | Edge | Delay (ns) | Time (ns) | Slew (ns) |
|---|---|---|---|---|---|---|
| 1 | ff1/CLK → ff1/Q | dfxtp_1 | fall | 0.3082 | 0.3082 | 0.0249 |
ff1/Q → u1/A | wire q1 | fall | 0.0000 | 0.3082 | 0.0249 | |
| 2 | u1/A → u1/Y | inv_1 | rise | 0.0376 | 0.3459 | 0.0299 |
u1/Y → u2/A | wire n1 | rise | 0.0000 | 0.3459 | 0.0299 | |
| 3 | u2/A → u2/Y | nand2_1 | fall | 0.0330 | 0.3789 | 0.0233 |
u2/Y → ff2/D | wire n2 | fall | 0.0000 | 0.3789 | 0.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
ff1 → ff2setup check, latest arrival3 cells
- Clock latency
- Cell delay
- Uncertainty
- Setup time
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).
| Cell | Arc | Through | Edge | Delay (ns) | Time (ns) | Slew (ns) |
|---|---|---|---|---|---|---|
| 1 | ff1/CLK → ff1/Q | dfxtp_1 | rise | 0.3171 | 0.3171 | 0.0388 |
ff1/Q → u1/A | wire q1 | rise | 0.0000 | 0.3171 | 0.0388 | |
| 2 | u1/A → u1/Y | inv_1 | fall | 0.0303 | 0.3474 | 0.0188 |
u1/Y → u2/A | wire n1 | fall | 0.0000 | 0.3474 | 0.0188 | |
| 3 | u2/A → u2/Y | nand2_1 | rise | 0.0354 | 0.3828 | 0.0345 |
u2/Y → ff2/D | wire n2 | rise | 0.0000 | 0.3828 | 0.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 slews | D rising | D falling |
|---|---|---|
| setup time | 0.0508 ns | 0.1033 ns |
| hold time | -0.0285 ns | -0.0468 ns |
| window, setup + hold | 0.0223 ns | 0.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.
hd1 (dlygate4sd3_1) sits between ff1 and ff2.ff1 → ff2hold check, earliest arrival2 cells
- Clock latency
- Cell delay
- Hold time
- The delay cell
hd1adds 0.5205 ns to the fastest path. - 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).
| Cell | Arc | Through | Edge | Delay (ns) | Time (ns) | Slew (ns) |
|---|---|---|---|---|---|---|
| 1 | ff1/CLK → ff1/Q | dfxtp_1 | rise | 0.3123 | 0.3123 | 0.0333 |
ff1/Q → hd1/A | wire q1 | rise | 0.0000 | 0.3123 | 0.0333 | |
| 2 | hd1/A → hd1/X | dlygate4sd3_1 | rise | 0.5205 | 0.8327 | 0.0451 |
hd1/X → ff2/D | wire q1d | rise | 0.0000 | 0.8327 | 0.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
ff1 → ff2setup check, latest arrival2 cells
- Clock latency
- Cell delay
- Setup time
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).
| Cell | Arc | Through | Edge | Delay (ns) | Time (ns) | Slew (ns) |
|---|---|---|---|---|---|---|
| 1 | ff1/CLK → ff1/Q | dfxtp_1 | fall | 0.3048 | 0.3048 | 0.0220 |
ff1/Q → hd1/A | wire q1 | fall | 0.0000 | 0.3048 | 0.0220 | |
| 2 | hd1/A → hd1/X | dlygate4sd3_1 | fall | 0.5291 | 0.8340 | 0.0484 |
hd1/X → ff2/D | wire q1d | fall | 0.0000 | 0.8340 | 0.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
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.
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.
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.
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.
Run to draw the timing paths here.
worst minimum slack -0.0399 ns WNS 0.9734 nsCheck yourself
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.