In part 6 we switched to four layers and compressed the placement. The metrics improved sharply - DRC 12 to 5, unrouted 3 to 1, detour ratio 3.07x to 2.08x. And then those “last few” refused to go away.
This installment is the record of fighting them. The longest stretch in automation is not the first 90 percent but the last single item, and we learned that the hard way.
Why a few always remain - five defects in our own tools
Five defects in our own tools were behind it. Told to “clear whatever is left”, we looked at the tools again and found every one of them suffering from the same illness.
| # | Defect | What we measured |
|---|---|---|
| 1 | Tried only one chamfer size | Stepping the size down through six levels solved half the right angles |
| 2 | Judged 15 moves as one batch - one bad move discarded the other 14 | Cutting the batch to 3 took survivors from 7 to 50 |
| 3 | Stopped everything at the first failure (break) | Switching to skip-and-continue unlocked the easy cases behind it |
| 4 | Fixed +/-12mm search window | If the way around lies outside it, it is never found |
| 5 | Tried only one point for a via candidate | A spiral search around it found a spot 0.3 to 0.6mm away |
The pattern is a single one. Narrow the search space, then conclude that it cannot be done. When we now see a log line saying every candidate was invalid, the first thing we question is how many candidates there were.
The prison built by the pass criteria - no metric priority
The pass criteria were the same in every tool: apply, check, revert if worse. The problem was weighing all metrics equally.
The maze search broke through the last unrouted net and produced zero unrouted, and our own tool cancelled that result because clearance violations went up by 3. We only noticed much later.
An unrouted net means the circuit does not work; a 0.02mm clearance shortfall is a manufacturing margin issue. Take the connection and fix the clearance separately. Conversely, a short is worse than an unrouted net - an unrouted net just sits there, but a short destroys the circuit.
Only after fixing the priority as shorts > unrouted > clearance did the move of stepping back once to go forward twice become possible.
Measurement wobbled again - overlapping zones make DRC non-deterministic
DRC repeatability broke again. Part 5 caught the problem of DRC overwriting the board, but this time the numbers wobbled even when measuring a copy. Three measurements of the same file gave 8/7/7.
The cause was overlapping zones. Once a power plane went on top of the GND pour, the zone fill came out differently on every run. A board without the plane measured 6/6/6, completely deterministic.
In that state the verdict “the fix made it worse” is itself noise. It throws away good edits and adopts bad ones. Two responses -
- The DRC used for judging is run three times and the worst value taken
- Stamp the measurement into the backup filename (
_BEST_e5u1s0.kicad_pcb). We once attached names like “final” and “verified” and then stacked work on top of a file that in fact carried 2 shorts
Power as a plane? - read the character of the layer
An inner-layer power plane was our attempt to clear the unrouted +5V in one move. We had measured production boards using their inner layers as power planes, after all.
The result was a disaster. Shorts swung between 0 and 4 from run to run.
What we had missed: that production board had only 21mm of routing on the inner layer, a pure plane layer, while ours was a routing layer carrying 1,755mm. Putting a plane on a densely routed layer made the fill squeeze between traces and turn unstable.
Even at the same “four layers”, a board whose inner layer is a plane and a board whose inner layer carries routing are different objects. When citing someone else’s design, look past the numbers to the character of the layer.
Removing the plane brought determinism back, and the unrouted net was eventually solved with a trace.
A via goes through every layer - the same mistake four times
Vias on a four-layer board were the mine we stepped on most often. On two layers you only look at the top and bottom when placing a via; on four layers the via punches through the inner routing as well.
We knew this and had even written it into the skill document, and still left it out every time we built a new tool.
| Attempt | Where | Result |
|---|---|---|
| 1 | Via placed at the unrouted point | Punched through another net on In1 - short |
| 2 | Via for a detour | Same |
| 3 | Start and end vias of a maze route (only intermediate vias were checked) | 2 shorts |
| 4 | Detour via at a wall cut | 10 shorts |
The lesson was not “we wrote it down, so we are covered.” If several pieces of code create vias, one of them will inevitably skip the check. The answer is to funnel via creation into a single helper with the all-layer check built in.
Autopsy - preserve the failed state and look at the real thing
“We laid the path but the unrouted count did not drop” happened three times. Each time we changed our guess about the cause and fixed that instead (endpoint vias, then layer awareness, then stitching). On the third we changed the method. We kept the failed state instead of reverting it and compared the added copper against the two points DRC was pointing at, by coordinate.
Everything came out in ten minutes.
- One of the three unrouted nets only needed a 6mm horizontal straight line at the same y coordinate (the tool had stopped at its first failure and never even tried)
- One was two traces 0.1mm apart - a single via’s worth of space
- One had a via trapped in a valley
One autopsy was cheaper than three guesses.
Siege - move the wall and cut a window
The last unrouted net took the longest. The via of an orphaned +5V fragment was trapped in a 1.7mm valley between two traces of another net, one above and one below. Trapped tightly enough that a 0.15mm grid maze search was surrounded after 137 nodes.
The autorouter could not solve it either, for a simple reason - every automatic tool treats existing traces as untouchable and only hunts for gaps. No gap, no answer.
A person in that situation lifts the offending line and moves it aside. We turned that into a transaction.
- Temporarily lift the blocking trace (the wall)
- Connect the trapped fragment
- Reroute the lifted wall along a different path
- Check everything - if any metric gets worse, roll the whole thing back
Lifting the entire wall (25.6mm) made rerouting impossible. So we switched to cutting a window only as wide as needed, 2.4mm - only the two ends of the window have to be reconnected around it. The first attempt actually printed zero unrouted (it was rolled back because the via at the cut caused a short, which is repeat number four above).
The scoreboard at this point
| Metric | 2-layer final | 4-layer, before the finish |
|---|---|---|
| DRC errors | 12 | 4 |
| Unrouted | 3 | 1 |
| Shorts | 0 | 0 |
| Arbitrary angles | 17 | 5 |
| Max detour ratio | 3.07x | 2.08x |
| Measurement repeatability | - | Deterministic (3 identical runs) |
The remaining unrouted net is the siege above, still in progress. Every time we stripped out one tool defect, one item resolved - so this one is a tool problem too, not a board problem.

Most of this endgame played out on this face. The surface-mount parts are crowded here, so pad-to-pad gaps are tight, and this is where the spots that are “0.06mm short of fitting a trace” turn up.
One line per lesson
- When you see “no valid candidates”, first question how many candidates there were
- Rank the metrics: shorts > unrouted > clearance
- Overlapping zones make DRC non-deterministic - judge on the worst of three runs
- Stamp the measurement into the backup filename
- When citing a layer stack, read its character (plane layer or routing layer), not just the numbers
- Funnel dangerous operations such as via creation into one helper with the check built in
- One autopsy is cheaper than three guesses
- For dense areas the automatic tools cannot solve, use a transaction that moves the wall
The last few items remain not because the board is hard, but because the tools narrow the search space and then conclude it cannot be done.
Part 8 closes the series: DRC 0 and zero arbitrary angles, decided by the last four errors and 0.1mm.
The earlier parts covered why we started this, the scale bug, the library, the routing failures, the measurement bug, and the move to four layers.
Contact
- Email: [email protected]
- Instagram: https://www.instagram.com/going.sen/
- Website: https://intosen.com/kr/consult/
Comments
Enter a nickname to leave a comment, or sign in with Google or GitHub.