Public

Thread: An optimization victory story

10 Discord messages from πŸ“ - Designing/πŸ•°οΈ-analog/threads/an-optimization-victory-story.md.

Category: πŸ“ - Designing Parent channel: #πŸ•°οΈ-analog Thread ID: 1520008973795983512

Messages: 10

message-1520008978531225601

2026-06-26T10:13:00.883+00:00 β€” dmv (@.dmv)

Content

I figure this might be the right crowd to  share my little celebration with. Given the extra time, I've taken on an ambitious respin. My primary design involves sixteen segments of a serpentine of a highly repeated component (an op amp) that collectively consumes most of the area. The routed serpentine segments were 169.1 Β΅m x 3963 Β΅m -- tight within a 1x1 slot. I have gotten it all to fit, route, and pass the design checks. Overall, I had about 1.8 mm^2 of uncontested area (before the final routing) at the end of the segments and I had optimized my ambitious change requirement to somewhere between 2.3 mm^2 and 3.2 mm^2. Just shy by 0.5-1.4 mm^2.
<details> <summary>Other message metadata</summary>
{
  "author": {
    "avatarUrl": "2026-06_media/cf91f9947bc37b8a1071311863f9c4b7-14667.png",
    "discriminator": "0000",
    "isBot": false
  },
  "message": {}
}
</details>

message-1520009054452187136

2026-06-26T10:13:18.984+00:00 β€” dmv (@.dmv)

Content

The op amp had been derived from simulation for minimum appropriate performance specs, but the geometry wasn't necessarily optimized for dense folding. It seemed reasonable to speculate that there existed an op amp reconfiguration such that my segments could free up 0.5 mm^2. But also *way* too hard to find the valid op amp design based only on spacial and packing needs.
<details> <summary>Other message metadata</summary>
{
  "author": {
    "avatarUrl": "2026-06_media/cf91f9947bc37b8a1071311863f9c4b7-14667.png",
    "discriminator": "0000",
    "isBot": false
  },
  "message": {}
}
</details>

message-1520013089674887219

2026-06-26T10:29:21.056+00:00 β€” dmv (@.dmv)

Content

So I wrote a search program, and went through a series of iterations. From mostly random permutations, it generated a set of plausible candidate geometry numbers given the fixed performance considerations. That was relatively cheap -- I generated 500K of them in a minute.

Then I had a series of filters against that candidate pool, each increasingly expensive:

**Tier-0**. Analytic bounding box + constraint check. That was ~1 ms/candidate

**Tier-1**. Parametric placement GDS into a bounding box. That was ~5 s/candidate

**Tier-2**. Placement DRC (for the segment). That was ~60 s/candidate.

**Tier-3**. Deep-LVS MATCH. ~3 m/candidate.

