Timing closure
Each case shows the tail of a real run, ending where the tool stopped or warned. Say what caused it, or what to do about it. A case you miss returns later in the round and starts its schedule over; one you get right returns after 1, 3, 7, then 21 days. Keys 1 to 4 choose an option, h shows a hint, and Enter moves on. Progress is stored in this browser.
All 6 cases in this stage, with answers
-
Hold repair ran to its last iteration. What is this table telling you?
4_1_cts log
[INFO RSZ-0046] Found 35 endpoints with hold violations. Iteration | Resized | Buffers | Cloned Gates | Area | WNS | TNS | Endpoint -------------------------------------------------------------------------------------- 0 | 0 | 0 | 0 | +0.0% | -0.186 | -5.960 | dpath.b_reg.out[9]$_DFFE_PP_/D 10 | 0 | 15 | 0 | +1.7% | -0.180 | -5.704 | dpath.b_reg.out[3]$_DFFE_PP_/D 20 | 0 | 1 | 0 | +3.0% | -0.172 | -5.567 | dpath.b_reg.out[1]$_DFFE_PP_/D 30 | 0 | 0 | 0 | +3.5% | -0.172 | -5.481 | dpath.b_reg.out[1]$_DFFE_PP_/D final | 0 | 0 | 0 | +3.7% | -0.172 | -5.434 | dpath.b_reg.out[1]$_DFFE_PP_/D -------------------------------------------------------------------------------------- [WARNING RSZ-0066] Unable to repair all hold violations.Repair is buying almost nothing for the area it is spending.Hint: Compare the first row's numbers with the last row's, and watch the area column.
Thirty iterations recovered 0.014 nanoseconds of the 0.186 that was failing, and spent 3.7 percent more area doing it. That shape means the requirement is not reachable by buffering, so the answer is upstream: on this run, 0.30 nanoseconds of hold uncertainty had been added to the constraints, which is far more than any insertion can absorb. A healthy run of this design reports no hold violations at all.
# uncertainty should reflect jitter and the timer's margin, not a guess set_clock_uncertainty -hold 0.03 [get_clocks core_clock]
-
The run finished and reported an area. One line here says the result is a fiction. Which?
6_report log
Design area 691 um^2 59% utilization. [WARNING GUI-0076] QStandardPaths: XDG_RUNTIME_DIR not set, defaulting to '/tmp/runtime-root' [WARNING GUI-0066] Heat map "IR Drop" has not been populated with data. [WARNING STA-0351] clock '*' not found. [WARNING GUI-0066] Heat map "Routing Congestion" has not been populated with data. Elapsed time: 0:01.06[h:]min:sec. CPU time: user 1.10 sys 0.13 (116%). Peak memory: 180016KB.
The one about a clock, since nothing was timed at all.Hint: Three warnings. Two of them appear in a healthy run of the same design.
A clean run of this design prints the same two heat-map warnings and the same runtime directory line, so neither means anything. The clock line does: the reporting script asked for every clock and there were none, so every timing number in the summary is empty rather than good. This is the last chance to notice, at the end of two hundred lines that all look normal.
# compare against a known-good log rather than reading warnings one by one diff <(grep WARNING good.log) <(grep WARNING this.log)
-
Setup repair ran to its limit. What should you conclude?
3_5_place_dp log
[INFO RSZ-0094] Found 49 endpoints with setup violations. [INFO RSZ-0099] Repairing 49 out of 49 (100.00%) violating endpoints... Iter | Removed | Resized | Inserted | Cloned | Pin | Area | WNS | StTNS | EnTNS | Viol | Worst | Buffers | Gates | Buffers | Gates | Swaps | | | | | Endpts | St/EnPt ------------------------------------------------------------------------------------------------------------------------------ 0* | 0 | 0 | 0 | 0 | 0 | +0.0% | -0.123 | -3.7 | -4.9 | 49 | resp_msg[14] 10* | 0 | 3 | 0 | 1 | 5 | +0.6% | -0.129 | -3.9 | -5.2 | 49 | dpath.a_reg.out[2]$_DFFE_PP_/D 20* | 0 | 11 | 0 | 1 | 7 | +1.2% | -0.129 | -3.9 | -5.3 | 49 | dpath.a_reg.out[6]$_DFFE_PP_/D ... final | 0 | 88 | 3 | 1 | 16 | +8.5% | -0.120 | -3.8 | -5.0 | 49 | resp_msg[14] ------------------------------------------------------------------------------------------------------------------------------ [INFO RSZ-0040] Inserted 3 buffers. [INFO RSZ-0051] Resized 88 instances: 88 up, 0 up match, 0 down, 0 VT [INFO RSZ-0043] Swapped pins on 16 instances. [INFO RSZ-0049] Cloned 1 instances. [WARNING RSZ-0062] Unable to repair all setup violations.The target is out of reach, since the area bought no slack.Hint: Read the first data row and the last one, and look at what the area column did in between.
Nearly eight hundred iterations moved the worst slack from -0.123 to -0.120 nanoseconds and spent 8.5 percent more area doing it, with the same 49 endpoints failing at the end as at the start. That is what an unreachable constraint looks like from inside the optimizer. The conversation to have is about the clock period or the architecture, not about optimization effort.
# give it a period the design can hold, then tighten in steps set clk_period 0.46
-
The worst endpoint is resp_msg[14]. What does that name tell you?
3_5_place_dp log
[INFO RSZ-0094] Found 49 endpoints with setup violations. [INFO RSZ-0099] Repairing 49 out of 49 (100.00%) violating endpoints... Iter | Removed | Resized | Inserted | Cloned | Pin | Area | WNS | StTNS | EnTNS | Viol | Worst | Buffers | Gates | Buffers | Gates | Swaps | | | | | Endpts | St/EnPt ------------------------------------------------------------------------------------------------------------------------------ 0* | 0 | 0 | 0 | 0 | 0 | +0.0% | -0.123 | -3.7 | -4.9 | 49 | resp_msg[14] 10* | 0 | 3 | 0 | 1 | 5 | +0.6% | -0.129 | -3.9 | -5.2 | 49 | dpath.a_reg.out[2]$_DFFE_PP_/D 20* | 0 | 11 | 0 | 1 | 7 | +1.2% | -0.129 | -3.9 | -5.3 | 49 | dpath.a_reg.out[6]$_DFFE_PP_/D ... final | 0 | 88 | 3 | 1 | 16 | +8.5% | -0.120 | -3.8 | -5.0 | 49 | resp_msg[14] ------------------------------------------------------------------------------------------------------------------------------ [INFO RSZ-0040] Inserted 3 buffers. [INFO RSZ-0051] Resized 88 instances: 88 up, 0 up match, 0 down, 0 VT [INFO RSZ-0043] Swapped pins on 16 instances. [INFO RSZ-0049] Cloned 1 instances. [WARNING RSZ-0062] Unable to repair all setup violations.The worst path ends at an output port, so the budget is the suspect.Hint: Compare that name with the register names in the rows above it.
Register endpoints carry the flop's name and a pin, as the rows above do. A bare port name means the path is checked against an output delay instead, which is a number someone chose. Before optimizing the logic it is worth asking whether the block was given a fair share of the period.
# check what the interface was promised before reoptimizing the logic report_checks -to [get_ports resp_msg*] -path_delay max
-
The setup check is clean and repair found nothing. What would you verify?
3_5_place_dp log
========================================================================== Floorplan check_setup -------------------------------------------------------------------------- number instances in verilog is 521 [INFO IFP-0107] Defining die area using utilization: 55.00% and aspect ratio: 1. [WARNING IFP-0028] Core area lower left (1.000, 1.000) snapped to (1.140, 1.400). [INFO IFP-0001] Added 24 rows of 182 site FreePDK45_38x28_10R_NP_162NW_34O. ... [WARNING EST-0027] no estimated parasitics. Using wire load models. [INFO RSZ-0100] Repair move sequence: UnbufferMove SizeUpMove SwapPinsMove [INFO RSZ-0098] No setup violations found [INFO RSZ-0505] Runtime: 0.03sWhether an exception has removed the paths from the analysis.Hint: Every earlier sign of an untimed design is absent here. What else could empty the reports?
This run carries a false path from the clock to itself, which removes every register-to-register path in the design. Unlike an undefined clock, it leaves no unclocked pins and no unconstrained endpoints, so the checks that catch the other mistakes say nothing. Counting the paths that were timed, or reporting the exceptions, is what finds it.
report_checks -path_delay max -group_path_count 1000 | grep -c Startpoint report_exceptions
-
A design closes with suspiciously good timing. Put these checks in the order that finds the cause fastest.
- read the constraint log for a clock or port that was not found
- read the floorplan check for unclocked pins and unconstrained endpoints
- count how many paths the timer actually reported
- report the exceptions that remove paths from the analysis
Hint: Each step catches a cause the step before it cannot see.
The first two are free and catch the common cases: a clock created on nothing, or ports with no delay. Counting the paths catches a design that is timed but barely. Exceptions come last because they take the most reading, and they are the only thing that catches a false path wide enough to empty the analysis while every check stays clean.