Global Optimization of a Symmetrical OTA on SKY130: Geometric Programming Across 45 PVT Corners

Posted on October 13, 2026

Category: Technology

Tags: analog-ic-design, cmos, symmetrical-ota, ota, sky130, ngspice, geometric-programming, convex-optimization, global-optimization, gm-id, ekv-model, transistor-sizing, pvt-corners, cvxpy, python, ai-agents, circuit-design

Views: 4

Global Optimization of a Symmetrical OTA on SKY130: Geometric Programming Across 45 PVT Corners

In Sizing a Symmetrical OTA on SKY130 in Ten Rounds of Conversation the OTA was sized the usual way: gm/Id tables, a greedy worst-case search, and a lot of simulation. The final hand design meets every spec at all 45 PVT conditions. It draws 15.39 μA15.39\,\mu A, uses 154 μm2154\,\mu m^2 of gate area, and the search behind it took 17,685 SPICE operating-point runs.

This post asks a different question: can the same circuit be sized by an optimizer that returns a global optimum, is that optimum better than the hand design, and how much faster is it to get there? The tool is geometric programming (GP). The work took four sessions, and most of it turned out not to be about the optimizer at all. As before, I am keeping my requests in the order I made them, compressed to the turning points.


The circuit and the spec

The circuit is unchanged: NMOS pair M1/M2M_1/M_2 with tail M0M_0 biased from MBM_B, diode loads M3/M4M_3/M_4, 1:B1:B PMOS mirrors M5/M6M_5/M_6, and an NMOS mirror M7/M8M_7/M_8 folding the left branch to the output.

Symmetrical OTA schematic: NMOS differential pair with tail transistor, diode-connected PMOS loads mirrored 1:B to the two output branches, and an NMOS mirror returning the left branch to the output, which drives a 2 pF load capacitor.

The spec is also unchanged, and it is tight:


Round 1 — "Rewrite every spec as a posynomial"

Me:

Last time the sizing relied on your circuit knowledge. This time let us research how to optimize it. Rewrite every OTA spec — gain, PM and so on — as posynomials that include each device's gm/Id, build an objective that minimizes the total device size, and solve it by geometric programming. Use the EKV (v2.6) equations where GP needs them. Can you do that?

And a little later:

Do you think EKV is the right choice here, or is there something better?

The ultimate goal is a general-purpose sizing method, one I can apply to other OTAs later.

What a geometric program is

A monomial is a function c x1a1x2a2⋯xnanc\,x_1^{a_1} x_2^{a_2} \cdots x_n^{a_n} with c>0c > 0 and any real exponents. A posynomial is a sum of monomials. A geometric program is:

min⁡  f0(x)s.t.fi(x)≤1,    gj(x)=1 \min\; f_0(x) \quad \text{s.t.} \quad f_i(x) \le 1,\;\; g_j(x) = 1

with every fif_i a posynomial and every gjg_j a monomial, over positive variables xx. The point of the form is a change of variables. With xi=eyix_i = e^{y_i}, a monomial becomes the exponential of an affine function of yy, and the log of a posynomial becomes a log-sum-exp, which is convex. A GP is a convex problem in disguise. Every local optimum is the global optimum, an interior-point solver finds it in seconds without a starting point, and if the solver says "infeasible," then no design in the model meets the spec.

Hershenson, Boyd and Lee showed in 2001 that a two-stage op-amp can be written this way with square-law devices. Square law is the weak link: every device in this OTA runs in moderate inversion, at gm/IDg_m/I_D between 16 and 23, where square law is off by tens of percent. So the work splits in two. The circuit equations are easy. The device equations are where the accuracy lives.

The circuit equations

Most specs are posynomial almost as written. The gain of the symmetrical OTA and its unity-gain frequency become:

A0=B gm1gds6+gds8  ⇒  10A0/20 (gds6+gds8)≤B gm1 A_0 = \frac{B\,g_{m1}}{g_{ds6} + g_{ds8}} \;\Rightarrow\; 10^{A_0/20}\,(g_{ds6} + g_{ds8}) \le B\,g_{m1}

