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.

Timing pathThe path after the inverter was upsizedFlop ff2 launches, 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 path after the inverter was upsized00.10.20.30.40.50.60.70.80.91time (ns)launch clk ↑capture clk ↑Data arrivesRequired byff2/CLK → ff2/Q (dfxtp_1): 0.3082 ns1 dfxtp_1db/A → db/Y (inv_1): 0.0784 ns2ub/A → ub/Y (inv_4): 0.0247 ns3setup −0.0858 nsslack +0.5029 ns · metarrival 0.4113required 0.9142The path after the inverter was upsized00.20.40.60.81time (ns)launch clk ↑capture clk ↑Data arrivesRequired byff2/CLK → ff2/Q (dfxtp_1): 0.3082 ns1 dfxtp_1db/A → db/Y (inv_1): 0.0784 ns2ub/A → ub/Y (inv_4): 0.0247 nssetup −0.0858 nsslack +0.5029 ns · metarrival 0.4113required 0.9142
  1. The driver pays

    db now drives 9.4 fF and takes 0.0784 ns. Before the change it drove 2.4 fF and took 0.0377 ns.

  2. The big cell saves little

    ub drives one flop input either way. As inv_4 it takes 0.0247 ns; as inv_1 it took 0.0253 ns.

  3. 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).

CellArcThroughEdgeDelay (ns)Time (ns)Slew (ns)
1ff2/CLK → ff2/Qdfxtp_1fall0.30820.30820.0249
ff2/Q → db/Awire q2fall0.00000.30820.0249
2db/A → db/Yinv_1rise0.07840.38670.0869
db/Y → ub/Awire nbrise0.00000.38670.0869
3ub/A → ub/Yinv_4fall0.02470.41130.0179
ub/Y → ffb/Dwire ybfall0.00000.41130.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.

Timing pathThe same path before the changeFlop ff1 launches, da (inv_1) drives ua (inv_1), and flop ffa captures.

ff1 → ffasetup check, latest arrival3 cells

  • Clock latency
  • Cell delay
  • Setup time
The same path before the change00.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_1da/A → da/Y (inv_1): 0.0377 ns2ua/A → ua/Y (inv_1): 0.0253 ns3setup −0.0845 nsslack +0.5442 ns · metarrival 0.3713required 0.9155The same path before the change00.20.40.60.81time (ns)launch clk ↑capture clk ↑Data arrivesRequired byff1/CLK → ff1/Q (dfxtp_1): 0.3082 ns1 dfxtp_1da/A → da/Y (inv_1): 0.0377 nsua/A → ua/Y (inv_1): 0.0253 nssetup −0.0845 nsslack +0.5442 ns · metarrival 0.3713required 0.9155
  1. A light load

    da drives one inv_1 input, 2.4 fF, in 0.0377 ns.

  2. The cell that was upsized

    ua drives 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).

CellArcThroughEdgeDelay (ns)Time (ns)Slew (ns)
1ff1/CLK → ff1/Qdfxtp_1fall0.30820.30820.0249
ff1/Q → da/Awire q1fall0.00000.30820.0249
2da/A → da/Yinv_1rise0.03770.34600.0300
da/Y → ua/Awire narise0.00000.34600.0300
3ua/A → ua/Yinv_1fall0.02530.37130.0150
ua/Y → ffa/Dwire yafall0.00000.37130.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 pFload 0.00356533 pF
slew 0.0230506 ns0.02199100.0299354
slew 0.0531329 ns0.03068060.0410519

Rows 2 and 3, columns 2 and 3 of the 7 × 7 table, copied from the pinned sky130_fd_sc_hd tt Liberty.

  1. 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.

  2. 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.

  3. Interpolate along the slew

    0.025264 + 0.5235 × (0.034954 − 0.025264) = 0.030337 ns. Rounded to four places, 0.0303 ns.

  4. 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.

Measured sweepinv_1 falling delay against load, one curve per input slewEvery point is a delay OpenSTA reported. The load axis is logarithmic, like the table's own index.
  • input slew 0.01 ns
  • input slew 0.0388 ns
  • input slew 0.28 ns
  • input slew 1.5 ns
00.2 ns0.4 ns0.6 ns0.8 ns1.0 ns1.2 ns1.4 ns1.6 nsDelay0.1 fF1 fF10 fF100 fF1 pFLoadmax_capacitancethe lookup: 0.0303 ns00.5 ns1.0 ns1.5 ns2.0 nsDelay0.1 fF10 fF1 pFLoadmax_capacitancethe lookup: 0.0303 ns
  1. 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.

  2. 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.

  3. 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
Loadinput slew 0.01 nsinput slew 0.0388 nsinput slew 0.28 nsinput slew 1.5 ns
1 fF16.2 ps24.9 ps50.1 ps48.1 ps
2.254 fF20.7 ps30.3 ps65.3 ps83.7 ps
10 fF47.1 ps57.7 ps126.9 ps233.4 ps
100 fF346.4 ps357.2 ps451.5 ps853.2 ps
250 fF845.4 ps855.8 ps952.3 ps1.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.

Measured sweepdfxtp_1: clock-to-Q and Q slew against the clock slewNine flops on nine clocks in one OpenSTA run, each Q falling into a flop's D pin.
  • clock to Q (falling Q)
  • Q slew (falling)
0100 ps200 ps300 ps400 ps500 ps600 psTime0.2 ns0.4 ns0.6 ns0.8 ns1.0 ns1.2 ns1.4 nsClock slew0100 ps200 ps300 ps400 ps500 ps600 psTime0.5 ns1.0 ns1.5 nsClock slew
  1. 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.

  2. 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 slewclock to Q (falling Q)Q slew (falling)
100 ps305.5 ps22.6 ps
200 ps336.7 ps22.6 ps
400 ps382.4 ps22.65 ps
600 ps415.3 ps22.7 ps
800 ps442.4 ps22.68 ps
1 ns461.9 ps22.6 ps
1.2 ns481.3 ps22.6 ps
1.4 ns500.8 ps22.6 ps
1.5 ns510.5 ps22.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
  1. 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.

  2. 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.

  3. 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.

  4. 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.

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

          
Expected: 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 ns
Read 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

Predict the outputThe same inverter, with the input slew and the load set exactly on a row and a column of its cell_fall table. What delay does OpenSTA report for u1/Y, in ns as the report prints it?
set_input_transition 0.0531329 [get_ports a]
set_load 0.00133517 [get_ports y]
set_max_delay 1.0 -from [get_ports a] -fall_to [get_ports y]
Read the netlist: design.v
module dcalc (a, y);
  input a;
  output y;
  sky130_fd_sc_hd__inv_1 u1 (.A(a), .Y(y));
endmodule
ConceptAn inv_1 keeps its input slew, and a second gate input is added to the net it drives. Where does the lookup move in its cell_fall table?
ConceptIn the hook, why did replacing ua (inv_1) with an inv_4 make the path 40 ps slower?
ConceptA net drives 0.25 pF from an inv_1, whose max_capacitance is 0.1813 pF. What does OpenSTA do with the delay?
ConceptRead the delay-against-load plot. At 100 fF, about how much slower is the inverter with a 1.5 ns input slew than with a 0.01 ns one?
ConceptWhy does the library measure delay from 50 % to 50 % but slew from 20 % to 80 %?

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.