From db5da7076e5d22556ab12a6fbc0992d5f2376bb9 Mon Sep 17 00:00:00 2001 From: htfab Date: Mon, 2 Mar 2026 04:39:38 +0100 Subject: [PATCH] feat!: replace ihp-sg13g2 with ihp-sg13cmos5l --- .github/workflows/test-harden.yaml | 16 +++--- config.py | 2 +- doc_utils.py | 6 +-- docs/typst/chapters/pinout-tables.typ | 2 +- docs/typst/src/datasheet.typ | 2 +- logo.py | 2 +- precheck/klayout_tools.py | 2 +- precheck/precheck.py | 14 +++--- precheck/reports/.gitignore | 2 +- precheck/tech-files/README.txt | 2 +- precheck/tech_data.py | 47 ++++++++---------- rom/config.json | 6 +-- tech.py | 40 +++++++-------- .../categories.json | 0 .../{ihp-sg13g2 => ihp-sg13cmos5l}/cells.json | 0 .../def/analog/magic_init_project.tcl | 2 +- .../def/analog/tt_analog_1x2.def | 4 -- .../def/analog/tt_analog_2x2.def | 4 -- .../def/tt_block_1x1_pgvdd.def | 4 -- .../def/tt_block_1x2_pgvdd.def | 4 -- .../def/tt_block_2x2_pgvdd.def | 4 -- .../def/tt_block_3x2_pgvdd.def | 4 -- .../def/tt_block_3x4_pgvdd.def | 4 -- .../def/tt_block_4x2_pgvdd.def | 4 -- .../def/tt_block_4x4_pgvdd.def | 4 -- .../def/tt_block_5x4_pgvdd.def | 4 -- .../def/tt_block_6x2_pgvdd.def | 4 -- .../def/tt_block_6x4_pgvdd.def | 4 -- .../def/tt_block_8x2_pgvdd.def | 4 -- .../tile_sizes.yaml | 0 tech/ihp-sg13cmos5l/tt_logo_corner.gds | Bin 0 -> 16638 bytes .../tt_logo_corner.lef | 2 +- .../tt_logo_corner.v | 0 tech/ihp-sg13g2/tt_logo_corner.gds | Bin 16638 -> 0 bytes tt_tool.py | 4 +- 35 files changed, 74 insertions(+), 129 deletions(-) rename tech/{ihp-sg13g2 => ihp-sg13cmos5l}/categories.json (100%) rename tech/{ihp-sg13g2 => ihp-sg13cmos5l}/cells.json (100%) rename tech/{ihp-sg13g2 => ihp-sg13cmos5l}/def/analog/magic_init_project.tcl (96%) rename tech/{ihp-sg13g2 => ihp-sg13cmos5l}/def/analog/tt_analog_1x2.def (98%) rename tech/{ihp-sg13g2 => ihp-sg13cmos5l}/def/analog/tt_analog_2x2.def (98%) rename tech/{ihp-sg13g2 => ihp-sg13cmos5l}/def/tt_block_1x1_pgvdd.def (98%) rename tech/{ihp-sg13g2 => ihp-sg13cmos5l}/def/tt_block_1x2_pgvdd.def (98%) rename tech/{ihp-sg13g2 => ihp-sg13cmos5l}/def/tt_block_2x2_pgvdd.def (98%) rename tech/{ihp-sg13g2 => ihp-sg13cmos5l}/def/tt_block_3x2_pgvdd.def (98%) rename tech/{ihp-sg13g2 => ihp-sg13cmos5l}/def/tt_block_3x4_pgvdd.def (99%) rename tech/{ihp-sg13g2 => ihp-sg13cmos5l}/def/tt_block_4x2_pgvdd.def (98%) rename tech/{ihp-sg13g2 => ihp-sg13cmos5l}/def/tt_block_4x4_pgvdd.def (99%) rename tech/{ihp-sg13g2 => ihp-sg13cmos5l}/def/tt_block_5x4_pgvdd.def (99%) rename tech/{ihp-sg13g2 => ihp-sg13cmos5l}/def/tt_block_6x2_pgvdd.def (98%) rename tech/{ihp-sg13g2 => ihp-sg13cmos5l}/def/tt_block_6x4_pgvdd.def (99%) rename tech/{ihp-sg13g2 => ihp-sg13cmos5l}/def/tt_block_8x2_pgvdd.def (98%) rename tech/{ihp-sg13g2 => ihp-sg13cmos5l}/tile_sizes.yaml (100%) create mode 100644 tech/ihp-sg13cmos5l/tt_logo_corner.gds rename tech/{ihp-sg13g2 => ihp-sg13cmos5l}/tt_logo_corner.lef (99%) rename tech/{ihp-sg13g2 => ihp-sg13cmos5l}/tt_logo_corner.v (100%) delete mode 100644 tech/ihp-sg13g2/tt_logo_corner.gds diff --git a/.github/workflows/test-harden.yaml b/.github/workflows/test-harden.yaml index cf3f9d1..05f5930 100644 --- a/.github/workflows/test-harden.yaml +++ b/.github/workflows/test-harden.yaml @@ -10,7 +10,7 @@ jobs: strategy: fail-fast: false matrix: - pdk: [sky130A, ihp-sg13g2, gf180mcuD] + pdk: [sky130A, ihp-sg13cmos5l, gf180mcuD] runs-on: ubuntu-24.04 @@ -35,24 +35,24 @@ jobs: run: pip install -r requirements.txt - name: Install librelane - if: "${{ matrix.pdk != 'ihp-sg13g2' }}" + if: "${{ matrix.pdk != 'ihp-sg13cmos5l' }}" run: pip install librelane==${LIBRELANE_VERSION} - # LibreLane 2.4.2 does not support ihp-sg13g2. Remove once 3.0.0 is released. + # LibreLane 2.4.2 does not support ihp-sg13cmos5l. Remove once 3.0.0 is released. - name: Install librelane 3 dev (IHP only) - if: "${{ matrix.pdk == 'ihp-sg13g2' }}" + if: "${{ matrix.pdk == 'ihp-sg13cmos5l' }}" run: pip install librelane==${LIBRELANE_VERSION_DEV} - name: Clone the factory test - if: "${{ matrix.pdk != 'ihp-sg13g2' }}" + if: "${{ matrix.pdk != 'ihp-sg13cmos5l' }}" run: git clone https://github.com/tinytapeout/ttsky25a-factory-test ${PROJECT_DIR} - - name: Clone the factory test (ihp-sg13g2) - if: "${{ matrix.pdk == 'ihp-sg13g2' }}" + - name: Clone the factory test (ihp-sg13cmos5l) + if: "${{ matrix.pdk == 'ihp-sg13cmos5l' }}" run: git clone https://github.com/TinyTapeout/ttihp25b-factory-test ${PROJECT_DIR} - name: Configure tt_tool.py args (IHP) - if: "${{ matrix.pdk == 'ihp-sg13g2' }}" + if: "${{ matrix.pdk == 'ihp-sg13cmos5l' }}" run: echo "TT_TOOL_ARGS=--ihp" >> $GITHUB_ENV - name: Configure tt_tool.py args (gf180mcuD) diff --git a/config.py b/config.py index 8ebc58b..8def56e 100644 --- a/config.py +++ b/config.py @@ -17,7 +17,7 @@ class DatasheetConfig(TypedDict): "caravel", "openframe", "openframe_sky130", - "customframe_ihp_sg13g2", + "customframe_ihp_sg13cmos5l", "customframe_gf180mcud", ] theme_override_colour: str diff --git a/doc_utils.py b/doc_utils.py index 765676f..e8d9d50 100644 --- a/doc_utils.py +++ b/doc_utils.py @@ -434,8 +434,8 @@ class DocsHelper: case "sky130A": content["pinout"] = "openframe_sky130" - case "ihp-sg13g2": - content["pinout"] = "customframe_ihp_sg13g2" + case "ihp-sg13cmos5l": + content["pinout"] = "customframe_ihp_sg13cmos5l" case "gf180mcuD": content["pinout"] = "customframe_gf180mcud" case _: @@ -451,7 +451,7 @@ class DocsHelper: content["pinout"] = "openframe_sky130" elif shuttle_config["id"].startswith("ttihp"): - content["pinout"] = "customframe_ihp_sg13g2" + content["pinout"] = "customframe_ihp_sg13cmos5l" elif shuttle_config["id"].startswith("ttgf"): content["pinout"] = "customframe_gf180mcud" diff --git a/docs/typst/chapters/pinout-tables.typ b/docs/typst/chapters/pinout-tables.typ index b810761..d265f86 100644 --- a/docs/typst/chapters/pinout-tables.typ +++ b/docs/typst/chapters/pinout-tables.typ @@ -227,7 +227,7 @@ ] } -#let customframe_ihp_sg13g2 = { +#let customframe_ihp_sg13cmos5l = { align(center, table( columns: 4, diff --git a/docs/typst/src/datasheet.typ b/docs/typst/src/datasheet.typ index b9b1712..d173426 100644 --- a/docs/typst/src/datasheet.typ +++ b/docs/typst/src/datasheet.typ @@ -483,7 +483,7 @@ caravel: (diagram: "chip_pinout_qfn64", table: pins.caravel), openframe: (diagram: "chip_pinout_qfn64", table: pins.openframe), openframe_sky130: (diagram: "chip_pinout_qfn64_sky130_openframe", table: pins.openframe_sky130), - customframe_ihp_sg13g2: (diagram: "chip_pinout_qfn64_ihp_sg13g2", table: pins.customframe_ihp_sg13g2), + customframe_ihp_sg13cmos5l: (diagram: "chip_pinout_qfn64_ihp_sg13cmos5l", table: pins.customframe_ihp_sg13cmos5l), customframe_gf180mcud: (diagram: "chip_pinout_qfn64_gf180mcud", table: pins.customframe_gf180mcud) ) diff --git a/logo.py b/logo.py index ac6aa57..eb42ceb 100755 --- a/logo.py +++ b/logo.py @@ -119,7 +119,7 @@ if __name__ == "__main__": "--pdk", type=str, default="sky130A", - choices=["sky130A", "ihp-sg13g2", "gf180mcuD"], + choices=["sky130A", "ihp-sg13cmos5l", "gf180mcuD"], ) parser.add_argument("--top", action="store_true") parser.add_argument("--bottom", action="store_true") diff --git a/precheck/klayout_tools.py b/precheck/klayout_tools.py index da59111..9430d4d 100644 --- a/precheck/klayout_tools.py +++ b/precheck/klayout_tools.py @@ -54,7 +54,7 @@ def parse_lyp_layers(lyp_file: str, only_valid: bool = True): if " " in source: assert source.count(" ") == 1 - # sky130A and sg13g2 has the name in the "name" field + # sky130A and sg13cmos5l has the name in the "name" field # gf180mcuD has the name as part of the "source" field # if a future PDK has it in both places, we'll trigger the # assertion below to decide which one has priority diff --git a/precheck/precheck.py b/precheck/precheck.py index 9b5dfec..038e174 100644 --- a/precheck/precheck.py +++ b/precheck/precheck.py @@ -112,11 +112,11 @@ def klayout_zero_area(gds: str): return klayout_drc(gds, "zero_area", "zeroarea.rb.drc") -def klayout_sg13g2(gds: str): +def klayout_sg13cmos5l(gds: str): return klayout_drc( gds, - "sg13g2", - f"{PDK_ROOT}/{PDK_NAME}/libs.tech/klayout/tech/drc/ihp-sg13g2.drc", + "sg13cmos5l", + f"{PDK_ROOT}/{PDK_NAME}/libs.tech/klayout/tech/drc/ihp-sg13cmos5l.drc", ) @@ -367,7 +367,7 @@ def main(): template_def = f"{def_root}/analog/tt_analog_{tiles}_3v3.def" else: template_def = f"{def_root}/analog/tt_analog_{tiles}.def" - elif tech == "ihp-sg13g2" or tech == "gf180mcuD": + elif tech == "ihp-sg13cmos5l" or tech == "gf180mcuD": template_def = f"{def_root}/tt_block_{tiles}_pgvdd.def" else: template_def = f"{def_root}/tt_block_{tiles}_pg.def" @@ -413,8 +413,8 @@ def main(): }, { "name": "KLayout SG13G2 DRC", - "check": lambda: klayout_sg13g2(gds_file), - "techs": ["ihp-sg13g2"], + "check": lambda: klayout_sg13cmos5l(gds_file), + "techs": ["ihp-sg13cmos5l"], }, {"name": "KLayout zero area", "check": lambda: klayout_zero_area(gds_file)}, { @@ -445,7 +445,7 @@ def main(): "check": lambda: analog_pin_check( gds_file, tech, is_analog, uses_3v3, analog_pins, pinout ), - "techs": ["sky130A", "ihp-sg13g2"], + "techs": ["sky130A", "ihp-sg13cmos5l"], }, ] diff --git a/precheck/reports/.gitignore b/precheck/reports/.gitignore index 8481468..2b7d558 100644 --- a/precheck/reports/.gitignore +++ b/precheck/reports/.gitignore @@ -4,7 +4,7 @@ drc_offgrid.xml drc_pin_label_purposes_overlapping_drawing.xml drc_zero_area.xml drc_nwell_urpm.xml -drc_sg13g2.xml +drc_sg13cmos5l.xml magic_drc.mag magic_drc.txt results.md diff --git a/precheck/tech-files/README.txt b/precheck/tech-files/README.txt index c53bd13..3187109 100644 --- a/precheck/tech-files/README.txt +++ b/precheck/tech-files/README.txt @@ -3,7 +3,7 @@ pin_label_purposes_overlapping_drawing.rb.drc from https://github.com/chipfoundr zeroarea.rb.drc from https://github.com/chipfoundry/mpw_precheck revision 4fd5283b124e931c9e71219f47270075176f84e2 nwell_urpm.drc from https://open-source-silicon.slack.com/archives/C05FW1VMY5A/p1729112262642699?thread_ts=1728921677.220509&cid=C05FW1VMY5A -sg13g2_mr.lydrc: +sg13cmos5l_mr.lydrc: from https://github.com/IHP-GmbH/TO_Apr2025 revision 772a369f3ceabc2c6e1eba57d91ae755682c8323 with the following minimum density rules disabled: - M1.j, M2.j, M3.j, M4.j, M5.j diff --git a/precheck/tech_data.py b/precheck/tech_data.py index adb1e81..21624bb 100644 --- a/precheck/tech_data.py +++ b/precheck/tech_data.py @@ -1,4 +1,4 @@ -tech_names = ["sky130A", "ihp-sg13g2", "gf180mcuD"] +tech_names = ["sky130A", "ihp-sg13cmos5l", "gf180mcuD"] # fmt: off valid_layers_sky130A = [ @@ -56,7 +56,7 @@ valid_layers_sky130A = [ (235, 0), (235, 250), (235, 252), (236, 0), ] -valid_layers_ihp_sg13g2 = [ +valid_layers_ihp_sg13cmos5l = [ "Substrate.drawing", "Substrate.text", "Activ.drawing", "Activ.label", "Activ.nofill", "Activ.pin", "GatPoly.drawing", "GatPoly.label", "GatPoly.nofill", "GatPoly.pin", "PolyRes.drawing", "PolyRes.label", "PolyRes.pin", "NWell.drawing", "NWell.label", "NWell.pin", "nBuLay.drawing", "nBuLay.label", "nBuLay.pin", "nBuLay.block", "PWell.block", @@ -65,17 +65,14 @@ valid_layers_ihp_sg13g2 = [ "Metal2.drawing", "Metal2.label", "Metal2.nofill", "Metal2.pin", "Metal2.slit", "Metal2.text", "Metal2.res", "Via2.drawing", "Via2.net", "Via2.boundary", "Metal3.drawing", "Metal3.label", "Metal3.nofill", "Metal3.pin", "Metal3.slit", "Metal3.text", "Metal3.res", "MIM.drawing", "Vmim.drawing", "Via3.drawing", "Metal4.drawing", - "Metal4.label", "Metal4.nofill", "Metal4.pin", "Metal4.slit", "Metal4.text", "Metal4.res", "Via4.drawing", - "Metal5.drawing", "Metal5.label", "Metal5.nofill", "Metal5.pin", "Metal5.slit", "Metal5.text", "Metal5.res", - "TopVia1.drawing", "TopMetal1.drawing", "TopMetal1.label", "TopMetal1.nofill", "TopMetal1.pin", "TopMetal1.slit", - "TopMetal1.text", "TopMetal1.res", "TopMetal2.nofill", "IND.drawing", "IND.pin", "IND.boundary", "IND.text", - "TEXT.drawing", "Recog.drawing", "Recog.pin", "Recog.esd", "Recog.diode", "Recog.tsv", "Recog.pdiode", "Recog.mom", - "DigiBnd.drawing", "DigiBnd.drawing0", "RES.drawing", "RES.label", "SRAM.drawing", "SRAM.label", "SRAM.boundary", - "DigiSub.drawing", "HeatRes.drawing", "NoRCX.drawing", "NoRCX.m2m3", "NoRCX.m2m4", "NoRCX.m2m5", "NoRCX.m2tm1", - "NoRCX.m2tm2", "NoRCX.m3m4", "NoRCX.m3m5", "NoRCX.m3tm1", "NoRCX.m3tm2", "NoRCX.m4m5", "NoRCX.m4tm1", "NoRCX.m4tm2", - "NoRCX.m5tm1", "NoRCX.m5tm2", "NoRCX.tm1tm2", "NoRCX.m1sub", "NoRCX.m2sub", "NoRCX.m3sub", "NoRCX.m4sub", "NoRCX.m5sub", - "NoRCX.tm1sub", "Varicap.drawing", "EXTBlock.drawing", "prBoundary.drawing", "prBoundary.label", "prBoundary.boundary", - "isoNWell.drawing", + "Metal4.label", "Metal4.nofill", "Metal4.pin", "Metal4.slit", "Metal4.text", "Metal4.res", "TopMetal1.nofill", + "IND.drawing", "IND.pin", "IND.boundary", "IND.text", "TEXT.drawing", "Recog.drawing", "Recog.pin", "Recog.esd", + "Recog.diode", "Recog.tsv", "Recog.pdiode", "Recog.mom", "DigiBnd.drawing", "DigiBnd.drawing0", "RES.drawing", + "RES.label", "SRAM.drawing", "SRAM.label", "SRAM.boundary", "DigiSub.drawing", "HeatRes.drawing", "NoRCX.drawing", + "NoRCX.m2m3", "NoRCX.m2m4", "NoRCX.m2m5", "NoRCX.m2tm1", "NoRCX.m2tm2", "NoRCX.m3m4", "NoRCX.m3m5", "NoRCX.m3tm1", + "NoRCX.m3tm2", "NoRCX.m4m5", "NoRCX.m4tm1", "NoRCX.m4tm2", "NoRCX.m5tm1", "NoRCX.m5tm2", "NoRCX.tm1tm2", "NoRCX.m1sub", + "NoRCX.m2sub", "NoRCX.m3sub", "NoRCX.m4sub", "NoRCX.m5sub", "NoRCX.tm1sub", "Varicap.drawing", "EXTBlock.drawing", + "prBoundary.drawing", "prBoundary.label", "prBoundary.boundary", "isoNWell.drawing", ] valid_layers_gf180mcuD = [ @@ -108,7 +105,7 @@ def analog_pin_rects(tech: str, uses_3v3: bool): x2, y2 = x1 + 0.9, y1 + 1.0 rect = ((x1, y1), (x2, y2)) yield (rect, pin_layer, via_layers) - elif tech == "ihp-sg13g2": + elif tech == "ihp-sg13cmos5l": pin_layer = (126, 0) # TopMetal1 via_layers = [(125, 0)] # TopVia1 for pin_number in range(8): @@ -127,12 +124,12 @@ def analog_pin_rects(tech: str, uses_3v3: bool): valid_layers = { "sky130A": valid_layers_sky130A, - "ihp-sg13g2": valid_layers_ihp_sg13g2, + "ihp-sg13cmos5l": valid_layers_ihp_sg13cmos5l, "gf180mcuD": valid_layers_gf180mcuD, } lyp_filename = { "sky130A": "sky130A.lyp", - "ihp-sg13g2": "sg13g2.lyp", + "ihp-sg13cmos5l": "sg13cmos5l.lyp", "gf180mcuD": "gf180mcu.lyp", } @@ -144,13 +141,11 @@ valid_lef_port_layers = { "met3.pin": (70, 16), "met4.pin": (71, 16), }, - "ihp-sg13g2": { + "ihp-sg13cmos5l": { "Metal1.pin": (8, 2), "Metal2.pin": (10, 2), "Metal3.pin": (30, 2), "Metal4.pin": (50, 2), - "Metal5.pin": (67, 2), - "TopMetal1.pin": (126, 2), }, } forbidden_layers = { @@ -159,10 +154,10 @@ forbidden_layers = { "met5.pin", "met5.label", ], - "ihp-sg13g2": [ - "TopMetal2.drawing", - "TopMetal2.pin", - "TopMetal2.label", + "ihp-sg13cmos5l": [ + "TopMetal1.drawing", + "TopMetal1.pin", + "TopMetal1.label", ], "gf180mcuD": [ "Metal5", @@ -171,16 +166,16 @@ forbidden_layers = { } power_pins_layer = { "sky130A": "met4", - "ihp-sg13g2": "TopMetal1", + "ihp-sg13cmos5l": "Metal4", "gf180mcuD": "Metal4", } power_pins_min_width = { "sky130A": 1200, # 1.2 um - "ihp-sg13g2": 2100, # 2.1 um + "ihp-sg13cmos5l": 2100, # 2.1 um "gf180mcuD": 1200, # 1.2 um } boundary_layer = { "sky130A": "prBoundary.boundary", - "ihp-sg13g2": "prBoundary.boundary", + "ihp-sg13cmos5l": "prBoundary.boundary", "gf180mcuD": "PR_bndry", } diff --git a/rom/config.json b/rom/config.json index d58ef2d..dea150d 100644 --- a/rom/config.json +++ b/rom/config.json @@ -36,9 +36,9 @@ "RUN_KLAYOUT_DRC": false }, - "pdk::ihp-sg13g2": { + "pdk::ihp-sg13cmos5l": { "DIE_AREA": [0, 0, 202.08, 154.98], - "FP_DEF_TEMPLATE": "ref::$DESIGN_DIR/../tech/ihp-sg13g2/def/tt_block_1x1_pgvdd.def", - "RT_MAX_LAYER": "Metal5" + "FP_DEF_TEMPLATE": "ref::$DESIGN_DIR/../tech/ihp-sg13cmos5l/def/tt_block_1x1_pgvdd.def", + "RT_MAX_LAYER": "Metal4" } } diff --git a/tech.py b/tech.py index 25dace3..eb1f504 100644 --- a/tech.py +++ b/tech.py @@ -2,7 +2,7 @@ import json import os from typing import Dict, List, Literal, Pattern, Protocol, Tuple, TypedDict, Union -TechName = Literal["sky130A", "ihp-sg13g2", "gf180mcuD", "fpgaUp5k"] +TechName = Literal["sky130A", "ihp-sg13cmos5l", "gf180mcuD", "fpgaUp5k"] class CellDefinition(TypedDict): @@ -128,16 +128,16 @@ class Sky130Tech(Tech): class IHPTech(Tech): is_fpga = False def_suffix = "pgvdd" - librelane_pdk_args = "--pdk ihp-sg13g2" + librelane_pdk_args = "--pdk ihp-sg13cmos5l --manual-pdk" tt_corner = "nom_typ_1p20V_25C" - cell_regexp = r"^\s*sg13g2_(?P\S+)_(?P\d+)" + cell_regexp = r"^\s*sg13cmos5l_(?P\S+)_(?P\d+)" netlist_type = "nl" - project_top_metal_layer = "TopMetal1" + project_top_metal_layer = "Metal4" librelane_config = {} label_layers = [ (8, 1), # Metal1.label (8, 25), # Metal1.text - (67, 25), # Metal5.text + (50, 25), # Metal4.text (126, 25), # TopMetal1.text ] buried_layers = [ @@ -147,32 +147,32 @@ class IHPTech(Tech): (51, 0), # HeatTrans.drawing (189, 4), # prBoundary.boundary ] - scramble_cells = "sg13g2_" - mux_config_yaml_name = "ihp-sg13g2.yaml" + scramble_cells = "sg13cmos5l_" + mux_config_yaml_name = "ihp-sg13cmos5l.yaml" mux_macros = [ - "pg/ihp-sg13g2/tt_pg_1v5_hp_1", - "pg/ihp-sg13g2/tt_pg_1v5_hp_2", - "pg/ihp-sg13g2/tt_pg_1v5_hp_4", - "pg/ihp-sg13g2/tt_pg_1v5_ll_1", - "pg/ihp-sg13g2/tt_pg_1v5_ll_2", - "pg/ihp-sg13g2/tt_pg_1v5_ll_4", + "pg/ihp-sg13cmos5l/tt_pg_1v5_hp_1", + "pg/ihp-sg13cmos5l/tt_pg_1v5_hp_2", + "pg/ihp-sg13cmos5l/tt_pg_1v5_hp_4", + "pg/ihp-sg13cmos5l/tt_pg_1v5_ll_1", + "pg/ihp-sg13cmos5l/tt_pg_1v5_ll_2", + "pg/ihp-sg13cmos5l/tt_pg_1v5_ll_4", ] extra_logo_macros = [ - "tech/ihp-sg13g2/tt_logo_corner", + "tech/ihp-sg13cmos5l/tt_logo_corner", ] prboundary_layer = (189, 4) # prBoundary.boundary - logo_layer = (67, 0) # Metal5.drawing - logo_layer_name = "Metal5" + logo_layer = (50, 0) # Metal4.drawing + logo_layer_name = "Metal4" logo_pixel_size = 0.25 # um def read_pdk_version(self, pdk_root: str) -> PDKVersionInfo: - pdk_sources_file = os.path.join(pdk_root, "ihp-sg13g2", "SOURCES") + pdk_sources_file = os.path.join(pdk_root, "ihp-sg13cmos5l", "SOURCES") return parse_openpdks_pdk_version(pdk_sources_file, "IHP-Open-PDK") def load_cell_definitions(self) -> Dict[str, CellDefinition]: - URL_FORMAT = "https://raw.githubusercontent.com/IHP-GmbH/IHP-Open-PDK/refs/heads/main/ihp-sg13g2/libs.ref/sg13g2_stdcell/doc/sg13g2_stdcell_typ_1p20V_25C.pdf#{ref}" + URL_FORMAT = "https://raw.githubusercontent.com/IHP-GmbH/IHP-Open-PDK/refs/heads/main/ihp-sg13cmos5l/libs.ref/sg13cmos5l_stdcell/doc/sg13cmos5l_stdcell_typ_1p20V_25C.pdf#{ref}" script_dir = os.path.dirname(os.path.realpath(__file__)) - with open(os.path.join(script_dir, "tech/ihp-sg13g2/cells.json")) as fh: + with open(os.path.join(script_dir, "tech/ihp-sg13cmos5l/cells.json")) as fh: cells = json.load(fh) for cell in cells.values(): cell["url"] = URL_FORMAT.format(ref=cell["doc_ref"]) @@ -277,7 +277,7 @@ class FpgaTech(Tech): tech_map: dict[TechName, Tech] = { - "ihp-sg13g2": IHPTech(), + "ihp-sg13cmos5l": IHPTech(), "gf180mcuD": GF180MCUDTech(), "sky130A": Sky130Tech(), "fpgaUp5k": FpgaTech(), diff --git a/tech/ihp-sg13g2/categories.json b/tech/ihp-sg13cmos5l/categories.json similarity index 100% rename from tech/ihp-sg13g2/categories.json rename to tech/ihp-sg13cmos5l/categories.json diff --git a/tech/ihp-sg13g2/cells.json b/tech/ihp-sg13cmos5l/cells.json similarity index 100% rename from tech/ihp-sg13g2/cells.json rename to tech/ihp-sg13cmos5l/cells.json diff --git a/tech/ihp-sg13g2/def/analog/magic_init_project.tcl b/tech/ihp-sg13cmos5l/def/analog/magic_init_project.tcl similarity index 96% rename from tech/ihp-sg13g2/def/analog/magic_init_project.tcl rename to tech/ihp-sg13cmos5l/def/analog/magic_init_project.tcl index 79e2469..229e6ef 100644 --- a/tech/ihp-sg13g2/def/analog/magic_init_project.tcl +++ b/tech/ihp-sg13cmos5l/def/analog/magic_init_project.tcl @@ -4,7 +4,7 @@ # Description: This script initializes a new Magic project for an analog design on Tiny Tapeout. # Important: before running this script, download the the .def file from -# https://raw.githubusercontent.com/TinyTapeout/tt-support-tools/main/tech/ihp-sg13g2/def/analog/tt_analog_1x2.def +# https://raw.githubusercontent.com/TinyTapeout/tt-support-tools/main/tech/ihp-sg13cmos5l/def/analog/tt_analog_1x2.def # Change the settings below to match your design: # ------------------------------------------------ diff --git a/tech/ihp-sg13g2/def/analog/tt_analog_1x2.def b/tech/ihp-sg13cmos5l/def/analog/tt_analog_1x2.def similarity index 98% rename from tech/ihp-sg13g2/def/analog/tt_analog_1x2.def rename to tech/ihp-sg13cmos5l/def/analog/tt_analog_1x2.def index 644bae7..7fec91e 100644 --- a/tech/ihp-sg13g2/def/analog/tt_analog_1x2.def +++ b/tech/ihp-sg13cmos5l/def/analog/tt_analog_1x2.def @@ -93,12 +93,8 @@ TRACKS X 480 DO 420 STEP 480 LAYER Metal3 ; TRACKS Y 420 DO 746 STEP 420 LAYER Metal3 ; TRACKS X 480 DO 420 STEP 480 LAYER Metal4 ; TRACKS Y 420 DO 746 STEP 420 LAYER Metal4 ; -TRACKS X 480 DO 420 STEP 480 LAYER Metal5 ; -TRACKS Y 420 DO 746 STEP 420 LAYER Metal5 ; TRACKS X 1640 DO 88 STEP 2280 LAYER TopMetal1 ; TRACKS Y 1640 DO 137 STEP 2280 LAYER TopMetal1 ; -TRACKS X 2000 DO 50 STEP 4000 LAYER TopMetal2 ; -TRACKS Y 2000 DO 78 STEP 4000 LAYER TopMetal2 ; COMPONENTS 0 ; END COMPONENTS PINS 51 ; diff --git a/tech/ihp-sg13g2/def/analog/tt_analog_2x2.def b/tech/ihp-sg13cmos5l/def/analog/tt_analog_2x2.def similarity index 98% rename from tech/ihp-sg13g2/def/analog/tt_analog_2x2.def rename to tech/ihp-sg13cmos5l/def/analog/tt_analog_2x2.def index 00978a9..20b4aa8 100644 --- a/tech/ihp-sg13g2/def/analog/tt_analog_2x2.def +++ b/tech/ihp-sg13cmos5l/def/analog/tt_analog_2x2.def @@ -93,12 +93,8 @@ TRACKS X 480 DO 873 STEP 480 LAYER Metal3 ; TRACKS Y 420 DO 746 STEP 420 LAYER Metal3 ; TRACKS X 480 DO 873 STEP 480 LAYER Metal4 ; TRACKS Y 420 DO 746 STEP 420 LAYER Metal4 ; -TRACKS X 480 DO 873 STEP 480 LAYER Metal5 ; -TRACKS Y 420 DO 746 STEP 420 LAYER Metal5 ; TRACKS X 1640 DO 183 STEP 2280 LAYER TopMetal1 ; TRACKS Y 1640 DO 137 STEP 2280 LAYER TopMetal1 ; -TRACKS X 2000 DO 105 STEP 4000 LAYER TopMetal2 ; -TRACKS Y 2000 DO 78 STEP 4000 LAYER TopMetal2 ; COMPONENTS 0 ; END COMPONENTS PINS 51 ; diff --git a/tech/ihp-sg13g2/def/tt_block_1x1_pgvdd.def b/tech/ihp-sg13cmos5l/def/tt_block_1x1_pgvdd.def similarity index 98% rename from tech/ihp-sg13g2/def/tt_block_1x1_pgvdd.def rename to tech/ihp-sg13cmos5l/def/tt_block_1x1_pgvdd.def index 3967277..81fad7b 100644 --- a/tech/ihp-sg13g2/def/tt_block_1x1_pgvdd.def +++ b/tech/ihp-sg13cmos5l/def/tt_block_1x1_pgvdd.def @@ -51,12 +51,8 @@ TRACKS X 480 DO 420 STEP 480 LAYER Metal3 ; TRACKS Y 420 DO 368 STEP 420 LAYER Metal3 ; TRACKS X 480 DO 420 STEP 480 LAYER Metal4 ; TRACKS Y 420 DO 368 STEP 420 LAYER Metal4 ; -TRACKS X 480 DO 420 STEP 480 LAYER Metal5 ; -TRACKS Y 420 DO 368 STEP 420 LAYER Metal5 ; TRACKS X 1640 DO 88 STEP 2280 LAYER TopMetal1 ; TRACKS Y 1640 DO 67 STEP 2280 LAYER TopMetal1 ; -TRACKS X 2000 DO 50 STEP 4000 LAYER TopMetal2 ; -TRACKS Y 2000 DO 38 STEP 4000 LAYER TopMetal2 ; COMPONENTS 0 ; END COMPONENTS PINS 43 ; diff --git a/tech/ihp-sg13g2/def/tt_block_1x2_pgvdd.def b/tech/ihp-sg13cmos5l/def/tt_block_1x2_pgvdd.def similarity index 98% rename from tech/ihp-sg13g2/def/tt_block_1x2_pgvdd.def rename to tech/ihp-sg13cmos5l/def/tt_block_1x2_pgvdd.def index fb21315..e239144 100644 --- a/tech/ihp-sg13g2/def/tt_block_1x2_pgvdd.def +++ b/tech/ihp-sg13cmos5l/def/tt_block_1x2_pgvdd.def @@ -93,12 +93,8 @@ TRACKS X 480 DO 420 STEP 480 LAYER Metal3 ; TRACKS Y 420 DO 746 STEP 420 LAYER Metal3 ; TRACKS X 480 DO 420 STEP 480 LAYER Metal4 ; TRACKS Y 420 DO 746 STEP 420 LAYER Metal4 ; -TRACKS X 480 DO 420 STEP 480 LAYER Metal5 ; -TRACKS Y 420 DO 746 STEP 420 LAYER Metal5 ; TRACKS X 1640 DO 88 STEP 2280 LAYER TopMetal1 ; TRACKS Y 1640 DO 137 STEP 2280 LAYER TopMetal1 ; -TRACKS X 2000 DO 50 STEP 4000 LAYER TopMetal2 ; -TRACKS Y 2000 DO 78 STEP 4000 LAYER TopMetal2 ; COMPONENTS 0 ; END COMPONENTS PINS 43 ; diff --git a/tech/ihp-sg13g2/def/tt_block_2x2_pgvdd.def b/tech/ihp-sg13cmos5l/def/tt_block_2x2_pgvdd.def similarity index 98% rename from tech/ihp-sg13g2/def/tt_block_2x2_pgvdd.def rename to tech/ihp-sg13cmos5l/def/tt_block_2x2_pgvdd.def index 6df20bd..52ba81a 100644 --- a/tech/ihp-sg13g2/def/tt_block_2x2_pgvdd.def +++ b/tech/ihp-sg13cmos5l/def/tt_block_2x2_pgvdd.def @@ -93,12 +93,8 @@ TRACKS X 480 DO 873 STEP 480 LAYER Metal3 ; TRACKS Y 420 DO 746 STEP 420 LAYER Metal3 ; TRACKS X 480 DO 873 STEP 480 LAYER Metal4 ; TRACKS Y 420 DO 746 STEP 420 LAYER Metal4 ; -TRACKS X 480 DO 873 STEP 480 LAYER Metal5 ; -TRACKS Y 420 DO 746 STEP 420 LAYER Metal5 ; TRACKS X 1640 DO 183 STEP 2280 LAYER TopMetal1 ; TRACKS Y 1640 DO 137 STEP 2280 LAYER TopMetal1 ; -TRACKS X 2000 DO 105 STEP 4000 LAYER TopMetal2 ; -TRACKS Y 2000 DO 78 STEP 4000 LAYER TopMetal2 ; COMPONENTS 0 ; END COMPONENTS PINS 43 ; diff --git a/tech/ihp-sg13g2/def/tt_block_3x2_pgvdd.def b/tech/ihp-sg13cmos5l/def/tt_block_3x2_pgvdd.def similarity index 98% rename from tech/ihp-sg13g2/def/tt_block_3x2_pgvdd.def rename to tech/ihp-sg13cmos5l/def/tt_block_3x2_pgvdd.def index 55e2b8b..ea16597 100644 --- a/tech/ihp-sg13g2/def/tt_block_3x2_pgvdd.def +++ b/tech/ihp-sg13cmos5l/def/tt_block_3x2_pgvdd.def @@ -93,12 +93,8 @@ TRACKS X 480 DO 1326 STEP 480 LAYER Metal3 ; TRACKS Y 420 DO 746 STEP 420 LAYER Metal3 ; TRACKS X 480 DO 1326 STEP 480 LAYER Metal4 ; TRACKS Y 420 DO 746 STEP 420 LAYER Metal4 ; -TRACKS X 480 DO 1326 STEP 480 LAYER Metal5 ; -TRACKS Y 420 DO 746 STEP 420 LAYER Metal5 ; TRACKS X 1640 DO 279 STEP 2280 LAYER TopMetal1 ; TRACKS Y 1640 DO 137 STEP 2280 LAYER TopMetal1 ; -TRACKS X 2000 DO 159 STEP 4000 LAYER TopMetal2 ; -TRACKS Y 2000 DO 78 STEP 4000 LAYER TopMetal2 ; COMPONENTS 0 ; END COMPONENTS PINS 43 ; diff --git a/tech/ihp-sg13g2/def/tt_block_3x4_pgvdd.def b/tech/ihp-sg13cmos5l/def/tt_block_3x4_pgvdd.def similarity index 99% rename from tech/ihp-sg13g2/def/tt_block_3x4_pgvdd.def rename to tech/ihp-sg13cmos5l/def/tt_block_3x4_pgvdd.def index 1581196..08c8ce9 100644 --- a/tech/ihp-sg13g2/def/tt_block_3x4_pgvdd.def +++ b/tech/ihp-sg13cmos5l/def/tt_block_3x4_pgvdd.def @@ -198,12 +198,8 @@ TRACKS X 480 DO 1326 STEP 480 LAYER Metal3 ; TRACKS Y 420 DO 1691 STEP 420 LAYER Metal3 ; TRACKS X 480 DO 1326 STEP 480 LAYER Metal4 ; TRACKS Y 420 DO 1691 STEP 420 LAYER Metal4 ; -TRACKS X 480 DO 1326 STEP 480 LAYER Metal5 ; -TRACKS Y 420 DO 1691 STEP 420 LAYER Metal5 ; TRACKS X 1640 DO 279 STEP 2280 LAYER TopMetal1 ; TRACKS Y 1640 DO 311 STEP 2280 LAYER TopMetal1 ; -TRACKS X 2000 DO 159 STEP 4000 LAYER TopMetal2 ; -TRACKS Y 2000 DO 177 STEP 4000 LAYER TopMetal2 ; COMPONENTS 0 ; END COMPONENTS PINS 43 ; diff --git a/tech/ihp-sg13g2/def/tt_block_4x2_pgvdd.def b/tech/ihp-sg13cmos5l/def/tt_block_4x2_pgvdd.def similarity index 98% rename from tech/ihp-sg13g2/def/tt_block_4x2_pgvdd.def rename to tech/ihp-sg13cmos5l/def/tt_block_4x2_pgvdd.def index 705f0b6..4667dd5 100644 --- a/tech/ihp-sg13g2/def/tt_block_4x2_pgvdd.def +++ b/tech/ihp-sg13cmos5l/def/tt_block_4x2_pgvdd.def @@ -93,12 +93,8 @@ TRACKS X 480 DO 1779 STEP 480 LAYER Metal3 ; TRACKS Y 420 DO 746 STEP 420 LAYER Metal3 ; TRACKS X 480 DO 1779 STEP 480 LAYER Metal4 ; TRACKS Y 420 DO 746 STEP 420 LAYER Metal4 ; -TRACKS X 480 DO 1779 STEP 480 LAYER Metal5 ; -TRACKS Y 420 DO 746 STEP 420 LAYER Metal5 ; TRACKS X 1640 DO 374 STEP 2280 LAYER TopMetal1 ; TRACKS Y 1640 DO 137 STEP 2280 LAYER TopMetal1 ; -TRACKS X 2000 DO 213 STEP 4000 LAYER TopMetal2 ; -TRACKS Y 2000 DO 78 STEP 4000 LAYER TopMetal2 ; COMPONENTS 0 ; END COMPONENTS PINS 43 ; diff --git a/tech/ihp-sg13g2/def/tt_block_4x4_pgvdd.def b/tech/ihp-sg13cmos5l/def/tt_block_4x4_pgvdd.def similarity index 99% rename from tech/ihp-sg13g2/def/tt_block_4x4_pgvdd.def rename to tech/ihp-sg13cmos5l/def/tt_block_4x4_pgvdd.def index f9c3e23..04e582c 100644 --- a/tech/ihp-sg13g2/def/tt_block_4x4_pgvdd.def +++ b/tech/ihp-sg13cmos5l/def/tt_block_4x4_pgvdd.def @@ -198,12 +198,8 @@ TRACKS X 480 DO 1779 STEP 480 LAYER Metal3 ; TRACKS Y 420 DO 1691 STEP 420 LAYER Metal3 ; TRACKS X 480 DO 1779 STEP 480 LAYER Metal4 ; TRACKS Y 420 DO 1691 STEP 420 LAYER Metal4 ; -TRACKS X 480 DO 1779 STEP 480 LAYER Metal5 ; -TRACKS Y 420 DO 1691 STEP 420 LAYER Metal5 ; TRACKS X 1640 DO 374 STEP 2280 LAYER TopMetal1 ; TRACKS Y 1640 DO 311 STEP 2280 LAYER TopMetal1 ; -TRACKS X 2000 DO 213 STEP 4000 LAYER TopMetal2 ; -TRACKS Y 2000 DO 177 STEP 4000 LAYER TopMetal2 ; COMPONENTS 0 ; END COMPONENTS PINS 43 ; diff --git a/tech/ihp-sg13g2/def/tt_block_5x4_pgvdd.def b/tech/ihp-sg13cmos5l/def/tt_block_5x4_pgvdd.def similarity index 99% rename from tech/ihp-sg13g2/def/tt_block_5x4_pgvdd.def rename to tech/ihp-sg13cmos5l/def/tt_block_5x4_pgvdd.def index b20e884..8fa7914 100644 --- a/tech/ihp-sg13g2/def/tt_block_5x4_pgvdd.def +++ b/tech/ihp-sg13cmos5l/def/tt_block_5x4_pgvdd.def @@ -198,12 +198,8 @@ TRACKS X 480 DO 2232 STEP 480 LAYER Metal3 ; TRACKS Y 420 DO 1691 STEP 420 LAYER Metal3 ; TRACKS X 480 DO 2232 STEP 480 LAYER Metal4 ; TRACKS Y 420 DO 1691 STEP 420 LAYER Metal4 ; -TRACKS X 480 DO 2232 STEP 480 LAYER Metal5 ; -TRACKS Y 420 DO 1691 STEP 420 LAYER Metal5 ; TRACKS X 1640 DO 470 STEP 2280 LAYER TopMetal1 ; TRACKS Y 1640 DO 311 STEP 2280 LAYER TopMetal1 ; -TRACKS X 2000 DO 268 STEP 4000 LAYER TopMetal2 ; -TRACKS Y 2000 DO 177 STEP 4000 LAYER TopMetal2 ; COMPONENTS 0 ; END COMPONENTS PINS 43 ; diff --git a/tech/ihp-sg13g2/def/tt_block_6x2_pgvdd.def b/tech/ihp-sg13cmos5l/def/tt_block_6x2_pgvdd.def similarity index 98% rename from tech/ihp-sg13g2/def/tt_block_6x2_pgvdd.def rename to tech/ihp-sg13cmos5l/def/tt_block_6x2_pgvdd.def index 180d549..4bcbe78 100644 --- a/tech/ihp-sg13g2/def/tt_block_6x2_pgvdd.def +++ b/tech/ihp-sg13cmos5l/def/tt_block_6x2_pgvdd.def @@ -93,12 +93,8 @@ TRACKS X 480 DO 2685 STEP 480 LAYER Metal3 ; TRACKS Y 420 DO 746 STEP 420 LAYER Metal3 ; TRACKS X 480 DO 2685 STEP 480 LAYER Metal4 ; TRACKS Y 420 DO 746 STEP 420 LAYER Metal4 ; -TRACKS X 480 DO 2685 STEP 480 LAYER Metal5 ; -TRACKS Y 420 DO 746 STEP 420 LAYER Metal5 ; TRACKS X 1640 DO 565 STEP 2280 LAYER TopMetal1 ; TRACKS Y 1640 DO 137 STEP 2280 LAYER TopMetal1 ; -TRACKS X 2000 DO 322 STEP 4000 LAYER TopMetal2 ; -TRACKS Y 2000 DO 78 STEP 4000 LAYER TopMetal2 ; COMPONENTS 0 ; END COMPONENTS PINS 43 ; diff --git a/tech/ihp-sg13g2/def/tt_block_6x4_pgvdd.def b/tech/ihp-sg13cmos5l/def/tt_block_6x4_pgvdd.def similarity index 99% rename from tech/ihp-sg13g2/def/tt_block_6x4_pgvdd.def rename to tech/ihp-sg13cmos5l/def/tt_block_6x4_pgvdd.def index 02b2824..26dde1e 100644 --- a/tech/ihp-sg13g2/def/tt_block_6x4_pgvdd.def +++ b/tech/ihp-sg13cmos5l/def/tt_block_6x4_pgvdd.def @@ -198,12 +198,8 @@ TRACKS X 480 DO 2685 STEP 480 LAYER Metal3 ; TRACKS Y 420 DO 1691 STEP 420 LAYER Metal3 ; TRACKS X 480 DO 2685 STEP 480 LAYER Metal4 ; TRACKS Y 420 DO 1691 STEP 420 LAYER Metal4 ; -TRACKS X 480 DO 2685 STEP 480 LAYER Metal5 ; -TRACKS Y 420 DO 1691 STEP 420 LAYER Metal5 ; TRACKS X 1640 DO 565 STEP 2280 LAYER TopMetal1 ; TRACKS Y 1640 DO 311 STEP 2280 LAYER TopMetal1 ; -TRACKS X 2000 DO 322 STEP 4000 LAYER TopMetal2 ; -TRACKS Y 2000 DO 177 STEP 4000 LAYER TopMetal2 ; COMPONENTS 0 ; END COMPONENTS PINS 43 ; diff --git a/tech/ihp-sg13g2/def/tt_block_8x2_pgvdd.def b/tech/ihp-sg13cmos5l/def/tt_block_8x2_pgvdd.def similarity index 98% rename from tech/ihp-sg13g2/def/tt_block_8x2_pgvdd.def rename to tech/ihp-sg13cmos5l/def/tt_block_8x2_pgvdd.def index 6037869..1b8ccee 100644 --- a/tech/ihp-sg13g2/def/tt_block_8x2_pgvdd.def +++ b/tech/ihp-sg13cmos5l/def/tt_block_8x2_pgvdd.def @@ -93,12 +93,8 @@ TRACKS X 480 DO 3591 STEP 480 LAYER Metal3 ; TRACKS Y 420 DO 746 STEP 420 LAYER Metal3 ; TRACKS X 480 DO 3591 STEP 480 LAYER Metal4 ; TRACKS Y 420 DO 746 STEP 420 LAYER Metal4 ; -TRACKS X 480 DO 3591 STEP 480 LAYER Metal5 ; -TRACKS Y 420 DO 746 STEP 420 LAYER Metal5 ; TRACKS X 1640 DO 756 STEP 2280 LAYER TopMetal1 ; TRACKS Y 1640 DO 137 STEP 2280 LAYER TopMetal1 ; -TRACKS X 2000 DO 431 STEP 4000 LAYER TopMetal2 ; -TRACKS Y 2000 DO 78 STEP 4000 LAYER TopMetal2 ; COMPONENTS 0 ; END COMPONENTS PINS 43 ; diff --git a/tech/ihp-sg13g2/tile_sizes.yaml b/tech/ihp-sg13cmos5l/tile_sizes.yaml similarity index 100% rename from tech/ihp-sg13g2/tile_sizes.yaml rename to tech/ihp-sg13cmos5l/tile_sizes.yaml diff --git a/tech/ihp-sg13cmos5l/tt_logo_corner.gds b/tech/ihp-sg13cmos5l/tt_logo_corner.gds new file mode 100644 index 0000000000000000000000000000000000000000..8584ca62eb7fa7796b53174a838d2be90c1897ff GIT binary patch literal 16638 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