Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace cell #230

Merged
merged 7 commits into from
Nov 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 54 additions & 2 deletions klayout_dot_config/python/SiEPIC/scripts.py
Original file line number Diff line number Diff line change
Expand Up @@ -3075,6 +3075,48 @@ def button(self):
wdg.show()


def check_bb_geometries(topcell, BB_layerinfo=pya.LayerInfo(998,0), verbose=True):
'''
Check if there are any Black Box layers in the layout.
Returns:
Count: number of different shapes
Args:
topcell: pya.Cell
BB_layerinfo: pya.LayerInfo
'''
layout = topcell.layout()
layer_bb = layout.layer(BB_layerinfo) # hard coded for the GSiP PDK
r1 = pya.Region(topcell.begin_shapes_rec(layer_bb))
diff_count = 0
if not r1.is_empty():
diff_count = r1.size()
if verbose:
print(
f" - SiEPIC.scripts.check_bb_geometries: {r1.size()} Black Box geometry(ies) found in {topcell.name} on layer {layout.get_info(layer_bb)}."
)
else:
if verbose:
print('Black box replacement -- success -- no black box layers remaining.')
return diff_count

def cells_containing_bb_layers(topcell, BB_layerinfo=pya.LayerInfo(998,0), verbose=True):
'''
return a list of cell names that contain black box polygons
Args:
topcell: pya.Cell
BB_layerinfo: pya.LayerInfo
'''
layout = topcell.layout()
iter1 = pya.RecursiveShapeIterator(layout, topcell, layout.layer(BB_layerinfo) )
cells = []
while not iter1.at_end():
cells.append (iter1.cell().name)
if verbose:
print(" - %s" % iter1.cell().name)
iter1.next()
# return unique cell names
return sorted(list(set(cells)))

def layout_diff(cell1, cell2, tol = 1, verbose=True):
'''
Check two cells to make sure they are identical, within a tolerance.
Expand Down Expand Up @@ -3135,7 +3177,7 @@ def layout_diff(cell1, cell2, tol = 1, verbose=True):
return diff_count


def replace_cell(layout, cell_x_name = None, cell_y_name=None, cell_y_file=None, cell_y_library=None, cell_ref_bb = None, Exact = True, RequiredCharacter = '$', run_layout_diff = True, debug = False):
def replace_cell(layout, cell_x_name = None, cell_y_name=None, cell_y_file=None, cell_y_library=None, cell_ref_bb = None, Exact = True, RequiredCharacter = '$', run_layout_diff = False, debug = False):
'''
SiEPIC-Tools: scripts.replace_cell
Search and replace: cell_x with cell_y
Expand All @@ -3158,6 +3200,13 @@ def replace_cell(layout, cell_x_name = None, cell_y_name=None, cell_y_file=None,
Basename, Basename* NO: Basename_extension
Basename, Basename* YES: DifferentName
'''

# Find the cell name from the cell_ref_bb
if not cell_x_name:
if cell_ref_bb:
cell_x_name = cell_ref_bb.name
else:
raise Exception ('missing replacement cell name')

import os
if debug:
Expand All @@ -3179,7 +3228,10 @@ def replace_cell(layout, cell_x_name = None, cell_y_name=None, cell_y_file=None,

# Find the cells that need replacement (cell_x)
# find cell name exactly matching cell_x_name
cells_x = [layout.cell(cell_x_name)]
if layout.cell(cell_x_name):
cells_x = [layout.cell(cell_x_name)]
else:
cells_x = []
if not Exact:
# replacement for all cells that:
# 1) cell name exact matching cell_x_name, OR
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@

"""

def test_replace_cell():
def test_replace_cell(show_klive=False):
'''

show_klive: True to open the layout in KLayout using KLive
'''

import pya
Expand All @@ -29,7 +29,7 @@ def test_replace_cell():
raise Exception("Errors", "This example requires SiEPIC-Tools version 0.5.4 or greater.")


from SiEPIC.scripts import replace_cell, delete_extra_topcells
from SiEPIC.scripts import replace_cell, delete_extra_topcells, cells_containing_bb_layers, check_bb_geometries

# The circuit layout that contains BB cells
path = os.path.dirname(os.path.realpath(__file__))
Expand All @@ -51,20 +51,6 @@ def test_replace_cell():
ly_wb.read(file_wb)
cell_wb = ly_wb.top_cell()
'''
def check_bb_geometries(layout):
'''
check if there are any Black Box layers in the layout
'''
layer_bb = layout.layer(pya.LayerInfo(998,0)) # hard coded for the GSiP PDK
r1 = pya.Region(top_cell.begin_shapes_rec(layer_bb))
diff_count = 0
if not r1.is_empty():
diff_count = r1.size()
print(
f" - SiEPIC.scripts.layout_diff: {r1.size()} Black Box geometry(ies) found in {top_cell.name} on layer {layout.get_info(layer_bb)}."
)
return diff_count


# Check -- exact replacement (without $)
if 1:
Expand All @@ -77,18 +63,17 @@ def check_bb_geometries(layout):
)
print('replaced %s' %count)
assert count == 1
assert check_bb_geometries(layout) == 1
assert check_bb_geometries(top_cell) == 1
assert cells_containing_bb_layers(top_cell) == ['ebeam_y_adiabatic_500pin$1']