2πCLfu≤B gm1,IDD=IB (2+B) 2\pi C_L f_u \le B\,g_{m1}, \qquad I_{DD} = I_B\,(2 + B)

The offset from Pelgrom mismatch, with σk=AVT/WkLk\sigma_k = A_{VT}/\sqrt{W_k L_k}, is a posynomial in transconductance ratios:

σos2=2[σ12+(gm3gm1)2(σ32+σ52)+(gm7B gm1)2σ72] \sigma_{os}^2 = 2\left[\sigma_1^2 + \left(\frac{g_{m3}}{g_{m1}}\right)^2 (\sigma_3^2 + \sigma_5^2) + \left(\frac{g_{m7}}{B\,g_{m1}}\right)^2 \sigma_7^2\right]

The objective started as total area, but I changed the priority once I saw it at work: current first, then area, because spending current makes small devices easy. In the final form it is a single product P⋅AwP \cdot A^w. With w=0w = 0 it is pure minimum current; with w=1w = 1, 1 % less current is worth 1 % more area.

The device equations: inversion coefficient and gm/Id

The gm/Id method sizes a transistor by choosing how strongly it is inverted rather than by choosing an overdrive voltage. The natural variable for that is the inversion coefficient from the EKV model:

IC=IDIs,sq(L) W/L IC = \frac{I_D}{I_{s,sq}(L)\,W/L}

IC≪1IC \ll 1 is weak inversion, IC≫1IC \gg 1 is strong inversion, and this design lives between about 0.030.03 and 33. The definition is a monomial equality, so WW, LL, IDI_D and ICIC of every device are GP variables tied together exactly.

EKV also gives gm/IDg_m/I_D as one expression valid in all regions:

gmID=1nUT(12+14+IC) \frac{g_m}{I_D} = \frac{1}{n U_T \left(\tfrac{1}{2} + \sqrt{\tfrac{1}{4} + IC}\right)}

It tends to 1/(nUT)1/(n U_T) in weak inversion and falls as 1/IC1/\sqrt{IC} in strong inversion. That was the answer to the question of whether EKV is the right choice: its structure is exactly what GP wants. Fitted to SKY130 tables as it stands, it was off by 11 % rms. One extra term, λ IC\lambda\,IC, standing in for velocity saturation and mobility reduction, brought the error to 1.9 %:

gm⋅n UT(12+(14+IC)1/2+λ IC)≤ID g_m \cdot n\,U_T \left(\tfrac{1}{2} + \left(\tfrac{1}{4} + IC\right)^{1/2} + \lambda\,IC\right) \le I_D

This is a valid GP constraint as written. A positive fractional power of a posynomial is still log-log convex, and CVXPY's disciplined GP accepts it directly. The parameters nn, Is,sqI_{s,sq} and λ\lambda are fitted jointly per length, and each is then expressed as a monomial c Lac\,L^a.

Much later I asked about the fitted value of nn:

You did not just use a constant like 1.4, did you? Isn't n usually below 1.5?

It was not a constant: it ranges from 1.5 to 1.9 for the nfet and is about 2.0 for the pfet, against a physical slope factor of 1.3 to 1.5 in BSIM. That is not a mistake, but it has to be read correctly. In a joint fit the parameters absorb the model's shape error, so they form a coordinate system rather than a measurement. The ICIC values in this post are on the fit's own scale.

Everything else: max-of-monomials fits

While the first fits were running, I checked the plan for whatever EKV could not cover:

Where EKV does not fit well, the plan is to fit the data and turn it into monomial or posynomial functions, piecewise or over the whole range, right?

That is what was done. The remaining quantities (gds/IDg_{ds}/I_D, VDSATV_{DSAT}, capacitance per width) have no compact physical formula. They are fitted from ngspice tables as the maximum of a few monomials. This is the GP-compatible form of a convex piecewise-linear fit in log space:

