mirror of
https://github.com/TinyTapeout/tt-support-tools.git
synced 2026-11-03 04:36:09 +01:00
feat(precheck): initial gf180mcuD support
This commit is contained in:
@@ -10,7 +10,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
env:
|
env:
|
||||||
PDK_ROOT: /home/runner/pdk
|
PDK_ROOT: /home/runner/pdk
|
||||||
PDK_VERSION: dd7771c384ed36b91a25e9f8b314355fc26561be
|
PDK_VERSION: d56f8a8ea0f9171cbdc5273035907b93f3f3bed7
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Check out code
|
- name: Check out code
|
||||||
|
|||||||
+51
-14
@@ -28,20 +28,57 @@ def parse_lyp_layers(lyp_file: str, only_valid: bool = True):
|
|||||||
if only_valid and valid is not None and valid.text == "false":
|
if only_valid and valid is not None and valid.text == "false":
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if (
|
if name is None or name.text is None:
|
||||||
name is not None
|
name = None
|
||||||
and name.text is not None
|
else:
|
||||||
and source is not None
|
name = name.text
|
||||||
and source.text is not None
|
|
||||||
):
|
if source is None or source.text is None:
|
||||||
name_key = name.text.split("-")[0].strip()
|
continue
|
||||||
layer, data_type = source.text.split("@")[0].split("/")
|
|
||||||
# Add the 'source' text as the value in the dictionary
|
source = source.text
|
||||||
layers_dict[name_key] = LayerInfo(
|
|
||||||
name=name.text,
|
name_orig = name
|
||||||
source=source.text,
|
source_orig = source
|
||||||
layer=int(layer),
|
|
||||||
data_type=int(data_type),
|
# for more details on the source field, see
|
||||||
|
# https://www.klayout.de/doc/about/layer_sources.html
|
||||||
|
# and klayout's src/laybasic/laybasic/layParsedLayerSource.cc
|
||||||
|
|
||||||
|
if "@" in source:
|
||||||
|
assert source.count("@") == 1
|
||||||
|
source, layout_index = source.split("@")
|
||||||
|
assert layout_index.isnumeric()
|
||||||
|
if layout_index != "1":
|
||||||
|
continue
|
||||||
|
|
||||||
|
if " " in source:
|
||||||
|
assert source.count(" ") == 1
|
||||||
|
# sky130A and sg13g2 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
|
||||||
|
assert name is None
|
||||||
|
name, source = source.split(" ")
|
||||||
|
|
||||||
|
if name is None:
|
||||||
|
name = source
|
||||||
|
|
||||||
|
# the source field can have further transformations & filters,
|
||||||
|
# but so far none of the PDKs use them, so we are ignoring them
|
||||||
|
|
||||||
|
layer, data_type = source.split("/")
|
||||||
|
assert layer.isnumeric()
|
||||||
|
assert data_type.isnumeric()
|
||||||
|
layer = int(layer)
|
||||||
|
data_type = int(data_type)
|
||||||
|
|
||||||
|
# sky130A includes an extra copy of layer & data_type
|
||||||
|
# as part of the name, let's remove that
|
||||||
|
name = name.split(" - ")[0]
|
||||||
|
|
||||||
|
layers_dict[name] = LayerInfo(
|
||||||
|
name=name_orig, source=source_orig, layer=layer, data_type=data_type
|
||||||
)
|
)
|
||||||
|
|
||||||
return layers_dict
|
return layers_dict
|
||||||
|
|||||||
+11
-3
@@ -112,6 +112,7 @@ def pin_check(
|
|||||||
# parse pins from template def
|
# parse pins from template def
|
||||||
# def syntax: https://coriolis.lip6.fr/doc/lefdef/lefdefref/DEFSyntax.html
|
# def syntax: https://coriolis.lip6.fr/doc/lefdef/lefdefref/DEFSyntax.html
|
||||||
|
|
||||||
|
units_re = re.compile(r"UNITS DISTANCE MICRONS (\S+) ;")
|
||||||
diearea_re = re.compile(r"DIEAREA \( (\S+) (\S+) \) \( (\S+) (\S+) \) ;")
|
diearea_re = re.compile(r"DIEAREA \( (\S+) (\S+) \) \( (\S+) (\S+) \) ;")
|
||||||
pins_re = re.compile(r"PINS (\d+) ;")
|
pins_re = re.compile(r"PINS (\d+) ;")
|
||||||
pin_re = re.compile(r" *- (\S+) \+ NET (\S+) \+ DIRECTION (\S+) \+ USE (\S+)")
|
pin_re = re.compile(r" *- (\S+) \+ NET (\S+) \+ DIRECTION (\S+) \+ USE (\S+)")
|
||||||
@@ -119,20 +120,27 @@ def pin_check(
|
|||||||
placed_re = re.compile(r" *\+ PLACED \( (\S+) (\S+) \) (\S+) ;")
|
placed_re = re.compile(r" *\+ PLACED \( (\S+) (\S+) \) (\S+) ;")
|
||||||
|
|
||||||
def_pins = {}
|
def_pins = {}
|
||||||
|
dbu_per_micron = 0
|
||||||
die_width = 0
|
die_width = 0
|
||||||
die_height = 0
|
die_height = 0
|
||||||
|
|
||||||
with open(template_def) as f:
|
with open(template_def) as f:
|
||||||
for line in f:
|
for line in f:
|
||||||
if line.startswith("DIEAREA "):
|
if line.startswith("UNITS "):
|
||||||
|
match = units_re.match(line)
|
||||||
|
(dbu_per_micron,) = map(int, match.groups())
|
||||||
|
elif line.startswith("DIEAREA "):
|
||||||
match = diearea_re.match(line)
|
match = diearea_re.match(line)
|
||||||
lx, by, rx, ty = map(int, match.groups())
|
lx, by, rx, ty = map(int, match.groups())
|
||||||
if (lx, by) != (0, 0):
|
if (lx, by) != (0, 0):
|
||||||
raise PrecheckFailure(
|
raise PrecheckFailure(
|
||||||
"Wrong die origin in template DEF, expecting (0, 0)"
|
"Wrong die origin in template DEF, expecting (0, 0)"
|
||||||
)
|
)
|
||||||
die_width = rx
|
assert dbu_per_micron != 0
|
||||||
die_height = ty
|
assert (rx * 1000) % dbu_per_micron == 0
|
||||||
|
assert (ty * 1000) % dbu_per_micron == 0
|
||||||
|
die_width = (rx * 1000) // dbu_per_micron
|
||||||
|
die_height = (ty * 1000) // dbu_per_micron
|
||||||
elif line.startswith("PINS "):
|
elif line.startswith("PINS "):
|
||||||
match = pins_re.match(line)
|
match = pins_re.match(line)
|
||||||
pin_count = int(match.group(1))
|
pin_count = int(match.group(1))
|
||||||
|
|||||||
+17
-14
@@ -19,6 +19,7 @@ from pin_check import pin_check
|
|||||||
from precheck_failure import PrecheckFailure
|
from precheck_failure import PrecheckFailure
|
||||||
from tech_data import (
|
from tech_data import (
|
||||||
analog_pin_pos,
|
analog_pin_pos,
|
||||||
|
boundary_layer,
|
||||||
forbidden_layers,
|
forbidden_layers,
|
||||||
layer_map,
|
layer_map,
|
||||||
lyp_filename,
|
lyp_filename,
|
||||||
@@ -128,13 +129,12 @@ def klayout_checks(gds: str, expected_name: str, tech: str):
|
|||||||
raise PrecheckFailure(f"Forbidden layer {layer} found in {gds}")
|
raise PrecheckFailure(f"Forbidden layer {layer} found in {gds}")
|
||||||
|
|
||||||
logging.info("Running prBoundary check...")
|
logging.info("Running prBoundary check...")
|
||||||
layer_info = layers["prBoundary.boundary"]
|
layer_name = boundary_layer[tech]
|
||||||
|
layer_info = layers[layer_name]
|
||||||
layer_index = layout.find_layer(layer_info.layer, layer_info.data_type)
|
layer_index = layout.find_layer(layer_info.layer, layer_info.data_type)
|
||||||
if layer_index is None:
|
if layer_index is None:
|
||||||
calma_index = f"{layer_info.layer}/{layer_info.data_type}"
|
calma_index = f"{layer_info.layer}/{layer_info.data_type}"
|
||||||
raise PrecheckFailure(
|
raise PrecheckFailure(f"{layer_name} ({calma_index}) layer not found in {gds}")
|
||||||
f"prBoundary.boundary ({calma_index}) layer not found in {gds}"
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def boundary_check(gds: str, tech: str):
|
def boundary_check(gds: str, tech: str):
|
||||||
@@ -147,7 +147,8 @@ def boundary_check(gds: str, tech: str):
|
|||||||
boundary = top.copy("test_boundary")
|
boundary = top.copy("test_boundary")
|
||||||
|
|
||||||
layers = load_layers(tech)
|
layers = load_layers(tech)
|
||||||
layer_info = layers["prBoundary.boundary"]
|
layer_name = boundary_layer[tech]
|
||||||
|
layer_info = layers[layer_name]
|
||||||
boundary.filter([(layer_info.layer, layer_info.data_type)], False)
|
boundary.filter([(layer_info.layer, layer_info.data_type)], False)
|
||||||
if top.bounding_box() != boundary.bounding_box():
|
if top.bounding_box() != boundary.bounding_box():
|
||||||
raise PrecheckFailure("Shapes outside project area")
|
raise PrecheckFailure("Shapes outside project area")
|
||||||
@@ -300,7 +301,7 @@ def main():
|
|||||||
yaml_dir = os.path.dirname(args.gds)
|
yaml_dir = os.path.dirname(args.gds)
|
||||||
while not os.path.exists(f"{yaml_dir}/info.yaml"):
|
while not os.path.exists(f"{yaml_dir}/info.yaml"):
|
||||||
yaml_dir = os.path.dirname(yaml_dir)
|
yaml_dir = os.path.dirname(yaml_dir)
|
||||||
if yaml_dir == "/":
|
if yaml_dir in ("/", ""):
|
||||||
raise PrecheckFailure("info.yaml not found")
|
raise PrecheckFailure("info.yaml not found")
|
||||||
yaml_file = f"{yaml_dir}/info.yaml"
|
yaml_file = f"{yaml_dir}/info.yaml"
|
||||||
yaml_data = yaml.safe_load(open(yaml_file))
|
yaml_data = yaml.safe_load(open(yaml_file))
|
||||||
@@ -323,7 +324,7 @@ def main():
|
|||||||
template_def = f"{def_root}/analog/tt_analog_{tiles}_3v3.def"
|
template_def = f"{def_root}/analog/tt_analog_{tiles}_3v3.def"
|
||||||
else:
|
else:
|
||||||
template_def = f"{def_root}/analog/tt_analog_{tiles}.def"
|
template_def = f"{def_root}/analog/tt_analog_{tiles}.def"
|
||||||
elif tech == "ihp-sg13g2":
|
elif tech == "ihp-sg13g2" or tech == "gf180mcuD":
|
||||||
template_def = f"{def_root}/tt_block_{tiles}_pgvdd.def"
|
template_def = f"{def_root}/tt_block_{tiles}_pgvdd.def"
|
||||||
else:
|
else:
|
||||||
template_def = f"{def_root}/tt_block_{tiles}_pg.def"
|
template_def = f"{def_root}/tt_block_{tiles}_pg.def"
|
||||||
@@ -336,22 +337,22 @@ def main():
|
|||||||
{
|
{
|
||||||
"name": "Magic DRC",
|
"name": "Magic DRC",
|
||||||
"check": lambda: magic_drc(gds_file, top_module),
|
"check": lambda: magic_drc(gds_file, top_module),
|
||||||
"tech": "sky130A",
|
"techs": ["sky130A"],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "KLayout FEOL",
|
"name": "KLayout FEOL",
|
||||||
"check": lambda: klayout_drc(gds_file, "feol"),
|
"check": lambda: klayout_drc(gds_file, "feol"),
|
||||||
"tech": "sky130A",
|
"techs": ["sky130A"],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "KLayout BEOL",
|
"name": "KLayout BEOL",
|
||||||
"check": lambda: klayout_drc(gds_file, "beol"),
|
"check": lambda: klayout_drc(gds_file, "beol"),
|
||||||
"tech": "sky130A",
|
"techs": ["sky130A"],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "KLayout offgrid",
|
"name": "KLayout offgrid",
|
||||||
"check": lambda: klayout_drc(gds_file, "offgrid"),
|
"check": lambda: klayout_drc(gds_file, "offgrid"),
|
||||||
"tech": "sky130A",
|
"techs": ["sky130A"],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "KLayout pin label overlapping drawing",
|
"name": "KLayout pin label overlapping drawing",
|
||||||
@@ -364,7 +365,7 @@ def main():
|
|||||||
{
|
{
|
||||||
"name": "KLayout SG13G2 DRC",
|
"name": "KLayout SG13G2 DRC",
|
||||||
"check": lambda: klayout_sg13g2(gds_file),
|
"check": lambda: klayout_sg13g2(gds_file),
|
||||||
"tech": "ihp-sg13g2",
|
"techs": ["ihp-sg13g2"],
|
||||||
},
|
},
|
||||||
{"name": "KLayout zero area", "check": lambda: klayout_zero_area(gds_file)},
|
{"name": "KLayout zero area", "check": lambda: klayout_zero_area(gds_file)},
|
||||||
{
|
{
|
||||||
@@ -376,18 +377,20 @@ def main():
|
|||||||
"check": lambda: pin_check(
|
"check": lambda: pin_check(
|
||||||
gds_file, lef_file, template_def, top_module, uses_3v3, tech
|
gds_file, lef_file, template_def, top_module, uses_3v3, tech
|
||||||
),
|
),
|
||||||
|
"techs": ["sky130A", "ihp-sg13g2"],
|
||||||
},
|
},
|
||||||
{"name": "Boundary check", "check": lambda: boundary_check(gds_file, tech)},
|
{"name": "Boundary check", "check": lambda: boundary_check(gds_file, tech)},
|
||||||
{
|
{
|
||||||
"name": "Power pin check",
|
"name": "Power pin check",
|
||||||
"check": lambda: power_pin_check(verilog_file, lef_file, uses_3v3),
|
"check": lambda: power_pin_check(verilog_file, lef_file, uses_3v3),
|
||||||
"tech": "sky130A",
|
"techs": ["sky130A", "gf180mcuD"],
|
||||||
},
|
},
|
||||||
{"name": "Layer check", "check": lambda: layer_check(gds_file, tech)},
|
{"name": "Layer check", "check": lambda: layer_check(gds_file, tech)},
|
||||||
{"name": "Cell name check", "check": lambda: cell_name_check(gds_file)},
|
{"name": "Cell name check", "check": lambda: cell_name_check(gds_file)},
|
||||||
{
|
{
|
||||||
"name": "urpm/nwell check",
|
"name": "urpm/nwell check",
|
||||||
"check": lambda: urpm_nwell_check(gds_file, top_module),
|
"check": lambda: urpm_nwell_check(gds_file, top_module),
|
||||||
|
"techs": ["sky130A"],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Analog pin check",
|
"name": "Analog pin check",
|
||||||
@@ -403,7 +406,7 @@ def main():
|
|||||||
markdown_table += "| Check | Result |\n|-----------|--------|\n"
|
markdown_table += "| Check | Result |\n|-----------|--------|\n"
|
||||||
for check in checks:
|
for check in checks:
|
||||||
name = check["name"]
|
name = check["name"]
|
||||||
if "tech" in check and check["tech"] != tech:
|
if "techs" in check and tech not in check["techs"]:
|
||||||
continue
|
continue
|
||||||
start_time = time.time()
|
start_time = time.time()
|
||||||
test_case = ET.SubElement(testsuite, "testcase", name=name)
|
test_case = ET.SubElement(testsuite, "testcase", name=name)
|
||||||
|
|||||||
+114
-175
@@ -1,180 +1,97 @@
|
|||||||
# fmt: off
|
# fmt: off
|
||||||
valid_layers_sky130A = {
|
valid_layers_sky130A = [
|
||||||
(10, 0), (11, 0), (11, 20), (11, 44), (17, 0), (18, 20), (20, 0), (21, 0),
|
'cldntm.mask', 'ldntm.drawing', 'cncm.mask', 'ctunm.mask', 'cnwm.mask', 'cnsm.mask', 'cfom.drawing', 'cfom.maskAdd',
|
||||||
(22, 0), (22, 20), (22, 21), (22, 22), (22, 23), (22, 24), (23, 0), (23, 28),
|
'cfom.maskDrop', 'cfom.waffleDrop', 'cfom.mask', 'cfom.fill', 'clvtnm.mask', 'cntm.drawing', 'cntm.mask', 'cp1m.mask',
|
||||||
(25, 0), (25, 42), (25, 43), (25, 44), (26, 20), (26, 21), (26, 22), (27, 0),
|
'cp1m.fill', 'cnsdm.drawing', 'cnsdm.maskAdd', 'cnsdm.maskDrop', 'cnsdm.mask', 'cpsdm.drawing', 'cpsdm.maskAdd',
|
||||||
(28, 0), (28, 28), (29, 20), (29, 21), (29, 22), (30, 0), (31, 20), (31, 21),
|
'cpsdm.maskDrop', 'cpsdm.mask', 'cp1m.waffleDrop', 'cp1m.maskDrop', 'cp1m.maskAdd', 'cmm3.mask', 'cmm3.fill',
|
||||||
(31, 22), (32, 0), (33, 24), (33, 42), (33, 43), (33, 44), (34, 0), (34, 28),
|
'cctm1.mask', 'cmm1.mask', 'cmm1.fill', 'cpdm.mask', 'chvntm.drawing', 'chvntm.mask', 'cviam.mask', 'cmm2.mask',
|
||||||
(35, 0), (36, 0), (36, 28), (37, 0), (38, 20), (38, 21), (38, 22), (39, 0),
|
'cmm2.fill', 'clicm1.mask', 'cviam2.mask', 'pwelliso.label', 'pwelliso.pin', 'cnpc.drawing', 'clvom.drawing',
|
||||||
(40, 0), (41, 0), (41, 28), (43, 0), (44, 0), (44, 5), (44, 16), (44, 20),
|
'clvom.mask', 'cdnm.mask', 'cnpc.mask', 'cviam3.mask', 'cmm4.mask', 'cmm4.fill', 'crpm.maskDrop', 'crpm.maskAdd',
|
||||||
(44, 42), (44, 43), (45, 20), (45, 21), (45, 22), (46, 0), (48, 0), (49, 0),
|
'crpm.drawing', 'cli1m.mask', 'cli1m.fill', 'cviam4.mask', 'cmm5.mask', 'cmm5.fill', 'nsm.drawing', 'cmm1.waffleDrop',
|
||||||
(50, 0), (51, 0), (51, 28), (53, 42), (53, 43), (53, 44), (56, 0), (56, 28),
|
'nwell.label', 'pwell.res', 'pwell.cut', 'nwell.pin', 'dnwell.drawing', 'nwell.drawing', 'pwell.drawing', 'pwell.label',
|
||||||
(58, 0), (59, 0), (59, 28), (61, 20), (62, 20), (62, 21), (62, 22), (62, 24),
|
'diff.hv', 'diff.res', 'diff.cut', 'diff.drawing', 'tap.drawing', 'poly.boundary', 'poly.label', 'poly.gate',
|
||||||
(64, 5), (64, 13), (64, 14), (64, 16), (64, 18), (64, 20), (64, 44), (64, 59),
|
'poly.res', 'poly.cut', 'poly.short', 'poly.pin', 'poly.drawing', 'poly.net', 'poly.probe', 'licon1.net',
|
||||||
(65, 4), (65, 5), (65, 6), (65, 8), (65, 13), (65, 14), (65, 16), (65, 20),
|
'licon1.drawing', 'licon1.boundary', 'poly.model', 'li1.boundary', 'li1.label', 'li1.blockage', 'li1.short', 'li1.pin',
|
||||||
(65, 23), (65, 41), (65, 44), (65, 48), (65, 60), (66, 4), (66, 5), (66, 9),
|
'li1.drawing', 'li1.net', 'li1.probe', 'mcon.net', 'mcon.drawing', 'mcon.boundary', 'met1.boundary', 'met1.label',
|
||||||
(66, 13), (66, 14), (66, 15), (66, 16), (66, 20), (66, 23), (66, 25), (66, 41),
|
'met1.blockage', 'met1.short', 'met1.pin', 'met1.drawing', 'met1.net', 'met1.probe', 'via.net', 'via.drawing',
|
||||||
(66, 44), (66, 58), (66, 60), (66, 83), (67, 4), (67, 5), (67, 10), (67, 13),
|
'via.boundary', 'met1.psa1', 'met1.psa2', 'met1.psa3', 'met1.psa4', 'met1.psa5', 'met1.psa6', 'met2.boundary',
|
||||||
(67, 14), (67, 15), (67, 16), (67, 20), (67, 23), (67, 25), (67, 41), (67, 44),
|
'met2.label', 'met2.blockage', 'met2.short', 'met2.pin', 'met2.drawing', 'met2.net', 'met2.probe', 'via2.net',
|
||||||
(67, 48), (67, 60), (68, 4), (68, 5), (68, 10), (68, 13), (68, 14), (68, 15),
|
'via2.drawing', 'via2.boundary', 'met2.psa1', 'met2.psa2', 'met2.psa3', 'met2.psa4', 'met2.psa5', 'met2.psa6',
|
||||||
(68, 16), (68, 20), (68, 23), (68, 25), (68, 32), (68, 33), (68, 34), (68, 35),
|
'met3.boundary', 'met3.label', 'met3.blockage', 'met3.short', 'met3.pin', 'met3.drawing', 'met3.net', 'met3.probe',
|
||||||
(68, 36), (68, 37), (68, 38), (68, 39), (68, 41), (68, 44), (68, 48), (68, 58),
|
'via3.net', 'via3.drawing', 'via3.boundary', 'met3.psa1', 'met3.psa2', 'met3.psa3', 'met3.psa4', 'met3.psa5',
|
||||||
(68, 60), (68, 88), (68, 89), (68, 90), (68, 91), (68, 92), (68, 93), (69, 4),
|
'met3.psa6', 'met4.boundary', 'met4.label', 'met4.blockage', 'met4.short', 'met4.pin', 'met4.drawing', 'met4.net',
|
||||||
(69, 5), (69, 10), (69, 13), (69, 14), (69, 15), (69, 16), (69, 20), (69, 23),
|
'met4.probe', 'via4.net', 'via4.drawing', 'via4.boundary', 'met4.psa1', 'met4.psa2', 'met4.psa3', 'met4.psa4',
|
||||||
(69, 25), (69, 32), (69, 33), (69, 34), (69, 35), (69, 36), (69, 37), (69, 38),
|
'met4.psa5', 'met4.psa6', 'met5.boundary', 'met5.label', 'met5.blockage', 'met5.short', 'met5.pin', 'met5.drawing',
|
||||||
(69, 39), (69, 41), (69, 44), (69, 48), (69, 58), (69, 60), (69, 88), (69, 89),
|
'met5.net', 'met5.probe', 'met5.psa1', 'met5.psa2', 'met5.psa3', 'met5.psa4', 'met5.psa5', 'met5.psa6', 'rdl.label',
|
||||||
(69, 90), (69, 91), (69, 92), (69, 93), (70, 4), (70, 5), (70, 10), (70, 13),
|
'rdl.res', 'rdl.cut', 'rdl.pin', 'rdl.drawing', 'vhvi.drawing', 'v20.drawing', 'rdl.psa1', 'rdl.psa2', 'rdl.psa3',
|
||||||
(70, 14), (70, 15), (70, 16), (70, 17), (70, 20), (70, 23), (70, 25), (70, 32),
|
'rdl.psa4', 'rdl.psa5', 'rdl.psa6', 'hvi.drawing', 'pad.label', 'pad.pin', 'pad.drawing', 'target.drawing',
|
||||||
(70, 33), (70, 34), (70, 35), (70, 36), (70, 37), (70, 38), (70, 39), (70, 41),
|
'pmm2.drawing', 'hvtp.drawing', 'urpm', 'tunm.drawing', 'areaid.seal', 'areaid.core', 'areaid.frame',
|
||||||
(70, 44), (70, 48), (70, 60), (70, 88), (70, 89), (70, 90), (70, 91), (70, 92),
|
'areaid.standardc', 'areaid.sigPadDiff', 'areaid.sigPadWell', 'areaid.sigPadMetNtr', 'areaid.moduleCut',
|
||||||
(70, 93), (71, 4), (71, 5), (71, 10), (71, 13), (71, 14), (71, 15), (71, 16),
|
'areaid.dieCut', 'areaid.frameRect', 'areaid.waffleWindow', 'areaid.lowTapDensity', 'areaid.notCritSide',
|
||||||
(71, 17), (71, 20), (71, 23), (71, 25), (71, 32), (71, 33), (71, 34), (71, 35),
|
'areaid.injection', 'areaid.esd', 'padCenter.drawing', 'areaid.diode', 'areaid.rdlprobepad', 'areaid.deadZon',
|
||||||
(71, 36), (71, 37), (71, 38), (71, 39), (71, 41), (71, 44), (71, 48), (71, 60),
|
'areaid.critCorner', 'areaid.critSid', 'areaid.substrateCut', 'areaid.opcDrop', 'areaid.extendedDrain',
|
||||||
(71, 88), (71, 89), (71, 90), (71, 91), (71, 92), (71, 93), (72, 4), (72, 5),
|
'areaid.lvNative', 'areaid.hvnwell', 'areaid.analog', 'areaid.photo', 'areaid.etest', 'areaid.rfdiode', 'npn.label',
|
||||||
(72, 10), (72, 13), (72, 14), (72, 15), (72, 16), (72, 17), (72, 20), (72, 23),
|
'npn.drawing', 'inductor.drawing', 'inductor.label', 'inductor.term1', 'inductor.term2', 'inductor.term3',
|
||||||
(72, 25), (72, 32), (72, 33), (72, 34), (72, 35), (72, 36), (72, 37), (72, 38),
|
'pnp.drawing', 'pnp.label', 'capacitor.drawing', 'text.drawing', 'nwell.net', 'prune.drawing', 'pmm.drawing',
|
||||||
(72, 39), (72, 88), (72, 89), (72, 90), (72, 91), (72, 92), (72, 93), (74, 5),
|
'rpm.drawing', 'conom.maskDrop', 'conom.maskAdd', 'conom.drawing', 'conom.mask', 'capm.drawing', 'overlap.boundary',
|
||||||
(74, 13), (74, 14), (74, 15), (74, 16), (74, 20), (74, 21), (74, 22), (74, 88),
|
'overlap.drawing', 'cpmm.drawing', 'ncm.drawing', 'nsdm.drawing', 'psdm.drawing', 'npc.drawing', 'crpm.mask',
|
||||||
(74, 89), (74, 90), (74, 91), (74, 92), (74, 93), (75, 20), (76, 5), (76, 16),
|
'ctunm.drawing', 'ctunm.maskAdd', 'ctunm.maskDrop', 'cncm.drawing', 'chvtpm.mask', 'capm2.drawing', 'cpbo.mask',
|
||||||
(76, 20), (76, 44), (77, 20), (78, 44), (79, 20), (80, 20), (81, 1), (81, 2),
|
'cmm2.waffleDrop', 'clicm1.maskDrop', 'clicm1.maskAdd', 'cmm3.waffleDrop', 'cdnm.drawing', 'cdnm.maskAdd',
|
||||||
(81, 3), (81, 4), (81, 6), (81, 7), (81, 8), (81, 10), (81, 11), (81, 12),
|
'cdnm.maskDrop', 'cmm4.waffleDrop', 'cmm4.maskDrop', 'cmm4.maskAdd', 'cli1m.maskDrop', 'cli1m.maskAdd',
|
||||||
(81, 13), (81, 14), (81, 15), (81, 17), (81, 19), (81, 20), (81, 23), (81, 27),
|
'cmm5.waffleDrop', 'pwell.pin', 'hvntm.drawing', 'lvtn.drawing', 'ubm.drawing', 'bump.drawing', 'r1c.drawing',
|
||||||
(81, 50), (81, 51), (81, 52), (81, 53), (81, 54), (81, 57), (81, 60), (81, 63),
|
'prBoundary.boundary', 'boundary',
|
||||||
(81, 79), (81, 81), (81, 101), (81, 125), (82, 5), (82, 20), (82, 24),
|
(10, 0), (11, 20), (18, 20), (22, 23), (25, 42), (25, 43), (25, 44), (26, 21), (26, 22), (33, 44), (38, 21), (38, 22),
|
||||||
(82, 25), (82, 26), (82, 27), (82, 28), (82, 44), (82, 59), (82, 64), (83, 44),
|
(44, 42), (44, 43), (45, 21), (45, 22), (62, 20), (62, 21), (62, 22), (65, 4), (65, 5), (65, 6), (65, 16), (65, 23),
|
||||||
(84, 23), (84, 44), (85, 44), (86, 20), (87, 42), (87, 43), (87, 44), (88, 0),
|
(65, 41), (65, 48), (65, 60), (66, 58), (67, 13), (67, 14), (67, 48), (68, 13), (68, 14), (68, 32), (68, 33), (68, 34),
|
||||||
(88, 44), (89, 32), (89, 33), (89, 34), (89, 35), (89, 36), (89, 37), (89, 38),
|
(68, 35), (68, 36), (68, 37), (68, 38), (68, 39), (68, 48), (68, 58), (69, 13), (69, 14), (69, 32), (69, 33), (69, 34),
|
||||||
(89, 39), (89, 44), (90, 4), (90, 20), (91, 44), (92, 44), (93, 0), (93, 44),
|
(69, 35), (69, 36), (69, 37), (69, 38), (69, 39), (69, 48), (69, 58), (70, 13), (70, 14), (70, 17), (70, 32), (70, 33),
|
||||||
(94, 0), (94, 20), (95, 20), (96, 0), (96, 20), (96, 21), (96, 22), (96, 44),
|
(70, 34), (70, 35), (70, 36), (70, 37), (70, 38), (70, 39), (70, 48), (71, 13), (71, 14), (71, 17), (71, 32), (71, 33),
|
||||||
(97, 0), (97, 42), (97, 43), (97, 44), (98, 0), (98, 42), (98, 43), (98, 44),
|
(71, 34), (71, 35), (71, 36), (71, 37), (71, 38), (71, 39), (71, 48), (72, 13), (72, 14), (72, 17), (72, 32), (72, 33),
|
||||||
(99, 0), (100, 0), (101, 0), (101, 42), (101, 43), (101, 44), (104, 42),
|
(72, 34), (72, 35), (72, 36), (72, 37), (72, 38), (72, 39), (74, 15), (88, 44), (89, 32), (89, 33), (89, 34), (89, 35),
|
||||||
(104, 43), (104, 44), (105, 20), (105, 21), (105, 22), (105, 42), (105, 43),
|
(89, 36), (89, 37), (89, 38), (89, 39), (93, 0), (94, 0), (97, 42), (97, 43), (98, 0), (98, 42), (98, 43), (98, 44),
|
||||||
(105, 44), (105, 52), (106, 42), (106, 43), (106, 44), (107, 20), (107, 21),
|
(100, 0), (101, 0), (101, 42), (101, 43), (101, 44), (104, 42), (104, 43), (104, 44), (105, 20), (105, 21), (105, 22),
|
||||||
(107, 22), (107, 24), (108, 20), (108, 21), (108, 22), (109, 42), (109, 43),
|
(105, 42), (105, 43), (105, 44), (106, 44), (107, 20), (107, 21), (107, 22), (108, 20), (108, 21), (108, 22), (109, 42),
|
||||||
(109, 44), (110, 20), (110, 21), (110, 22), (112, 4), (112, 20), (112, 21),
|
(109, 43), (109, 44), (112, 20), (112, 21), (112, 22), (115, 44), (117, 20), (117, 21), (117, 22), (122, 5), (124, 40),
|
||||||
(112, 22), (112, 42), (112, 43), (115, 42), (115, 43), (115, 44), (117, 4),
|
(235, 0), (235, 252), (236, 0),
|
||||||
(117, 20), (117, 21), (117, 22), (122, 5), (122, 16), (124, 40), (125, 20),
|
]
|
||||||
(125, 44), (127, 21), (127, 22), (201, 20), (235, 0), (235, 4), (235, 250),
|
|
||||||
(235, 252), (236, 0)
|
|
||||||
}
|
|
||||||
# fmt: on
|
|
||||||
|
|
||||||
valid_layers_ihp_sg13g2 = [
|
valid_layers_ihp_sg13g2 = [
|
||||||
"Substrate.drawing",
|
"Substrate.drawing", "Substrate.text", "Activ.drawing", "Activ.label", "Activ.pin", "GatPoly.drawing", "GatPoly.label",
|
||||||
"Substrate.text",
|
"GatPoly.pin", "PolyRes.drawing", "PolyRes.label", "PolyRes.pin", "NWell.drawing", "NWell.label", "NWell.pin",
|
||||||
"Activ.drawing",
|
"nBuLay.drawing", "nBuLay.label", "nBuLay.pin", "nBuLay.block", "PWell.block", "pSD.drawing", "nSD.drawing",
|
||||||
"Activ.label",
|
"nSD.block", "SalBlock.drawing", "ThickGateOx.drawing", "Cont.drawing", "Metal1.drawing", "Metal1.label", "Metal1.pin",
|
||||||
"Activ.pin",
|
"Metal1.text", "Metal1.res", "Via1.drawing", "Metal2.drawing", "Metal2.label", "Metal2.pin", "Metal2.text",
|
||||||
"GatPoly.drawing",
|
"Metal2.res", "Via2.drawing", "Via2.net", "Via2.boundary", "Metal3.drawing", "Metal3.label", "Metal3.pin",
|
||||||
"GatPoly.label",
|
"Metal3.text", "Metal3.res", "MIM.drawing", "Vmim.drawing", "Via3.drawing", "Metal4.drawing", "Metal4.label",
|
||||||
"GatPoly.pin",
|
"Metal4.pin", "Metal4.text", "Metal4.res", "Via4.drawing", "Metal5.drawing", "Metal5.label", "Metal5.pin",
|
||||||
"PolyRes.drawing",
|
"Metal5.text", "Metal5.res", "TopVia1.drawing", "TopMetal1.drawing", "TopMetal1.label", "TopMetal1.pin",
|
||||||
"PolyRes.label",
|
"TopMetal1.text", "TopMetal1.res", "IND.drawing", "IND.pin", "IND.boundary", "IND.text", "TEXT.drawing",
|
||||||
"PolyRes.pin",
|
"Recog.drawing", "Recog.pin", "Recog.esd", "Recog.diode", "Recog.tsv", "Recog.pdiode", "Recog.mom", "DigiBnd.drawing",
|
||||||
"NWell.drawing",
|
"DigiBnd.drawing0", "RES.drawing", "RES.label", "SRAM.drawing", "SRAM.label", "SRAM.boundary", "DigiSub.drawing",
|
||||||
"NWell.label",
|
"HeatRes.drawing", "NoRCX.drawing", "NoRCX.m2m3", "NoRCX.m2m4", "NoRCX.m2m5", "NoRCX.m2tm1", "NoRCX.m2tm2",
|
||||||
"NWell.pin",
|
"NoRCX.m3m4", "NoRCX.m3m5", "NoRCX.m3tm1", "NoRCX.m3tm2", "NoRCX.m4m5", "NoRCX.m4tm1", "NoRCX.m4tm2", "NoRCX.m5tm1",
|
||||||
"nBuLay.drawing",
|
"NoRCX.m5tm2", "NoRCX.tm1tm2", "NoRCX.m1sub", "NoRCX.m2sub", "NoRCX.m3sub", "NoRCX.m4sub", "NoRCX.m5sub",
|
||||||
"nBuLay.label",
|
"NoRCX.tm1sub", "Varicap.drawing", "EXTBlock.drawing", "prBoundary.drawing", "prBoundary.label", "prBoundary.boundary",
|
||||||
"nBuLay.pin",
|
|
||||||
"nBuLay.block",
|
|
||||||
"PWell.block",
|
|
||||||
"pSD.drawing",
|
|
||||||
"nSD.drawing",
|
|
||||||
"nSD.block",
|
|
||||||
"SalBlock.drawing",
|
|
||||||
"ThickGateOx.drawing",
|
|
||||||
"Cont.drawing",
|
|
||||||
"Metal1.drawing",
|
|
||||||
"Metal1.label",
|
|
||||||
"Metal1.pin",
|
|
||||||
"Metal1.text",
|
|
||||||
"Metal1.res",
|
|
||||||
"Via1.drawing",
|
|
||||||
"Metal2.drawing",
|
|
||||||
"Metal2.label",
|
|
||||||
"Metal2.pin",
|
|
||||||
"Metal2.text",
|
|
||||||
"Metal2.res",
|
|
||||||
"Via2.drawing",
|
|
||||||
"Via2.net",
|
|
||||||
"Via2.boundary",
|
|
||||||
"Metal3.drawing",
|
|
||||||
"Metal3.label",
|
|
||||||
"Metal3.pin",
|
|
||||||
"Metal3.text",
|
|
||||||
"Metal3.res",
|
|
||||||
"MIM.drawing",
|
|
||||||
"Vmim.drawing",
|
|
||||||
"Via3.drawing",
|
|
||||||
"Metal4.drawing",
|
|
||||||
"Metal4.label",
|
|
||||||
"Metal4.pin",
|
|
||||||
"Metal4.text",
|
|
||||||
"Metal4.res",
|
|
||||||
"Via4.drawing",
|
|
||||||
"Metal5.drawing",
|
|
||||||
"Metal5.label",
|
|
||||||
"Metal5.pin",
|
|
||||||
"Metal5.text",
|
|
||||||
"Metal5.res",
|
|
||||||
"TopVia1.drawing",
|
|
||||||
"TopMetal1.drawing",
|
|
||||||
"TopMetal1.label",
|
|
||||||
"TopMetal1.pin",
|
|
||||||
"TopMetal1.text",
|
|
||||||
"TopMetal1.res",
|
|
||||||
"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",
|
"isoNWell.drawing",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
valid_layers_gf180mcuD = [
|
||||||
|
'PR_bndry', 'pass_mk', 'fail_mk', 'polygon_mk', 'NAT', 'violation_mk', 'MCELL_FEOL_MK', 'MVPSD', 'rule_txt_mk',
|
||||||
|
'DNWELL', 'PROBE_MK', 'case_txt_mk', 'Nwell', 'COMP', 'COMP_Dummy', 'COMP_Label', 'ESD', 'ESD_MK', 'Poly2',
|
||||||
|
'Poly2_Dummy', 'Poly2_Label', 'Pplus', 'Nplus', 'Contact', 'Metal1', 'Metal1_Slot', 'Metal1_Dummy', 'Metal1_BLK',
|
||||||
|
'Metal1_Label', 'Via1', 'Metal2', 'Metal2_Slot', 'Metal2_Dummy', 'Metal2_BLK', 'Metal2_Label', 'Pad', 'Via2', 'Via3',
|
||||||
|
'Via4', 'Metal3', 'Metal3_Slot', 'Metal3_Dummy', 'Metal3_BLK', 'Metal3_Label', 'Metal4', 'Metal4_Slot', 'Metal4_Dummy',
|
||||||
|
'Metal4_BLK', 'Metal4_Label', 'SAB', 'MetalTop', 'MetalTop_Slot', 'MetalTop_Dummy', 'MetalT_BLK', 'MetalTop_Label',
|
||||||
|
'Dualgate', 'Resistor', 'Border', 'FuseTop', 'EFUSE_MK', 'Metal5', 'Metal5_Slot', 'Metal5_Dummy', 'Metal5_BLK',
|
||||||
|
'Metal5_Label', 'Via5', 'YMTP_MK', 'NEO_EE_MK', 'FuseWindow_D', 'LVS_RF', 'LVS_Drain', 'LVS_Source', 'SramCore',
|
||||||
|
'RES_MK', 'Metal1_Res', 'Metal2_Res', 'Metal3_Res', 'Metal4_Res', 'Metal5_Res', 'Metal6_Res', 'NDMY', 'V5_XTOR',
|
||||||
|
'DIODE_MK', 'MDIODE', 'CAP_MK', 'MIM_L_MK', 'LVS_BJT', 'LVS_IO', 'MTPMARK', 'HVPOLYRS', 'OPC_drc', 'PLFUSE', 'DRC_BJT',
|
||||||
|
'DEV_WF_MK', 'Latchup_MK', 'IND_MK', 'PMNDMY', 'WELL_DIODE_MK', 'MOS_CAP_MK', 'GUARD_RING_MK', 'OTP_MK', 'ZENER',
|
||||||
|
'UBMPPeri', 'UBMPArray', 'UBMEPlate', 'LVPWELL', 'MVSD', 'POLYFUSE', 'LDMOS_XTOR', 'FHRES', 'Schottky_diode',
|
||||||
|
(1, 222), (5, 222), (12, 222), (14, 222), (15, 222), (21, 10), (63, 63), (204, 10),
|
||||||
|
]
|
||||||
|
# fmt: on
|
||||||
|
|
||||||
# layers used for the analog pin check
|
# layers used for the analog pin check
|
||||||
layer_map_sky130A = {
|
layer_map_sky130A = {
|
||||||
"met4": (71, 20),
|
"met4": (71, 20),
|
||||||
@@ -186,10 +103,18 @@ def analog_pin_pos_sky130A(pin_number: int, uses_3v3: bool):
|
|||||||
return 151.81 - 19.32 * pin_number - (15.64 if uses_3v3 else 0)
|
return 151.81 - 19.32 * pin_number - (15.64 if uses_3v3 else 0)
|
||||||
|
|
||||||
|
|
||||||
valid_layers = {"sky130A": valid_layers_sky130A, "ihp-sg13g2": valid_layers_ihp_sg13g2}
|
valid_layers = {
|
||||||
|
"sky130A": valid_layers_sky130A,
|
||||||
|
"ihp-sg13g2": valid_layers_ihp_sg13g2,
|
||||||
|
"gf180mcuD": valid_layers_gf180mcuD,
|
||||||
|
}
|
||||||
layer_map = {"sky130A": layer_map_sky130A}
|
layer_map = {"sky130A": layer_map_sky130A}
|
||||||
analog_pin_pos = {"sky130A": analog_pin_pos_sky130A}
|
analog_pin_pos = {"sky130A": analog_pin_pos_sky130A}
|
||||||
lyp_filename = {"sky130A": "sky130A.lyp", "ihp-sg13g2": "sg13g2.lyp"}
|
lyp_filename = {
|
||||||
|
"sky130A": "sky130A.lyp",
|
||||||
|
"ihp-sg13g2": "sg13g2.lyp",
|
||||||
|
"gf180mcuD": "gf180mcu.lyp",
|
||||||
|
}
|
||||||
|
|
||||||
# TODO: read layer numbers from lyp file
|
# TODO: read layer numbers from lyp file
|
||||||
valid_lef_port_layers = {
|
valid_lef_port_layers = {
|
||||||
@@ -208,7 +133,11 @@ valid_lef_port_layers = {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
forbidden_layers = {
|
forbidden_layers = {
|
||||||
"sky130A": ["met5.drawing", "met5.pin", "met5.label"],
|
"sky130A": [
|
||||||
|
"met5.drawing",
|
||||||
|
"met5.pin",
|
||||||
|
"met5.label",
|
||||||
|
],
|
||||||
"ihp-sg13g2": [
|
"ihp-sg13g2": [
|
||||||
"TopMetal1.drawing",
|
"TopMetal1.drawing",
|
||||||
"TopMetal1.pin",
|
"TopMetal1.pin",
|
||||||
@@ -217,10 +146,20 @@ forbidden_layers = {
|
|||||||
"TopMetal2.pin",
|
"TopMetal2.pin",
|
||||||
"TopMetal2.label",
|
"TopMetal2.label",
|
||||||
],
|
],
|
||||||
|
"gf180mcuD": [
|
||||||
|
"Metal5",
|
||||||
|
"Metal5_Label",
|
||||||
|
],
|
||||||
}
|
}
|
||||||
power_pins_layer = {
|
power_pins_layer = {
|
||||||
"sky130A": "met4",
|
"sky130A": "met4",
|
||||||
"ihp-sg13g2": "Metal5",
|
"ihp-sg13g2": "Metal5",
|
||||||
|
"gf180mcuD": "Metal4",
|
||||||
|
}
|
||||||
|
boundary_layer = {
|
||||||
|
"sky130A": "prBoundary.boundary",
|
||||||
|
"ihp-sg13g2": "prBoundary.boundary",
|
||||||
|
"gf180mcuD": "PR_bndry",
|
||||||
}
|
}
|
||||||
|
|
||||||
tech_names = ["sky130A", "ihp-sg13g2"]
|
tech_names = ["sky130A", "ihp-sg13g2", "gf180mcuD"]
|
||||||
|
|||||||
Reference in New Issue
Block a user