Update bandgap.

Up bandgap code now provided in c4m.pdk.sky130
Add three bandgaps: 3.3V, 1.8V with low Vt devs, and 1.8V with regular Vt
devs.
diff --git a/doitcode/bandgap.py b/doitcode/bandgap.py
index fcd9d95..4c38897 100644
--- a/doitcode/bandgap.py
+++ b/doitcode/bandgap.py
@@ -15,625 +15,6 @@
 __all__ = ["ConnectedBandGap"]
 
 
-class _BandGap3V3(_lbry._OnDemandCell[_lbry.Library]):
-    def __init__(self, *, lib: _lbry.Library):
-        super().__init__(lib=lib, name="BandGap3V3")
-
-    def _create_circuit(self):
-        ckt = self.new_circuit()
-
-        ln = 2.0
-        wn = 3.7
-        lp  = 2.0
-        wp = 18
-
-        res1_h = 11.5
-        res2_h = 20.0
-        self.res2_n = res2_n = 7
-
-        self.pnp_ratio = pnp_ratio = 4
-
-        nmos = cast(_prm.MOSFET, _prims.nfet_g5v0d10v5)
-        pmos = cast(_prm.MOSFET, _prims.pfet_g5v0d10v5)
-        res = cast(_prm.Resistor, _prims.poly_res)
-
-        p1 = ckt.instantiate(pmos, name="p1", l=lp, w=wp)
-        p2 = ckt.instantiate(pmos, name="p2", l=lp, w=wp)
-        p3 = ckt.instantiate(pmos, name="p3", l=lp, w=wp)
-        ps = (p1, p2, p3)
-
-        n1 = ckt.instantiate(nmos, name="n1", l=ln, w=wn)
-        n2 = ckt.instantiate(nmos, name="n2", l=ln, w=wn)
-        ns = (n1, n2)
-
-        res1 = ckt.instantiate(res, name="res1", height=res1_h)
-        res2s = tuple(
-            ckt.instantiate(res, name=f"res2[{n}]", height=res2_h)
-            for n in range(res2_n)
-        )
-
-        pnp_cell = sky130.macrolib.cells["PNP_05v5_W3u40L3u40"]
-        pnp1 = ckt.instantiate(pnp_cell, name="pnp1")
-        pnp2s = tuple(
-            ckt.instantiate(pnp_cell, name=f"pnp2[{n}]")
-            for n in range(pnp_ratio)
-        )
-        pnp3s = tuple(
-            ckt.instantiate(pnp_cell, name=f"pnp3[{n}]")
-            for n in range(pnp_ratio)
-        )
-        pnps = (pnp1, *pnp2s, *pnp3s)
-
-        ckt.new_net(name="vss", external=True, childports=(
-            *(n.ports.bulk for n in ns),
-            *(pnp.ports.base for pnp in pnps),
-            *(pnp.ports.collector for pnp in pnps),
-        ))
-        ckt.new_net(name="vdd", external=True, childports=(
-            *(p.ports.sourcedrain1 for p in ps),
-            *(p.ports.bulk for p in ps),
-        ))
-        ckt.new_net(name="vref", external=True, childports=(
-            p3.ports.sourcedrain2, res2s[-1].ports.port2,
-        ))
-
-        ckt.new_net(name="p_gate", external=False, childports=(
-            *(p.ports.gate for p in ps),
-            p2.ports.sourcedrain2, n2.ports.sourcedrain2,
-        ))
-        ckt.new_net(name="n_gate", external=False, childports=(
-            *(n.ports.gate for n in ns),
-            n1.ports.sourcedrain2, p1.ports.sourcedrain2,
-        ))
-        ckt.new_net(name="vq1", external=False, childports=(
-            pnp1.ports.emitter, n1.ports.sourcedrain1,
-        ))
-        ckt.new_net(name="vq2", external=False, childports=(
-            *(pnp2.ports.emitter for pnp2 in pnp2s), res1.ports.port1,
-        ))
-        ckt.new_net(name="vq2r1", external=False, childports=(
-            res1.ports.port2, n2.ports.sourcedrain1,
-        ))
-        ckt.new_net(name="vq3", external=False, childports=(
-            *(pnp3.ports.emitter for pnp3 in pnp3s), res2s[0].ports.port1,
-        ))
-
-        for n in range(res2_n - 1):
-            res2_1 = res2s[n]
-            res2_2 = res2s[n + 1]
-            ckt.new_net(name=f"res2_{n}", external=False, childports=(
-                res2_1.ports.port2, res2_2.ports.port1,
-            ))
-
-    def _create_layout(self):
-        tech = self.tech
-
-        # We don't try to optimize area for this circuit yet.
-        ckt = self.circuit
-        nets = ckt.nets
-        insts = ckt.instances
-
-        nwm = cast(_prm.Well, _prims.nwm)
-        difftap = cast(_prm.WaferWire, _prims.difftap)
-        nsdm = cast(_prm.Implant, _prims.nsdm)
-        psdm = cast(_prm.Implant, _prims.psdm)
-        hvi = cast(_prm.Insulator, _prims.hvi)
-        poly = cast(_prm.GateWire, _prims.poly)
-        licon = cast(_prm.Via, _prims.licon)
-        li = cast(_prm.MetalWire, _prims.li)
-        assert li.pin is not None
-        lipin = li.pin[0]
-        mcon = cast(_prm.Via, _prims.mcon)
-        m1 = cast(_prm.MetalWire, _prims.m1)
-        assert m1.pin is not None
-        m1pin = m1.pin[0]
-        via = cast(_prm.Via, _prims.via)
-        m2 = cast(_prm.MetalWire, _prims.m2)
-        assert m2.pin is not None
-        bnd = cast(_prm.Auxiliary, _prims.prBoundary)
-
-        layouter = self.new_circuitlayouter()
-        layout = layouter.layout
-
-        # place res1
-        _res1 = layouter.inst_layout(inst=insts.res1, rotation=_geo.Rotation.MX)
-        _bb = _res1.bounds()
-        x = -1.0 - _bb.right
-        y = 20.0 - _bb.top
-        res1_lay = layouter.place(insts.res1, x=x, y=y)
-        res1vq2_libb = res1_lay.bounds(net=nets.vq2, mask=li.mask)
-        res1vq2r1_libb = res1_lay.bounds(net=nets.vq2r1, mask=li.mask)
-
-        # place bipolars
-        pnp1 = cast(_ckt._CellInstance, insts.pnp1)
-        pnp2s = tuple(
-            cast(_ckt._CellInstance, insts[f"pnp2[{n}]"])
-            for n in range(self.pnp_ratio)
-        )
-        pnp3s = tuple(
-            cast(_ckt._CellInstance, insts[f"pnp3[{n}]"])
-            for n in range(self.pnp_ratio)
-        )
-
-        _pnp1_bb = pnp1.cell.layout.boundary
-        assert _pnp1_bb is not None
-
-        x0_pnp = -_pnp1_bb.left
-        y0_pnp = -_pnp1_bb.bottom
-        dx_pnp = _pnp1_bb.width
-        dy_pnp = _pnp1_bb.height
-
-        assert self.pnp_ratio == 4, "Internal error"
-        inst_matrix = (
-            (pnp2s[0], pnp2s[1], pnp3s[0]),
-            (pnp3s[1], pnp1, pnp3s[2]),
-            (pnp3s[3], pnp2s[2], pnp2s[3]),
-        )
-        lay_matrix: List[Tuple[_lay._Layout, _lay._Layout, _lay._Layout]] = []
-        for row in range(3):
-            row_lays: List[_lay._Layout] = []
-            y = y0_pnp + row*dy_pnp
-            for col in range(3):
-                x = x0_pnp + col*dx_pnp
-                inst = inst_matrix[row][col]
-                row_lays.append(layouter.place(inst, x=x, y=y))
-            lay_matrix.append(tuple(row_lays))
-
-        # vss connection to the bipolars
-        right = 0.0
-        top = 0.0
-        for ms in lay_matrix[0][0].filter_polygons(
-            net=nets.vss, mask=lipin.mask, split=True
-        ):
-            shape = ms.shape
-            right = max(right, shape.bounds.left)
-            top = max(top, shape.bounds.bottom)
-
-        shape = _geo.Rect(left=0.0, bottom=0.0, right=3*dx_pnp, top=top)
-        layouter.add_wire(net=nets.vss, wire=li, pin=lipin, shape=shape)
-        shape = _geo.Rect(
-            left=0.0, bottom=(dy_pnp - top), right=3*dx_pnp, top=(dy_pnp + top),
-        )
-        layouter.add_wire(net=nets.vss, wire=li, shape=shape)
-        shape = _geo.Rect(
-            left=0.0, bottom=(2*dy_pnp - top), right=3*dx_pnp, top=(2*dy_pnp + top),
-        )
-        layouter.add_wire(net=nets.vss, wire=li, shape=shape)
-        shape = _geo.Rect(
-            left=0.0, bottom=(3*dy_pnp - top), right=3*dx_pnp, top=3*dy_pnp,
-        )
-        layouter.add_wire(net=nets.vss, wire=li, shape=shape)
-
-        shape = _geo.Rect(left=0.0, bottom=0.0, right=right, top=3*dy_pnp)
-        layouter.add_wire(net=nets.vss, wire=li, shape=shape)
-        shape = _geo.Rect(
-            left=(dx_pnp - right), bottom=0.0, right=(dx_pnp + right), top=3*dy_pnp,
-        )
-        layouter.add_wire(net=nets.vss, wire=li, shape=shape)
-        shape = _geo.Rect(
-            left=(2*dx_pnp - right), bottom=0.0, right=(2*dx_pnp + right), top=3*dy_pnp,
-        )
-        layouter.add_wire(net=nets.vss, wire=li, shape=shape)
-        shape = _geo.Rect(
-            left=(3*dx_pnp - right), bottom=0.0, right=3*dx_pnp, top=3*dy_pnp,
-        )
-        layouter.add_wire(net=nets.vss, wire=li, shape=shape)
-
-        # Place res2s
-        polyport2bb = liport2bb = None
-        x = 3*dx_pnp + 1.0
-        vq3res2_libb = None
-        vrefres2_libb = None
-        for n in range(self.res2_n):
-            if (n%2) == 0:
-                _res_lay = layouter.inst_layout(inst=insts[f"res2[{n}]"])
-            else:
-                _res_lay = layouter.inst_layout(
-                    inst=insts[f"res2[{n}]"], rotation=_geo.Rotation.MX,
-                )
-            _res_polybb = _res_lay.bounds(mask=poly.mask)
-
-            x_res = x - _res_polybb.left
-            y_res = -_res_polybb.bottom
-            res_lay = layouter.place(_res_lay, x=x_res, y=y_res)
-            res_polybb = res_lay.bounds(mask=poly.mask)
-            res_libb = res_lay.bounds(mask=li.mask)
-
-            if polyport2bb is not None:
-                assert n > 0
-                assert liport2bb is not None
-
-                net = nets[f"res2_{n - 1}"]
-                shape = _geo.Rect.from_rect(rect=polyport2bb, right=res_polybb.right)
-                layouter.add_wire(net=net, wire=poly, shape=shape)
-
-                shape = _geo.Rect.from_rect(rect=liport2bb, right=res_libb.right)
-                layouter.add_wire(net=net, wire=li, shape=shape)
-
-            if n == 0:
-                vq3res2_libb = res_lay.bounds(mask=li.mask, net=nets.vq3)
-
-            if n < (self.res2_n - 1):
-                net = nets[f"res2_{n}"]
-                polyport2bb = res_lay.bounds(mask=poly.mask, net=net)
-                liport2bb = res_lay.bounds(mask=li.mask, net=net)
-            else:
-                vrefres2_libb = res_lay.bounds(mask=li.mask, net=nets.vref)
-
-            x = res_polybb.right + poly.min_space
-        assert vq3res2_libb is not None
-        assert vrefres2_libb is not None
-
-        # Place mosfets
-        _n1_lay = layouter.inst_layout(inst=insts.n1)
-        _n1_bb = _n1_lay.bounds()
-        _p1_lay = layouter.inst_layout(inst=insts.p1)
-        _p1_bb = _p1_lay.bounds()
-
-        x = 1.5 - min(_n1_bb.left, _p1_bb.left)
-        dx_mos = _n1_bb.width + 0.5
-        y_n = 3*dy_pnp + 0.5 - _n1_bb.bottom
-        y_p = y_n + _n1_bb.top + 0.8 - _p1_bb.bottom
-
-        n1_lay = layouter.place(_n1_lay, x=x, y=y_n)
-        n1_actbb = n1_lay.bounds(mask=difftap.mask)
-        n1_nsdmbb = n1_lay.bounds(mask=nsdm.mask)
-        n1_hvibb = n1_lay.bounds(mask=hvi.mask)
-        n1_polybb = n1_lay.bounds(mask=poly.mask)
-        p1_lay = layouter.place(_p1_lay, x=x, y=y_p)
-        p1_actbb = p1_lay.bounds(mask=difftap.mask)
-        p1_psdmbb = p1_lay.bounds(mask=psdm.mask)
-        p1_hvibb = p1_lay.bounds(mask=hvi.mask)
-        p1_polybb = p1_lay.bounds(mask=poly.mask)
-
-        x += dx_mos
-        n2_lay = layouter.place(insts.n2, x=x, y=y_n)
-        n2_actbb = n2_lay.bounds(mask=difftap.mask)
-        n2_nsdmbb = n2_lay.bounds(mask=nsdm.mask)
-        n2_polybb = n2_lay.bounds(mask=poly.mask)
-        p2_lay = layouter.place(insts.p2, x=x, y=y_p)
-        p2_actbb = p2_lay.bounds(mask=difftap.mask)
-        p2_polybb = p2_lay.bounds(mask=poly.mask)
-        x += dx_mos
-        p3_lay = layouter.place(insts.p3, x=x, y=y_p)
-        p3_nwbb = p3_lay.bounds(mask=nwm.mask)
-        p3_actbb = p3_lay.bounds(mask=difftap.mask)
-        p3_psdmbb = p3_lay.bounds(mask=psdm.mask)
-        p3_polybb = p3_lay.bounds(mask=poly.mask)
-
-        # n_gate
-        net = nets.n_gate
-
-        _chngaten_lay = layouter.wire_layout(
-            net=net, wire=licon, bottom=difftap, bottom_implant=nsdm,
-            bottom_height=n1_actbb.height, bottom_enclosure="wide",
-        )
-        _chngaten_actbb = _chngaten_lay.bounds(mask=difftap.mask)
-        x = n1_polybb.right - _chngaten_actbb.left
-        y = n1_actbb.bottom - _chngaten_actbb.bottom
-        chngaten_lay = layouter.place(_chngaten_lay, x=x, y=y)
-        chngaten_libb = chngaten_lay.bounds(mask=li.mask)
-
-        _chngatep_lay = layouter.wire_layout(
-            net=net, well_net=nets.vdd, wire=licon,
-            bottom=difftap, bottom_implant=psdm, bottom_well=nwm,
-            bottom_height=p1_actbb.height, bottom_enclosure="wide",
-        )
-        _chngatep_actbb = _chngatep_lay.bounds(mask=difftap.mask)
-        x = p1_polybb.right - _chngatep_actbb.left
-        y = p1_actbb.bottom - _chngatep_actbb.bottom
-        chngatep_lay = layouter.place(_chngatep_lay, x=x, y=y)
-        chngatep_libb = chngatep_lay.bounds(mask=li.mask)
-
-        _chngatepad_lay = layouter.wire_layout(
-            net=net, wire=licon, bottom=poly, bottom_enclosure="tall",
-        )
-        _chngatepad_polybb = _chngatepad_lay.bounds(mask=poly.mask)
-        # x = x # Keep the x value
-        y = n1_polybb.top - _chngatepad_polybb.bottom
-        chngatepad_lay = layouter.place(_chngatepad_lay, x=x, y=y)
-        chngatepad_polybb = chngatepad_lay.bounds(mask=poly.mask)
-
-        shape = _geo.Rect.from_rect(
-            rect=chngaten_libb, top=chngatep_libb.top)
-        layouter.add_wire(net=net, wire=li, shape=shape)
-
-        ngatepad_bb = _geo.Rect.from_rect(
-            rect=chngatepad_polybb, left=n1_polybb.left, right=n2_polybb.right,
-        )
-        layouter.add_wire(net=net, wire=poly, shape=ngatepad_bb)
-
-        # p_gate
-        net = nets.p_gate
-
-        _chpgaten_lay = layouter.wire_layout(
-            net=net, wire=licon, bottom=difftap, bottom_implant=nsdm,
-            bottom_height=n2_actbb.height, bottom_enclosure="wide",
-        )
-        _chpgaten_actbb = _chpgaten_lay.bounds(mask=difftap.mask)
-        x = n2_polybb.right - _chpgaten_actbb.left
-        y = n2_actbb.bottom - _chpgaten_actbb.bottom
-        chpgaten_lay = layouter.place(_chpgaten_lay, x=x, y=y)
-        chpgaten_libb = chpgaten_lay.bounds(mask=li.mask)
-
-        _chpgatep_lay = layouter.wire_layout(
-            net=net, well_net=nets.vdd, wire=licon,
-            bottom=difftap, bottom_implant=psdm, bottom_well=nwm,
-            bottom_height=p1_actbb.height, bottom_enclosure="wide",
-        )
-        _chpgatep_actbb = _chpgatep_lay.bounds(mask=difftap.mask)
-        x = p2_polybb.right - _chpgatep_actbb.left
-        y = p2_actbb.bottom - _chpgatep_actbb.bottom
-        chpgatep_lay = layouter.place(_chpgatep_lay, x=x, y=y)
-        chpgatep_libb = chpgatep_lay.bounds(mask=li.mask)
-
-        _chpgatepad_lay = layouter.wire_layout(
-            net=net, wire=licon, bottom=poly, bottom_enclosure="tall",
-        )
-        _chpgatepad_polybb = _chpgatepad_lay.bounds(mask=poly.mask)
-        # x = x # Keep the x value
-        y = p2_polybb.bottom - _chngatepad_polybb.top
-        chpgatepad_lay = layouter.place(_chpgatepad_lay, x=x, y=y)
-        chpgatepad_polybb = chpgatepad_lay.bounds(mask=poly.mask)
-
-        shape = _geo.Rect.from_rect(
-            rect=chpgaten_libb, top=chpgatep_libb.top)
-        layouter.add_wire(net=net, wire=li, shape=shape)
-
-        pgatepad_bb = _geo.Rect.from_rect(
-            rect=chpgatepad_polybb, left=p1_polybb.left, right=p3_polybb.right,
-        )
-        layouter.add_wire(net=net, wire=poly, shape=pgatepad_bb)
-
-        # vq1
-        net = nets.vq1
-
-        lay = lay_matrix[1][1] # pnp1
-        m1pinbb = lay.bounds(mask=m1pin.mask, net=nets.vq1)
-        via_lay = layouter.add_wire(net=nets.vq1, wire=via, bottom_shape=m1pinbb)
-        viavq1pnp1_m2bb = via_lay.bounds(mask=m2.mask)
-
-        _chvq1n1_lay = layouter.wire_layout(
-            net=net, wire=licon, bottom=difftap, bottom_implant=nsdm,
-            bottom_height=n1_actbb.height, bottom_enclosure="wide",
-        )
-        _chvq1n1_actbb = _chvq1n1_lay.bounds(mask=difftap.mask)
-        _mconvq1m1_lay = layouter.wire_layout(
-            net=net, wire=mcon, bottom_height=n1_actbb.height,
-            top_height=n1_actbb.height,
-        )
-        _viavq1m1_lay = layouter.wire_layout(
-            net=net, wire=via, bottom_height=n1_actbb.height,
-            top_height=n1_actbb.height,
-        )
-
-        x = n1_polybb.left - _chvq1n1_actbb.right
-        y = n1_actbb.bottom - _chvq1n1_actbb.bottom
-        layouter.place(_chvq1n1_lay, x=x, y=y)
-        layouter.place(_mconvq1m1_lay, x=x, y=y)
-        viavq1n1_lay = layouter.place(_viavq1m1_lay, x=x, y=y)
-        viavq1n1_m2bb = viavq1n1_lay.bounds(mask=m2.mask)
-
-        shape = _geo.Rect.from_rect(
-            rect=viavq1n1_m2bb, right=viavq1pnp1_m2bb.right
-        )
-        layouter.add_wire(net=net, wire=m2, shape=shape)
-        shape = _geo.Rect.from_rect(
-            rect=viavq1pnp1_m2bb, top=viavq1n1_m2bb.top
-        )
-        layouter.add_wire(net=net, wire=m2, shape=shape)
-
-        # vq2
-        net = nets.vq2
-        lay0 = lay_matrix[0][0]
-        lay0_m1pinbb = lay0.bounds(mask=m1pin.mask, net=net)
-        lay1 = lay_matrix[0][1]
-        lay1_m1pinbb = lay1.bounds(mask=m1pin.mask, net=net)
-        lay2 = lay_matrix[2][1]
-        lay2_m1pinbb = lay2.bounds(mask=m1pin.mask, net=net)
-        lay3 = lay_matrix[2][2]
-        lay3_m1pinbb = lay3.bounds(mask=m1pin.mask, net=net)
-
-        shape1 = _geo.Rect.from_rect(rect=lay0_m1pinbb, right=lay1_m1pinbb.right)
-        layouter.add_wire(net=net, wire=m1, shape=shape1)
-        shape2 = _geo.Rect.from_rect(rect=lay2_m1pinbb, right=lay3_m1pinbb.right)
-        layouter.add_wire(net=net, wire=m1, shape=shape2)
-
-        o = res1vq2_libb.center
-        mconvq2res1_lay = layouter.add_wire(net=net, wire=mcon, columns=2, origin=o)
-        mconvq2res1_m1bb = mconvq2res1_lay.bounds(mask=m1.mask)
-
-        w = mconvq2res1_m1bb.width
-        left = mconvq2res1_m1bb.left
-        right = 2*dx_pnp + 0.5*w
-        top = shape1.top
-        bottom = top - w
-        shape = _geo.Rect(left=left, bottom=bottom, right=right, top=top)
-        layouter.add_wire(net=net, wire=m1, shape=shape)
-
-        # right = right; keep same right
-        left = right - w
-        # bottom = bottom; keep same bottom
-        top = shape2.top
-        shape = _geo.Rect(left=left, bottom=bottom, right=right, top=top)
-        layouter.add_wire(net=net, wire=m1, shape=shape)
-
-        shape = _geo.Rect.from_rect(rect=mconvq2res1_m1bb, bottom=bottom)
-        layouter.add_wire(net=net, wire=m1, shape=shape)
-
-        # vq2r1
-        _mconvq2r1res1_lay = layouter.wire_layout(net=net, wire=mcon, rows=2)
-        _mconvq2r1res1_libb = _mconvq2r1res1_lay.bounds(mask=li.mask)
-
-        x = res1vq2r1_libb.center.x
-        y = res1vq2r1_libb.bottom - _mconvq2r1res1_libb.bottom
-        mconvq2r1res1_lay = layouter.place(_mconvq2r1res1_lay, x=x, y=y)
-        mconvq2r1res1_m1bb = mconvq2r1res1_lay.bounds(mask=m1.mask)
-
-        _chvq2r1n2_lay = layouter.wire_layout(
-            net=net, wire=licon, bottom=difftap, bottom_implant=nsdm,
-            bottom_height=n2_actbb.height, bottom_enclosure="wide",
-            top_height=n2_actbb.height,
-        )
-        _chvq2r1n2_actbb = _chvq2r1n2_lay.bounds(mask=difftap.mask)
-        _mconvq2r1n2_lay = layouter.wire_layout(
-            net=net, wire=mcon,
-            bottom_height=n2_actbb.height, top_height=n2_actbb.height,
-        )
-
-        x = n2_polybb.left - _chvq2r1n2_actbb.right
-        y = n2_actbb.bottom - _chvq2r1n2_actbb.bottom
-        layouter.place(_chvq2r1n2_lay, x=x, y=y)
-        mconvq2r1n2_lay = layouter.place(_mconvq2r1n2_lay, x=x, y=y)
-        mconvq2r1n2_m1bb = mconvq2r1n2_lay.bounds(mask=m1.mask)
-
-        shape = _geo.Rect.from_rect(rect=mconvq2r1res1_m1bb, right=mconvq2r1n2_m1bb.right)
-        layouter.add_wire(net=net, wire=m1, shape=shape)
-        shape = _geo.Rect.from_rect(rect=mconvq2r1n2_m1bb, bottom=mconvq2r1res1_m1bb.bottom)
-        layouter.add_wire(net=net, wire=m1, shape=shape)
-
-        # vq3
-        net = nets.vq3
-
-        lay0 = lay_matrix[0][2]
-        lay0_m1pinbb = lay0.bounds(mask=m1pin.mask, net=net)
-        lay1 = lay_matrix[1][2]
-        lay1_m1pinbb = lay1.bounds(mask=m1pin.mask, net=net)
-        lay2 = lay_matrix[1][0]
-        lay2_m1pinbb = lay2.bounds(mask=m1pin.mask, net=net)
-        lay3 = lay_matrix[2][0]
-        lay3_m1pinbb = lay3.bounds(mask=m1pin.mask, net=net)
-
-        shape1 = _geo.Rect.from_rect(rect=lay0_m1pinbb, top=lay1_m1pinbb.top)
-        layouter.add_wire(net=net, wire=m1, shape=shape1)
-        shape2 = _geo.Rect.from_rect(rect=lay3_m1pinbb, bottom=dy_pnp)
-        layouter.add_wire(net=net, wire=m1, shape=shape2)
-
-        viavq3_lay1 = layouter.add_wire(
-            net=net, wire=via, x=shape2.center.x, y=dy_pnp,
-            bottom_width=shape2.width,
-        )
-        viavq3_m2bb1 = viavq3_lay1.bounds(mask=m2.mask)
-        layouter.add_wire(
-            net=net, wire=via, x=shape1.center.x, y=dy_pnp,
-            bottom_width=shape1.width,
-        )
-
-        _mconvq3res2_lay = layouter.wire_layout(net=net, wire=mcon, rows=2)
-        _mconvq3res2_libb = _mconvq3res2_lay.bounds(mask=li.mask)
-        x = vq3res2_libb.center.x
-        y = vq3res2_libb.bottom - _mconvq3res2_libb.bottom
-        mconvq3res2_lay = layouter.place(_mconvq3res2_lay, x=x, y=y)
-        mconvq3res2_m1bb = mconvq3res2_lay.bounds(mask=m1.mask)
-        viavq3res2_lay = layouter.add_wire(
-            net=net, wire=via, rows=2, x=x, y=dy_pnp,
-        )
-        viavq3res2_m1bb = viavq3res2_lay.bounds(mask=m1.mask)
-        viavq3res2_m2bb = viavq3res2_lay.bounds(mask=m2.mask)
-
-        shape = _geo.Rect.from_rect(
-            rect=viavq3res2_m1bb, bottom=mconvq3res2_m1bb.bottom,
-        )
-        layouter.add_wire(net=net, wire=m1, shape=shape)
-
-        shape = _geo.Rect.from_rect(
-            rect=viavq3res2_m2bb, left=viavq3_m2bb1.left,
-        )
-        layouter.add_wire(net=net, wire=m2, shape=shape)
-
-        # vref
-        net = nets.vref
-
-        _chvrefp_lay = layouter.wire_layout(
-            net=net, well_net=nets.vdd, wire=licon,
-            bottom=difftap, bottom_implant=psdm, bottom_well=nwm,
-            bottom_height=p1_actbb.height, bottom_enclosure="wide",
-        )
-        _chvrefp_actbb = _chvrefp_lay.bounds(mask=difftap.mask)
-        x = p3_polybb.right - _chvrefp_actbb.left
-        y = p3_actbb.bottom - _chvrefp_actbb.bottom
-        chvrefp_lay = layouter.place(_chvrefp_lay, x=x, y=y)
-        chvrefp_libb = chvrefp_lay.bounds(mask=li.mask)
-
-        shape = _geo.Rect.from_rect(rect=vrefres2_libb, top=chvrefp_libb.top)
-        layouter.add_wire(net=net, wire=li, shape=shape)
-        shape = _geo.Rect.from_rect(rect=chvrefp_libb, right=vrefres2_libb.right)
-        layouter.add_wire(net=net, wire=li, pin=lipin, shape=shape)
-
-        # vdd
-        net = nets.vdd
-
-        _chvdd_lay = layouter.wire_layout(
-            net=net, well_net=net, wire=licon,
-            bottom=difftap, bottom_implant=psdm, bottom_well=nwm,
-            bottom_height=p1_actbb.height, bottom_enclosure="wide",
-        )
-        _chvdd_actbb = _chvdd_lay.bounds(mask=difftap.mask)
-        _mconvdd_lay = layouter.wire_layout(
-            net=net, wire=mcon, bottom_height=p1_actbb.height,
-        )
-
-        x = p1_polybb.left - _chvdd_actbb.right
-        y = p1_actbb.bottom - _chvdd_actbb.bottom
-        lay = layouter.place(_chvdd_lay, x=x, y=y)
-        actbb = lay.bounds(mask=difftap.mask)
-        libb = lay.bounds(mask=li.mask)
-        lay = layouter.place(_mconvdd_lay, x=x, y=y)
-        mconp1_m1bb = lay.bounds(mask=m1.mask)
-        x = p2_polybb.left - _chvdd_actbb.right
-        layouter.place(_chvdd_lay, x=x, y=y)
-        layouter.place(_mconvdd_lay, x=x, y=y)
-        x = p3_polybb.left - _chvdd_actbb.right
-        layouter.place(_chvdd_lay, x=x, y=y)
-        lay = layouter.place(_mconvdd_lay, x=x, y=y)
-        mconp3_m1bb = lay.bounds(mask=m1.mask)
-
-        _chvddnw_lay = layouter.wire_layout(
-            net=net, well_net=net, wire=licon, columns=2,
-            bottom=difftap, bottom_implant=nsdm, bottom_well=nwm,
-            bottom_height=p1_actbb.height, bottom_enclosure="wide",
-        )
-        _chvddnw_actbb = _chvddnw_lay.bounds(mask=difftap.mask)
-
-        x = actbb.left - 0.5 - _chvddnw_actbb.right
-        chvddnw_lay = layouter.place(_chvddnw_lay, x=x, y=y)
-        chvddnw_nwbb = chvddnw_lay.bounds(mask=nwm.mask)
-        chvddnw_libb = chvddnw_lay.bounds(mask=li.mask)
-
-        shape = _geo.Rect.from_rect(rect=libb, left=chvddnw_libb.left)
-        layouter.add_wire(net=net, wire=li, shape=shape)
-
-        shape = _geo.Rect.from_rect(rect=mconp1_m1bb, right=mconp3_m1bb.right)
-        layouter.add_wire(net=net, wire=m1, pin=m1pin, shape=shape)
-
-        # nsdm; cover poly contact hole
-        shape = _geo.Rect.from_rect(
-            rect=n1_nsdmbb, right=n2_nsdmbb.right, top=ngatepad_bb.top,
-        )
-        layouter.add_portless(prim=nsdm, shape=shape)
-
-        # psdm; cover poly contact hole
-        shape = _geo.Rect.from_rect(
-            rect=p1_psdmbb, right=p3_psdmbb.right, bottom=pgatepad_bb.bottom,
-        )
-        layouter.add_portless(prim=psdm, shape=shape)
-
-        # nwell
-        shape = _geo.Rect.from_rect(rect=p3_nwbb, left=chvddnw_nwbb.left)
-        layouter.add_wire(net=nets.vdd, wire=nwm, shape=shape)
-
-        # hvi
-        shape = _geo.Rect(
-            left=0.0, bottom=n1_hvibb.bottom, right=3*dx_pnp, top=p1_hvibb.top,
-        )
-        layouter.add_portless(prim=hvi, shape=shape)
-
-        # Boundary
-        shape = _geo.Rect.from_rect(rect=layout.bounds(), bias=0.2)
-        layout.boundary = shape
-        layouter.add_portless(prim=bnd, shape=shape)
-
-
 class ConnectedBandGap(_lbry._Cell[_lbry.Library]):
     def __init__(self, *, lib: _lbry.Library):
         super().__init__(lib=lib, name="ConnectedBandGap")