gdsID≤max⁡k  ck ICakLbkVDSdk \frac{g_{ds}}{I_D} \le \max_k\; c_k\, IC^{a_k} L^{b_k} V_{DS}^{d_k}

VDSAT≤max⁡k  ck ICakLbkVDSdk(VSB+ϕ)ek V_{DSAT} \le \max_k\; c_k\, IC^{a_k} L^{b_k} V_{DS}^{d_k} (V_{SB} + \phi)^{e_k}

These quantities sit on the "less than" side of each spec, so an upper fit keeps the GP conservative.


Round 2 — "Isn't GP supposed to be global?"

Two specs did not fit the pure form. The EKV constraint only bounds gmg_m from above. That is fine where a spec wants gmg_m large, but in the offset formula gm3g_{m3} sits in a numerator, and the solver could report a gm3g_{m3} smaller than physics allows. Phase margin is a sum of arctangents of pole ratios, and an arctangent is not a posynomial. Claude handled both with sequential GP (SGP): replace each awkward term by a monomial bound around a previous solution, solve, repeat. The cold start of that loop kept failing.

Me:

What is SGP, and why does the cold start fail? I thought GP gives a global optimum, with no dependence on the initial value.

With SGP, global optimality is no longer guaranteed, and I do not like the dependence on the initial value. What about two steps? If the device sizes can be found first from only the specs that GP can express, do that in phase 1. Then use the result as the initial condition of the SGP problem with all specs in phase 2.

That became the structure of every solve. Phase 1 is two pure GPs with opposite approximations, so each one is a true global optimum of its own problem:

Phase 2 is SGP started from the safe solution. Each step tightens the AM-GM and tangent bounds around the previous point, so every step stays feasible and is no worse than the last. The true optimum is bracketed between relax and the SGP result.

I pushed on what that means:

If GP is solvable in a given design space and returns a result, isn't that the optimized result? Shouldn't the answer be a yes or a no?

For the pure GPs it is a yes or a no. SGP adds refinement. In practice the safe point was within 1 % of the converged optimum, and two SGP steps matched full convergence to four digits in 52 s instead of 144 s.

So SGP is a kind of fine tuning.

That is the right way to see it. The honest claim is a global optimum of a convex inner approximation, plus a fine-tuning step whose gap is measured.


Round 3 — "Put every corner into one design space"

The first GP was sized at tt, 27∘C27^\circ C, with targets set to the hand design's tt performance. It came back at 16.47 μA16.47\,\mu A and 138.8 μm2138.8\,\mu m^2, smaller than the hand design, and failed the 45-condition SPICE check on saturation at the swing ends: 14 to 36 mV of margin against 50. The hand design passes.

My first idea was design centering by overspec:

We already have equations for every spec. Put the tt GP sizes and the fitted corner parameters into them, and we can predict how far each spec will drift at the worst case. Then solve the tt GP again with that much overspec.

It failed for a structural reason. The drift between tt and the worst corner depends on the design, so the drift measured on one design is wrong for the next one, and the second solve became infeasible. So I changed the approach:

Let us rethink this. Instead of two GP solves, do one, and widen the design space so it contains the corners. Put the multi-corner GP into a single design space and solve it once. If each corner's design space is 1×1, do not run a GP in each one; run one GP over the 3×3 space that contains them all.

The spec stays the same everywhere. What changes per corner are the constants inside the GP constraints.

In GP form this is natural. Every condition gets its own copy of the device equations, built from that condition's fitted model. Widths, lengths and currents are shared, while ICIC, gmg_m, gdsg_{ds} and VDSATV_{DSAT} are per condition. The feasible set is the intersection of all 45, so a solution meets every condition at once. It takes 15 model files (5 corners × 3 temperatures). The supply only enters the headroom equations, so it stays a constant in the formulas.

Earlier I had worried that more variables would make the optimum harder to judge. It does not. The design variables do not grow with the number of conditions. Only the per-condition state variables do, and they are fixed by the design variables. The problem stays convex.


Round 4 — "L belongs in the design space too"

