Wirelength, Congestion and Timing
The previous article ended on a clean idea: minimise total wirelength and you have done your job. If only. A placer that cares only about the sum of every net’s length will happily cram cells into a tight, wirelength-efficient blob, and then routing turns up and discovers there is not enough room between those cells to lay down all the wires it was promised. Or the placer shaves a fraction of a percent off total wirelength by nudging two cells on your worst timing path a little further apart, because the sum over all nets went down, even though the one net you actually care about got worse.
Total wirelength, routing congestion and timing are three different scorecards. Optimising hard for one does not merely fail to help the others. It can actively hurt them.
Wirelength against congestion
Total wirelength shrinks fastest when cells cluster tightly, with fewer and shorter hops between connected cells. But every one of those cells has pins that need wires, and those wires have to run through the space around the cell on a finite number of routing tracks per layer. Pack too many cells, and therefore too many net segments, into too small a region and you exceed the tracks available to route them. The wirelength number looks great on paper and the design is unroutable in practice. Section 4.4 is entirely about this failure.
Wirelength against timing
This one is subtler. A global placer’s cost function sums HPWL over every net in the design, thousands of them even for a small block. A single net on your worst timing path is one term in that giant sum. If shortening it would require lengthening several less critical nets by more than it saves, the optimiser leaves the critical net long, and by its own arithmetic it is right to. It has no idea that net matters more than the others unless you tell it.
That is why real placers support timing-driven placement. OpenROAD’s global placer takes a -timing_driven flag that feeds STA-derived criticality back into the cost function. Nets on paths with less slack get heavier weights, so the optimiser spends its wirelength budget disproportionately on the nets that threaten the clock period, at the expense of nets with slack to spare. The mechanism is simple: instead of plain HPWL, minimise a weighted sum,
$$WL_{\text{weighted}} = \sum_i w_i \cdot \text{HPWL}_i$$
where a critical net’s weight (w_i) might be 3 to 5 times a typical net’s weight of 1.0. The optimiser still minimises total cost, but now shortening one heavily weighted net is worth more than shortening several unweighted ones, and the maths naturally pulls that net’s endpoints together.
Spotting the conflict
A scenario, stated plainly. Two flops, op_reg and result_reg, sit on the single worst timing path in the design after synthesis-stage STA. In the placement that minimises total wirelength, op_reg lands in the lower-left corner of the core, because it also feeds three lightly loaded nets that pull it that way, and result_reg lands near the upper-right, because it is the endpoint of a wide, high-fanout control bus that dominates its own local wirelength terms.
Is that placement good or bad? Decide before reading on.
It is a real conflict, and this is its precise shape. Total wirelength across the design is genuinely minimised by this arrangement; every other net is about as short as it can be. But the one net from op_reg to result_reg, the net with the least timing margin in the whole design, is now stretched across most of the core’s diagonal. Global wirelength optimality and this one path’s timing point in opposite directions, and unweighted placement has no way to know that matters.
The wrong conclusion here is “the placer did something wrong”. It did not. It solved exactly the problem you gave it. The fix is not a bug fix, it is better information: turn on timing-driven placement so the critical net’s weight says that it is not just another net.
Practice Exercise
A design has three nets: netA (weight 1.0, HPWL 8), netB (weight 1.0, HPWL 6) and netC (weight 1.0, HPWL 4), and netC is the most timing-critical net in the design. A candidate move shrinks netA to HPWL 6, leaves netB at 6, and grows netC to 6. Unweighted total wirelength is 18 before and 18 after, a wash under plain HPWL.
Re-weight netC to 4.0, leaving the others at 1.0. Compute the weighted cost before and after the move, and decide whether a timing-driven placer would now accept or reject it.
Solution
Before: (1.0 \times 8 + 1.0 \times 6 + 4.0 \times 4 = 8 + 6 + 16 = 30).
After: (1.0 \times 6 + 1.0 \times 6 + 4.0 \times 6 = 6 + 6 + 24 = 36).
Plain wirelength is identical before and after (18 either way), but the weighted cost goes up, from 30 to 36, because the move lengthened the heavily weighted critical net. A timing-driven placer minimising the weighted sum rejects the move; a plain wirelength placer would see it as neutral. That is the whole mechanism by which net weighting changes placement outcomes.
Wirelength against timing is a tradeoff you steer with weights and flags. The algorithm doing the steering, OpenROAD’s RePlAce, has its own internal way of balancing “pack cells efficiently” against “do not overload any one region”. The next article looks at how it actually thinks.