@@ -657,91 +38,298 @@
         m3pin = m3.pin[0]
         bnd = cast(_prm.Auxiliary, _prims.prBoundary)
 
-        bg_cell = _BandGap3V3(lib=lib)
-        lib.cells += bg_cell
-        _bg_bb = bg_cell.layout.boundary
-        assert _bg_bb is not None
-        _bgvref = bg_cell.circuit.nets.vref
-        _bgvref_lipinbb = bg_cell.layout.bounds(mask=lipin.mask, net=_bgvref)
+        nmos3v3 = cast(_prm.MOSFET, _prims.nfet_g5v0d10v5)
+        nmos1v8lvt = cast(_prm.MOSFET, _prims.nfet_01v8_lvt)
+        nmos1v8 = cast(_prm.MOSFET, _prims.nfet_01v8)
+        pmos3v3 = cast(_prm.MOSFET, _prims.pfet_g5v0d10v5)
+        pmos1v8lvt = cast(_prm.MOSFET, _prims.pfet_01v8_lvt)
+        pmos1v8 = cast(_prm.MOSFET, _prims.pfet_01v8)
+        pnp = sky130.macrolib.cells.PNP_05v5_W3u40L3u40
+        res = cast(_prm.Resistor, _prims.poly_res)
 
-        bg = ckt.instantiate(bg_cell, name="bg")
+        # Create the bandgap subcells
+        bg3v3_cell = sky130.BandgapCell(
+            lib=lib, name="Bandgap3V3",
+            nmos=nmos3v3, nmos_l=25.0, nmos_w=40.0,
+            pmos=pmos3v3, pmos_l=7.75, pmos_w=40.0,
+            pnp=pnp, pnp_ratio=2,
+            resistor=res, r1_height=13.055, r2_height=329.85,
+        )
+        lib.cells += bg3v3_cell
+        _bg3v3_bb = bg3v3_cell.layout.bounds()
+        assert _bg3v3_bb is not None
+        _bg3v3vref = bg3v3_cell.circuit.nets.vref
+        _bg3v3vref_m1pinbb = bg3v3_cell.layout.bounds(mask=m1pin.mask, net=_bg3v3vref)
+
+        bg1v8lvt_cell = sky130.BandgapCell(
+            lib=lib, name="Bandgap1V8lvt",
+            nmos=nmos1v8lvt, nmos_l=1.0, nmos_w=40.0,
+            pmos=pmos1v8lvt, pmos_l=25.0, pmos_w=40.0,
+            pnp=pnp, pnp_ratio=2,
+            resistor=res, r1_height=62.85, r2_height=1091.20,
+        )
+        lib.cells += bg1v8lvt_cell
+        _bg1v8lvt_bb = bg1v8lvt_cell.layout.bounds()
+        assert _bg1v8lvt_bb is not None
+        _bg1v8lvtvref = bg1v8lvt_cell.circuit.nets.vref
+        _bg1v8lvtvref_m1pinbb = bg1v8lvt_cell.layout.bounds(mask=m1pin.mask, net=_bg1v8lvtvref)
+
+        bg1v8_cell = sky130.BandgapCell(
+            lib=lib, name="Bandgap1V8",
+            nmos=nmos1v8, nmos_l=25.0, nmos_w=40.0,
+            pmos=pmos1v8, pmos_l=0.5, pmos_w=40.0,
+            pnp=pnp, pnp_ratio=2,
+            resistor=res, r1_height=32.14, r2_height=458.46,
+        )
+        lib.cells += bg1v8_cell
+        _bg1v8_bb = bg1v8_cell.layout.bounds()
+        assert _bg1v8_bb is not None
+        _bg1v8vref = bg1v8_cell.circuit.nets.vref
+        _bg1v8vref_m1pinbb = bg1v8_cell.layout.bounds(mask=m1pin.mask, net=_bg1v8vref)
+
+        # Instantiate the bandgap cells
+        bg3v3 = ckt.instantiate(bg3v3_cell, name="bg3v3")
+        bg1v8lvt = ckt.instantiate(bg1v8lvt_cell, name="bg1v8lvt")
+        bg1v8 = ckt.instantiate(bg1v8_cell, name="bg1v8")
 
         # Add pins + nets for the io signals of the bandgap