The first multi-corner version still treated lengths as a discrete grid and solved one GP per combination of BB and the group lengths, 2,662 of them in the last version. While watching it run, I stopped it:

Going about it this way does not seem to mean much.

Put the L enumeration into the design space as an equation. If it is in the design space, one GP solve per B should be the end of it.

That required fitting each device quantity as a function of LL, and that is where the first real modeling problem appeared. In SKY130, nfet gds/IDg_{ds}/I_D rises with LL up to about 1 μm1\,\mu m, stays flat to 2 μm2\,\mu m, and then falls steeply. In log-log space that is a hump, a concave shape. A max-of-monomials fit is convex, so it cannot follow a hump. Its rms error floors around 10 % no matter how many monomials are used.

The optimizer then did exactly what an optimizer does. It went to the lengths where the fit was most optimistic, L=1.6L = 1.6 to 2 μm2\,\mu m on the NMOS mirror, and the SPICE gain came out 0.6 dB below the model's prediction.

Can't we express two pieces as a piecewise-linear equation and put them into one space? Or split it in two and double the design space?

Doubling the space does not work the way corners do. Corners must all hold, an intersection, which a single convex problem handles. Length segments are alternatives, a union, and the choice between them sits outside convexity. But the hump's corners line up with the BSIM length bins at 11 and 2 μm2\,\mu m. Split there, each of the three segments is convex on its own. The GP assumes a segment per device group, solves, checks where each length landed, and re-solves with those segments until nothing moves:

Let us try the concave upper-bound iteration.

It converges in about two passes. A six-condition solve went from 1,434 s with enumeration to 13 s. The full 45-condition solve takes about two minutes per value of BB.


Round 5 — "Manual passes with B = 2"

After every GP solution, the pipeline runs the 45-condition SPICE check and feeds the shortfalls back as per-condition targets for the next solve. The aim was the hand design's B=2B = 2, which halves the input-pair current needed for a given UGF. Instead, B=2B = 2 kept dropping out and the loop fell back to B=1B = 1.

Several model fixes went in along the way. The gdsg_{ds} fit was weighted 10× in the operating window, which brought the model's average gain bias from +0.33+0.33 to −0.11 dB-0.11\,dB. The VDSATV_{DSAT} fit gained VDSV_{DS} and VSBV_{SB} axes, because it had ignored body effect on the pair and the low VDSV_{DS} at the swing ends, together worth up to 4 mV at 85∘C85^\circ C. Then I looked at the correction loop itself:

Does the correction adjust every spec at once, or only raise the ones that fell short?

Isn't adjusting all of them at once the problem? Only the specs that fell short should move.

It had been resetting every target at every condition on every round, so it raised targets that already passed. Changed to ratchet up only on shortfalls, it finally passed:

Version Change Round 0 (B=2B = 2) Outcome
v1 45-PVT single GP A0 44.62 dB, FAIL B = 2 dropped in round 1; B = 1 NEAR
v3 gdsg_{ds} fit weighted in the operating window A0 44.94, sat 47.7 mV, FAIL B = 2 dropped again
v4 VDSATV_{DSAT} fit with VDSV_{DS} and VSBV_{SB} axes B = 2 infeasible in the GP B = 1, A0 stuck at 44.89
v5 correction raises shortfalls only — B = 1 PASS: 20.70 μA20.70\,\mu A, 262.9 μm2262.9\,\mu m^2

That is 35 % more current and 71 % more area than the hand design.

The manual design was done with B = 2 and passed every corner, so the spec is not impossible.

So "B = 2 is infeasible" was not a statement about the circuit. It was a statement about the model, or about the design space.


Round 6 — "Why does the GP solution fail in SPICE?"

Me:

Compare with the manual sizing for now. The biggest problem is finding out why the GP solution, especially with B = 2, does not meet the spec in SPICE, and fixing it.

Claude wrote a script to evaluate any fixed design with the GP model at its SPICE operating points, condition by condition, and ran it on the hand design. Up to then every model bias had been measured on the optimizer's own solutions, and that is a blind spot. If the model is pessimistic in some region, the optimizer avoids that region, so the bias never shows up in the solutions being checked.

