Module 7: Timing Closure & Static Timing Analysis · 7.5 Signoff Timing

Running a Full Signoff Timing Pass on the UART

This is the last article of the module, and nothing in it is new. Every command and idea has appeared somewhere in the previous fourteen articles. What is new is running them together, in the order a real signoff does, on the ECO-fixed UART.

The signoff sequence

Figure 1 shows the sequence. Timing closure is not a single command. It is this loop, check, fix, re-extract, re-check, run until every corner and mode that matters comes back clean.

The signoff timing loop
Figure 1: Extract, load all corners, derate, and loop through ECO and re-extraction until no corner violates

Setting up the signoff session

openroad
% define_corners tt ss ff
% read_liberty -corner tt $PDK_ROOT/sky130A/libs.ref/sky130_fd_sc_hd/lib/sky130_fd_sc_hd__tt_025C_1v80.lib
% read_liberty -corner ss $PDK_ROOT/sky130A/libs.ref/sky130_fd_sc_hd/lib/sky130_fd_sc_hd__ss_100C_1v60.lib
% read_liberty -corner ff $PDK_ROOT/sky130A/libs.ref/sky130_fd_sc_hd/lib/sky130_fd_sc_hd__ff_n40C_1v95.lib

% read_lef $PDK_ROOT/sky130A/libs.ref/sky130_fd_sc_hd/techlef/sky130_fd_sc_hd__nom.tlef
% read_lef $PDK_ROOT/sky130A/libs.ref/sky130_fd_sc_hd/lef/sky130_fd_sc_hd.lef
% read_def runs/uart_full/results/routing/uart_top.eco.def
% read_sdc runs/uart_full/results/routing/uart_top.sdc
% set_propagated_clock [all_clocks]

% read_spef -corner tt runs/uart_full/results/extraction/uart_top.nom.eco.spef
% read_spef -corner ss runs/uart_full/results/extraction/uart_top.max.eco.spef
% read_spef -corner ff runs/uart_full/results/extraction/uart_top.min.eco.spef

% set_timing_derate -late 1.05
% set_timing_derate -early 0.95

This is the ECO’d design from Section 7.4, re-extracted at each RC corner as in Section 7.3, loaded into one multi-corner session, with the derating from the previous article applied to everything.

First pass: a margin too thin for derating

% report_checks -corner ss -path_delay max -format end

The worst setup endpoint at the slow corner is rx_ctrl/parity_err_reg/D, at −0.03 ns.

The ECO in Section 7.4 closed the corner-level violation to +0.14 ns, but the previous article already predicted this: 5% of a 3.42 ns path is more than 0.14 ns. This is not a new bug. It is the derating example from the previous article showing up as a real gate in the flow.

This is why experienced engineers aim ECOs at a margin clearly larger than “just positive” at the corner level, even when a corner-only check would call the job finished. A margin that survives the corner check but not the margining step after it has not been closed. It has been postponed.

Repairing again, with derating in place

This time the repair runs with derating already applied, so it sees the same numbers signoff does:

% repair_timing -setup -setup_margin 0.05

It needs only one small change: the buffer inserted in Section 7.4 is upsized from buf_4 to buf_6, which drives the long route faster. No second buffer is needed. After legalising, re-routing the changed net and re-extracting as before, the slow-corner path looks like this:

   0.36    3.04 ^ _2204_/X (sky130_fd_sc_hd__xor2_4)
   0.01    3.05 ^ _eco_buf_1_/A (sky130_fd_sc_hd__buf_6)
   0.25    3.30 ^ _eco_buf_1_/X (sky130_fd_sc_hd__buf_6)
   0.02    3.32 ^ rx_ctrl/parity_err_reg/D (sky130_fd_sc_hd__dfxtp_2)

These are the delays before derating, for comparison with Section 7.4. With the 5% derate the arrival becomes 3.32 × 1.05 ≈ 3.49 ns, against 3.56 ns required, for a derated slack of +0.07 ns.

The final signoff summary

With derating applied at every corner and the buffer upsized, this is the setup picture the whole module has been building towards:

Corner Liberty / extraction Setup slack (derated) Status
ff ff_n40C_1v95 / min RC +1.91 ns PASS
tt tt_025C_1v80 / nominal RC +1.19 ns PASS
ss ss_100C_1v60 / max RC +0.07 ns PASS
Check Status Notes
Setup, all corners PASS ss closed by the ECO in Section 7.4 and the buffer upsize here
Hold, fast corner To confirm Both ECOs made paths faster. A real signoff re-runs the min-delay check at ff with derating and repairs with repair_timing -hold if anything fails, as in the Section 7.4 exercise
Parasitics Current Extracted from the final ECO’d layout, not from Module 6’s routing

The single-corner check in the first article of Section 7.3 said this design passed with 0.19 ns to spare. The full picture, three corners, extracted parasitics, two rounds of ECO and standard derating, says something similar but importantly different. The design does pass, but because the real worst case was found, fixed and confirmed, not because the first positive number was taken at face value.

If I had to put this module in one sentence: a single passing timing report proves nothing about signoff. A signoff result is a named set of corners, checked against extracted parasitics with real margins, all coming back positive at the same time, and the habit of finding that out matters more than any one number along the way.

Practice Exercise

A colleague proposes dropping the tt corner from future signoff runs: if ss (worst for setup) and ff (worst for hold) both pass, tt cannot fail, so it is redundant. Is that reasoning sound, or is there a reason to keep checking tt?

Solution

For setup and hold pass/fail on ordinary logic the reasoning is broadly right: if both ends of the range pass their respective checks, the middle is unlikely to fail a check it is not the worst case for. But it does not make tt redundant in practice.

First, tt is the corner used throughout development, so it is the one that power estimates, earlier reports and most documentation refer to. Keeping it in the signoff run gives you a reference point to compare against all of that. Second, the assumption that the middle can never be worse than the ends is not guaranteed. Effects such as temperature inversion, mentioned in Section 7.3, can make an intermediate or low-temperature condition slower than expected. Third, once the libraries and SPEFs for ss and ff are loaded, checking tt in the same session costs almost nothing, while catching an unexpected tool or characterisation quirk is worth a great deal. The reasoning about worst-case coverage is fair, but it is not a good enough reason to remove the check.

That closes Module 7. The UART now has a real, signed-off timing result behind it: not an estimate and not one lucky corner, but a checked, fixed and re-verified result at the corners that matter. In Module 8 we turn to the other half of signoff, physical verification, starting with what design rule checking actually checks and why a design can pass every timing corner in this module and still not be ready to tape out.

← Margining and Derating: Designing for the Worst Case You'll Actually See