-        vss_pinname = "io_analog[7]"
-        vss_m3pinbb = _frm.toppins[vss_pinname]
-        vss = ckt.new_net(name=vss_pinname, external=True, childports=bg.ports.vss)
-        layouter.add_wire(net=vss, wire=m3, pin=m3pin, shape=vss_m3pinbb)
+        vss3v3_pinname = "io_analog[7]"
+        vss3v3_m3pinbb = _frm.toppins[vss3v3_pinname]
+        vss3v3 = ckt.new_net(name=vss3v3_pinname, external=True, childports=bg3v3.ports.vss)
+        layouter.add_wire(net=vss3v3, wire=m3, pin=m3pin, shape=vss3v3_m3pinbb)
 
-        vdd_pinname = "io_analog[9]"
-        vdd_m3pinbb = _frm.toppins[vdd_pinname]
-        vdd = ckt.new_net(name=vdd_pinname, external=True, childports=bg.ports.vdd)
-        layouter.add_wire(net=vdd, wire=m3, pin=m3pin, shape=vdd_m3pinbb)
+        vdd3v3_pinname = "io_analog[9]"
+        vdd3v3_m3pinbb = _frm.toppins[vdd3v3_pinname]
+        vdd3v3 = ckt.new_net(name=vdd3v3_pinname, external=True, childports=bg3v3.ports.vdd)
+        layouter.add_wire(net=vdd3v3, wire=m3, pin=m3pin, shape=vdd3v3_m3pinbb)
 