On the hand design, the model's gain was 1.1 to 1.66 dB too low at all 45 conditions. Split by term, gds8g_{ds8} was overestimated by 12 to 18 % and gds6g_{ds6} by 7 to 10 %.

The NMOS mirror explained most of it. The hand design draws M8M_8 as one finger of 15.9 μm15.9\,\mu m. The GP's design space allowed fingers up to 4 μm4\,\mu m, and its models were characterized at 2 μm2\,\mu m. A single-device simulation with the same total width, length, current and VDSV_{DS} separated the effects:

The model was accurate for the device it described. The device it described was not the one in the hand design. BSIM parameters are binned in width as well as length, and a sweep of finger width shows the steps:

Line chart of output conductance over drain current, relative to a 2 micrometre finger, for finger widths from 1 to 32 micrometres. The nfet at L 2.8 micrometres falls from 1.0 to 0.80 and the nfet at L 1.0 from 1.0 to 0.85 as fingers widen past 4 micrometres; the pfet at L 0.8 stays near 0.98. Values below 4 micrometres jump non-monotonically. The region up to 4 micrometres, the first GP design space, is shaded.

The steps are not monotonic, so a smooth monomial correction such as (Wf/2)α(W_f/2)^\alpha cannot model them. Instead, finger width became a discrete choice per device group, with a full model set at each bin: 22, 55, 88 and 16 μm16\,\mu m, 60 model files in all, solved in parallel. The pfet gdsg_{ds} fit, which had been 7 % pessimistic at the fast-slow 85∘C85^\circ C corner only, was split at the length bins like the nfet's. Re-evaluated, the hand design's gain bias at the binding condition went from −1.18-1.18 to −0.07 dB-0.07\,dB.

So in the end, the GP solver did not fail because the spec was hard to reach. The problem was the accuracy of the model the GP used?

Then it sounds like with Wf≤4 μmW_f \le 4\,\mu m the GP solver would still find no solution.

Both, and the second one was checked in SPICE. The new GP's B=2B = 2 solution uses a single 16 μm16\,\mu m finger on the NMOS mirror. Redrawn as 4×4 μm4 \times 4\,\mu m with the same total width, it fails at 44.13 dB44.13\,dB. With fingers capped at 4 μm4\,\mu m, B=2B = 2 really is impossible under this spec. The earlier "infeasible" answers were correct for the space the optimizer was given; that space just did not contain the hand design.

The correction loop showed one more failure along the way. Raising each target by exactly its shortfall shrinks the shortfall geometrically, so it approaches the spec boundary and never crosses it. In the end the remaining shortfall was smaller than the 0.01 µm rounding of a finger width, and the design stopped changing at 49.98 mV of margin. A small guard band (0.5 mV on saturation, 0.5 % on UGF) fixed it, and B=2B = 2 passed in round 2.


Round 7 — "Why is the pfet Vdsat optimistic?"

One bias remained. At the swing end, the VDSATV_{DSAT} fit was about 3 mV optimistic for the output PMOS. A one-at-a-time decomposition (real VDSV_{DS} against characterization VDSV_{DS}, real against reference width, real against grid length) left almost all of it as pure fit error. Two things bent the fit:

Filtering the table to VDS≥VDSAT+30 mVV_{DS} \ge V_{DSAT} + 30\,mV and IC≤3IC \le 3, and splitting at the same length bins, cut the worst error in the operating window from −7.7-7.7 to −1.0 mV-1.0\,mV.

With that model, the pipeline passed all 45 conditions on the first GP solution, with no correction rounds: 138 SPICE runs and 170 s in total.


Round 8 — "Run it once more with a larger area weight"

Me:

Set w-area to 1.0, run the GP pipeline once more with B = 2, and compare again, including the manual design's IDD.

With w=1w = 1 the first two solutions missed the offset spec by a fraction of a millivolt (5.04 and 4.98 mV in Monte Carlo, against 4.84). The offset correction fixed it in round 2.


