def chip_frame(size=(20e3, 20e3), street_width=150, street_length=1e3, layer=pt.LayoutDefault.layerTop, name=None, text_pos={ 'anchor_source': 's', 'anchor_dest': 's' }): die_cell = pg.basic_die(size=size, die_name="", layer=layer, draw_bbox=False, street_length=street_length, street_width=street_width) if name is not None: cell = dl.Device(name=str(name.label)) else: cell = dl.Device(name='default') cell.absorb(cell << die_cell) if name is not None: text_cell = name.draw() pt._move_relative_to_cell(cell << text_cell, cell, **text_pos) return cell
def align_TE_on_via(): cell = dl.Device("Align TE on VIA") circle = pg.circle(radius=50, layer=pt.LayoutDefault.layerVias) cross = pg.cross(width=30, length=250, layer=pt.LayoutDefault.layerVias) g = Group([circle, cross]) g.align(alignment='x') g.align(alignment='y') circle.add(cross) viapattern = pg.union(circle, 'A+B', layer=pt.LayoutDefault.layerVias) TEpattern = pg.union(circle, 'A+B', layer=pt.LayoutDefault.layerTop).copy('tmp', scale=0.8) cell.add(viapattern) cell.add(TEpattern) cell.align(alignment='x') cell.align(alignment='y') cell.flatten() return cell
def load_gds(cells): if isinstance(cells, str): cells = pathlib.Path(cells) elif isinstance(cells, list) or isinstance(cells, tuple): cells_logo = [] for p in cells: if isinstance(p, str): # import pdb ; pdb.set_trace() cells_logo.append(pg.import_gds(p)) elif isinstance(p, pathlib.Path): cells_logo.append(pg.import_gds(str(p.absolute()))) g = Group(cells_logo) g.distribute(direction='x', spacing=150) g.align(alignment='y') logo_cell = dl.Device(name="cells") for c in cells_logo: logo_cell.add(c) logo_cell.flatten() logo_cell.name = 'Logos' return logo_cell
import phidl.geometry as pg import phidl.device_layout as dl r = pg.rectangle() p = dl.Device('parent') rect_ref = p.add_ref(r, alias='rect_ref') rect_ref.move(destination=(5, 0)) gp = dl.Device('grandparent') parent_ref = gp.add_ref(p, alias='parent_ref') parent_ref.move(destination=(5, 0)) print(gp['parent_ref'].parent['rect_ref'].origin)
def verniers(scale=[1, 0.5, 0.1], layers=[1, 2], label='TE', text_size=20, reversed=False): """ Create a cell with vernier aligners. Parameters ---------- scale : iterable of float (default [1,0.5,0.25]) each float in list is the offset of a vernier. for each of them a vernier will be created in the X-Y axis layers : 2-len iterable of int (default [1,2]) define the two layers for the verniers. label : str (default "TE") add a label to the set of verniers. text_size : float (default) label size reversed : boolean if true, creates a negative alignment mark for the second layer Returns ------- cell : phidl.Device. """ cell = dl.Device(name="verniers") import numpy if not isinstance(scale, numpy.ndarray): scale = np.array(scale) scale = np.sort(scale) xvern = [] for dim in scale: notch_size = [dim * 5, dim * 25] notch_spacing = dim * 10 num_notches = 5 notch_offset = dim row_spacing = 0 layer1 = layers[0] layer2 = layers[1] cal=pg.litho_calipers(\ notch_size,\ notch_spacing,\ num_notches,\ notch_offset,\ row_spacing,\ layer1,\ layer2) cal.flatten() if reversed: tobedel = cal.get_polygons(by_spec=(layer2, 0)) cal = cal.remove_polygons( lambda pts, layer, datatype: layer == layer2) replica = dl.Device() replica.add(gdspy.PolygonSet(tobedel, layer=layer2)) frame = dl.Device() frame.add(pg.bbox(replica.bbox, layer=layer2)) frame_ext = dl.Device() frame_ext.add( gdspy.PolygonSet(frame.copy('tmp', scale=1.5).get_polygons(), layer=layer2)) frame_ext.flatten() frame_ext.move(origin=frame_ext.center, destination=replica.center) new_cal = pg.boolean(replica, frame_ext, 'xor', layer=layer2) new_cal.rotate(angle=180, center=(cal.xmin + cal.xsize / 2, cal.ymin)) new_cal.move(destination=(0, -notch_size[1])) cal << new_cal cal.flatten() xvern.append(cal) g = dl.Group(xvern) g.distribute(direction='y', spacing=scale[-1] * 20) g.align(alignment='x') xcell = dl.Device(name="x") for x in xvern: xcell << x xcell = pt.join(xcell) vern_x = cell << xcell vern_y = cell << xcell vern_y.rotate(angle=-90) vern_y.move(origin=(vern_y.xmin,vern_y.y),\ destination=(vern_x.x+scale[-1]*10,vern_x.ymin-scale[-1]*10)) cell.absorb(vern_x) cell.absorb(vern_y) label = pg.text(text=label, size=text_size, layer=layers[0]) label.move(destination=(cell.xmax - label.xsize / 2, cell.ymax - 2 * label.ysize)) overlabel = pg.bbox(label.bbox, layer=layers[1]) overlabel_scaled = dl.Device().add( gdspy.PolygonSet(overlabel.copy('tmp', scale=2).get_polygons(), layer=layers[1])) overlabel_scaled.move(origin=overlabel_scaled.center,\ destination=label.center) cutlab = pg.boolean(label, overlabel_scaled, 'xor', layer=layers[1]) cell << label cell << cutlab cell = pt.join(cell) return cell