-        vref_pinname = "io_analog[8]"
-        vref_m3pinbb = _frm.toppins[vref_pinname]
-        vref = ckt.new_net(name=vref_pinname, external=True, childports=bg.ports.vref)
-        layouter.add_wire(net=vref, wire=m3, pin=m3pin, shape=vref_m3pinbb)
+        vref3v3_pinname = "io_analog[8]"
+        vref3v3_m3pinbb = _frm.toppins[vref3v3_pinname]
+        vref3v3 = ckt.new_net(name=vref3v3_pinname, external=True, childports=bg3v3.ports.vref)
+        layouter.add_wire(net=vref3v3, wire=m3, pin=m3pin, shape=vref3v3_m3pinbb)
 
-        # Place bandgap, align vref pin with top pin
-        x = vref_m3pinbb.center.x - _bgvref_lipinbb.center.x
-        y = vref_m3pinbb.bottom - 5.0 - _bg_bb.top
-        bg_lay = layouter.place(bg, x=x, y=y)
-        bgvss_lipinbb = bg_lay.bounds(mask=lipin.mask, net=vss, depth=1)
-        bgvdd_m1pinbb = bg_lay.bounds(mask=m1pin.mask, net=vdd, depth=1)
-        bgvref_lipinbb = bg_lay.bounds(mask=lipin.mask, net=vref, depth=1)
+        # vss and vdd are shared between bg1v8lvt and bg1v8
+        vss1v8_pinname = "io_analog[0]"
+        vss1v8_m3pinbb = _frm.toppins[vss1v8_pinname]
+        vss1v8 = ckt.new_net(name=vss1v8_pinname, external=True, childports=(
+            bg1v8.ports.vss, bg1v8lvt.ports.vss,
+        ))
+        layouter.add_wire(net=vss1v8, wire=m3, pin=m3pin, shape=vss1v8_m3pinbb)
+
+        vdd1v8_pinname = "io_analog[3]"
+        vdd1v8_m3pinbb = _frm.toppins[vdd1v8_pinname]
+        vdd1v8 = ckt.new_net(name=vdd1v8_pinname, external=True, childports=(
+            bg1v8.ports.vdd, bg1v8lvt.ports.vdd,
+        ))
+        layouter.add_wire(net=vdd1v8, wire=m3, pin=m3pin, shape=vdd1v8_m3pinbb)
+
+        vref1v8lvt_pinname = "io_analog[2]"
+        vref1v8lvt_m3pinbb = _frm.toppins[vref1v8lvt_pinname]
+        vref1v8lvt = ckt.new_net(
+            name=vref1v8lvt_pinname, external=True, childports=bg1v8lvt.ports.vref,
+        )
+        layouter.add_wire(net=vref1v8lvt, wire=m3, pin=m3pin, shape=vref1v8lvt_m3pinbb)
+
+        vref1v8_pinname = "io_analog[1]"
+        vref1v8_m3pinbb = _frm.toppins[vref1v8_pinname]
+        vref1v8 = ckt.new_net(
+            name=vref1v8_pinname, external=True, childports=bg1v8.ports.vref,
+        )
+        layouter.add_wire(net=vref1v8, wire=m3, pin=m3pin, shape=vref1v8_m3pinbb)
 
         # Boundary
         layout.boundary = _frm.boundary
         layouter.add_portless(prim=bnd, shape=_frm.boundary)
 