The result

All three designs were measured on the same bench: 45-PVT worst case for every spec, supply current at tt, and offset from a 200-run mismatch Monte Carlo.

Spec Manual GP, w=0.2w = 0.2 GP, w=1.0w = 1.0
IBI_B / IDDI_{DD} (μA\mu A) — 4.000 / 15.39 3.511 / 13.67 (−11.2 %) 3.699 / 14.20 (−7.7 %)
Area (μm2\mu m^2) — 154.0 177.9 (+15.5 %) 153.0 (−0.6 %)
A0A_0 (dB) ≥ 45 45.08 45.04 45.05
UGF (MHz) ≥ 5 5.573 5.060 5.112
PM (°) ≥ 70 72.98 73.40 73.74
Saturation, VCM / swing (mV) ≥ 50 66.8 / 50.6 66.3 / 50.1 53.9 / 50.4
σos\sigma_{os} (mV) ≤ 4.84 4.83 4.19 4.83
SPICE correction rounds — — 0 2
Group (W/LW/L in μm\mu m, multiplier) Manual GP, w=0.2w = 0.2 GP, w=1.0w = 1.0
Tail MB/M0M_B/M_0 4/0.8 m1 2.99/2.05 m2 2.27/1.08 m2
Pair M1/M2M_1/M_2 6.4/0.6 m2 3.94/0.89 m4 2.75/0.64 m4
PMOS M3M_3–M6M_6 9/0.8 8.19/0.85 8.8/0.87
NMOS mirror M7/M8M_7/M_8 15.9/2.8 m1 16/2.61 m1 16/2.6 m1

Scatter plot of gate area against supply current for every design that reached the 45-PVT check. Manual sits at 15.39 microamps and 154 square micrometres. The GP designs that pass all 45 conditions are at 20.70 and 262.9 with B equal to 1, 13.67 and 177.9 with B equal to 2 and area weight 0.2, and 14.20 and 153.0 with area weight 1.0. A tt-only GP design at 16.47 and 138.8 is drawn hollow because it fails the corners.

At equal area, the GP design draws 7.7 % less current. Most of the difference is the hand design's spare UGF: 11.5 % above spec at the worst corner, against 1 to 2 % for the GP. The rest is small and spread out: a slightly lower gm/IDg_m/I_D on the input pair, a longer or multi-finger tail mirror, and area placed where the offset needs it.

The most telling row is the last one in the size table. Given the freedom to choose, the GP's NMOS mirror is almost exactly the hand design's: one wide finger, L≈2.6 μmL \approx 2.6\,\mu m. The operating points agree too. At tt, gm/IDg_m/I_D is within about 1 per device across all three designs: about 23 for the pair, 16 for the PMOS, and 19 to 20 for the NMOS mirror.


Design speed — from hours of SPICE to one verification

A better design was only half of what I wanted from GP. In the first session I asked for this comparison too:

Later, also compare whether designing the OTA with this general GP actually helps over the manual design, in speed as well as performance. On speed, I expect it to help a lot, since it cuts the number of loops.

When Claude first reported the numbers, they mixed up two different things:

Are the counts in this speed comparison all simulation counts? They look mixed with GP iteration counts.

And what is a "round" in the manual design?

So the comparison below uses one unit throughout: SPICE operating-point analyses. Checking one candidate at 45 PVT conditions takes 135 of them, one at the common-mode point and one at each swing end. A "round" of the manual greedy search changes one device group at a time, tries about twelve candidates, and keeps the best. The manual counts come from its logs.

Manual (greedy) GP, first PASS (run 11) GP, final, w=0.2w = 0.2 GP, final, w=1.0w = 1.0
Candidates checked at 45 PVT 131 in 11 rounds — 1 3
SPICE op analyses 17,685 3,012 138 414
Fewer than manual — 5.9× 128× 43×
Monte Carlo (mismatch) final check only 13 × 1,000 1 × 200 3 × 200
Wall-clock time several sessions, partly by hand about 21 min, automatic 170 s, automatic 329 s, automatic

