Timing arcs: what a cell promises
See a cell the way a timing tool does: a few arcs between pins, each with a type, a sense and its own tables, from gates to flops and their reset checks.
- Lesson
- L2.1
- Time
- 25 min
- Runs on
- OpenROAD
- Check
- 5 questions
An engineer chasing a slow path looked up the NAND's delay in the library: 0.0206 ns, the first entry of its A-to-Y falling table. The timing report said 0.0425 ns for the same cell. The report had timed the B input with a rising output, at this net's slew and load.
u1 (inv_1) drives the B input of u2 (nand2_1), and flop ff2 captures. A 1 ns ideal clock.ff1 → ff2setup check, latest arrival3 cells
- Clock latency
- Cell delay
- Setup time
- B falls
u1's output falls at 0.3473 ns with a 0.0186 ns slew. That is the input edge of the NAND. - Y rises
The NAND's B-to-Y arc with a rising output: 0.0425 ns at a 0.0017 pF load.
- The path meets 1 ns
Slack 0.5665 ns; the NAND is a small share of it.
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, library setup time −0.0438 ns.
Arrival 0.3898 ns, required 0.9562 ns, slack 0.5665 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.0302 | 0.3473 | 0.0186 |
u1/Y → u2/B | wire n1 | fall | 0.0000 | 0.3473 | 0.0186 | |
| 3 | u2/B → u2/Y | nand2_1 | rise | 0.0425 | 0.3898 | 0.0345 |
u2/Y → ff2/D | wire n2 | rise | 0.0000 | 0.3898 | 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.0022 0.0186 0.0302 0.3473 v u1/Y (sky130_fd_sc_hd__inv_1)
n1 (net)
0.0186 0.0000 0.3473 v u2/B (sky130_fd_sc_hd__nand2_1)
1 0.0017 0.0345 0.0425 0.3898 ^ u2/Y (sky130_fd_sc_hd__nand2_1)
n2 (net)
0.0345 0.0000 0.3898 ^ ff2/D (sky130_fd_sc_hd__dfxtp_1)
0.3898 data arrival time
0.1000 1.0000 1.0000 clock clk (rise edge)
0.0000 1.0000 clock network delay (ideal)
0.0000 1.0000 clock reconvergence pessimism
1.0000 ^ ff2/CLK (sky130_fd_sc_hd__dfxtp_1)
-0.0438 0.9562 library setup time
0.9562 data required time
-------------------------------------------------------------------------------------
0.9562 data required time
-0.3898 data arrival time
-------------------------------------------------------------------------------------
0.5665 slack (MET)OpenSTA 3.1.0 on the sky130 tt library, ideal clock with a 0.1 ns slew, no wires.
A cell has no single delay: it has arcs, each with its own tables.
A cell is a small graph
A static timing tool never looks inside a cell. It sees a few timing arcs, each from one pin to another, carrying tables. The Liberty file lists them as timing groups with a related_pin (where the arc starts), a timing_type and a timing_sense.
There are three kinds. A combinational arc runs from a gate's input to its output. A sequential arc runs from a flop's clock pin to its output. A check arc carries no delay: it holds a setup, hold, recovery or removal time around a clock edge.
- Two gate arcs
nand2_1 has one arc from each input to Y. Both are negative unate: a rising input can only pull Y down.
- The launch arc
dfxtp_1 has one delay arc, CLK to Q. It fires on the rising clock edge.
- The check arcs
CLK to D carries the setup and hold tables. No signal travels along it; it bounds when D may change.
Read the diagram as text
- nand2_1 A: input
- nand2_1 B: input
- nand2_1 Y: output
- dfxtp_1 CLK: clock pin
- dfxtp_1 D: data pin
- dfxtp_1 Q: output
- nand2_1 A → nand2_1 Y: combinational
- nand2_1 B → nand2_1 Y: combinational
- dfxtp_1 CLK → dfxtp_1 D: setup, hold
- dfxtp_1 CLK → dfxtp_1 Q: rising_edge
A min_pulse_width check on CLK itself is not drawn: it runs from the pin to itself.
| Cell | Arc | timing_type | timing_sense | Tables |
|---|---|---|---|---|
inv_1 | A → Y | combinational | negative_unate | cell_fall, cell_rise, fall_transition, rise_transition |
buf_1 | A → X | combinational | positive_unate | cell_fall, cell_rise, fall_transition, rise_transition |
nand2_1 | A → Y | combinational | negative_unate | cell_fall, cell_rise, fall_transition, rise_transition |
nand2_1 | B → Y | combinational | negative_unate | cell_fall, cell_rise, fall_transition, rise_transition |
xor2_1 | A → X | combinational | positive_unate | cell_fall, cell_rise, fall_transition, rise_transition |
xor2_1 | A → X | combinational | negative_unate | cell_fall, cell_rise, fall_transition, rise_transition |
xor2_1 | B → X | combinational | positive_unate | cell_fall, cell_rise, fall_transition, rise_transition |
xor2_1 | B → X | combinational | negative_unate | cell_fall, cell_rise, fall_transition, rise_transition |
dfxtp_1 | CLK → CLK | min_pulse_width | none | fall_constraint, rise_constraint |
dfxtp_1 | CLK → D | setup_rising | none | fall_constraint, rise_constraint |
dfxtp_1 | CLK → D | hold_rising | none | fall_constraint, rise_constraint |
dfxtp_1 | CLK → Q | rising_edge | non_unate | cell_fall, cell_rise, fall_transition, rise_transition |
dfrtp_1 | CLK → CLK | min_pulse_width | none | fall_constraint, rise_constraint |
dfrtp_1 | CLK → D | setup_rising | none | fall_constraint, rise_constraint |
dfrtp_1 | CLK → D | hold_rising | none | fall_constraint, rise_constraint |
dfrtp_1 | CLK → Q | rising_edge | non_unate | cell_fall, cell_rise, fall_transition, rise_transition |
dfrtp_1 | RESET_B → Q | clear | positive_unate | cell_fall, fall_transition |
dfrtp_1 | CLK → RESET_B | recovery_rising | none | rise_constraint |
dfrtp_1 | CLK → RESET_B | removal_rising | none | rise_constraint |
dfrtp_1 | RESET_B → RESET_B | min_pulse_width | none | fall_constraint |
Every timing group of six cells in the pinned sky130_fd_sc_hd tt Liberty. A constraint table holds a check time; the others hold delays and slews.
Each delay arc carries a delay table and an output-slew table per output edge, because pull-up and pull-down differ in strength. L2.2 reads them by hand.
The sense pairs input and output edges
The timing sense, or unateness, says which output edge an input edge can cause. Negative unate: a rising input can only make the output fall, as in inv_1 and nand2_1. Positive unate: a rising input can only make it rise, as in buf_1. The tool uses the sense to pair edges. It times a rising NAND input only to a falling output, and never looks the other table up.
An XOR is non-unate: the other input decides the direction. With B low, a rising A makes X rise. With B high, the same rising A makes X fall.
Logic values only: the delays are in the paths below.
This library writes xor2_1 as two arcs from each input, one positive and one negative unate (the table above). Together they act as one non-unate arc. So the same flop reaches ff2 through the XOR four ways: each Q edge to each X edge. An inverter in that place gives only two.
x1 (xor2_1); B comes from an input port; ff2 captures.ff1 → ff2setup check, latest arrival2 cells
- Clock latency
- Cell delay
- Setup time
- Q falls
ff1's Q falls at 0.3177 ns.
- X rises
The negative-unate arc: X rises 0.1208 ns later.
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, library setup time −0.0571 ns.
Arrival 0.4385 ns, required 0.9429 ns, slack 0.5045 ns (met).
| Cell | Arc | Through | Edge | Delay (ns) | Time (ns) | Slew (ns) |
|---|---|---|---|---|---|---|
| 1 | ff1/CLK → ff1/Q | dfxtp_1 | fall | 0.3177 | 0.3177 | 0.0336 |
ff1/Q → x1/A | wire q1 | fall | 0.0000 | 0.3177 | 0.0336 | |
| 2 | x1/A → x1/X | xor2_1 | rise | 0.1208 | 0.4385 | 0.0928 |
x1/X → ff2/D | wire n2 | rise | 0.0000 | 0.4385 | 0.0928 |
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.0042 0.0336 0.3177 0.3177 v ff1/Q (sky130_fd_sc_hd__dfxtp_1)
q1 (net)
0.0336 0.0000 0.3177 v x1/A (sky130_fd_sc_hd__xor2_1)
1 0.0017 0.0928 0.1208 0.4385 ^ x1/X (sky130_fd_sc_hd__xor2_1)
n2 (net)
0.0928 0.0000 0.4385 ^ ff2/D (sky130_fd_sc_hd__dfxtp_1)
0.4385 data arrival time
0.1000 1.0000 1.0000 clock clk (rise edge)
0.0000 1.0000 clock network delay (ideal)
0.0000 1.0000 clock reconvergence pessimism
1.0000 ^ ff2/CLK (sky130_fd_sc_hd__dfxtp_1)
-0.0571 0.9429 library setup time
0.9429 data required time
-------------------------------------------------------------------------------------
0.9429 data required time
-0.4385 data arrival time
-------------------------------------------------------------------------------------
0.5045 slack (MET)The third of four paths to ff2/D in one OpenSTA run, ideal 1 ns clock.
The same Q edge through the positive-unate arc
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 (ideal). Capture: clk rise edge at 1.0000 ns, latency 0.0000 ns, library setup time −0.0933 ns.
Arrival 0.4600 ns, required 0.9067 ns, slack 0.4467 ns (met).
| Cell | Arc | Through | Edge | Delay (ns) | Time (ns) | Slew (ns) |
|---|---|---|---|---|---|---|
| 1 | ff1/CLK → ff1/Q | dfxtp_1 | fall | 0.3177 | 0.3177 | 0.0336 |
ff1/Q → x1/A | wire q1 | fall | 0.0000 | 0.3177 | 0.0336 | |
| 2 | x1/A → x1/X | xor2_1 | fall | 0.1423 | 0.4600 | 0.0351 |
x1/X → ff2/D | wire n2 | fall | 0.0000 | 0.4600 | 0.0351 |
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.0042 0.0336 0.3177 0.3177 v ff1/Q (sky130_fd_sc_hd__dfxtp_1)
q1 (net)
0.0336 0.0000 0.3177 v x1/A (sky130_fd_sc_hd__xor2_1)
1 0.0017 0.0351 0.1423 0.4600 v x1/X (sky130_fd_sc_hd__xor2_1)
n2 (net)
0.0351 0.0000 0.4600 v ff2/D (sky130_fd_sc_hd__dfxtp_1)
0.4600 data arrival time
0.1000 1.0000 1.0000 clock clk (rise edge)
0.0000 1.0000 clock network delay (ideal)
0.0000 1.0000 clock reconvergence pessimism
1.0000 ^ ff2/CLK (sky130_fd_sc_hd__dfxtp_1)
-0.0933 0.9067 library setup time
0.9067 data required time
-------------------------------------------------------------------------------------
0.9067 data required time
-0.4600 data arrival time
-------------------------------------------------------------------------------------
0.4467 slack (MET)The worst of the four paths in the same run.
Same Q edge at 0.3177 ns, opposite X edge: 0.1423 ns through the positive-unate arc against 0.1208 ns through the negative one.
Four delays in one NAND
Two inputs and two output edges give nand2_1 four delay tables. At the first point of each table, a 0.01 ns input slew and a 0.5 fF load, A to Y takes 0.0240 ns rising and 0.0206 ns falling. B to Y takes 0.0314 and 0.0249 ns.
- A to Y, Y rising
- A to Y, Y falling
- B to Y, Y rising
- B to Y, Y falling
- Input slew 10 psA to Y, Y rising = 53.5 ps · A to Y, Y falling = 44.1 ps · B to Y, Y rising = 60 ps · B to Y, Y falling = 48.5 ps
A sharp input: A to Y 0.0535 ns rising, B to Y 0.0600 ns.
- Input slew 500 psA to Y, Y rising = 206.8 ps · A to Y, Y falling = 126.4 ps · B to Y, Y rising = 225.6 ps · B to Y, Y falling = 130.7 ps
At 0.5 ns: 0.2068, 0.1264, 0.2256 and 0.1307 ns. Each arc and edge has its own curve.
- Input slew 1.5 nsA to Y, Y rising = 375.6 ps · A to Y, Y falling = 159.7 ps · B to Y, Y rising = 412 ps · B to Y, Y falling = 170.8 ps
At 1.5 ns the edges have split: from A, 0.3756 ns rising against 0.1597 ns falling. A slow input hurts the rising output most here.
Read the plot as a table
| Input slew | A to Y, Y rising | A to Y, Y falling | B to Y, Y rising | B to Y, Y falling |
|---|---|---|---|---|
| 10 ps | 53.5 ps | 44.1 ps | 60 ps | 48.5 ps |
| 200 ps | 127.9 ps | 93.1 ps | 138.7 ps | 95.1 ps |
| 400 ps | 183.5 ps | 117.9 ps | 199.8 ps | 121.3 ps |
| 500 ps | 206.8 ps | 126.4 ps | 225.6 ps | 130.7 ps |
| 600 ps | 227.1 ps | 132.4 ps | 248 ps | 137.6 ps |
| 800 ps | 265.4 ps | 142.7 ps | 290.4 ps | 149.4 ps |
| 1 ns | 296.9 ps | 147.6 ps | 325.2 ps | 155.5 ps |
| 1.2 ns | 328.4 ps | 152.4 ps | 359.9 ps | 161.6 ps |
| 1.4 ns | 359.9 ps | 157.3 ps | 394.6 ps | 167.7 ps |
| 1.5 ns | 375.6 ps | 159.7 ps | 412 ps | 170.8 ps |
OpenSTA 3.1.0, nand2_1 from the sky130_fd_sc_hd tt library, no wires.
B is slower than A on both edges at every slew in the plot. The library does not say why. The usual cause is the series stack: the input farther from the output must also move the charge between the transistors. Optimization tools swap pins to put the latest signal on the faster input.
Clock arcs and check arcs
dfxtp_1 has one delay arc, CLK to Q, of type rising_edge. Its sense is non_unate: after a rising clock, Q may rise or fall, depending on D. Its other arcs are checks: setup_rising and hold_rising from CLK to D, and a min_pulse_width on CLK, the shortest high or low time the clock may have.
dfrtp_1 adds an active-low asynchronous reset with 4 more arcs. RESET_B to Q is a clear arc with only a falling table: reset can only pull Q low. Two checks guard the release, the rising edge of RESET_B, as R2.2 described. recovery_rising acts like setup: the release must come early enough before an edge. removal_rising acts like hold: it must not come too soon after one.
fr → ffremoval check, earliest arrival1 cell
- Clock latency
- Cell delay
- Removal time
- The release
Flop fr's Q rises 0.3259 ns after the clock edge, releasing ff.
- The removal time
ff needs the release no sooner than 0.3364 ns after that same edge.
- Too soon
Removal slack -0.0105 ns: the flop may leave reset at this edge or the next.
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 0.0000 ns, latency 0.0000 ns, library removal time 0.3364 ns.
Arrival 0.3259 ns, required 0.3364 ns, slack −0.0105 ns (violated).
| Cell | Arc | Through | Edge | Delay (ns) | Time (ns) | Slew (ns) |
|---|---|---|---|---|---|---|
| 1 | fr/CLK → fr/Q | dfxtp_1 | rise | 0.3259 | 0.3259 | 0.0492 |
fr/Q → ff/RESET_B | wire r1 | rise | 0.0000 | 0.3259 | 0.0492 |
The report
Startpoint: fr (rising edge-triggered flip-flop clocked by clk)
Endpoint: ff (removal check against rising-edge clock clk)
Path Group: asynchronous
Path Type: min
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 ^ fr/CLK (sky130_fd_sc_hd__dfxtp_1)
1 0.0036 0.0492 0.3259 0.3259 ^ fr/Q (sky130_fd_sc_hd__dfxtp_1)
r1 (net)
0.0492 0.0000 0.3259 ^ ff/RESET_B (sky130_fd_sc_hd__dfrtp_1)
0.3259 data arrival time
0.1000 0.0000 0.0000 clock clk (rise edge)
0.0000 0.0000 clock network delay (ideal)
0.0000 0.0000 clock reconvergence pessimism
0.0000 ^ ff/CLK (sky130_fd_sc_hd__dfrtp_1)
0.3364 0.3364 library removal time
0.3364 data required time
-------------------------------------------------------------------------------------
0.3364 data required time
-0.3259 data arrival time
-------------------------------------------------------------------------------------
-0.0105 slack (VIOLATED)OpenSTA 3.1.0, ideal 1 ns clock with a 0.1 ns slew. Recovery and removal paths form their own path group, asynchronous.
The recovery check of the same release
fr → ffrecovery check, latest arrival1 cell
- Clock latency
- Cell delay
- Recovery 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, library recovery time 0.2461 ns.
Arrival 0.3259 ns, required 1.2461 ns, slack 0.9202 ns (met).
| Cell | Arc | Through | Edge | Delay (ns) | Time (ns) | Slew (ns) |
|---|---|---|---|---|---|---|
| 1 | fr/CLK → fr/Q | dfxtp_1 | rise | 0.3259 | 0.3259 | 0.0492 |
fr/Q → ff/RESET_B | wire r1 | rise | 0.0000 | 0.3259 | 0.0492 |
The report
Startpoint: fr (rising edge-triggered flip-flop clocked by clk)
Endpoint: ff (recovery check against rising-edge clock clk)
Path Group: asynchronous
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 ^ fr/CLK (sky130_fd_sc_hd__dfxtp_1)
1 0.0036 0.0492 0.3259 0.3259 ^ fr/Q (sky130_fd_sc_hd__dfxtp_1)
r1 (net)
0.0492 0.0000 0.3259 ^ ff/RESET_B (sky130_fd_sc_hd__dfrtp_1)
0.3259 data arrival time
0.1000 1.0000 1.0000 clock clk (rise edge)
0.0000 1.0000 clock network delay (ideal)
0.0000 1.0000 clock reconvergence pessimism
1.0000 ^ ff/CLK (sky130_fd_sc_hd__dfrtp_1)
0.2461 1.2461 library recovery time
1.2461 data required time
-------------------------------------------------------------------------------------
1.2461 data required time
-0.3259 data arrival time
-------------------------------------------------------------------------------------
0.9202 slack (MET)The same run, max path.
Recovery passes with 0.9202 ns. Its library time is negative here, so the release may even come up to 0.2461 ns after the next edge. Releases between 0.2461 and 0.3364 ns after an edge are the unsafe window.
Removal behaves like hold: the clock period never enters the check.
Asked in interviews
What is a timing arc?
A pin-to-pin relation in a cell's Liberty model. A delay arc runs from an input or clock to an output and has delay and slew tables. A check arc runs from a clock to a data pin and holds a setup, hold, recovery or removal table.
What is unateness? Name a non-unate cell.
The direction an output can move for a given input edge. An inverter is negative unate, a buffer positive unate. An XOR is non-unate: the other input decides, so the tool times both output edges.
What are recovery and removal checks?
Setup and hold for the release of an asynchronous reset: early enough before an edge, late enough after one. Then every flop leaves reset on the same edge.
Why do two inputs of one NAND have different delays?
They drive different transistors in the series stack, and the one farther from the output must also move the charge between them. Tools swap pins to put the late signal on the fast input.
Try it
Two copies of nand2_1 share their inputs. The SDC asks for a rising output at yr and a falling one at yf, and puts each input-output pair in its own path group. The slew, 0.0230506 ns, is row 2 of the tables, and the load, 0.00346659 pF, is column 3.
Run it and read the four NAND lines: A falling 0.0403, A rising 0.0488, B falling 0.0447 and B rising 0.0556 ns. On the grid there is nothing to interpolate, so each is a table entry. Then change nand2_1 to nor2_1 in the netlist and compare.
Run to draw the timing paths here.
path 1 arc 2 delay 0.0403 ns path 2 arc 2 delay 0.0488 ns path 3 arc 2 delay 0.0447 ns path 4 arc 2 delay 0.0556 nsCheck yourself
Remember
- A timing tool sees a cell as arcs between pins: combinational, sequential (clock to output) and check arcs.
- The timing sense pairs edges: negative unate inverts, positive unate follows, and non-unate arcs are timed for both output edges.
- Each input and each output edge has its own table, so one NAND has four delays at the same slew and load.
- Flops add check arcs: setup and hold on D, and recovery and removal on the release of an asynchronous reset.