-        # vss
-        net = vss
+        # Place bg3v3, align vref pin with top pin
+        x = vref3v3_m3pinbb.center.x - _bg3v3vref_m1pinbb.center.x
+        y = vref3v3_m3pinbb.bottom - 5.0 - _bg3v3_bb.top
+        bg3v3_lay = layouter.place(bg3v3, x=x, y=y)
+        bg3v3vss_m1pinbb = bg3v3_lay.bounds(mask=m1pin.mask, net=vss3v3, depth=1)
+        bg3v3vss_m1pinbb = _geo.Rect.from_rect(
+            rect=bg3v3vss_m1pinbb, top=(bg3v3vss_m1pinbb.top + 5.0),
+        )
+        bg3v3vdd_m1pinbb = bg3v3_lay.bounds(mask=m1pin.mask, net=vdd3v3, depth=1)
+        bg3v3vdd_m1pinbb = _geo.Rect.from_rect(
+            rect=bg3v3vdd_m1pinbb, bottom=(bg3v3vdd_m1pinbb.bottom - 5.0),
+        )
+        bg3v3vref_m1pinbb = bg3v3_lay.bounds(mask=m1pin.mask, net=vref3v3, depth=1)
+        bg3v3vref_m1pinbb = _geo.Rect.from_rect(
+            rect=bg3v3vref_m1pinbb, right=(bg3v3vref_m1pinbb.right + 5.0),
+        )
+
+        # Place bg1v8lvt, align vref pin with top pin
+        x = vref1v8lvt_m3pinbb.center.x - _bg1v8lvtvref_m1pinbb.center.x
+        y = vref1v8lvt_m3pinbb.bottom - 10.0 - _bg1v8lvt_bb.top
+        bg1v8lvt_lay = layouter.place(bg1v8lvt, x=x, y=y)
+        bg1v8lvtvss_m1pinbb = bg1v8lvt_lay.bounds(mask=m1pin.mask, net=vss1v8, depth=1)
+        bg1v8lvtvss_m1pinbb = _geo.Rect.from_rect(
+            rect=bg1v8lvtvss_m1pinbb, top=(bg1v8lvtvss_m1pinbb.top + 5.0),
+        )
+        bg1v8lvtvss_m2pinbb = _geo.Rect.from_rect(
+            rect=bg1v8lvtvss_m1pinbb, bottom=vss1v8_m3pinbb.bottom,
+        )
+        bg1v8lvtvss_m3pinbb = _geo.Rect.from_rect(
+            rect=bg1v8lvtvss_m2pinbb, top=vss1v8_m3pinbb.top,
+        )
+        bg1v8lvtvdd_m1pinbb = bg1v8lvt_lay.bounds(mask=m1pin.mask, net=vdd1v8, depth=1)
+        bg1v8lvtvdd_m1pinbb = _geo.Rect.from_rect(
+            rect=bg1v8lvtvdd_m1pinbb, top=(bg1v8lvtvdd_m1pinbb.top + 6.0),
+        )
+        bg1v8lvtvdd_m2pinbb = _geo.Rect.from_rect(
+            rect=bg1v8lvtvdd_m1pinbb, bottom=(bg1v8lvtvdd_m1pinbb.top - 5.0),
+        )
+        bg1v8lvtvref_m1pinbb = bg1v8lvt_lay.bounds(mask=m1pin.mask, net=vref1v8lvt, depth=1)
+        bg1v8lvtvref_m1pinbb = _geo.Rect.from_rect(
+            rect=bg1v8lvtvref_m1pinbb, right=(bg1v8lvtvref_m1pinbb.right + 5.0),
+        )
+
+        # Place bg1v8 below bg1v8lvt
+        x = vref1v8_m3pinbb.center.x - _bg1v8vref_m1pinbb.center.x
+        y = vref1v8_m3pinbb.bottom - 10.0 - _bg1v8_bb.top
+        bg1v8_lay = layouter.place(bg1v8, x=x, y=y)
+        bg1v8vss_m1pinbb = bg1v8_lay.bounds(mask=m1pin.mask, net=vss1v8, depth=1)
+        bg1v8vss_m1pinbb = _geo.Rect.from_rect(
+            rect=bg1v8vss_m1pinbb, top=(bg1v8vss_m1pinbb.top + 5.0),
+        )
+        bg1v8vss_m2pinbb = _geo.Rect.from_rect(
+            rect=bg1v8vss_m1pinbb, bottom=vss1v8_m3pinbb.bottom,
+        )
+        bg1v8vss_m3pinbb = _geo.Rect.from_rect(
+            rect=bg1v8vss_m2pinbb, top=vss1v8_m3pinbb.top,
+        )
+        bg1v8vdd_m1pinbb = bg1v8_lay.bounds(mask=m1pin.mask, net=vdd1v8, depth=1)
+        bg1v8vdd_m1pinbb = _geo.Rect.from_rect(
+            rect=bg1v8vdd_m1pinbb, top=(bg1v8vdd_m1pinbb.top + 6.0),
+        )
+        bg1v8vdd_m2pinbb = _geo.Rect.from_rect(
+            rect=bg1v8vdd_m1pinbb, bottom=(bg1v8vdd_m1pinbb.top - 5.0),
+        )
+        bg1v8vref_m1pinbb = bg1v8_lay.bounds(mask=m1pin.mask, net=vref1v8, depth=1)
+        bg1v8vref_m1pinbb = _geo.Rect.from_rect(
+            rect=bg1v8vref_m1pinbb, right=(bg1v8vref_m1pinbb.right + 5.0),
+        )
+
+        # vss3v3
+        net = vss3v3
 
         layouter.add_wire(
-            net=net, wire=mcon, bottom_shape=bgvss_lipinbb, top_shape=bgvss_lipinbb,
-        )
-        layouter.add_wire(
-            net=net, wire=via, bottom_shape=bgvss_lipinbb, top_shape=bgvss_lipinbb,
+            net=net, wire=via, bottom_shape=bg3v3vss_m1pinbb, top_shape=bg3v3vss_m1pinbb,
         )
         lay = layouter.add_wire(
-            net=net, wire=via2, bottom_shape=bgvss_lipinbb, top_shape=bgvss_lipinbb,
+            net=net, wire=via2, bottom_shape=bg3v3vss_m1pinbb, top_shape=bg3v3vss_m1pinbb,
         )
         m3bb = lay.bounds(mask=m3.mask)
 