The manual count is a lower bound. It includes only the greedy run that was kept. With the abandoned first run (zero saturation margin) the total is 43,740. It also leaves out the hand calculations and tt simulations used to find a starting point, and the check after the tail was resized by hand, because none of those were logged.

The reason for the gap is where SPICE sits in the loop. In the manual flow, SPICE is the search: every candidate is a 45-condition simulation, and the greedy search needs a hundred or more of them to settle. In the GP flow the search happens inside the solver, against fitted models that evaluate in microseconds. SPICE moves to the end and only verifies the answer. How often it has to verify depends entirely on model accuracy. Run 11, with coarse models and enumerated lengths, needed 3,012 analyses. Each later fix cut that number: 966 once the tail length became continuous, and 138 once the model was right in the region that mattered. At that point there is one GP solve, one 45-PVT check, and done.

Changing the design is cheap too. Moving the area weight from 0.2 to 1.0 was one command line and five minutes. In the manual flow, a different priority means another greedy run from a new starting point.

Two costs sit outside this table, and both are paid once rather than per design:


Afterwards — was the spec fair?

Near the end I asked whether any spec item was unusually hard compared with typical ones. The answer was the swing: a 50 mV saturation margin with the output only 150 mV from either rail.

A saturation margin of 50 to 100 mV is common, but a 0.15 V output swing limit was a bit tight. Usually it is set to around 0.2 to 0.25 V.

No, never mind. It is a test design anyway, so let us call it an attempt at a tight spec. It cost us some effort, but we learned a lot from it. No need to rerun.

The tightness is what made the model errors visible. At the swing end, a 3 mV VDSATV_{DSAT} error or a 0.15 dB gain bias was enough to decide between B=1B = 1 and B=2B = 2, a 35 % difference in current. A looser spec would have hidden all of them.


What I am taking from this

"Global" means global inside the model and the design space, nothing more. The solver was never wrong. Every time the GP said a design was infeasible, it was right about the problem it had been given. The problem was wrong: a convex fit of a concave curve, a fit dragged by points the circuit never visits, and a finger-width cap that excluded the hand design. A convex formulation turns optimization from a search into a modeling exercise, and the modeling exercise is the hard part.

Measure model error on a design the optimizer did not choose. On the optimizer's own solutions, the gain bias averaged −0.11 dB-0.11\,dB, which looked excellent. On the hand design it was over −1 dB-1\,dB. An optimizer avoids regions where its model is pessimistic, so checking only its own answers hides exactly the errors that matter. A known-good design is the cheapest independent test there is.

An optimizer finds every optimistic error in a fit. It went straight to L=1.6L = 1.6–2 μm2\,\mu m, where the convex fit was most optimistic, and gained 0.6 dB on paper. A fit used for optimization should be judged by its worst residual in the region the optimizer can reach, not by its rms.

EKV gives the right structure, but its parameters are a coordinate system. One formula from weak to strong inversion is what let gm/IDg_m/I_D fit the GP form at all, and one extra λ IC\lambda\,IC term brought it to 2 %. A fitted slope factor of 2.0 is not a physical number.

Keep the global part and make the local part small. Splitting each solve into two pure GPs that bracket the answer, and then SGP fine tuning from the safe side, kept the guarantee where it matters: feasibility and a known gap, instead of a dependence on the starting point.

The speed comes from moving SPICE from search to verification. The hand search ran 131 candidates through 45 conditions; the final GP ran one. That is a 128× cut in SPICE analyses and minutes instead of sessions, and it holds only as long as the model is accurate. Every model error showed up as extra verification rounds.

When the model is right, the correction loop disappears. The SPICE feedback loop was built to absorb model error. Once the device fits were accurate where it mattered, the first GP solution passed and the loop had nothing left to do.


References


Disclaimer: This blog post was created with assistance from Claude, an AI developed by Anthropic, under my direct supervision and guidance to ensure accuracy and alignment with my vision for the content.