Skip to content

Commit

Permalink
find_pins, hierarchical improvement (WIP)
Browse files Browse the repository at this point in the history
- allow for overlapping pins, in different cells. Look for exact pin match. Implemented in PinA. Needs to be done for PinB.
@lukasc-ubc
  • Loading branch information
lukasc-ubc committed Jul 6, 2024
1 parent 2691501 commit b5a6a0b
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 22 deletions.
12 changes: 8 additions & 4 deletions klayout_dot_config/python/SiEPIC/extend.py
Original file line number Diff line number Diff line change
Expand Up @@ -749,10 +749,14 @@ def find_pins(self, verbose=False, polygon_devrec=None, GUI=False):
while not(iter2.at_end()):
if iter2.shape().is_text():
pin_name = iter2.shape().text.string
iter2.next()
if pin_name and pin_path.num_points()==2:
# Store the pin information in the pins array
pins.append(Pin(path=pin_path, _type=_globals.PIN_TYPES.OPTICAL, pin_name=pin_name))
# make sure that the Pin's path and text are in the same cell:
if it.shape().cell.name == iter2.shape().cell.name:
# Store the pin information in the pins array
pins.append(Pin(path=pin_path, _type=_globals.PIN_TYPES.OPTICAL, pin_name=pin_name))
if verbose:
print(' - found pin: %s in cell %s, in %s, text %s' % (pin_name, subcell.name, it.shape().cell.name, iter2.shape().cell.name ))
iter2.next()
if pin_name == None or pin_path.num_points()!=2:
print("Invalid pin Path detected: %s. Cell: %s" % (pin_path, subcell.name))
error_text += ("Invalid pin Path detected: %s, in Cell: %s, Optical Pins must have a pin name.\n" %
Expand Down Expand Up @@ -1767,7 +1771,7 @@ def find_pin(self, pin_name, verbose=False):
raise Exception ('Multiple Pins with name "%s" found in cell "%s"' % (pin_name, self.cell.basic_name()) )
return p[0]
else:
raise Exception ('Pin with name "%s" not found in cell "%s"' % (pin_name, self.cell.basic_name()) )
raise Exception ('Pin with name "%s" not found in cell "%s". Available pins: %s' % (pin_name, self.cell.basic_name(), [p.pin_name for p in pins]) )
else:
raise Exception ('No Pins found in cell "%s"' % (self.cell.basic_name()) )

Expand Down
47 changes: 30 additions & 17 deletions klayout_dot_config/python/SiEPIC/scripts.py
Original file line number Diff line number Diff line change
Expand Up @@ -205,45 +205,58 @@ def connect_pins_with_waveguide(instanceA, pinA, instanceB, pinB, waveguide = No

else:
cell=instanceA.parent_cell

# Find the two components:
from time import time
t = time()
# benchmarking: find_components here takes 0.015 s
componentA = instanceA.parent_cell.find_components(inst=instanceA)
componentB = instanceB.parent_cell.find_components(inst=instanceB)
# print('Time elapsed: %s' % (time() - t))
if componentA==[]:
print('InstA: %s, %s' % (instanceA.cell.name, instanceA) )
print('componentA: %s' % (componentA) )
print('parent_cell A: %s, cell A: %s' % (instanceA.parent_cell, instanceA.cell) )
print('all found components A: instance variable: %s' % ([n.instance for n in instanceA.parent_cell.find_components()]) )
print('all found components A: component variable: %s' % ([n.component for n in instanceA.parent_cell.find_components()]) )
raise Exception("Component '%s' not found. \nCheck that the component is correctly built (DevRec and PinRec layers). \nTry SiEPIC > Layout > Show Selected Component Information for debugging." %instanceA.cell.name)

# Find the instance's pins, and see if they uniquely match
ipinA = [p for p in instanceA.find_pins()[0] if p.pin_name == pinA]
ipinB = [p for p in instanceB.find_pins()[0] if p.pin_name == pinB]
if len(ipinA) == 1:
cpinA = ipinA
if verbose:
print(' - connect_pins_with_waveguide: found unique pin %s' % pinA)
else:
if verbose:
print(' - connect_pins_with_waveguide: searching for pin %s' % pinA)
componentA = instanceA.parent_cell.find_components(inst=instanceA)
if componentA==[]:
print('InstA: %s, %s' % (instanceA.cell.name, instanceA) )
print('componentA: %s' % (componentA) )
print('parent_cell A: %s, cell A: %s' % (instanceA.parent_cell, instanceA.cell) )
print('all found components A: instance variable: %s' % ([n.instance for n in instanceA.parent_cell.find_components()]) )
print('all found components A: component variable: %s' % ([n.component for n in instanceA.parent_cell.find_components()]) )
raise Exception("Component '%s' not found. \nCheck that the component is correctly built (DevRec and PinRec layers). \nTry SiEPIC > Layout > Show Selected Component Information for debugging." %instanceA.cell.name)
# if the instance had sub-cells, then there will be many components. Pick the first one.
if type(componentA) == type([]):
componentA = componentA[0]
# Find pinA and pinB
cpinA = [p for p in componentA.pins if p.pin_name == pinA]


componentB = instanceB.parent_cell.find_components(inst=instanceB)
if componentB==[]:
print('InstB: %s, %s' % (instanceB.cell.name, instanceB) )
print('componentB: %s' % (componentB) )
print('parent_cell B: %s, cell B: %s' % (instanceB.parent_cell, instanceB.cell) )
print('all found components B: instance variable: %s' % ([n.instance for n in instanceB.parent_cell.find_components()]) )
print('all found components B: component variable: %s' % ([n.component for n in instanceB.parent_cell.find_components()]) )
raise Exception("Component '%s' not found. \nCheck that the component is correctly built (DevRec and PinRec layers). \nTry SiEPIC > Layout > Show Selected Component Information for debugging." %instanceB.cell.name)

# if the instance had sub-cells, then there will be many components. Pick the first one.
if type(componentA) == type([]):
componentA = componentA[0]
if type(componentB) == type([]):
componentB = componentB[0]
# Find pinA and pinB
cpinB = [p for p in componentB.pins if p.pin_name == pinB]

if verbose:
print('InstA: %s, InstB: %s' % (instanceA, instanceB) )
print('componentA: %s, componentB: %s' % (componentA, componentB) )

componentA.display()
componentB.display()

# Find pinA and pinB
cpinA = [p for p in componentA.pins if p.pin_name == pinA]
cpinB = [p for p in componentB.pins if p.pin_name == pinB]

# relaxed_pinnames: scan for only the number
if relaxed_pinnames==True:
Expand Down
6 changes: 5 additions & 1 deletion klayout_dot_config/python/SiEPIC/utils/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,14 +63,18 @@
import pya
'''

def create_cell2(ly, cell_name, library_name):
def create_cell2(ly, cell_name, library_name, load_check=True):
'''
Wrapper for KLayout Layout.create_cell(name, library),
with error handling, and debugging information if unsuccessful.
ly: pya.Layout
cell_name: string name for pya.Cell
library_name: string name for a pya.Library
'''
# check if it is already loaded
if load_check and ly.cell(cell_name):
return ly.cell(cell_name)
# load the cell from the library
pcell = ly.create_cell(cell_name, library_name)
if not pcell:
if library_name not in pya.Library().library_names():
Expand Down
3 changes: 3 additions & 0 deletions klayout_dot_config/python/SiEPIC/utils/layout.py
Original file line number Diff line number Diff line change
Expand Up @@ -494,6 +494,9 @@ def layout_waveguide2(TECHNOLOGY, layout, cell, layers, widths, offsets, pts, ra

wg_pts += [pts[-1]]
wg_pts = pya.Path(wg_pts, 0).unique_points().get_points()
if len(wg_pts) < 2:
print (' - warning: SiEPIC.utils.layout.layout_waveguide2: less than 2 points.')
return 0
wg_polygon = Polygon(translate_from_normal(wg_pts, width/2 + (offset if turn > 0 else - offset)) +
translate_from_normal(wg_pts, -width/2 + (offset if turn > 0 else - offset))[::-1])
cell.shapes(layer).insert(wg_polygon)
Expand Down

0 comments on commit b5a6a0b

Please sign in to comment.