Reading a Full OpenSTA Report, End to End
In Section 7.2 we extracted real parasitics for the routed UART. In this section we give them to OpenSTA. Section 7.1 did a slack calculation by hand with three or four tidy numbers. A real OpenSTA report looks busier: cumulative time columns, rise and fall markers, clock network delay, uncertainty, pessimism removal and library setup time, all before the one number you came for. In this article we take a full report apart line by line, using the path this module has been following.
Running the report
Load the libraries, the routed design, its SDC and the SPEF from Section 7.2 into an OpenROAD session, then ask for the worst setup path into the parity-error flop:
openroad
% read_liberty $PDK_ROOT/sky130A/libs.ref/sky130_fd_sc_hd/lib/sky130_fd_sc_hd__tt_025C_1v80.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.def
% read_sdc runs/uart_full/results/routing/uart_top.sdc
% read_spef runs/uart_full/results/extraction/uart_top.nom.spef
% set_propagated_clock [all_clocks]
% report_checks -path_delay max -to rx_ctrl/parity_err_reg/D
set_propagated_clock tells OpenSTA to use the real clock tree delays from CTS instead of an ideal clock. After CTS you always want this.
The full report
Startpoint: rx_ctrl/shift_reg_reg[7]
(rising edge-triggered flip-flop clocked by clk)
Endpoint: rx_ctrl/parity_err_reg
(rising edge-triggered flip-flop clocked by clk)
Path Group: clk
Path Type: max
Delay Time Description
-----------------------------------------------------------------
0.00 0.00 clock clk (rise edge)
0.00 0.00 clock network delay (propagated)
0.00 0.00 ^ rx_ctrl/shift_reg_reg[7]/CLK (sky130_fd_sc_hd__dfxtp_2)
0.58 0.58 ^ rx_ctrl/shift_reg_reg[7]/Q (sky130_fd_sc_hd__dfxtp_2)
0.31 0.89 v _2201_/X (sky130_fd_sc_hd__xor2_2)
0.34 1.23 ^ _2202_/X (sky130_fd_sc_hd__xor2_1)
0.34 1.57 v _2203_/X (sky130_fd_sc_hd__xor2_1)
1.94 3.51 ^ _2204_/X (sky130_fd_sc_hd__xor2_2)
0.01 3.52 ^ rx_ctrl/parity_err_reg/D (sky130_fd_sc_hd__dfxtp_2)
3.52 data arrival time
4.00 4.00 clock clk (rise edge)
0.00 4.00 clock network delay (propagated)
-0.15 3.85 clock uncertainty
0.00 3.85 clock reconvergence pessimism
3.85 ^ rx_ctrl/parity_err_reg/CLK (sky130_fd_sc_hd__dfxtp_2)
-0.14 3.71 library setup time
3.71 data required time
-----------------------------------------------------------------
3.71 data required time
-3.52 data arrival time
-----------------------------------------------------------------
0.19 slack (MET)
On this path the launch and capture flops sit on sibling branches of the clock tree with the same latency, so in your run both “clock network delay” lines will show the same few hundred picoseconds and cancel out. I have shown them as zero here so the arithmetic matches Section 7.1.
Reading it section by section
Header. Startpoint and Endpoint name the launching and capturing flops. Path Group: clk says which clock the path belongs to. That matters a great deal once a design has several clocks and less here, since the UART has one. Path Type: max means this is a setup check. A hold check says Path Type: min and has the same structure, with the comparison between arrival and required time turned around.
Arrival side. This is the same stage-by-stage trace you saw in the Verilog course, now with real numbers. Delay is each line’s own contribution and Time is the running total. The ^ and v markers show whether the signal is rising or falling at that point. Real cells have different rise and fall delays, so the engine has to track which edge is actually travelling.
Cell lines are the output pins (/Q, /X), and their delay includes charging whatever load the pin drives. Input pin lines, like the last one at parity_err_reg/D, carry the wire delay from the driver to that pin. Look at the last two lines. _2204_/X takes 1.94 ns, far more than the other XORs, because it is charging the 118.6 fF of parity_net we read in the SPEF. The wire itself adds only 0.01 ns on the D line, which matches the few picoseconds of Elmore delay we calculated. This is where the SPEF actually gets used.
Required side. Many people skim this part, and it matters just as much. It starts from the next clock edge at 4.00 ns and removes everything that eats into the margin before data must be stable. Clock uncertainty (−0.15 ns) covers jitter and any skew the SDC budgets for. Clock reconvergence pessimism removal (0.00 here) is a correction that gives back pessimism when the launch and capture clock paths share part of the tree. It is zero on this path because the report shows no clock latency. Finally library setup time (−0.14 ns) is the capturing flop’s own setup requirement from the Liberty file. What remains, 3.71 ns, is the latest moment data may arrive.
The last three lines are the point of everything above them. Required time minus arrival time is slack, and +0.19 ns means this path meets timing, only just, as Section 7.1 calculated by hand.
Everything subtracted on the required side is margin you are choosing to hold back for something the nominal calculation does not model: clock jitter, variation the library does not cover, or plain engineering caution. A design that passes with zero uncertainty has only been checked against an ideal clock. Section 7.5 comes back to this under the names margining and derating.
A mistake I see often is reading only the arrival trace and jumping to the slack. Two designs can show the same arrival and the same slack while one budgets real jitter and the other has set_clock_uncertainty left at zero. The second design’s “pass” is worth less than the first.
Practice Exercise
A colleague’s report shows an arrival time of 2.90 ns, a data required time of 3.71 ns and “slack (MET) 0.81”. The clock period is 4.00 ns, the setup time is 0.14 ns and there is no reconvergence pessimism or clock latency. What clock uncertainty did the report use?
Solution
Required time = period − uncertainty − pessimism − setup, so
3.71 = 4.00 − uncertainty − 0 − 0.14 uncertainty = 4.00 − 0.14 − 3.71 = 0.15 ns
This matches the 0.15 ns used throughout this module. The required time is not a mysterious tool output. You can rebuild it from the few quantities every report lists.
This report was run at one corner, tt_025C_1v80. In the next article we look at why one corner is not enough, and at the process, voltage and temperature corners and operating modes a real signoff has to check.