-        shape = _geo.Rect.from_rect(rect=m3bb, right=vss_m3pinbb.right)
+        shape = _geo.Rect.from_rect(rect=m3bb, right=vss3v3_m3pinbb.right)
         layouter.add_wire(net=net, wire=m3, shape=shape)
-        shape = _geo.Rect.from_rect(rect=vss_m3pinbb, bottom=m3bb.bottom)
+        shape = _geo.Rect.from_rect(rect=vss3v3_m3pinbb, bottom=m3bb.bottom)
         layouter.add_wire(net=net, wire=m3, shape=shape)
 
-        # vss
-        net = vdd
+        # vdd3v3
+        net = vdd3v3
 
         layouter.add_wire(
-            net=net, wire=via, bottom_shape=bgvdd_m1pinbb, top_shape=bgvdd_m1pinbb,
+            net=net, wire=via, bottom_shape=bg3v3vdd_m1pinbb, top_shape=bg3v3vdd_m1pinbb,
         )
         lay = layouter.add_wire(
-            net=net, wire=via2, bottom_shape=bgvdd_m1pinbb, top_shape=bgvdd_m1pinbb,
+            net=net, wire=via2, bottom_shape=bg3v3vdd_m1pinbb, top_shape=bg3v3vdd_m1pinbb,
         )
         m3bb = lay.bounds(mask=m3.mask)
 
