Generating Your Own Congestion Map
Every congestion table so far in this section was hand-built to make a point. Time to generate a real one, on alu8’s actual placement from Section 4.2, and see what OpenROAD itself reports.
Congestion estimation does not need a real, DRC-legal detailed route. It uses OpenROAD’s global router, the same tool that will produce real routing guides in Module 6, run here purely as a diagnostic. Global routing estimates which GCell-to-GCell path each net will roughly take and tallies demand per layer, without working out exact legal wire geometry. That is the right amount of information for a congestion check, and it is fast enough to run right after placement as a routine health check.
Running the estimate
Inside OpenROAD’s Tcl shell, with the placed design’s LEF, DEF and Liberty loaded (the same database run_placement produced):
openroad> global_route -guide_file alu8_congestion.guide \
-congestion_report_file alu8_congestion.rpt \
-congestion_iterations 50
Exact flag names shift a little between OpenROAD versions, so treat this as a representative invocation of the idea, run the global router and ask it to report congestion, rather than something to copy without checking help global_route on your install. The concept is what matters: you ask the global router to do its normal job and summarise demand against capacity per layer along the way.
Reading the report
[INFO GRT-0001] Reading global routing guides from previous run.
[INFO GRT-0018] Total wirelength: 148,662 um
[INFO GRT-0096] Routing congestion report by layer:
Layer Resource Demand Usage(%) H overflow V overflow
li1 3840 3512 91.5% 2 0
met1 5120 4877 95.3% 4 1
met2 5120 5390 105.3% 0 6
met3 2560 2190 85.5% 0 0
met4 1280 1050 82.0% 0 0
[WARNING GRT-0019] Overflow found on layer met2: 6 vertical GCell edges.
[INFO GRT-0020] Total design overflow: 6 GCell edges (0.03% of all edges).
Scan the Usage(%) column first, the same way you scanned the heatmap tables. li1, met1, met3 and met4 are busy, between 82% and 95%, but under 100%: tight, worth remembering, not yet a problem. met2 is the outlier at 105.3%, and the explicit warning line confirms it: six vertical GCell edges on met2 are oversubscribed.
The “6 GCell edges” and the “0.03% of all edges” matter together. A handful of overflowing edges out of thousands is a small, localised hotspot, almost certainly traceable to one structure in the design; the previous article used exactly this kind of decode region as the likely culprit. This is not “the whole design is too dense”, it is “one small region is too dense”, and those call for different fixes. A small, isolated overflow like this is often fixable with a local nudge, a small placement adjustment in that region, or by accepting the router’s own detour during real routing. Overflow across hundreds or thousands of edges spanning a large fraction of the core is a structurally different problem, and usually points back to PL_TARGET_DENSITY set too aggressively for the whole design, which is Section 4.5’s subject.
One caution about the severity tag. Seeing WARNING rather than ERROR on the overflow line does not make it safe to ignore. At this diagnostic stage a warning means “here is a real condition, you decide what to do”. A small ignored met2 overflow here is exactly what resurfaces as a blocking DRC violation once Module 6’s detailed router tries to lay down legal wires in the same spot.
Diagnosing from the table alone
Using only the excerpt above, which single layer would you investigate first, and which two numbers justify the choice?
met2, on the strength of its 105.3% usage, the only layer over 100%, and its vertical overflow count of 6, the only nonzero overflow entry in the table. Every other layer sits under 100% with zero reported overflow. There is no ambiguity about where to look, which is the value of a well-organised per-layer report: it turns “something might be wrong somewhere” into a specific line item.
Practice Exercise
A rerun of the estimate after a placement change reports met2 usage at 88.0% with 0 overflow edges, with every other layer unchanged from the table above. Has the change fixed the problem, made it worse, or had no effect? Which single number is the evidence?
Solution
Fixed. met2 usage dropped from 105.3% with 6 overflowing edges to 88.0% with 0. The clearest single piece of evidence is the overflow edge count going from 6 to 0, since that is the number tied directly to “will this cause a routing failure”, rather than the usage percentage alone. This is the before-and-after comparison the module’s closing article builds into a full worked example: change one knob, rerun the check, read the same report and confirm the fix worked rather than assuming it did.
You have now run and read a real congestion report end to end. The natural next question is what you actually turn to fix a result like this. Section 4.5 introduces the knob that controls it, PL_TARGET_DENSITY, and the disciplined loop for tuning it.