file_out = os.path.join(path,'example_replaced.gds')
delete_extra_topcells(layout, top_cell.name)
layout.write(file_out)
try:
if show_klive:
# Display the layout in KLayout, using KLayout Package "klive", which needs to be installed in the KLayout Application
if Python_Env == 'Script':
from SiEPIC.utils import klive
klive.show(file_out, technology='EBeam')
except:
pass
os.remove(file_out)


Expand All @@ -106,18 +91,17 @@ def check_bb_geometries(layout):
)
print('replaced %s' %count)
assert count == 2
assert check_bb_geometries(layout) == 0
assert check_bb_geometries(top_cell) == 0
assert cells_containing_bb_layers(top_cell) == []

file_out = os.path.join(path,'example_replaced2.gds')
delete_extra_topcells(layout, top_cell.name)
layout.write(file_out)
try:
if show_klive:
# Display the layout in KLayout, using KLayout Package "klive", which needs to be installed in the KLayout Application
if Python_Env == 'Script':
from SiEPIC.utils import klive
klive.show(file_out, technology='EBeam')
except:
pass
os.remove(file_out)

# Check -- Run BB reference vs. design layout difference, non-exact replacement (with $)
Expand All @@ -134,8 +118,9 @@ def check_bb_geometries(layout):
)
print('replaced %s' %count)
assert count == 2
assert check_bb_geometries(layout) == 0
assert check_bb_geometries(top_cell) == 0
assert error == False
assert cells_containing_bb_layers(top_cell) == []

# Check -- Run BB reference (changed) vs. design layout difference, non-exact replacement (with $)
if 1:
Expand All @@ -157,4 +142,4 @@ def check_bb_geometries(layout):
assert error == True

if __name__ == "__main__":
test_replace_cell()
test_replace_cell(show_klive=True)
11 changes: 6 additions & 5 deletions klayout_dot_config/tech/GSiP/pymacros/tests/test_FaML.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

