mirror of
https://github.com/TinyTapeout/tt-support-tools.git
synced 2026-11-03 04:36:09 +01:00
feat(precheck): add analog pin check for ihp-sg13g2
This commit is contained in:
+28
-21
@@ -17,10 +17,9 @@ from klayout_tools import parse_lyp_layers
|
|||||||
from pin_check import pin_check
|
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_rects,
|
||||||
boundary_layer,
|
boundary_layer,
|
||||||
forbidden_layers,
|
forbidden_layers,
|
||||||
layer_map,
|
|
||||||
lyp_filename,
|
lyp_filename,
|
||||||
tech_names,
|
tech_names,
|
||||||
valid_layers,
|
valid_layers,
|
||||||
@@ -261,42 +260,50 @@ def analog_pin_check(
|
|||||||
if is_analog:
|
if is_analog:
|
||||||
lib = gdstk.read_gds(gds)
|
lib = gdstk.read_gds(gds)
|
||||||
top = lib.top_level()[0]
|
top = lib.top_level()[0]
|
||||||
met4 = top.copy("test_met4")
|
filtered = {}
|
||||||
met4.flatten()
|
|
||||||
met4.filter([layer_map[tech]["met4"]], False)
|
|
||||||
via3 = top.copy("test_via3")
|
|
||||||
via3.flatten()
|
|
||||||
via3.filter([layer_map[tech]["via3"]], False)
|
|
||||||
|
|
||||||
for pin in range(8):
|
for pin, (rect, pin_layer, via_layers) in enumerate(
|
||||||
x = analog_pin_pos[tech](pin, uses_3v3)
|
analog_pin_rects(tech, uses_3v3)
|
||||||
pin_over = gdstk.rectangle((x, 0), (x + 0.9, 1.0))
|
):
|
||||||
pin_around = gdstk.boolean(
|
for layer in [pin_layer] + via_layers:
|
||||||
gdstk.offset(pin_over, 0.5), gdstk.offset(pin_over, 0.1), "not"
|
if layer not in filtered:
|
||||||
|
i = len(filtered)
|
||||||
|
lf = top.copy(f"test_lf_{i}")
|
||||||
|
lf.flatten()
|
||||||
|
lf.filter([layer], False)
|
||||||
|
filtered[layer] = lf
|
||||||
|
|
||||||
|
pin_rect = gdstk.rectangle(*rect)
|
||||||
|
pin_ring = gdstk.boolean(
|
||||||
|
gdstk.offset(pin_rect, 0.5), gdstk.offset(pin_rect, 0.1), "not"
|
||||||
)
|
)
|
||||||
|
|
||||||
via3_over = gdstk.boolean(via3.polygons, pin_over, "and")
|
pin_layer_polygons = filtered[pin_layer].polygons
|
||||||
met4_around = gdstk.boolean(met4.polygons, pin_around, "and")
|
connected = bool(gdstk.boolean(pin_layer_polygons, pin_ring, "and"))
|
||||||
connected = bool(via3_over) or bool(met4_around)
|
for via_layer in via_layers:
|
||||||
|
via_layer_polygons = filtered[via_layer].polygons
|
||||||
|
connected = connected or bool(
|
||||||
|
gdstk.boolean(via_layer_polygons, pin_rect, "and")
|
||||||
|
)
|
||||||
|
|
||||||
expected_pc = pin < analog_pins
|
expected_pc = pin < analog_pins
|
||||||
expected_pd = bool(pinout.get(f"ua[{pin}]", ""))
|
expected_pd = bool(pinout.get(f"ua[{pin}]", ""))
|
||||||
|
|
||||||
if connected and not expected_pc:
|
if connected and not expected_pc:
|
||||||
raise PrecheckFailure(
|
raise PrecheckFailure(
|
||||||
f"Analog pin `ua[{pin}]` is connected to some metal but `analog_pins` is set to {analog_pins} in `info.yaml`. Either increase `analog_pins` to at least {pin+1}, or remove any metal4 or via3 adjacent to `ua[{pin}]`."
|
f"Analog pin `ua[{pin}]` is connected to some metal but `analog_pins` is set to {analog_pins} in `info.yaml`. Either increase `analog_pins` to at least {pin+1}, or remove any metal or via adjacent to `ua[{pin}]`."
|
||||||
)
|
)
|
||||||
elif connected and not expected_pd:
|
elif connected and not expected_pd:
|
||||||
raise PrecheckFailure(
|
raise PrecheckFailure(
|
||||||
f"Analog pin `ua[{pin}]` is connected to some metal but the description of `ua[{pin}]` in the pinout section of `info.yaml` is empty. Either add a description or remove any metal4 or via3 adjacent to `ua[{pin}]`."
|
f"Analog pin `ua[{pin}]` is connected to some metal but the description of `ua[{pin}]` in the pinout section of `info.yaml` is empty. Either add a description or remove any metal or via adjacent to `ua[{pin}]`."
|
||||||
)
|
)
|
||||||
elif not connected and expected_pc:
|
elif not connected and expected_pc:
|
||||||
raise PrecheckFailure(
|
raise PrecheckFailure(
|
||||||
f"Analog pin `ua[{pin}]` is not connected to any adjacent metal but `analog_pins` is set to {analog_pins} in `info.yaml`. Either wire up `ua[{pin}]` to your design using metal4 or via3, or decrease `analog_pins` to {pin}."
|
f"Analog pin `ua[{pin}]` is not connected to any adjacent metal but `analog_pins` is set to {analog_pins} in `info.yaml`. Either wire up `ua[{pin}]` to your design or decrease `analog_pins` to {pin}."
|
||||||
)
|
)
|
||||||
elif not connected and expected_pd:
|
elif not connected and expected_pd:
|
||||||
raise PrecheckFailure(
|
raise PrecheckFailure(
|
||||||
f"Analog pin `ua[{pin}]` is not connected to any adjacent metal but the description of `ua[{pin}]` in the pinout section of `info.yaml` is non-empty. Either wire up `ua[{pin}]` to your design using metal4 or via3, or remove the description for the disconnected pin."
|
f"Analog pin `ua[{pin}]` is not connected to any adjacent metal but the description of `ua[{pin}]` in the pinout section of `info.yaml` is non-empty. Either wire up `ua[{pin}]` to your design or remove the description for the disconnected pin."
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -437,7 +444,7 @@ def main():
|
|||||||
"check": lambda: analog_pin_check(
|
"check": lambda: analog_pin_check(
|
||||||
gds_file, tech, is_analog, uses_3v3, analog_pins, pinout
|
gds_file, tech, is_analog, uses_3v3, analog_pins, pinout
|
||||||
),
|
),
|
||||||
"techs": ["sky130A"],
|
"techs": ["sky130A", "ihp-sg13g2"],
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
+29
-12
@@ -1,3 +1,5 @@
|
|||||||
|
tech_names = ["sky130A", "ihp-sg13g2", "gf180mcuD"]
|
||||||
|
|
||||||
# fmt: off
|
# fmt: off
|
||||||
valid_layers_sky130A = [
|
valid_layers_sky130A = [
|
||||||
'cldntm.mask', 'ldntm.drawing', 'cncm.mask', 'ctunm.mask', 'cnwm.mask', 'cnsm.mask', 'cfom.drawing', 'cfom.maskAdd',
|
'cldntm.mask', 'ldntm.drawing', 'cncm.mask', 'ctunm.mask', 'cnwm.mask', 'cnsm.mask', 'cfom.drawing', 'cfom.maskAdd',
|
||||||
@@ -93,15 +95,34 @@ valid_layers_gf180mcuD = [
|
|||||||
]
|
]
|
||||||
# fmt: on
|
# fmt: on
|
||||||
|
|
||||||
# layers used for the analog pin check
|
|
||||||
layer_map_sky130A = {
|
|
||||||
"met4": (71, 20),
|
|
||||||
"via3": (70, 44),
|
|
||||||
}
|
|
||||||
|
|
||||||
|
def analog_pin_rects(tech: str, uses_3v3: bool):
|
||||||
def analog_pin_pos_sky130A(pin_number: int, uses_3v3: bool):
|
if tech == "sky130A":
|
||||||
return 151.81 - 19.32 * pin_number - (15.64 if uses_3v3 else 0)
|
pin_layer = (71, 20) # met4
|
||||||
|
via_layers = [(70, 44)] # via3
|
||||||
|
for pin_number in range(8):
|
||||||
|
if uses_3v3:
|
||||||
|
x1, y1 = 136.17 - 19.32 * pin_number, 0.0
|
||||||
|
else:
|
||||||
|
x1, y1 = 151.81 - 19.32 * pin_number, 0.0
|
||||||
|
x2, y2 = x1 + 0.9, y1 + 1.0
|
||||||
|
rect = ((x1, y1), (x2, y2))
|
||||||
|
yield (rect, pin_layer, via_layers)
|
||||||
|
elif tech == "ihp-sg13g2":
|
||||||
|
pin_layer = (126, 0) # TopMetal1
|
||||||
|
via_layers = [(125, 0)] # TopVia1
|
||||||
|
for pin_number in range(8):
|
||||||
|
if uses_3v3:
|
||||||
|
raise NotImplementedError
|
||||||
|
else:
|
||||||
|
x1, y1 = 190.165 - 24.48 * pin_number, 0.0
|
||||||
|
x2, y2 = x1 + 1.75, y1 + 2.0
|
||||||
|
rect = ((x1, y1), (x2, y2))
|
||||||
|
yield (rect, pin_layer, via_layers)
|
||||||
|
elif tech in tech_names:
|
||||||
|
raise NotImplementedError
|
||||||
|
else:
|
||||||
|
raise ValueError(f"unexpected tech {tech}")
|
||||||
|
|
||||||
|
|
||||||
valid_layers = {
|
valid_layers = {
|
||||||
@@ -109,8 +130,6 @@ valid_layers = {
|
|||||||
"ihp-sg13g2": valid_layers_ihp_sg13g2,
|
"ihp-sg13g2": valid_layers_ihp_sg13g2,
|
||||||
"gf180mcuD": valid_layers_gf180mcuD,
|
"gf180mcuD": valid_layers_gf180mcuD,
|
||||||
}
|
}
|
||||||
layer_map = {"sky130A": layer_map_sky130A}
|
|
||||||
analog_pin_pos = {"sky130A": analog_pin_pos_sky130A}
|
|
||||||
lyp_filename = {
|
lyp_filename = {
|
||||||
"sky130A": "sky130A.lyp",
|
"sky130A": "sky130A.lyp",
|
||||||
"ihp-sg13g2": "sg13g2.lyp",
|
"ihp-sg13g2": "sg13g2.lyp",
|
||||||
@@ -165,5 +184,3 @@ boundary_layer = {
|
|||||||
"ihp-sg13g2": "prBoundary.boundary",
|
"ihp-sg13g2": "prBoundary.boundary",
|
||||||
"gf180mcuD": "PR_bndry",
|
"gf180mcuD": "PR_bndry",
|
||||||
}
|
}
|
||||||
|
|
||||||
tech_names = ["sky130A", "ihp-sg13g2", "gf180mcuD"]
|
|
||||||
|
|||||||
Reference in New Issue
Block a user