mirror of
https://github.com/TinyTapeout/tt-support-tools.git
synced 2026-11-03 04:36:09 +01:00
fix(precheck): rename "sky130" to "sky130A"
Keep the tech naming consistent with the rest of tt-support-tools code
This commit is contained in:
@@ -27,7 +27,7 @@ jobs:
|
|||||||
run: pip install -r requirements.txt
|
run: pip install -r requirements.txt
|
||||||
|
|
||||||
- name: Install Sky130 PDK
|
- name: Install Sky130 PDK
|
||||||
uses: TinyTapeout/volare-action@v2
|
uses: TinyTapeout/ciel-action@v1
|
||||||
with:
|
with:
|
||||||
pdk_name: sky130
|
pdk_name: sky130
|
||||||
pdk_version: ${{ env.PDK_VERSION }}
|
pdk_version: ${{ env.PDK_VERSION }}
|
||||||
|
|||||||
@@ -293,9 +293,9 @@ def main():
|
|||||||
else:
|
else:
|
||||||
raise PrecheckFailure("Layout file extension is neither .gds nor .gds.br")
|
raise PrecheckFailure("Layout file extension is neither .gds nor .gds.br")
|
||||||
|
|
||||||
if args.tech not in tech_names:
|
|
||||||
raise PrecheckFailure(f"Invalid tech: {args.tech}")
|
|
||||||
tech = args.tech
|
tech = args.tech
|
||||||
|
if tech not in tech_names:
|
||||||
|
raise PrecheckFailure(f"Invalid tech: {tech}")
|
||||||
|
|
||||||
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"):
|
||||||
@@ -336,22 +336,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": "sky130",
|
"tech": "sky130A",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "KLayout FEOL",
|
"name": "KLayout FEOL",
|
||||||
"check": lambda: klayout_drc(gds_file, "feol"),
|
"check": lambda: klayout_drc(gds_file, "feol"),
|
||||||
"tech": "sky130",
|
"tech": "sky130A",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "KLayout BEOL",
|
"name": "KLayout BEOL",
|
||||||
"check": lambda: klayout_drc(gds_file, "beol"),
|
"check": lambda: klayout_drc(gds_file, "beol"),
|
||||||
"tech": "sky130",
|
"tech": "sky130A",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "KLayout offgrid",
|
"name": "KLayout offgrid",
|
||||||
"check": lambda: klayout_drc(gds_file, "offgrid"),
|
"check": lambda: klayout_drc(gds_file, "offgrid"),
|
||||||
"tech": "sky130",
|
"tech": "sky130A",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "KLayout pin label overlapping drawing",
|
"name": "KLayout pin label overlapping drawing",
|
||||||
@@ -381,7 +381,7 @@ def main():
|
|||||||
{
|
{
|
||||||
"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": "sky130",
|
"tech": "sky130A",
|
||||||
},
|
},
|
||||||
{"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)},
|
||||||
|
|||||||
+11
-11
@@ -1,5 +1,5 @@
|
|||||||
# fmt: off
|
# fmt: off
|
||||||
valid_layers_sky130 = {
|
valid_layers_sky130A = {
|
||||||
(10, 0), (11, 0), (11, 20), (11, 44), (17, 0), (18, 20), (20, 0), (21, 0),
|
(10, 0), (11, 0), (11, 20), (11, 44), (17, 0), (18, 20), (20, 0), (21, 0),
|
||||||
(22, 0), (22, 20), (22, 21), (22, 22), (22, 23), (22, 24), (23, 0), (23, 28),
|
(22, 0), (22, 20), (22, 21), (22, 22), (22, 23), (22, 24), (23, 0), (23, 28),
|
||||||
(25, 0), (25, 42), (25, 43), (25, 44), (26, 20), (26, 21), (26, 22), (27, 0),
|
(25, 0), (25, 42), (25, 43), (25, 44), (26, 20), (26, 21), (26, 22), (27, 0),
|
||||||
@@ -176,24 +176,24 @@ valid_layers_ihp_sg13g2 = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
# layers used for the analog pin check
|
# layers used for the analog pin check
|
||||||
layer_map_sky130 = {
|
layer_map_sky130A = {
|
||||||
"met4": (71, 20),
|
"met4": (71, 20),
|
||||||
"via3": (70, 44),
|
"via3": (70, 44),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def analog_pin_pos_sky130(pin_number: int, uses_3v3: bool):
|
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 = {"sky130": valid_layers_sky130, "ihp-sg13g2": valid_layers_ihp_sg13g2}
|
valid_layers = {"sky130A": valid_layers_sky130A, "ihp-sg13g2": valid_layers_ihp_sg13g2}
|
||||||
layer_map = {"sky130": layer_map_sky130}
|
layer_map = {"sky130A": layer_map_sky130A}
|
||||||
analog_pin_pos = {"sky130": analog_pin_pos_sky130}
|
analog_pin_pos = {"sky130A": analog_pin_pos_sky130A}
|
||||||
lyp_filename = {"sky130": "sky130A.lyp", "ihp-sg13g2": "sg13g2.lyp"}
|
lyp_filename = {"sky130A": "sky130A.lyp", "ihp-sg13g2": "sg13g2.lyp"}
|
||||||
|
|
||||||
# TODO: read layer numbers from lyp file
|
# TODO: read layer numbers from lyp file
|
||||||
valid_lef_port_layers = {
|
valid_lef_port_layers = {
|
||||||
"sky130": {
|
"sky130A": {
|
||||||
"met1.pin": (68, 16),
|
"met1.pin": (68, 16),
|
||||||
"met2.pin": (69, 16),
|
"met2.pin": (69, 16),
|
||||||
"met3.pin": (70, 16),
|
"met3.pin": (70, 16),
|
||||||
@@ -208,7 +208,7 @@ valid_lef_port_layers = {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
forbidden_layers = {
|
forbidden_layers = {
|
||||||
"sky130": ["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",
|
||||||
@@ -219,8 +219,8 @@ forbidden_layers = {
|
|||||||
],
|
],
|
||||||
}
|
}
|
||||||
power_pins_layer = {
|
power_pins_layer = {
|
||||||
"sky130": "met4",
|
"sky130A": "met4",
|
||||||
"ihp-sg13g2": "Metal5",
|
"ihp-sg13g2": "Metal5",
|
||||||
}
|
}
|
||||||
|
|
||||||
tech_names = ["sky130", "ihp-sg13g2"]
|
tech_names = ["sky130A", "ihp-sg13g2"]
|
||||||
|
|||||||
+19
-19
@@ -477,14 +477,14 @@ def test_klayout_beol_fail(gds_fail_met1_poly: str):
|
|||||||
|
|
||||||
|
|
||||||
def test_klayout_checks_pass(gds_valid: str):
|
def test_klayout_checks_pass(gds_valid: str):
|
||||||
precheck.klayout_checks(gds_valid, "TEST_valid", "sky130")
|
precheck.klayout_checks(gds_valid, "TEST_valid", "sky130A")
|
||||||
|
|
||||||
|
|
||||||
def test_klayout_checks_fail_metal5(gds_fail_metal5_poly: str):
|
def test_klayout_checks_fail_metal5(gds_fail_metal5_poly: str):
|
||||||
with pytest.raises(
|
with pytest.raises(
|
||||||
precheck.PrecheckFailure, match=r"Forbidden layer met5\.drawing found in .+"
|
precheck.PrecheckFailure, match=r"Forbidden layer met5\.drawing found in .+"
|
||||||
):
|
):
|
||||||
precheck.klayout_checks(gds_fail_metal5_poly, "TEST_met5_error", "sky130")
|
precheck.klayout_checks(gds_fail_metal5_poly, "TEST_met5_error", "sky130A")
|
||||||
|
|
||||||
|
|
||||||
def test_klayout_checks_fail_pr_boundary(gds_no_pr_boundary: str):
|
def test_klayout_checks_fail_pr_boundary(gds_no_pr_boundary: str):
|
||||||
@@ -492,7 +492,7 @@ def test_klayout_checks_fail_pr_boundary(gds_no_pr_boundary: str):
|
|||||||
precheck.PrecheckFailure,
|
precheck.PrecheckFailure,
|
||||||
match=r"prBoundary.boundary \(235/4\) layer not found in .+",
|
match=r"prBoundary.boundary \(235/4\) layer not found in .+",
|
||||||
):
|
):
|
||||||
precheck.klayout_checks(gds_no_pr_boundary, "TEST_no_prboundary", "sky130")
|
precheck.klayout_checks(gds_no_pr_boundary, "TEST_no_prboundary", "sky130A")
|
||||||
|
|
||||||
|
|
||||||
def test_klayout_top_module_name(gds_invalid_macro_name: str):
|
def test_klayout_top_module_name(gds_invalid_macro_name: str):
|
||||||
@@ -501,7 +501,7 @@ def test_klayout_top_module_name(gds_invalid_macro_name: str):
|
|||||||
match="Top macro name mismatch: expected TEST_invalid_macro_name, got wrong_name",
|
match="Top macro name mismatch: expected TEST_invalid_macro_name, got wrong_name",
|
||||||
):
|
):
|
||||||
precheck.klayout_checks(
|
precheck.klayout_checks(
|
||||||
gds_invalid_macro_name, "TEST_invalid_macro_name", "sky130"
|
gds_invalid_macro_name, "TEST_invalid_macro_name", "sky130A"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -516,7 +516,7 @@ def test_klayout_zero_area_drc_fail(gds_zero_area: str):
|
|||||||
|
|
||||||
def test_shapes_outside_area(gds_shapes_outside_area: str):
|
def test_shapes_outside_area(gds_shapes_outside_area: str):
|
||||||
with pytest.raises(precheck.PrecheckFailure, match="Shapes outside project area"):
|
with pytest.raises(precheck.PrecheckFailure, match="Shapes outside project area"):
|
||||||
precheck.boundary_check(gds_shapes_outside_area, "sky130")
|
precheck.boundary_check(gds_shapes_outside_area, "sky130A")
|
||||||
|
|
||||||
|
|
||||||
def test_wrong_power_pins_1(verilog_lef_wrong_power_pins: tuple[str, str]):
|
def test_wrong_power_pins_1(verilog_lef_wrong_power_pins: tuple[str, str]):
|
||||||
@@ -533,7 +533,7 @@ def test_wrong_power_pins_2(verilog_lef_wrong_power_pins: tuple[str, str]):
|
|||||||
|
|
||||||
def test_invalid_layer(gds_invalid_layer: str):
|
def test_invalid_layer(gds_invalid_layer: str):
|
||||||
with pytest.raises(precheck.PrecheckFailure, match="Invalid layers in GDS"):
|
with pytest.raises(precheck.PrecheckFailure, match="Invalid layers in GDS"):
|
||||||
precheck.layer_check(gds_invalid_layer, "sky130")
|
precheck.layer_check(gds_invalid_layer, "sky130A")
|
||||||
|
|
||||||
|
|
||||||
def test_invalid_cell_name(gds_invalid_cell_name: str):
|
def test_invalid_cell_name(gds_invalid_cell_name: str):
|
||||||
@@ -560,7 +560,7 @@ def test_pin_analog_example(gds_lef_analog_example: tuple[str, str]):
|
|||||||
"../tech/sky130A/def/analog/tt_analog_1x2.def",
|
"../tech/sky130A/def/analog/tt_analog_1x2.def",
|
||||||
"TEST_analog_example",
|
"TEST_analog_example",
|
||||||
False,
|
False,
|
||||||
"sky130",
|
"sky130A",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -572,7 +572,7 @@ def test_pin_analog_power_compat(gds_lef_analog_power_compat: tuple[str, str]):
|
|||||||
"../tech/sky130A/def/analog/tt_analog_1x2.def",
|
"../tech/sky130A/def/analog/tt_analog_1x2.def",
|
||||||
"TEST_analog_power_compat",
|
"TEST_analog_power_compat",
|
||||||
False,
|
False,
|
||||||
"sky130",
|
"sky130A",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -588,7 +588,7 @@ def test_pin_analog_wrong_vgnd(gds_lef_analog_wrong_vgnd: tuple[str, str]):
|
|||||||
"../tech/sky130A/def/analog/tt_analog_1x2.def",
|
"../tech/sky130A/def/analog/tt_analog_1x2.def",
|
||||||
"TEST_analog_wrong_vgnd",
|
"TEST_analog_wrong_vgnd",
|
||||||
False,
|
False,
|
||||||
"sky130",
|
"sky130A",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -604,7 +604,7 @@ def test_pin_analog_overlapping_vgnd(gds_lef_analog_overlapping_vgnd: tuple[str,
|
|||||||
"../tech/sky130A/def/analog/tt_analog_1x2.def",
|
"../tech/sky130A/def/analog/tt_analog_1x2.def",
|
||||||
"TEST_analog_overlapping_vgnd",
|
"TEST_analog_overlapping_vgnd",
|
||||||
False,
|
False,
|
||||||
"sky130",
|
"sky130A",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -616,7 +616,7 @@ def test_pin_analog_compound_vgnd(gds_lef_analog_compound_vgnd: tuple[str, str])
|
|||||||
"../tech/sky130A/def/analog/tt_analog_1x2.def",
|
"../tech/sky130A/def/analog/tt_analog_1x2.def",
|
||||||
"TEST_analog_compound_vgnd",
|
"TEST_analog_compound_vgnd",
|
||||||
False,
|
False,
|
||||||
"sky130",
|
"sky130A",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -628,7 +628,7 @@ def test_pin_analog_example_3v3(gds_lef_analog_example_3v3: tuple[str, str]):
|
|||||||
"../tech/sky130A/def/analog/tt_analog_1x2.def",
|
"../tech/sky130A/def/analog/tt_analog_1x2.def",
|
||||||
"TEST_analog_example_3v3",
|
"TEST_analog_example_3v3",
|
||||||
True,
|
True,
|
||||||
"sky130",
|
"sky130A",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -644,7 +644,7 @@ def test_pin_analog_3v3_mismatch1(gds_lef_analog_example: tuple[str, str]):
|
|||||||
"../tech/sky130A/def/analog/tt_analog_1x2.def",
|
"../tech/sky130A/def/analog/tt_analog_1x2.def",
|
||||||
"TEST_analog_example",
|
"TEST_analog_example",
|
||||||
True,
|
True,
|
||||||
"sky130",
|
"sky130A",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -660,14 +660,14 @@ def test_pin_analog_3v3_mismatch2(gds_lef_analog_example_3v3: tuple[str, str]):
|
|||||||
"../tech/sky130A/def/analog/tt_analog_1x2.def",
|
"../tech/sky130A/def/analog/tt_analog_1x2.def",
|
||||||
"TEST_analog_example_3v3",
|
"TEST_analog_example_3v3",
|
||||||
False,
|
False,
|
||||||
"sky130",
|
"sky130A",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_analog_exact_pins(gds_lef_analog_pin_example: tuple[str, str]):
|
def test_analog_exact_pins(gds_lef_analog_pin_example: tuple[str, str]):
|
||||||
gds_file, lef_file = gds_lef_analog_pin_example
|
gds_file, lef_file = gds_lef_analog_pin_example
|
||||||
precheck.analog_pin_check(
|
precheck.analog_pin_check(
|
||||||
gds_file, "sky130", True, False, 2, {"ua[0]": "x", "ua[1]": "x"}
|
gds_file, "sky130A", True, False, 2, {"ua[0]": "x", "ua[1]": "x"}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -678,7 +678,7 @@ def test_analog_less_pins(gds_lef_analog_pin_example: tuple[str, str]):
|
|||||||
match="Analog pin `ua\\[1\\]` is connected to some metal but `analog_pins` is set to 1 .*",
|
match="Analog pin `ua\\[1\\]` is connected to some metal but `analog_pins` is set to 1 .*",
|
||||||
):
|
):
|
||||||
precheck.analog_pin_check(
|
precheck.analog_pin_check(
|
||||||
gds_file, "sky130", True, False, 1, {"ua[0]": "x", "ua[1]": "x"}
|
gds_file, "sky130A", True, False, 1, {"ua[0]": "x", "ua[1]": "x"}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -689,7 +689,7 @@ def test_analog_more_pins(gds_lef_analog_pin_example: tuple[str, str]):
|
|||||||
match="Analog pin `ua\\[2\\]` is not connected to any adjacent metal but `analog_pins` is set to 3 .*",
|
match="Analog pin `ua\\[2\\]` is not connected to any adjacent metal but `analog_pins` is set to 3 .*",
|
||||||
):
|
):
|
||||||
precheck.analog_pin_check(
|
precheck.analog_pin_check(
|
||||||
gds_file, "sky130", True, False, 3, {"ua[0]": "x", "ua[1]": "x"}
|
gds_file, "sky130A", True, False, 3, {"ua[0]": "x", "ua[1]": "x"}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -699,7 +699,7 @@ def test_analog_less_ua_entries(gds_lef_analog_pin_example: tuple[str, str]):
|
|||||||
precheck.PrecheckFailure,
|
precheck.PrecheckFailure,
|
||||||
match="Analog pin `ua\\[1\\]` is connected to some metal but the description of `ua\\[1\\]` .*",
|
match="Analog pin `ua\\[1\\]` is connected to some metal but the description of `ua\\[1\\]` .*",
|
||||||
):
|
):
|
||||||
precheck.analog_pin_check(gds_file, "sky130", True, False, 2, {"ua[0]": "x"})
|
precheck.analog_pin_check(gds_file, "sky130A", True, False, 2, {"ua[0]": "x"})
|
||||||
|
|
||||||
|
|
||||||
def test_analog_more_ua_entries(gds_lef_analog_pin_example: tuple[str, str]):
|
def test_analog_more_ua_entries(gds_lef_analog_pin_example: tuple[str, str]):
|
||||||
@@ -710,7 +710,7 @@ def test_analog_more_ua_entries(gds_lef_analog_pin_example: tuple[str, str]):
|
|||||||
):
|
):
|
||||||
precheck.analog_pin_check(
|
precheck.analog_pin_check(
|
||||||
gds_file,
|
gds_file,
|
||||||
"sky130",
|
"sky130A",
|
||||||
True,
|
True,
|
||||||
False,
|
False,
|
||||||
2,
|
2,
|
||||||
|
|||||||
Reference in New Issue
Block a user