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