From a4b71b13036dc7b60e6ed2ffe2191893333d8296 Mon Sep 17 00:00:00 2001 From: Nimish Kapoor <67710754+Nimok15@users.noreply.github.com> Date: Wed, 10 Jun 2026 18:35:10 +0530 Subject: [PATCH 1/6] Update opamp.py --- src/glayout/cells/composite/opamp/opamp.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/glayout/cells/composite/opamp/opamp.py b/src/glayout/cells/composite/opamp/opamp.py index cf9d1c0f..9ae9ce2d 100644 --- a/src/glayout/cells/composite/opamp/opamp.py +++ b/src/glayout/cells/composite/opamp/opamp.py @@ -356,7 +356,7 @@ def opamp( # already match an opamp top-level pin. We purge them all because # the opamp's add_opamp_labels below re-emits the right set on # the right metal. - ["VP", "VN", "VDD1", "VDD2", "IBIAS", "VSS", "B"], + ["VP", "VN", "VDD1", "VDD2", "IBIAS", "VSS", "B", "VTAIL"], ) # add LVS pin/label rects so netgen can name-match the top-level signals opamp_top = add_opamp_labels(opamp_top, pdk, add_output_stage=add_output_stage) From 01d6a5ed5875397b568661cd07d0f20dcf91547b Mon Sep 17 00:00:00 2001 From: Nimish Kapoor <67710754+Nimok15@users.noreply.github.com> Date: Wed, 10 Jun 2026 19:42:46 +0530 Subject: [PATCH 2/6] Update diff_pair_cmirrorbias.py --- .../diffpair_cmirror_bias/diff_pair_cmirrorbias.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/glayout/cells/composite/diffpair_cmirror_bias/diff_pair_cmirrorbias.py b/src/glayout/cells/composite/diffpair_cmirror_bias/diff_pair_cmirrorbias.py index c1a47743..57e5eb3d 100644 --- a/src/glayout/cells/composite/diffpair_cmirror_bias/diff_pair_cmirrorbias.py +++ b/src/glayout/cells/composite/diffpair_cmirror_bias/diff_pair_cmirrorbias.py @@ -194,6 +194,9 @@ def diff_pair_ibias( viaoffset=None, ) cmirror.add_ports(srcshort.get_ports_list(), prefix="purposegndports") + _lastcol = diffpair_bias[2] - 1 + cmirror << straight_route(pdk, cmirror.ports["A_0_dummy_L_gsdcon_top_met_W"], cmirror.ports["welltie_W_top_met_W"], glayer2="met1") + cmirror << straight_route(pdk, cmirror.ports[f"B_{_lastcol}_dummy_R_gsdcon_top_met_E"], cmirror.ports["welltie_E_top_met_E"], glayer2="met1") # current mirror netlist — gf180 needs `dummies_tied_to_bulk=False` # because here we use raw two_nfet_interdigitized + custom routing, # NOT current_mirror, so the standalone-cell's straight_route from @@ -201,9 +204,7 @@ def diff_pair_ibias( # cmirror dummies on a per-cell floating net. sky130 magic merges # the floating dummies into the bulk so the schematic must keep # them tied to VB or magic counts an extra net. - ## HACK: Note that this is a hack for magic LVS, and it's likely incorrect - ## we probably want to fix it properly - _dummies_tied = (pdk.name.lower() == "sky130") + _dummies_tied = True cmirror.info['netlist'] = current_mirror_netlist( pdk, width=diffpair_bias[0], @@ -297,3 +298,5 @@ def diff_pair_ibias( diffpair_i_flat.info['netlist'] = diff_pair_ibias_netlist(center_diffpair_comp, cmirror, antenna_diode_comp) return diffpair_i_flat + + From 628bd70b5185f2bdfa902b85b7804dc6c9ea7185 Mon Sep 17 00:00:00 2001 From: Nimish Kapoor <67710754+Nimok15@users.noreply.github.com> Date: Wed, 10 Jun 2026 20:39:06 +0530 Subject: [PATCH 3/6] Update diff_pair_cmirrorbias.py --- .../composite/diffpair_cmirror_bias/diff_pair_cmirrorbias.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/glayout/cells/composite/diffpair_cmirror_bias/diff_pair_cmirrorbias.py b/src/glayout/cells/composite/diffpair_cmirror_bias/diff_pair_cmirrorbias.py index 57e5eb3d..df25b13c 100644 --- a/src/glayout/cells/composite/diffpair_cmirror_bias/diff_pair_cmirrorbias.py +++ b/src/glayout/cells/composite/diffpair_cmirror_bias/diff_pair_cmirrorbias.py @@ -195,8 +195,8 @@ def diff_pair_ibias( ) cmirror.add_ports(srcshort.get_ports_list(), prefix="purposegndports") _lastcol = diffpair_bias[2] - 1 - cmirror << straight_route(pdk, cmirror.ports["A_0_dummy_L_gsdcon_top_met_W"], cmirror.ports["welltie_W_top_met_W"], glayer2="met1") - cmirror << straight_route(pdk, cmirror.ports[f"B_{_lastcol}_dummy_R_gsdcon_top_met_E"], cmirror.ports["welltie_E_top_met_E"], glayer2="met1") + cmirror << straight_route(pdk, cmirror.ports["A_0_dummy_L_gsdcon_top_met_W"], cmirror.ports["welltie_W_top_met_W"]) + cmirror << straight_route(pdk, cmirror.ports[f"B_{_lastcol}_dummy_R_gsdcon_top_met_E"], cmirror.ports["welltie_E_top_met_E"]) # current mirror netlist — gf180 needs `dummies_tied_to_bulk=False` # because here we use raw two_nfet_interdigitized + custom routing, # NOT current_mirror, so the standalone-cell's straight_route from From 118fbd1cd0f1f6aac1c4ebc733d26f9fdf13ee71 Mon Sep 17 00:00:00 2001 From: Nimish Kapoor <67710754+Nimok15@users.noreply.github.com> Date: Wed, 10 Jun 2026 21:09:57 +0530 Subject: [PATCH 4/6] Update diff_pair_cmirrorbias.py --- .../composite/diffpair_cmirror_bias/diff_pair_cmirrorbias.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/glayout/cells/composite/diffpair_cmirror_bias/diff_pair_cmirrorbias.py b/src/glayout/cells/composite/diffpair_cmirror_bias/diff_pair_cmirrorbias.py index df25b13c..e2e8c446 100644 --- a/src/glayout/cells/composite/diffpair_cmirror_bias/diff_pair_cmirrorbias.py +++ b/src/glayout/cells/composite/diffpair_cmirror_bias/diff_pair_cmirrorbias.py @@ -195,8 +195,8 @@ def diff_pair_ibias( ) cmirror.add_ports(srcshort.get_ports_list(), prefix="purposegndports") _lastcol = diffpair_bias[2] - 1 - cmirror << straight_route(pdk, cmirror.ports["A_0_dummy_L_gsdcon_top_met_W"], cmirror.ports["welltie_W_top_met_W"]) - cmirror << straight_route(pdk, cmirror.ports[f"B_{_lastcol}_dummy_R_gsdcon_top_met_E"], cmirror.ports["welltie_E_top_met_E"]) + cmirror << L_route(pdk, cmirror.ports["A_0_dummy_L_gsdcon_top_met_W"], cmirror.ports["welltie_W_top_met_E"]) + cmirror << L_route(pdk, cmirror.ports[f"B_{_lastcol}_dummy_R_gsdcon_top_met_E"], cmirror.ports["welltie_E_top_met_W"]) # current mirror netlist — gf180 needs `dummies_tied_to_bulk=False` # because here we use raw two_nfet_interdigitized + custom routing, # NOT current_mirror, so the standalone-cell's straight_route from From 96793e34edffadb78b77541959f1e269e967afa0 Mon Sep 17 00:00:00 2001 From: Nimish Kapoor <67710754+Nimok15@users.noreply.github.com> Date: Thu, 11 Jun 2026 02:39:52 +0530 Subject: [PATCH 5/6] Update diff_pair_cmirrorbias.py --- .../diffpair_cmirror_bias/diff_pair_cmirrorbias.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/glayout/cells/composite/diffpair_cmirror_bias/diff_pair_cmirrorbias.py b/src/glayout/cells/composite/diffpair_cmirror_bias/diff_pair_cmirrorbias.py index e2e8c446..31e216af 100644 --- a/src/glayout/cells/composite/diffpair_cmirror_bias/diff_pair_cmirrorbias.py +++ b/src/glayout/cells/composite/diffpair_cmirror_bias/diff_pair_cmirrorbias.py @@ -195,8 +195,15 @@ def diff_pair_ibias( ) cmirror.add_ports(srcshort.get_ports_list(), prefix="purposegndports") _lastcol = diffpair_bias[2] - 1 - cmirror << L_route(pdk, cmirror.ports["A_0_dummy_L_gsdcon_top_met_W"], cmirror.ports["welltie_W_top_met_E"]) - cmirror << L_route(pdk, cmirror.ports[f"B_{_lastcol}_dummy_R_gsdcon_top_met_E"], cmirror.ports["welltie_E_top_met_W"]) + # Ground the outer dummies to the adjacent welltie ring segment. + # Port orientations differ between PDKs (L_route's perpendicularity + # assert fails on sky130), so route on the ring's metal explicitly: + # straight west/east from the dummy gsdcon into the ring's inner edge. + for _dumport, _tieport in ( + ("A_0_dummy_L_gsdcon_top_met_W", "welltie_W_top_met_E"), + (f"B_{_lastcol}_dummy_R_gsdcon_top_met_E", "welltie_E_top_met_W"), + ): + cmirror << straight_route(pdk, cmirror.ports[_dumport], cmirror.ports[_tieport]) # current mirror netlist — gf180 needs `dummies_tied_to_bulk=False` # because here we use raw two_nfet_interdigitized + custom routing, # NOT current_mirror, so the standalone-cell's straight_route from From ee907aeb571cac0310608e36d62fc7f1aacbb8ad Mon Sep 17 00:00:00 2001 From: Nimish Kapoor <67710754+Nimok15@users.noreply.github.com> Date: Thu, 11 Jun 2026 03:09:43 +0530 Subject: [PATCH 6/6] Update diff_pair_cmirrorbias.py --- .../diff_pair_cmirrorbias.py | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/src/glayout/cells/composite/diffpair_cmirror_bias/diff_pair_cmirrorbias.py b/src/glayout/cells/composite/diffpair_cmirror_bias/diff_pair_cmirrorbias.py index 31e216af..63a63a7d 100644 --- a/src/glayout/cells/composite/diffpair_cmirror_bias/diff_pair_cmirrorbias.py +++ b/src/glayout/cells/composite/diffpair_cmirror_bias/diff_pair_cmirrorbias.py @@ -163,7 +163,7 @@ def diff_pair_ibias( gate_route_topmet="met3", sd_route_topmet="met3", rmult=rmult, - tie_layers=("met2", "met2"), + tie_layers=("met2", "met1"), ) # cmirror routing metal_sep = pdk.util_max_metal_seperation() @@ -195,15 +195,11 @@ def diff_pair_ibias( ) cmirror.add_ports(srcshort.get_ports_list(), prefix="purposegndports") _lastcol = diffpair_bias[2] - 1 - # Ground the outer dummies to the adjacent welltie ring segment. - # Port orientations differ between PDKs (L_route's perpendicularity - # assert fails on sky130), so route on the ring's metal explicitly: - # straight west/east from the dummy gsdcon into the ring's inner edge. - for _dumport, _tieport in ( - ("A_0_dummy_L_gsdcon_top_met_W", "welltie_W_top_met_E"), - (f"B_{_lastcol}_dummy_R_gsdcon_top_met_E", "welltie_E_top_met_W"), - ): - cmirror << straight_route(pdk, cmirror.ports[_dumport], cmirror.ports[_tieport]) + # Ground the outer dummies to the welltie — same recipe as the standalone + # current_mirror cell (which passes DRC+LVS on both PDKs): met1 strap to + # the ring's met1 vertical segment. + cmirror << straight_route(pdk, cmirror.ports["A_0_dummy_L_gsdcon_top_met_W"], cmirror.ports["welltie_W_top_met_W"], glayer2="met1") + cmirror << straight_route(pdk, cmirror.ports[f"B_{_lastcol}_dummy_R_gsdcon_top_met_E"], cmirror.ports["welltie_E_top_met_E"], glayer2="met1") # current mirror netlist — gf180 needs `dummies_tied_to_bulk=False` # because here we use raw two_nfet_interdigitized + custom routing, # NOT current_mirror, so the standalone-cell's straight_route from