Skip to content

Commit

Permalink
Merge pull request #6 from martinjankoehler/pdk-refactoring
Browse files Browse the repository at this point in the history
Local PDK (additions) refactoring
  • Loading branch information
martinjankoehler authored Dec 5, 2024
2 parents ac2646f + 0af7d58 commit b4c781c
Show file tree
Hide file tree
Showing 49 changed files with 5,836 additions and 8 deletions.
16 changes: 10 additions & 6 deletions kpex/kpex_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,10 +87,10 @@ class KpexCLI:
def parse_args(arg_list: List[str] = None) -> argparse.Namespace:
# epilog = f"See '{PROGRAM_NAME} <subcommand> -h' for help on subcommand"
epilog = """
| Variable | Example |
| -------- | -------------------- |
| PDKPATH | (e.g. $HOME/.volare) |
| PDK | (e.g. sky130A) |
| Variable | Example | Description |
| -------- | -------------------- | --------------------------------------- |
| PDKPATH | (e.g. $HOME/.volare) | Optional (required for default magigrc) |
| PDK | (e.g. sky130A) | Optional (required for default magigrc) |
"""
epilog_md = rich.console.Group(
rich.text.Text('Environmental variables:', style='argparse.groups'),
Expand Down Expand Up @@ -128,7 +128,8 @@ def parse_args(arg_list: List[str] = None) -> argparse.Namespace:
group_pex_input.add_argument("--lvsdb", "-l", dest="lvsdb_path", help="KLayout LVSDB path (bypass LVS)")
group_pex_input.add_argument("--cell", "-c", dest="cell_name", default=None,
help="Cell (default is the top cell)")
default_lvs_script_path = os.path.realpath(os.path.join(__file__, '..', '..', 'pdk', 'sky130A', 'kpex', 'sky130.lvs'))
default_lvs_script_path = os.path.realpath(os.path.join(__file__, '..', '..', 'pdk',
'sky130A', 'libs.tech', 'kpex', 'sky130.lvs'))

group_pex_input.add_argument("--lvs_script", dest="lvs_script_path",
default=default_lvs_script_path,
Expand Down Expand Up @@ -199,7 +200,10 @@ def parse_args(arg_list: List[str] = None) -> argparse.Namespace:
action='store_true', default=False,
help="FasterCap -pj Use Jacobi preconditioner (default is %(default)s)")

default_magicrc_path = os.path.abspath(f"{os.environ['PDKPATH']}/libs.tech/magic/{os.environ['PDK']}.magicrc")
PDKPATH = os.environ.get('PDKPATH', None)
default_magicrc_path = \
None if PDKPATH is None \
else os.path.abspath(f"{PDKPATH}/libs.tech/magic/{os.environ['PDK']}.magicrc")
group_magic = main_parser.add_argument_group("MAGIC options")
group_magic.add_argument('--magicrc', dest='magicrc_path', default=default_magicrc_path,
help=f"Path to magicrc configuration file (default is '%(default)s')")
Expand Down
1 change: 0 additions & 1 deletion pdk/ihp_sg13g2/kpex/rule_decks

This file was deleted.

69 changes: 69 additions & 0 deletions pdk/ihp_sg13g2/libs.tech/kpex/rule_decks/bjt_connections.lvs
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# frozen_string_literal: true

#==========================================================================
# Copyright 2024 IHP PDK Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# SPDX-License-Identifier: Apache-2.0
#==========================================================================

#================================
# ------ BJT CONNECTIONS --------
#================================

logger.info('Starting LVS BJT CONNECTIONS')

# =============
# ---- NPN ----
# =============

# General
connect(npn_sub, pwell)

# npn13G2 nodes connections
connect(npn13G2_te, npn13G2_e_pin)
connect(npn13G2_tc, npn13G2_c_pin)
connect(npn13G2_tb, npn13G2_b_pin)
connect(npn13G2_e_pin, cont_drw)
connect(npn13G2_c_pin, cont_drw)
connect(npn13G2_b_pin, cont_drw)
connect(npn_sub, pwell)
connect(npn13G2_e_pin, emwind_drw)
connect(emwind_drw, metal1_con)

# npn13G2L nodes connections
connect(npn13G2l_te, npn13G2l_e_pin)
connect(npn13G2l_tc, npn13G2l_c_pin)
connect(npn13G2l_tb, npn13G2l_b_pin)
connect(npn13G2l_e_pin, cont_drw)
connect(npn13G2l_c_pin, cont_drw)
connect(npn13G2l_b_pin, cont_drw)
connect(npn_sub, pwell)

# npn13G2V nodes connections
connect(npn13G2v_te, npn13G2v_e_pin)
connect(npn13G2v_tc, npn13G2v_c_pin)
connect(npn13G2v_tb, npn13G2v_b_pin)
connect(npn13G2v_e_pin, cont_drw)
connect(npn13G2v_c_pin, cont_drw)
connect(npn13G2v_b_pin, cont_drw)
connect(npn_sub, pwell)

# =============
# ---- PNP ----
# =============

# pnp_mpa nodes connections
connect(pnp_mpa_e, cont_drw)
connect(pnp_mpa_b, cont_drw)
connect(pnp_mpa_c, cont_drw)
125 changes: 125 additions & 0 deletions pdk/ihp_sg13g2/libs.tech/kpex/rule_decks/bjt_derivations.lvs
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
# frozen_string_literal: true

#==========================================================================
# Copyright 2024 IHP PDK Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# SPDX-License-Identifier: Apache-2.0
#==========================================================================

#================================
# ------ BJT DERIVATIONS --------
#================================

logger.info('Starting BJT DERIVATIONS')

# =============
# ---- NPN ----
# =============

logger.info('Starting NPN-BJT DERIVATIONS')

bjt_exclude = gatpoly.join(pwell_block).join(nsd_drw)
.join(salblock_drw).join(polyres_drw).join(extblock_drw)
.join(res_drw).join(recog_diode).join(recog_esd)
.join(ind_drw).join(ind_pin).join(substrate_drw)

npn_exclude = nwell_drw.join(psd_drw).join(nbulay_drw).join(bjt_exclude)

# ---------- General NPN ----------
npn_mk = trans_drw.and(pwell).and(ptap_holes)
npn_c_exc = emwind_drw.join(emwihv_drw).join(activ_mask)
.join(nsd_block).join(npn_exclude)
npn_b_exc = emwind_drw.join(emwihv_drw).join(npn_exclude)
npn_sub = npn_mk.not(npn_exclude)
npn_dev = activ.join(activ_mask).and(npn_mk)

# ---------- npn13G2 ----------
# npn13G2 exclusion layers
npn13G2_e_exc = activ.join(emwihv_drw).join(npn_exclude)
npn13G2_b_exc = npn_b_exc.join(activ_mask)

# npn13G2 nodes
npn13G2_e_ = emwind_drw.and(activ_mask).and(nsd_block).and(npn_mk).not(npn13G2_e_exc)
# npn13G2 is a fixed device (0.07um X 0.9um)
npn13G2_e_pin = npn13G2_e_.with_bbox_min(0.07.um).with_bbox_max(0.9.um).with_area(0.063.um)
npn13G2_b_pin = nsd_block.and(npn_mk).not(npn13G2_b_exc)
npn13G2_c_pin = activ.and(npn_mk).not_overlapping(npn_c_exc)

npn13G2_dev = npn_dev.join(nsd_block).extents.covering(npn13G2_e_pin).covering(npn13G2_b_pin).covering(npn13G2_c_pin)
npn13G2_c = npn13G2_dev.sized(-1.nm)
npn13G2_tc = npn13G2_dev.not(npn13G2_c).interacting(npn13G2_c_pin)
npn13G2_b = npn13G2_dev.not(npn13G2_c_pin)
npn13G2_tb = npn13G2_b.not(npn13G2_e_pin).merged
npn13G2_e = npn13G2_e_pin
npn13G2_te = npn13G2_e

# ---------- npn13G2L ----------
# npn13G2L exclusion layers
npn13G2l_e_exc = activ_mask.join(nsd_block).join(emwihv_drw).join(npn_exclude)
npn13G2l_b_exc = npn_b_exc.join(activ).join(nsd_block)

# npn13G2L nodes
npn13G2l_e_ = emwind_drw.and(activ).and(npn_mk).not(npn13G2l_e_exc)
# npn13G2L has fixed width (0.07um), Length could vary from 1:2.5 um
npn13G2l_e_pin = npn13G2l_e_.with_bbox_min(0.07.um).with_bbox_max(1.um, 2.5.um).with_area(0.07.um, 0.175.um)
npn13G2l_b_pin = activ_mask.and(npn_mk).not(npn13G2l_b_exc)
npn13G2l_c_pin = npn13G2_c_pin

npn13G2l_dev = npn_dev.covering(npn13G2l_e_pin).covering(npn13G2l_b_pin).covering(npn13G2l_c_pin)
npn13G2l_c = npn13G2l_dev.sized(1.nm)
npn13G2l_tc = npn13G2l_c.not(npn13G2l_dev).interacting(npn13G2l_c_pin)
npn13G2l_b = npn13G2l_dev.not(npn13G2l_c_pin)
npn13G2l_tb = npn13G2l_b.not(npn13G2l_e_pin).merged
npn13G2l_e = npn13G2l_e_pin
npn13G2l_te = npn13G2l_e

# # ---------- npn13G2V ----------
# npn13G2V exclusion layers
npn13G2v_e_exc = activ_mask.join(nsd_block).join(emwind_drw).join(npn_exclude)

# npn13G2V nodes
npn13G2v_e_ = emwihv_drw.and(activ).and(npn_mk).not(npn13G2v_e_exc)
# npn13G2L has fixed width (0.12um), Length could vary from 1:5 um
npn13G2v_e_pin = npn13G2v_e_.with_bbox_min(0.12.um).with_bbox_max(1.um, 5.um).with_area(0.12.um, 0.6.um)
npn13G2v_b_pin = npn13G2l_b_pin
npn13G2v_c_pin = npn13G2l_c_pin

npn13G2v_dev = npn_dev.covering(npn13G2v_e_pin).covering(npn13G2v_b_pin).covering(npn13G2v_c_pin)
npn13G2v_c = npn13G2v_dev.sized(1.nm)
npn13G2v_tc = npn13G2v_c.not(npn13G2v_dev).interacting(npn13G2v_c_pin)
npn13G2v_b = npn13G2v_dev.not(npn13G2v_c_pin)
npn13G2v_tb = npn13G2v_b.not(npn13G2v_e_pin).merged
npn13G2v_e = npn13G2v_e_pin
npn13G2v_te = npn13G2v_e

# =============
# ---- PNP ----
# =============

logger.info('Starting PNP-BJT DERIVATIONS')

pnp_exclude = trans_drw.join(emwind_drw)
.join(emwihv_drw).join(nsd_block).join(bjt_exclude)

pnp_mk = ptap_holes.not(pnp_exclude)

# pnp general nodes DERIVATIONS
pnp_e = pactiv.and(pnp_mk).and(nwell_iso)
pnp_b = nactiv.and(pnp_mk).and(nwell_iso)
pnp_c = ptap.interacting(pnp_mk).not(pnp_exclude)

# pnp_mpa nodes DERIVATIONS
pnp_mpa_e = pnp_e.and(pnp_b.extents).and(pnp_c.extents)
pnp_mpa_b = pnp_b.interacting(pnp_b.extents.interacting(pnp_mpa_e))
pnp_mpa_c = pnp_c.interacting(pnp_c.extents.interacting(pnp_mpa_e))
81 changes: 81 additions & 0 deletions pdk/ihp_sg13g2/libs.tech/kpex/rule_decks/bjt_extraction.lvs
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
# frozen_string_literal: true

#==========================================================================
# Copyright 2024 IHP PDK Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# SPDX-License-Identifier: Apache-2.0
#==========================================================================

#================================
# ------- BJT EXTRACTION --------
#================================

logger.info('Starting BJT EXTRACTION')

# =============
# ---- NPN ----
# =============

logger.info('Starting NPN-BJT EXTRACTION')

logger.info('Extraction of npn13G2 BJT transistor')
extract_devices(bjt4('npn13G2', CustomBJT4), {
'C' => npn13G2_c,
'B' => npn13G2_b,
'E' => npn13G2_e,
'S' => npn_sub,
'tC' => npn13G2_tc,
'tB' => npn13G2_tb,
'tE' => npn13G2_te,
'tS' => npn_sub
})

logger.info('Extraction of npn13G2L BJT transistor')
extract_devices(bjt4('npn13G2l', CustomBJT4), {
'C' => npn13G2l_c,
'B' => npn13G2l_b,
'E' => npn13G2l_e,
'S' => npn_sub,
'tC' => npn13G2l_tc,
'tB' => npn13G2l_tb,
'tE' => npn13G2l_te,
'tS' => npn_sub
})

logger.info('Extraction of npn13G2V BJT transistor')
extract_devices(bjt4('npn13G2v', CustomBJT4), {
'C' => npn13G2v_c,
'B' => npn13G2v_b,
'E' => npn13G2v_e,
'S' => npn_sub,
'tC' => npn13G2v_tc,
'tB' => npn13G2v_tb,
'tE' => npn13G2v_te,
'tS' => npn_sub
})

# =============
# ---- PNP ----
# =============

logger.info('Starting PNP-BJT EXTRACTION')

# pnp_mpa BJT
logger.info('Extracting pnpMPA BJT')
extract_devices(bjt3('pnpMPA', CustomBJT3), { 'C' => pnp_mpa_c.extents,
'B' => pnp_mpa_b.extents,
'E' => pnp_mpa_e,
'tC' => pnp_mpa_c,
'tB' => pnp_mpa_b,
'tE' => pnp_mpa_e })
39 changes: 39 additions & 0 deletions pdk/ihp_sg13g2/libs.tech/kpex/rule_decks/cap_connections.lvs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# frozen_string_literal: true

#==========================================================================
# Copyright 2024 IHP PDK Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# SPDX-License-Identifier: Apache-2.0
#==========================================================================

#==================================
# ------ MIMCAP CONNECTIONS -------
#==================================

logger.info('Starting LVS CAP CONNECTIONS')

# === cap_mim ===
connect(cmim_btm, metal5_con)
connect(cmim_top, mim_via)
connect(mim_via, topmetal1_con)

# === rfcmim ===
connect(rfmim_btm, metal5_con)
connect(rfmim_top, mim_via)
connect(rfmim_sub, ptap)

# === svarivap ===
connect(varicap_ports, cont_drw)
connect(varicap_ports, text_drw)
connect(varicap_sub, ptap)
Loading

0 comments on commit b4c781c

Please sign in to comment.