-        shape = _geo.Rect.from_rect(rect=m3bb, left=vdd_m3pinbb.left)
+        shape = _geo.Rect.from_rect(rect=m3bb, left=vdd3v3_m3pinbb.left)
         layouter.add_wire(net=net, wire=m3, shape=shape)
-        shape = _geo.Rect.from_rect(rect=vdd_m3pinbb, bottom=m3bb.bottom)
+        shape = _geo.Rect.from_rect(rect=vdd3v3_m3pinbb, bottom=m3bb.bottom)
         layouter.add_wire(net=net, wire=m3, shape=shape)
 
-        # vref
-        net = vref
+        # vref3v3
+        net = vref3v3
 
         layouter.add_wire(
-            net=net, wire=mcon, bottom_shape=bgvref_lipinbb, top_shape=bgvref_lipinbb,
-        )
-        layouter.add_wire(
-            net=net, wire=via, bottom_shape=bgvref_lipinbb, top_shape=bgvref_lipinbb,
+            net=net, wire=via, bottom_shape=bg3v3vref_m1pinbb, top_shape=bg3v3vref_m1pinbb,
         )
         lay = layouter.add_wire(
-            net=net, wire=via2, bottom_shape=bgvref_lipinbb, top_shape=bgvref_lipinbb,
+            net=net, wire=via2, bottom_shape=bg3v3vref_m1pinbb, top_shape=bg3v3vref_m1pinbb,
         )
         m3bb = lay.bounds(mask=m3.mask)
 