"""

def test_FaML_two():
def test_FaML_two(show_klive=False):
'''
--- Simple MZI, tested using Facet-Attached Micro Lenses (FaML) ---

Expand Down Expand Up @@ -102,13 +102,14 @@ def test_FaML_two():
print('Number of errors: %s' % num_errors)

# Display the layout in KLayout, using KLayout Package "klive", which needs to be installed in the KLayout Application
if Python_Env == 'Script':
from SiEPIC.utils import klive
klive.show(file_out, lyrdb_filename=file_lyrdb, technology=tech_name)
if show_klive:
if Python_Env == 'Script':
from SiEPIC.utils import klive
klive.show(file_out, lyrdb_filename=file_lyrdb, technology=tech_name)
os.remove(file_out)

if num_errors > 0:
raise Exception ('Errors found in test_FaML_two')

if __name__ == "__main__":
test_FaML_two()
test_FaML_two(show_klive=True)
11 changes: 6 additions & 5 deletions klayout_dot_config/tech/GSiP/pymacros/tests/test_SiEPIC_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ def test_create_cell2():
topcell.insert(CellInstArray(cell_y.cell_index(), t))


def test_waveguide_length():
def test_waveguide_length(show_klive=False):
import pya
import SiEPIC
from SiEPIC._globals import Python_Env
Expand Down Expand Up @@ -124,9 +124,10 @@ def test_waveguide_length():

# Display in KLayout
from SiEPIC._globals import Python_Env
if Python_Env == 'Script':
from SiEPIC.utils import klive
klive.show(file_out, technology=tech_name, keep_position=True)
if show_klive:
if Python_Env == 'Script':
from SiEPIC.utils import klive
klive.show(file_out, technology=tech_name, keep_position=True)
os.remove(file_out)


Expand All @@ -137,4 +138,4 @@ def test_waveguide_length():
if __name__ == "__main__":
test_load_layout()
test_create_cell2()
test_waveguide_length()
test_waveguide_length(show_klive=True)
20 changes: 11 additions & 9 deletions klayout_dot_config/tech/GSiP/pymacros/tests/test_bezier.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

from pya import *

def test_bezier_bends():
def test_bezier_bends(show_klive=False):
designer_name = 'Test_Bezier_bend'
top_cell_name = 'GSiP_%s' % designer_name

Expand Down Expand Up @@ -124,15 +124,16 @@ def test_bezier_bends():

# Display in KLayout
from SiEPIC._globals import Python_Env
if Python_Env == 'Script':
from SiEPIC.utils import klive
klive.show(file_out, technology=tech_name, keep_position=True)
if show_klive:
if Python_Env == 'Script':
from SiEPIC.utils import klive
klive.show(file_out, technology=tech_name, keep_position=True)
os.remove(file_out)
# Plot
# cell.plot() # in the browser


def test_bezier_tapers():
def test_bezier_tapers(show_klive=False):
designer_name = 'Test_Bezier_tapers'
top_cell_name = 'GSiP_%s' % designer_name

Expand Down Expand Up @@ -220,9 +221,10 @@ def test_bezier_tapers():

# Display in KLayout
from SiEPIC._globals import Python_Env
if Python_Env == 'Script':
from SiEPIC.utils import klive
klive.show(file_out, technology=tech_name, keep_position=True)
if show_klive:
if Python_Env == 'Script':
from SiEPIC.utils import klive
klive.show(file_out, technology=tech_name, keep_position=True)
os.remove(file_out)

# Plot
Expand All @@ -231,5 +233,5 @@ def test_bezier_tapers():

if __name__ == "__main__":
# test_bezier_bends()
test_bezier_tapers()
test_bezier_tapers(show_klive=True)

Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

"""

def test_coupler_array():
def test_coupler_array(show_klive=False):
'''
--- Simple MZI, tested using Facet-Attached Micro Lenses (FaML) ---

Expand Down Expand Up @@ -101,13 +101,14 @@ def test_coupler_array():
print('Number of errors: %s' % num_errors)

# Display the layout in KLayout, using KLayout Package "klive", which needs to be installed in the KLayout Application
if Python_Env == 'Script':
from SiEPIC.utils import klive
klive.show(file_out, lyrdb_filename=file_lyrdb, technology=tech_name)
if show_klive:
if Python_Env == 'Script':
from SiEPIC.utils import klive
klive.show(file_out, lyrdb_filename=file_lyrdb, technology=tech_name)
os.remove(file_out)

if num_errors > 0:
raise Exception ('Errors found in test_coupler_array')

if __name__ == "__main__":
test_coupler_array()
test_coupler_array(show_klive=True)
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

from pya import *

def example_circuit():
def example_circuit(show_klive=False):
designer_name = 'Test'
top_cell_name = 'GSiP_%s' % designer_name

Expand Down Expand Up @@ -122,9 +122,10 @@ def example_circuit():

# Display in KLayout
from SiEPIC._globals import Python_Env
if Python_Env == 'Script':
from SiEPIC.utils import klive
klive.show(file_out, technology=tech_name, keep_position=True)
if show_klive:
if Python_Env == 'Script':
from SiEPIC.utils import klive
klive.show(file_out, technology=tech_name, keep_position=True)
os.remove(file_out)

# Plot
Expand All @@ -143,5 +144,5 @@ def test_example_circuit():
assert example_circuit() == 0

if __name__ == "__main__":
example_circuit()
example_circuit(show_klive=True)

Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

from pya import *

def test_all_library_cells():
def test_all_library_cells(show_klive=False):
designer_name = 'Test'
top_cell_name = 'GSiP_%s' % designer_name

Expand Down Expand Up @@ -54,7 +54,8 @@ def test_all_library_cells():
if c.is_empty() or c.bbox().area() == 0:
raise Exception('Empty cell: %s' % c.name)

topcell.show()
if show_klive:
topcell.show()

# Verify
num_errors = layout_check(cell=topcell, verify_DFT=False, verbose=False, GUI=True)
Expand All @@ -64,4 +65,4 @@ def test_all_library_cells():


if __name__ == "__main__":
test_all_library_cells()
test_all_library_cells(show_klive=True)
Loading