Module 6: Routing ยท 6.2 Detailed Routing

Running Global and Detailed Routing

The previous two articles built towards one moment: pointing the router at the UART and watching it either finish clean or say exactly where it is stuck. This is that article.

Where the UART stands

The UART netlist, roughly 1,300 cells post-CTS including the clock buffers TritonCTS inserted, is legally placed in a 300 um square core at a PL_TARGET_DENSITY around 0.50, with a single 50 MHz clock domain already built into a balanced tree. The power grid from Module 3 is in place on the upper layers. Nothing has a real wire yet.

The config fields that shape the run

A handful of config.json fields matter directly for routing. A representative excerpt:

{
    "DESIGN_NAME": "uart",
    "CLOCK_PORT": "clk",
    "CLOCK_PERIOD": "20.0",
    "RT_MIN_LAYER": "met1",
    "RT_MAX_LAYER": "met4",
    "GRT_ALLOW_CONGESTION": false,
    "ROUTING_CORES": 4,
    "DRT_OPT_ITERS": 64
}

RT_MIN_LAYER and RT_MAX_LAYER bound the layers signal routing may use, with met5 left to the power straps as in the metal stack article. GRT_ALLOW_CONGESTION set to false tells the global router to treat leftover overflow as a hard failure rather than quietly passing it downstream. You want to know about congestion at the cheap global stage, not discover it as a wall of detailed violations. DRT_OPT_ITERS caps the rip-up-and-reroute iterations TritonRoute attempts before giving up on a stubborn violation, the same counter you read in the previous article’s log.

Running the flow

In the interactive Tcl flow, both passes run under one command once placement and CTS are done:

% prep -design uart -tag routing_run_01
% run_placement
% run_cts
% run_routing

run_routing invokes global routing (FastRoute) first, then hands its output to track assignment and TritonRoute, the three-step sequence from Sections 6.1 and 6.2 run back to back as one stage. The non-interactive equivalent is the usual full-flow invocation:

./flow.tcl -design uart -tag routing_run_01

Reading the routing summary

A realistic summary after run_routing completes on the UART:

====== Global Routing Summary ======
Design: uart
GCell grid: 42 x 42
Total nets routed: 1428
Nets with overflow: 0
Peak overflow (any edge): 0
Total estimated wirelength: 51,904 um

====== Detailed Routing Summary ======
Design: uart
Routing layers used: met1 - met4
Initial violations (iteration 0): 187
Final violations: 0
Rip-up/reroute iterations used: 3 (of 64 available)
Total wirelength (actual): 48,912 um
Total via count: 3,204
  via1 (li1-met1):    612
  via2 (met1-met2):  1,441
  via3 (met2-met3):    889
  via4 (met3-met4):    262
Unrouted nets: 0
Routing DRC violations: 0

Run status: ROUTING COMPLETE - CLEAN

Read it the way you will read every routing report from here on. Global routing’s zero nets with overflow confirms the coarse capacity check passed with no structural congestion. Detailed routing’s count dropping from 187 to 0 in 3 of the 64 available iterations is healthy convergence, well inside budget. Zero unrouted nets and zero DRC violations together are the two numbers that mean done. A run can report progress on everything else and still not be finished if either is nonzero. The actual wirelength came in slightly under global routing’s estimate, which is normal: detailed routing snaps to real tracks and finds marginally shorter legal paths than the coarse estimate assumed.

Via count by layer pair on the clean run
Figure 1: The via breakdown from the summary. via2 dominates and the count shrinks going up: most connections are short local hops, and only a few nets climb to met3 and met4.

The via breakdown by layer pair is worth a habit of checking even when everything is clean. A design this size showing via2 dominant and a shrinking count going up matches the expectation from the metal stack article that most connections are short. An unusually large met3-met4 via count on a design this small would hint that more nets than expected are being routed further than necessary, and that is worth a look at placement.

One trap: stopping at “ROUTING COMPLETE” without checking whether it says CLEAN or VIOLATIONS PRESENT. The routing step can complete, meaning it ran to the end without crashing, and still leave unrouted nets or violations behind if it hit its iteration budget. Completed and clean are different claims. You want both.

Diagnosing a different report

Same UART, different run. This time the detailed summary reads:

Initial violations (iteration 0): 340
Final violations: 22
Rip-up/reroute iterations used: 64 (of 64 available)
Unrouted nets: 4
Routing DRC violations: 22
Run status: ROUTING COMPLETE - VIOLATIONS PRESENT

Using every available iteration and still finishing with 22 violations means the router was not converging. It kept trying local fixes and the count was not dropping towards zero the way the clean run’s did. That pattern, budget exhausted and violations still present, is the signature of a structural conflict local rip-up cannot resolve, most often a region where there simply is not enough room to route everything legally. More iterations would not fix it. Section 6.5 builds towards exactly this diagnosis: when the router hits its ceiling instead of converging, the fix is not raising DRT_OPT_ITERS, it is looking upstream at placement density wherever the 22 violations cluster.

Practice Exercise

Looking at the clean run’s via breakdown again, 612 via1, 1,441 via2, 889 via3, 262 via4, explain in a sentence or two why you would expect the count to shrink going up the stack for a design this size, tying it to the layer roles from the metal stack article.

Solution

Each higher via pair connects layers reserved for progressively longer, less frequent routing. Most connections in a small design are short local hops on li1, met1 and met2, hence the large via1 and via2 counts, while only a shrinking fraction of nets need to travel far enough to justify climbing to met3 or met4. The shrink is the fingerprint of the “short nets stay low, long nets go high” discipline. If the counts did not shrink that way on a design this small, more nets than expected would be travelling unnecessarily far, and placement is where to look.

Routing runs clean when every layer, spacing and via rule is respected, but you have not yet looked at why those rules exist. Section 6.3 goes into the SKY130 routing rules themselves, starting with spacing and width.

โ† Vias and Design-Rule-Correct Wires Spacing and Width Rules โ†’