Delay and slew from the Liberty tables
Read a cell's delay and output slew out of its Liberty tables by hand, match OpenSTA to the last digit, and see why a bigger cell can make a path slower.
- Lesson
- L2.2
- Time
- 30 min
- Runs on
- OpenROAD
- Check
- 6 questions
A timing fix replaced one inv_1 on a register-to-register path with an inv_4, the same inverter at drive strength 4. The path got 40 ps slower. The new input, 9.4 fF against 2.4 fF, now loads the weak inv_1 in front of it.
db (inv_1) drives ub (inv_4), and flop ffb captures one clock period of 1 ns later.ff2 → ffbsetup check, latest arrival3 cells
- Clock latency
- Cell delay
- Setup time
- The driver pays
dbnow drives 9.4 fF and takes 0.0784 ns. Before the change it drove 2.4 fF and took 0.0377 ns. - The big cell saves little
ubdrives one flop input either way. As inv_4 it takes 0.0247 ns; as inv_1 it took 0.0253 ns. - Net result
The data arrives at 0.4113 ns instead of 0.3713 ns. The path still meets 1 ns, but the fix made it worse.
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.0858 ns.
Arrival 0.4113 ns, required 0.9142 ns, slack 0.5029 ns (met).
| Cell | Arc | Through | Edge | Delay (ns) | Time (ns) | Slew (ns) |
|---|---|---|---|---|---|---|
| 1 | ff2/CLK → ff2/Q | dfxtp_1 | fall | 0.3082 | 0.3082 | 0.0249 |
ff2/Q → db/A | wire q2 | fall | 0.0000 | 0.3082 | 0.0249 | |
| 2 | db/A → db/Y | inv_1 | rise | 0.0784 | 0.3867 | 0.0869 |
db/Y → ub/A | wire nb | rise | 0.0000 | 0.3867 | 0.0869 | |
| 3 | ub/A → ub/Y | inv_4 | fall | 0.0247 | 0.4113 | 0.0179 |
ub/Y → ffb/D | wire yb | fall | 0.0000 | 0.4113 | 0.0179 |
The report
Startpoint: ff2 (rising edge-triggered flip-flop clocked by clk)
Endpoint: ffb (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 ^ ff2/CLK (sky130_fd_sc_hd__dfxtp_1)
1 0.0022 0.0249 0.3082 0.3082 v ff2/Q (sky130_fd_sc_hd__dfxtp_1)
q2 (net)
0.0249 0.0000 0.3082 v db/A (sky130_fd_sc_hd__inv_1)
1 0.0094 0.0869 0.0784 0.3867 ^ db/Y (sky130_fd_sc_hd__inv_1)
nb (net)
0.0869 0.0000 0.3867 ^ ub/A (sky130_fd_sc_hd__inv_4)
1 0.0017 0.0179 0.0247 0.4113 v ub/Y (sky130_fd_sc_hd__inv_4)
yb (net)
0.0179 0.0000 0.4113 v ffb/D (sky130_fd_sc_hd__dfxtp_1)
0.4113 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 ^ ffb/CLK (sky130_fd_sc_hd__dfxtp_1)
-0.0858 0.9142 library setup time
0.9142 data required time
-------------------------------------------------------------------------------------
0.9142 data required time
-0.4113 data arrival time
-------------------------------------------------------------------------------------
0.5029 slack (MET)Measured with OpenSTA 3.1.0 in OpenROAD 26Q2 on the sky130 tt library, ideal clock, no wires.
A delay depends on what the cell drives, and what it drives is the next cell's input.
Two numbers set every delay
A static timing tool does not simulate transistors. It looks the delay of each cell up in tables that the library vendor measured once, for every input of every cell. Two numbers index each table.
The first is the input transition, or slew: how long the input takes to change. This library measures it from 20 % to 80 % of the supply. The second is the load: the total capacitance the output drives, which is the input capacitance of every pin on the net plus the wire. The delay runs from the input crossing 50 % to the output crossing 50 %.
Each table is a grid of 7 by 7 points: rows are input slews, columns are loads. This is the non-linear delay model (NLDM). Every arc has four tables: the delay for a rising and a falling output, and the output slew for each. The output slew becomes the next cell's input slew, so slew travels down the path with the arrival time.
da (inv_1) drives ua (inv_1), and flop ffa captures.ff1 → ffasetup check, latest arrival3 cells
- Clock latency
- Cell delay
- Setup time
- A light load
dadrives one inv_1 input, 2.4 fF, in 0.0377 ns. - The cell that was upsized
uadrives a flop's D pin in 0.0253 ns, with an output slew of 0.0150 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, library setup time −0.0845 ns.
Arrival 0.3713 ns, required 0.9155 ns, slack 0.5442 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 → da/A | wire q1 | fall | 0.0000 | 0.3082 | 0.0249 | |
| 2 | da/A → da/Y | inv_1 | rise | 0.0377 | 0.3460 | 0.0300 |
da/Y → ua/A | wire na | rise | 0.0000 | 0.3460 | 0.0300 | |
| 3 | ua/A → ua/Y | inv_1 | fall | 0.0253 | 0.3713 | 0.0150 |
ua/Y → ffa/D | wire ya | fall | 0.0000 | 0.3713 | 0.0150 |
The report
Startpoint: ff1 (rising edge-triggered flip-flop clocked by clk)
Endpoint: ffa (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 da/A (sky130_fd_sc_hd__inv_1)
1 0.0024 0.0300 0.0377 0.3460 ^ da/Y (sky130_fd_sc_hd__inv_1)
na (net)
0.0300 0.0000 0.3460 ^ ua/A (sky130_fd_sc_hd__inv_1)
1 0.0017 0.0150 0.0253 0.3713 v ua/Y (sky130_fd_sc_hd__inv_1)
ya (net)
0.0150 0.0000 0.3713 v ffa/D (sky130_fd_sc_hd__dfxtp_1)
0.3713 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 ^ ffa/CLK (sky130_fd_sc_hd__dfxtp_1)
-0.0845 0.9155 library setup time
0.9155 data required time
-------------------------------------------------------------------------------------
0.9155 data required time
-0.3713 data arrival time
-------------------------------------------------------------------------------------
0.5442 slack (MET)Same netlist and clock as the figure above: the report's Cap column is the load of each output.
Each cell has its own load axis. inv_1's columns end at 0.1813 pF, nand2_1's at 0.1666 pF, each cell's max_capacitance. Column 4 of one table is a different load from column 4 of another, so always read the index values.
Look a delay up by hand
Take the inverter in the two-flop path. The flop's output rises with a slew of 0.0388 ns and drives inv_1, whose falling output drives one nand2_1 input. A falling input pin of nand2_1 presents 0.002254 pF. Neither number is on the grid, so the tool interpolates between the four surrounding points.
| inv_1 cell_fall (ns) | load 0.00133517 pF | load 0.00356533 pF |
|---|---|---|
| slew 0.0230506 ns | 0.0219910 | 0.0299354 |
| slew 0.0531329 ns | 0.0306806 | 0.0410519 |
Rows 2 and 3, columns 2 and 3 of the 7 × 7 table, copied from the pinned sky130_fd_sc_hd tt Liberty.
Find the fractions
The slew sits 0.5235 of the way from row 2 to row 3. The load sits 0.4120 of the way from column 2 to column 3.
Interpolate along the load
In row 2: 0.0219910 + 0.4120 × (0.0299354 − 0.0219910) = 0.025264 ns. In row 3 the same step gives 0.034954 ns.
Interpolate along the slew
0.025264 + 0.5235 × (0.034954 − 0.025264) = 0.030337 ns. Rounded to four places, 0.0303 ns.
The output slew
The fall_transition table, read the same way, gives 0.018760 ns. That becomes
nand2_1's input slew.
OpenSTA reports 0.0303 ns for this arc and an output slew of 0.0188 ns, in the Try it below. With no wires, the tool's delay is exactly this bilinear interpolation. With extracted wires, OpenSTA first reduces the wire to an effective capacitance, a later lesson's subject.
Delay grows with load, and the table ends
Sweep the load and the delay rises with it. Past about 10 fF each extra femtofarad adds a nearly fixed 3.3 ps: a straight line, which the logarithmic axis bends into a curve. A slower input lifts the curve at almost every load. The plot is one OpenSTA run of 52 inverters, each with its own input slew and load.
- input slew 0.01 ns
- input slew 0.0388 ns
- input slew 0.28 ns
- input slew 1.5 ns
- Load 2.254 fFinput slew 0.01 ns = 20.7 ps · input slew 0.0388 ns = 30.3 ps · input slew 0.28 ns = 65.3 ps · input slew 1.5 ns = 83.7 ps
The worked lookup: 2.254 fF at a 0.0388 ns slew gives 0.0303 ns.
- Load 100 fFinput slew 0.01 ns = 346.4 ps · input slew 0.0388 ns = 357.2 ps · input slew 0.28 ns = 451.5 ps · input slew 1.5 ns = 853.2 ps
At 100 fF the fast input gives 0.3464 ns and the 1.5 ns input gives 0.8532 ns. The 1.5 ns input is slower than the 0.01 ns one at every load.
- Load 250 fFinput slew 0.01 ns = 845.4 ps · input slew 0.0388 ns = 855.8 ps · input slew 0.28 ns = 952.3 ps · input slew 1.5 ns = 1.496 ns
At 0.25 pF the load is past the table's last column, 0.1813 pF. The tool extrapolates the last two columns in a straight line: 0.8558 ns.
Read the plot as a table
| Load | input slew 0.01 ns | input slew 0.0388 ns | input slew 0.28 ns | input slew 1.5 ns |
|---|---|---|---|---|
| 1 fF | 16.2 ps | 24.9 ps | 50.1 ps | 48.1 ps |
| 2.254 fF | 20.7 ps | 30.3 ps | 65.3 ps | 83.7 ps |
| 10 fF | 47.1 ps | 57.7 ps | 126.9 ps | 233.4 ps |
| 100 fF | 346.4 ps | 357.2 ps | 451.5 ps | 853.2 ps |
| 250 fF | 845.4 ps | 855.8 ps | 952.3 ps | 1.496 ns |
OpenSTA 3.1.0, inv_1 from the sky130_fd_sc_hd tt library, falling output, no wires.
Past the last column the number is a guess. Extending the table by hand gives 0.8558 ns, the same as the tool, with an output slew of 1.1124 ns. That is why every output pin carries a max_capacitance and the library a default_max_transition of 1.5 ns. Beyond them the tool still prints a number, and a design-rule check reports the violation.
Try it shows that check too. With a 0.25 pF load, its Output lists u1/Y under the design rules: over its max_capacitance of 0.1813 pF, and over its max slew as well. L4 repairs such violations in the flow.
A flop drives with its own output stage
A flip-flop has tables too: from CLK to Q. Its delay grows with the clock slew, but its output slew hardly moves. A slow clock edge only delays the moment Q starts to switch; how fast Q then switches depends on what Q drives. Here the clock slew runs from 0.01 to 1.5 ns. Clock-to-Q rises from 0.2724 to 0.5105 ns, while the Q slew stays near 0.0226 ns.
- clock to Q (falling Q)
- Q slew (falling)
- Clock slew 100 psclock to Q (falling Q) = 305.5 ps · Q slew (falling) = 22.6 ps
At a 0.1 ns clock slew: clock-to-Q 0.3055 ns, Q slew 0.0226 ns.
- Clock slew 1.5 nsclock to Q (falling Q) = 510.5 ps · Q slew (falling) = 22.6 ps
At 1.5 ns the clock-to-Q is 0.5105 ns, but the Q slew is still 0.0226 ns.
Read the plot as a table
| Clock slew | clock to Q (falling Q) | Q slew (falling) |
|---|---|---|
| 100 ps | 305.5 ps | 22.6 ps |
| 200 ps | 336.7 ps | 22.6 ps |
| 400 ps | 382.4 ps | 22.65 ps |
| 600 ps | 415.3 ps | 22.7 ps |
| 800 ps | 442.4 ps | 22.68 ps |
| 1 ns | 461.9 ps | 22.6 ps |
| 1.2 ns | 481.3 ps | 22.6 ps |
| 1.4 ns | 500.8 ps | 22.6 ps |
| 1.5 ns | 510.5 ps | 22.6 ps |
OpenSTA 3.1.0, dfxtp_1 from the sky130_fd_sc_hd tt library, setup paths.
So a slow clock edge costs time at every flop, which is one reason the clock tree in L5 keeps its slews short.
Asked in interviews
How does a static timing tool compute a cell's delay?
It looks it up in the Liberty tables of that arc, indexed by the input slew and the output load, and interpolates between the four nearest points. The output slew comes from a second table the same way and feeds the next cell.
What is NLDM?
The non-linear delay model: delay and output slew stored as 2-D tables of input transition against output capacitance, one per arc and edge. The non-linearity is in the table, and the tool only interpolates.
Why can upsizing a cell make a path slower?
The bigger cell has a bigger input capacitance, which loads the cell in front of it. When the upsized cell drives a light load, the driver loses more time than the bigger cell saves.
What happens when a net exceeds max_capacitance?
The load is outside the characterized table, so the tool extrapolates and the number is untrustworthy. A design-rule check flags it, and the fix is a stronger driver or a buffer.
Try it
The netlist is one inverter between an input port and an output port. The SDC sets the input slew and the output load, and asks for the falling output. Run it and find the u1/Y line: the Slew and Delay columns are the two lookups worked above.
Now change the load to 0.00952062, a column of the table, and predict the delay before you run. Then try 0.25: the report still prints a number, 0.8558 ns, although the load is past max_capacitance.
Run to draw the timing paths here.
1 0.0023 0.0188 0.0303 0.0303 v u1/Y (sky130_fd_sc_hd__inv_1) path 1 arc 2 delay 0.0303 ns path 1 arc 2 slew 0.0188 nsRead the netlist: dcalc.v
module dcalc (a, y);
input a;
output y;
sky130_fd_sc_hd__inv_1 u1 (.A(a), .Y(y));
endmodule
Check yourself
Remember
- Every arc of a cell has delay and output-slew tables indexed by input slew and output load; OpenSTA interpolates bilinearly between the four nearest points.
- The load is the sum of the input capacitances on the net plus the wire, so a bigger cell slows the cell that drives it.
- Delay is measured 50 % to 50 %; slew 20 % to 80 % in this library, and the output slew becomes the next cell's input slew.
- Past max_capacitance the tool extrapolates in a straight line and still prints a number; design-rule checks catch it.