-        shape = _geo.Rect.from_rect(rect=m3bb, top=vref_m3pinbb.bottom)
+        shape = _geo.Rect.from_rect(rect=m3bb, top=vref3v3_m3pinbb.bottom)
+        layouter.add_wire(net=net, wire=m3, shape=shape)
+
+        # vss1v8
+        net = vss1v8
+
+        layouter.add_wire(
+            net=net, wire=via,
+            bottom_shape=bg1v8lvtvss_m1pinbb, top_shape=bg1v8lvtvss_m2pinbb,
+        )
+        layouter.add_wire(
+            net=net, wire=via,
+            bottom_shape=bg1v8vss_m1pinbb, top_shape=bg1v8vss_m2pinbb,
+        )
+
+        layouter.add_wire(
+            net=net, wire=via2,
+            bottom_shape=bg1v8lvtvss_m3pinbb, top_shape=bg1v8lvtvss_m3pinbb,
+        )
+        layouter.add_wire(
+            net=net, wire=via2,
+            bottom_shape=bg1v8vss_m3pinbb, top_shape=bg1v8vss_m3pinbb,
+        )
+
+        shape = _geo.Rect.from_rect(rect=bg1v8lvtvss_m3pinbb, right=vss1v8_m3pinbb.right)
+        layouter.add_wire(net=net, wire=m3, shape=shape)
+
+        # vdd1v8
+        net = vdd1v8
+
+        layouter.add_wire(
+            net=net, wire=via,
+            bottom_shape=bg1v8lvtvdd_m1pinbb, top_shape=bg1v8lvtvdd_m2pinbb,
+        )
+        layouter.add_wire(
+            net=net, wire=via,
+            bottom_shape=bg1v8vdd_m1pinbb, top_shape=bg1v8vdd_m2pinbb,
+        )
+        via2bb = _geo.Rect.from_rect(
+            rect=bg1v8vdd_m2pinbb, left=vdd1v8_m3pinbb.left, right=vdd1v8_m3pinbb.right,
+        )
+        layouter.add_wire(
+            net=net, wire=via2, bottom_shape=via2bb, top_shape=via2bb,
+        )
+        shape = _geo.Rect.from_rect(rect=via2bb, right=bg1v8vdd_m2pinbb.right)
+        layouter.add_wire(net=net, wire=m2, shape=shape)
+        shape = _geo.Rect.from_rect(rect=via2bb, top=vdd1v8_m3pinbb.top)
+        layouter.add_wire(net=net, wire=m3, shape=shape)
+
+        # vref1v8lvt
+        net = vref1v8lvt
+
+        layouter.add_wire(
+            net=net, wire=via,
+            bottom_shape=bg1v8lvtvref_m1pinbb, top_shape=bg1v8lvtvref_m1pinbb,
+        )
+        lay = layouter.add_wire(
+            net=net, wire=via2,
+            bottom_shape=bg1v8lvtvref_m1pinbb, top_shape=bg1v8lvtvref_m1pinbb,
+        )
+        m3bb = lay.bounds(mask=m3.mask)
+
+        shape = _geo.Rect.from_rect(rect=m3bb, top=vref1v8lvt_m3pinbb.bottom)
+        layouter.add_wire(net=net, wire=m3, shape=shape)
+
+        # vref1v8
+        net = vref1v8
+
+        layouter.add_wire(
+            net=net, wire=via,
+            bottom_shape=bg1v8vref_m1pinbb, top_shape=bg1v8vref_m1pinbb,
+        )
+        lay = layouter.add_wire(
+            net=net, wire=via2,
+            bottom_shape=bg1v8vref_m1pinbb, top_shape=bg1v8vref_m1pinbb,
+        )
+        m3bb = lay.bounds(mask=m3.mask)
+
+        shape = _geo.Rect.from_rect(rect=m3bb, top=vref1v8_m3pinbb.bottom)
         layouter.add_wire(net=net, wire=m3, shape=shape)
diff --git a/gds/user_analog_project_wrapper.gds.gz b/gds/user_analog_project_wrapper.gds.gz
index 61b5864..45b162d 100644
--- a/gds/user_analog_project_wrapper.gds.gz
+++ b/gds/user_analog_project_wrapper.gds.gz
Binary files differ