Tier-0 and Tier-1 took the 500K starting candidates down to 3655 remaining. Those filters constrained it so that any of those remaining would work -- and I only needed one of them to work (I didn't need global optimal, just "sufficiently better"). 3655 Tier-2 evaluations should have taken about 6 hours (took a bit more due to various workflow interruption bugs). So it ran all day today.
<details> <summary>Other message metadata</summary>
{
  "author": {
    "avatarUrl": "2026-06_media/cf91f9947bc37b8a1071311863f9c4b7-14667.png",
    "discriminator": "0000",
    "isBot": false
  },
  "message": {}
}
</details>

message-1520013309615673405

2026-06-26T10:30:13.494+00:00 β€” dmv (@.dmv)

Content

When I got home to review the results this evening... the conclusion was that 0 candidates had made it to Tier-3. πŸ™
<details> <summary>Other message metadata</summary>
{
  "author": {
    "avatarUrl": "2026-06_media/cf91f9947bc37b8a1071311863f9c4b7-14667.png",
    "discriminator": "0000",
    "isBot": false
  },
  "message": {
    "inlineEmojis": [
      {
        "code": "slight_frown",
        "id": "",
        "imageUrl": "2026-06_media/1f641-E1429.svg",
        "isAnimated": false,
        "name": "πŸ™"
      }
    ]
  }
}
</details>

message-1520014151525732502

2026-06-26T10:33:34.221+00:00 β€” dmv (@.dmv)

Content

But looking closer, while many of the candidates had failed with hundreds of DRC errors, some had failed with few. One had *only* 4 DRC errors. That seemed like a DRC construction issue, and it was. More bugs, but fixing them resulted in... that candidate still being disqualified at Tier-3, but now a chance that some of the other barely disqualified might also make it to Tier-3.
<details> <summary>Other message metadata</summary>
{
  "author": {
    "avatarUrl": "2026-06_media/cf91f9947bc37b8a1071311863f9c4b7-14667.png",
    "discriminator": "0000",
    "isBot": false
  },
  "message": {}
}
</details>

message-1520014820794040392

2026-06-26T10:36:13.787+00:00 β€” dmv (@.dmv)

Content

None of the Tier-2 close washouts made it through Tier-3. But there was another bug (in resumption), where about 100 of the 3655 candidates had not been given a Tier-2 evaluation.

So ran those through Tier-2 as well. Two hours later... the last of the missed Tier-2 candidates passed the fixed Tier-2... and Tier-3!
<details> <summary>Other message metadata</summary>
{
  "author": {
    "avatarUrl": "2026-06_media/cf91f9947bc37b8a1071311863f9c4b7-14667.png",
    "discriminator": "0000",
    "isBot": false
  },
  "message": {}
}
</details>

message-1520016197431595048

2026-06-26T10:41:42.003+00:00 β€” dmv (@.dmv)

Content

So, search space of 500K possible op amp geometries... and I found one that happens to fold just right, shrinking the width of my serpentine segments from 169.1 Β΅m to ~150-159Β΅m (haven't finished the full DRC/LVS reassembly) while more importantly reducing serpentine segment height from 3963 Β΅m to 3869 Β΅m -- the 0.1 mm savings per segment (16x0.1 -> 1.6 mm^2) that should be enough to fit my ambitious extra feature.

Now just a whole lot of routing to do, but... woo!
<details> <summary>Other message metadata</summary>
{
  "author": {
    "avatarUrl": "2026-06_media/cf91f9947bc37b8a1071311863f9c4b7-14667.png",
    "discriminator": "0000",
    "isBot": false
  },
  "message": {}
}
</details>

message-1520017054789275749

2026-06-26T10:45:06.413+00:00 β€” dmv (@.dmv)

Content

(Thanks for indulging my story telling here.)

Reactions

<details> <summary>Reactions data</summary>
[
  {
    "count": 2,
    "emoji": {
      "code": "tada",
      "id": "",
      "imageUrl": "2026-06_media/1f389-5C738.svg",
      "isAnimated": false,
      "name": "πŸŽ‰"
    },
    "users": [
      {
        "avatarUrl": "2026-06_media/3-FB033.png",
        "color": null,
        "discriminator": "0000",
        "id": "376976238528692225",
        "isBot": false,
        "name": "nmz787",
        "nickname": "nmz787"
      },
      {
        "avatarUrl": "2026-06_media/0-EB806.png",
        "color": null,
        "discriminator": "0000",
        "id": "738396032295108721",
        "isBot": false,
        "name": "bailey8889",
        "nickname": "bailey"
      }
    ]
  }
]
</details><details> <summary>Other message metadata</summary>
{
  "author": {
    "avatarUrl": "2026-06_media/cf91f9947bc37b8a1071311863f9c4b7-14667.png",
    "discriminator": "0000",
    "isBot": false
  },
  "message": {}
}
</details>

message-1520019175769247894

2026-06-26T10:53:32.094+00:00 β€” namibj

Reply/reference

<details> <summary>Reference data</summary>
{
  "channelId": "1520008973795983512",
  "guildId": "1361349522684510449",
  "messageId": "1520016197431595048"
}
</details>

Content

Oh, so routing feasibility (let alone proving the feasibility by constructing a valid routing) wasn't part of the automated generation scripting?
<details> <summary>Other message metadata</summary>
{
  "author": {
    "avatarUrl": "2026-06_media/f885abc0dddd0a33e4d4991b3c99091d-7ACD2.png",
    "discriminator": "0000",
    "isBot": false
  },
  "message": {
    "mentions": [
      {
        "avatarUrl": "2026-06_media/cf91f9947bc37b8a1071311863f9c4b7-14667.png",
        "color": null,
        "discriminator": "0000",
        "id": "356185479911047169",
        "isBot": false,
        "name": ".dmv",
        "nickname": "dmv",
        "roles": []
      }
    ]
  }
}
</details>

message-1520020608803541042

2026-06-26T10:59:13.756+00:00 β€” dmv (@.dmv)

Content

Right -- that would have made the candidate generation much more expensive. And/or restricted the search space to iterations based on what was known to work. This is kind of like the philosophical difference between Monte Carlo (throw lots of darts, explore the space) and Hillclimbing (find local optima). I could generate more candidates without ensuring they were viable than to start with viable candidates. I'd already taken a couple passes at reconfiguring my existing op amp into a better geometry... but nothing was working out there. I was already near a local maxima. The successful replacement is pretty different.
<details> <summary>Other message metadata</summary>
{
  "author": {
    "avatarUrl": "2026-06_media/cf91f9947bc37b8a1071311863f9c4b7-14667.png",
    "discriminator": "0000",
    "isBot": false
  },
  "message": {}
}
</details>