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..99943290 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 @@ -80,6 +80,7 @@ def diff_pair_ibias( diffpair_bias: tuple[float, float, int], rmult: int = 1, with_antenna_diode_on_diffinputs: int = 0, + dummies_tied_to_bulk: Optional[bool] = None, ) -> Component: # create and center diffpair diffpair_i_ = Component("temp diffpair and current source") @@ -203,7 +204,10 @@ def diff_pair_ibias( # 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") + if dummies_tied_to_bulk is None: + _dummies_tied = (pdk.name.lower() == "sky130") + else: + _dummies_tied = dummies_tied_to_bulk cmirror.info['netlist'] = current_mirror_netlist( pdk, width=diffpair_bias[0], diff --git a/src/glayout/cells/composite/opamp/diff_pair_stackedcmirror.py b/src/glayout/cells/composite/opamp/diff_pair_stackedcmirror.py index abe009db..50f2f161 100644 --- a/src/glayout/cells/composite/opamp/diff_pair_stackedcmirror.py +++ b/src/glayout/cells/composite/opamp/diff_pair_stackedcmirror.py @@ -22,9 +22,9 @@ @validate_arguments -def __add_diff_pair_and_bias(pdk: MappedPDK, toplevel_stacked: Component, half_diffpair_params: tuple[float, float, int], diffpair_bias: tuple[float, float, int], rmult: int, with_antenna_diode_on_diffinputs: int) -> Component: +def __add_diff_pair_and_bias(pdk: MappedPDK, toplevel_stacked: Component, half_diffpair_params: tuple[float, float, int], diffpair_bias: tuple[float, float, int], rmult: int, with_antenna_diode_on_diffinputs: int, dummies_tied_to_bulk: Optional[bool] = None) -> Component: clear_cache() - diffpair_i_ref = diff_pair_ibias(pdk, half_diffpair_params, diffpair_bias, rmult, with_antenna_diode_on_diffinputs) + diffpair_i_ref = diff_pair_ibias(pdk, half_diffpair_params, diffpair_bias, rmult, with_antenna_diode_on_diffinputs, dummies_tied_to_bulk=dummies_tied_to_bulk) toplevel_stacked.add(diffpair_i_ref) toplevel_stacked.add_ports(diffpair_i_ref.get_ports_list(),prefix="diffpair_") @@ -150,12 +150,13 @@ def diff_pair_stackedcmirror( diffpair_bias: tuple[float, float, int], half_common_source_nbias: tuple[float, float, int, int], rmult: int, - with_antenna_diode_on_diffinputs: int + with_antenna_diode_on_diffinputs: int, + dummies_tied_to_bulk: Optional[bool] = None, ) -> Component: # create toplevel_stacked component toplevel_stacked = Component() # place nmos components - diffpair_and_bias = __add_diff_pair_and_bias(pdk, toplevel_stacked, half_diffpair_params, diffpair_bias, rmult, with_antenna_diode_on_diffinputs) + diffpair_and_bias = __add_diff_pair_and_bias(pdk, toplevel_stacked, half_diffpair_params, diffpair_bias, rmult, with_antenna_diode_on_diffinputs, dummies_tied_to_bulk=dummies_tied_to_bulk) # create and position each half of the nmos bias transistor for the common source stage symetrically toplevel_stacked = __add_common_source_nbias_transistors(pdk, toplevel_stacked, half_common_source_nbias, rmult) toplevel_stacked.add_padding(layers=(pdk.get_glayer("pwell"),),default=0) diff --git a/src/glayout/cells/composite/opamp/opamp_twostage.py b/src/glayout/cells/composite/opamp/opamp_twostage.py index 5ac43f91..7d968da4 100644 --- a/src/glayout/cells/composite/opamp/opamp_twostage.py +++ b/src/glayout/cells/composite/opamp/opamp_twostage.py @@ -225,7 +225,7 @@ def opamp_twostage( raise ValueError("number of antenna diodes should be at least 2 (or 0 to specify no diodes)") if half_common_source_bias[3] < 2: raise ValueError("half_common_source_bias num multiplier must be >= 2") - opamp_top, halfmultn_drain_routeref, halfmultn_gate_routeref, _cref = diff_pair_stackedcmirror(pdk, half_diffpair_params, diffpair_bias, half_common_source_bias, rmult, with_antenna_diode_on_diffinputs) + opamp_top, halfmultn_drain_routeref, halfmultn_gate_routeref, _cref = diff_pair_stackedcmirror(pdk, half_diffpair_params, diffpair_bias, half_common_source_bias, rmult, with_antenna_diode_on_diffinputs,) opamp_top.info['netlist'].circuit_name = "INPUT_STAGE" @@ -268,21 +268,20 @@ def opamp_twostage( # as literals — see DIFF_TO_SINGLE's netlist for the same pattern. source_netlist=( ".subckt {circuit_name} {nodes} " - + f"l={_csb_l} w={_csb_w} mr={_csb_f} mo={_csb_f * _csb_m} " - + f"dr={2} do={2 * _csb_m}\n" + + f"l={_csb_l} w={_csb_w} mr={_csb_f} mo={_csb_f * _csb_m}\n" + "XREFL VREF VREF VSS B {model} l={{l}} w={{w}} m={{mr}}\n" + "XREFR VREF VREF VSS B {model} l={{l}} w={{w}} m={{mr}}\n" + "XOUTL VOUT VREF VSS B {model} l={{l}} w={{w}} m={{mo}}\n" + "XOUTR VOUT VREF VSS B {model} l={{l}} w={{w}} m={{mo}}\n" - + "XDREFL B B B B {model} l={{l}} w={{w}} m={{dr}}\n" - + "XDREFR B B B B {model} l={{l}} w={{w}} m={{dr}}\n" - + "XDOUTL B B B B {model} l={{l}} w={{w}} m={{do}}\n" - + "XDOUTR B B B B {model} l={{l}} w={{w}} m={{do}}\n" + + "".join( + f"XDUM{_i+1} B B B B {{model}} l={_csb_l} w={_csb_w}\n" + for _i in range(2 * (2 + 2 * _csb_m)) + ) + ".ends {circuit_name}" ), instance_format=( "X{name} {nodes} {circuit_name} l={length} w={width} " - "mr={mr} mo={mo} dr={dr} do={do}" + "mr={mr} mo={mo}" ), parameters={ 'model': _nfet_model, @@ -290,8 +289,6 @@ def opamp_twostage( 'length': _csb_l, 'mr': _csb_f, 'mo': _csb_f * _csb_m, - 'dr': 2, - 'do': 2 * _csb_m, } )