diff --git a/pyproject.toml b/pyproject.toml index 9e630bf8..01a67775 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -16,7 +16,8 @@ classifiers = [ ] dependencies = [ "gdsfactory[cad]==7.8.18", - "gplugins[tidy3d,sax,schematic]>=0.8.4,<0.9.0" + "gplugins[tidy3d,sax,schematic]>=0.8.4,<0.9.0", + 'siepic==0.5.3' ] description = "ubcpdk pdk" keywords = ["python"] diff --git a/tests/test_verification.py b/tests/test_verification.py new file mode 100644 index 00000000..69b94b93 --- /dev/null +++ b/tests/test_verification.py @@ -0,0 +1,22 @@ +"""Test functional verification of simple layouts """ +import os + +import gdsfactory as gf + +import ubcpdk.components as uc +from ubcpdk.verification import layout_check + + +def test_verification_import_gds(): + file_path = os.path.join( + os.path.dirname(os.path.realpath(__file__)), "tests/mmi2x2.oas" + ) + c = gf.import_gds(file_path) + layout_check(c) + + +def test_verification_mzi(): + splitter = uc.ebeam_y_1550(decorator=gf.port.auto_rename_ports) + mzi = gf.components.mzi(splitter=splitter) + c = uc.add_fiber_array(component=mzi) + layout_check(c) diff --git a/tests/tests/mmi2x2.oas b/tests/tests/mmi2x2.oas new file mode 100644 index 00000000..72b658b0 Binary files /dev/null and b/tests/tests/mmi2x2.oas differ diff --git a/ubcpdk/verification.py b/ubcpdk/verification.py new file mode 100644 index 00000000..4bd8b755 --- /dev/null +++ b/ubcpdk/verification.py @@ -0,0 +1,58 @@ +from pathlib import Path + +import gdsfactory +import klayout.db as kdb +import pya +import SiEPIC +import SiEPIC.verification +from SiEPIC.utils import get_technology_by_name, klive + +from ubcpdk.config import PATH + + +def layout_check( + component: gdsfactory.Component, + klayout_tech_path: str | Path | None = PATH.lyt, + show_klive: bool = False, +) -> int: + """Run a layout check using SiEPIC-Tool's functional verification. + + Args: + component: gdsfactory component. + klayout_tech_path: path to the klayout technology folder. + show_klive: show results in KLayout. + """ + + gdspath = component.write_gds() + + # load in KLayout database + ly = pya.Layout() + + # load SiEPIC technology + tech = kdb.Technology() + tech.load(str(klayout_tech_path)) + tech.create_technology("UBCPDK") + ly.TECHNOLOGY = get_technology_by_name("UBCPDK") + + ly.read(str(gdspath)) + if len(ly.top_cells()) != 1: + raise ValueError("Layout can only have one top cell") + topcell = ly.top_cell() + + # perform verification + file_lyrdb = str(gdspath) + ".lyrdb" + num_errors = SiEPIC.verification.layout_check(cell=topcell, file_rdb=file_lyrdb) + + if show_klive: + klive.show(gdspath, lyrdb_filename=file_lyrdb) + + return num_errors + + +if __name__ == "__main__": + import gdsfactory as gf + + file_path = PATH.repo / "tests" / "tests" / "mmi2x2.oas" + c = gf.import_gds(file_path, read_metadata=True) + + layout_check(c)