diff --git a/precheck/klayout_tools.py b/precheck/klayout_tools.py index 288a72b..9b130a8 100644 --- a/precheck/klayout_tools.py +++ b/precheck/klayout_tools.py @@ -28,7 +28,12 @@ def parse_lyp_layers(lyp_file: str): if valid is not None and valid.text == "false": continue - if name is not None and source is not None: + if ( + name is not None + and name.text is not None + and source is not None + and source.text is not None + ): name_key = name.text.split("-")[0].strip() layer, data_type = source.text.split("@")[0].split("/") # Add the 'source' text as the value in the dictionary diff --git a/precheck/precheck.py b/precheck/precheck.py index 9349d65..d589406 100644 --- a/precheck/precheck.py +++ b/precheck/precheck.py @@ -13,6 +13,10 @@ LYP_FILE = f"{PDK_ROOT}/{PDK_NAME}/libs.tech/klayout/tech/{PDK_NAME}.lyp" REPORTS_PATH = os.path.join(os.path.dirname(os.path.realpath(__file__)), "reports") +if not PDK_ROOT: + logging.error("PDK_ROOT environment variable not set") + exit(1) + def magic_drc(gds: str, toplevel: str): logging.info(f"Running magic DRC on {gds} (module={toplevel})") @@ -61,7 +65,8 @@ def klayout_drc(gds: str, check: str): logging.error(f"Klayout {check} failed") return False - report = rdb.ReportDatabase().load(report_file) + report = rdb.ReportDatabase("DRC") + report.load(report_file) if report.num_items() > 0: logging.error( diff --git a/precheck/test_precheck.py b/precheck/test_precheck.py index 807862c..8aeda06 100644 --- a/precheck/test_precheck.py +++ b/precheck/test_precheck.py @@ -13,7 +13,7 @@ @pytest.fixture(scope="session") -def gds_empty(tmp_path_factory): +def gds_empty(tmp_path_factory: pytest.TempPathFactory): """Creates a GDS with an empty cell that should pass DRC.""" gds_file = tmp_path_factory.mktemp("gds") / "gds_empty.gds" layout = pya.Layout() @@ -23,7 +23,7 @@ def gds_empty(tmp_path_factory): @pytest.fixture(scope="session") -def gds_fail_met1_poly(tmp_path_factory): +def gds_fail_met1_poly(tmp_path_factory: pytest.TempPathFactory): """Creates a GDS that fails Magic DRC and BEOL because the met1 rect is too small.""" gds_file = tmp_path_factory.mktemp("gds") / "gds_met1_fail.gds" layout = pya.Layout() @@ -39,7 +39,7 @@ def gds_fail_met1_poly(tmp_path_factory): @pytest.fixture(scope="session") -def gds_fail_nwell_poly(tmp_path_factory): +def gds_fail_nwell_poly(tmp_path_factory: pytest.TempPathFactory): """Creates a GDS that fails FEOL because the nwell is too small.""" gds_file = tmp_path_factory.mktemp("gds") / "gds_nwell_fail.gds" layout = pya.Layout() @@ -54,7 +54,7 @@ def gds_fail_nwell_poly(tmp_path_factory): @pytest.fixture(scope="session") -def gds_fail_metal5_poly(tmp_path_factory): +def gds_fail_metal5_poly(tmp_path_factory: pytest.TempPathFactory): """Creates a GDS with drawings on layer5, should fail our precheck.""" gds_file = tmp_path_factory.mktemp("gds") / "gds_metal5_fail.gds" layout = pya.Layout() @@ -67,41 +67,41 @@ def gds_fail_metal5_poly(tmp_path_factory): return str(gds_file) -def test_magic_drc_pass(gds_empty): +def test_magic_drc_pass(gds_empty: str): result = precheck.magic_drc(gds_empty, "TEST_empty") assert result is True -def test_magic_drc_fail(gds_fail_met1_poly): +def test_magic_drc_fail(gds_fail_met1_poly: str): result = precheck.magic_drc(gds_fail_met1_poly, "TEST_met1_error") assert result is False -def test_klayout_feol_pass(gds_empty): +def test_klayout_feol_pass(gds_empty: str): result = precheck.klayout_drc(gds_empty, "feol") assert result is True -def test_klayout_feol_fail(gds_fail_nwell_poly): +def test_klayout_feol_fail(gds_fail_nwell_poly: str): result = precheck.klayout_drc(gds_fail_nwell_poly, "feol") assert result is False -def test_klayout_beol_pass(gds_empty): +def test_klayout_beol_pass(gds_empty: str): result = precheck.klayout_drc(gds_empty, "beol") assert result is True -def test_klayout_beol_fail(gds_fail_met1_poly): +def test_klayout_beol_fail(gds_fail_met1_poly: str): result = precheck.klayout_drc(gds_fail_met1_poly, "beol") assert result is False -def test_klayout_checks_pass(gds_empty): +def test_klayout_checks_pass(gds_empty: str): result = precheck.klayout_checks(gds_empty) assert result is True -def test_klayout_checks_fail(gds_fail_metal5_poly): +def test_klayout_checks_fail(gds_fail_metal5_poly: str): result = precheck.klayout_checks(gds_fail_metal5_poly) assert result is False