class PI(i3.PCell): _name_prefix = "PI" # Center of the structure position = i3.Coord2Property(default=(0.0, 0.0)) # Layer layer = i3.LayerProperty(default=i3.TECH.PPLAYER.HFW) layer_bool = i3.LayerProperty(default=i3.TECH.PPLAYER.NONE.DOC) # Mesa parameters length = i3.PositiveNumberProperty(default=7000.0) width = i3.PositiveNumberProperty(default=630.0) pocket = i3.BoolProperty(default=False) tilt = i3.BoolProperty(default=False) # Recess label label = i3.StringProperty(default="PI_") class Layout(i3.LayoutView): def _generate_elements(self, elems): # Center of the structure (x0, y0) = self.position elems += i3.Rectangle(layer=self.layer, center=(x0 + 6500, y0 + 1000 + (3000 - self.width) / 4), box_size=(self.length, (3000 - self.width) / 2)) elems += i3.Rectangle(layer=self.layer, center=(x0 + 6500, y0 + 1000 + self.width + (3000 - self.width) * 3 / 4), box_size=(self.length, (3000 - self.width) / 2)) elems += i3.SRef(reference=Interface(pocket=self.pocket, tilt=self.tilt)) for i in range(7): elems += i3.Rectangle(layer=self.layer, center=(10000 - 725 - i * 750, 1000 + (3000 - self.width) / 2 + 185), box_size=(50, 50)) elems += i3.Rectangle(layer=self.layer, center=(10000 - 725 - i * 750, 1000 + (3000 - self.width) / 2 + self.width - 185), box_size=(50, 50)) if self.pocket: self.label += "WP" if self.tilt: self.label += "WT" elems += i3.PolygonText(layer=self.layer_bool, text=self.label, coordinate=(6000, 4000), # alignment=(i3.TEXT_ALIGN_LEFT, i3.TEXT_ALIGN_LEFT), font=2, height=700.0) generated1 = self.layer - self.layer_bool mapping = {generated1: self.layer} elems = i3.get_elements_for_generated_layers(elems, mapping) return elems
class Interface_mmi12(i3.PCell): _name_prefix = "INTERFACE_" # Center of the structure position = i3.Coord2Property(default=(0.0, 0.0)) # Layer layer = i3.LayerProperty(default=i3.TECH.PPLAYER.HFW) layer_bool = i3.LayerProperty(default=i3.TECH.PPLAYER.NONE.DOC) # Mesa parameters length = i3.PositiveNumberProperty(default=2500) # shrink width = i3.PositiveNumberProperty(default=3000.0 * 0.6) pocket = i3.BoolProperty(default=False) tilt = i3.BoolProperty(default=False) class Layout(i3.LayoutView): def _generate_elements(self, elems): # Center of the structure (x0, y0) = self.position elems += i3.Rectangle(layer=self.layer, center=(x0 + 7500 + 2000+1500, y0 + 4500 - 1800+500), box_size=(10000, 1600)) # change # elems += i3.Rectangle(layer=i3.TECH.PPLAYER.NONE.DOC, center=(x0 + 7500, y0 + 4500), # box_size=(15000, 1000)) elems += i3.Rectangle(layer=self.layer, center=(x0 + 7500 + 2000+1500, y0 + 500 - 200-500), box_size=(10000, 1600)) elems += i3.Rectangle(layer=self.layer, center=(x0 + 12500 + 1000 - 250, y0 + 2500 - 1000), # change box_size=(self.length, self.width)) elems +=i3.Rectangle(layer=self.layer, center=(x0+ 15250, y0+1500),box_size=(1500,1800)) #add if self.pocket: PO = i3.Rectangle(layer=self.layer_bool, center=(10001 + 2000, 2500 - 1000), box_size=(2, 160)) # change elems += PO generated1 = self.layer - self.layer_bool mapping = {generated1: self.layer} elems = i3.get_elements_for_generated_layers(elems, mapping) if self.tilt: # TI = i3.Rectangle(layer=self.layer_bool, center=(10001, 2500), box_size=(2, 160)) # elems += TI TI_shape = i3.Shape(points=[(10000.0 + 2000, 2470.0 - 1000), (10010.58 + 2000, 2530.0 - 1000), (10000.0 + 2000, 2530.0 - 1000)], closed=True) # change TI = i3.Boundary(layer=self.layer_bool, shape=TI_shape) elems += TI generated1 = self.layer - self.layer_bool mapping = {generated1: self.layer} elems = i3.get_elements_for_generated_layers(elems, mapping) return elems
class SiN_NP(i3.PCell): _name_prefix = "SiN_NP" # Center of the structure position = i3.Coord2Property(default=(0.0, 0.0)) # Layer layer = i3.LayerProperty(default=i3.TECH.PPLAYER.SIL.LINE) layer_bool = i3.LayerProperty(default=i3.TECH.PPLAYER.NONE.DOC) # Mesa parameters length = i3.PositiveNumberProperty(default=7000.0) width = i3.PositiveNumberProperty(default=330.0) pillar = i3.BoolProperty(default=False) tilt_0 = i3.BoolProperty(default=False) class Layout(i3.LayoutView): def _generate_elements(self, elems): # Center of the structure (x0, y0) = self.position elems += i3.Rectangle(layer=self.layer, center=(1500 - 20, 2500), box_size=(3000 - 40, 3000 - 40 * 2)) if self.tilt_0: elems += i3.Rectangle(layer=self.layer, center=(x0 + 6500 - 40 + 20 + 7.5, 2500), box_size=(self.length + 40 + 15, self.width - 40 * 2)) else: elems += i3.Rectangle(layer=self.layer, center=(x0 + 6500 - 40 + 20 + 5, 2500), box_size=(self.length + 40 + 10, self.width - 40 * 2)) if self.pillar: for i in range(7): elems += i3.Rectangle( layer=self.layer_bool, center=(10000 - 725 - i * 750, 1000 + (3000 - self.width) / 2 + 30), box_size=(130, 140)) elems += i3.Rectangle( layer=self.layer_bool, center=(10000 - 725 - i * 750, 1000 + (3000 - self.width) / 2 + self.width - 30), box_size=(130, 140)) generated1 = self.layer - self.layer_bool mapping = {generated1: self.layer} elems = i3.get_elements_for_generated_layers(elems, mapping) return elems
class Layout(i3.LayoutView): """ Cross marker Layout view """ inversion = i3.BoolProperty( default=False, doc="if True: open cross - white cross on black background") cross_bar_width = i3.PositiveNumberProperty(default=8, doc="width of the cross") cross_boundary_width = i3.PositiveNumberProperty( default=50, doc="width the boundary box") #process = i3.ProcessProperty(default=i3.TECH.PPLAYER.CH2.TRENCH)#i3.TECH.PROCESS.WG, doc="Process Layer on which the cross is drawn") # Purpose Property cannot be set from outside #purpose = i3.PurposeProperty(locked=True, default=i3.TECH.PPLAYER.CH2.TRENCH)#i3.TECH.PURPOSE.DF.LINE, doc="Process Purpose of the cross") def _generate_elements(self, elems): rect_size = (self.cross_boundary_width - self.cross_bar_width) / 2 rect_center = self.cross_bar_width / 2 + rect_size / 2 if not self.inversion: # Dark cross elems += i3.Cross( layer=i3.TECH.PPLAYER.CH1. TRENCH, #i3.PPLayer(self.process,self.purpose), center=(0, 0), box_size=self.cross_boundary_width, thickness=self.cross_bar_width) else: # Open cross: formed by 4 dark squares at corners elems += i3.Rectangle( layer=i3.TECH.PPLAYER.CH2. TRENCH, #i3.PPLayer(self.process, self.purpose), center=(rect_center, rect_center), box_size=(rect_size, rect_size)) elems += i3.Rectangle( layer=i3.TECH.PPLAYER.CH2. TRENCH, #i3.PPLayer(self.process, self.purpose), center=(rect_center, -rect_center), box_size=(rect_size, rect_size)) elems += i3.Rectangle( layer=i3.TECH.PPLAYER.CH2. TRENCH, #i3.PPLayer(self.process, self.purpose), center=(-rect_center, rect_center), box_size=(rect_size, rect_size)) elems += i3.Rectangle( layer=i3.TECH.PPLAYER.CH2. TRENCH, #i3.PPLayer(self.process, self.purpose), center=(-rect_center, -rect_center), box_size=(rect_size, rect_size)) return elems
class AlignmentMarker(i3.PCell): _name_prefix = "ALIGNMENT MARKER" # Center of the structure position = i3.Coord2Property(default=(0.0, 0.0)) # Layer layer = i3.LayerProperty(required=True) # Complement complement = i3.BoolProperty(default=False) # Protection protection = i3.BoolProperty(default=False) # Marker parameters cross_length = i3.PositiveNumberProperty(default=150.0) cross_width = i3.PositiveNumberProperty(default=16.0) cross_margin = i3.PositiveNumberProperty(default=4.0) vernier_length = i3.PositiveNumberProperty(default=30.0) vernier_width = i3.PositiveNumberProperty(default=8.0) vernier_period = i3.PositiveNumberProperty(default=20.25) vernier_left_center = i3.Coord2Property(default=(-121.0, 24.0)) vernier_top_center = i3.Coord2Property(default=(-6.0, 119.0)) vernier_complement_length = i3.PositiveNumberProperty(default=18.0) vernier_complement_long_length = i3.PositiveNumberProperty(default=28.0) vernier_complement_width = i3.PositiveNumberProperty(default=10.0) vernier_complement_shift = i3.PositiveNumberProperty(default=9.0) vernier_complement_period = i3.PositiveNumberProperty(default=20) protection_length = i3.PositiveNumberProperty(default=300.0) protection_width = i3.PositiveNumberProperty(default=320.0) # Layer text layer_text = i3.StringProperty(default="Mesa") class Layout(i3.LayoutView): def _generate_elements(self, elems): # Center of the structure (x0, y0) = self.position shift = 0.5 * self.cross_width + self.cross_margin square_length = 0.5 * self.cross_length - shift if (self.complement == False and self.protection == False): # Add cross elems += i3.Rectangle(layer=self.layer, center=(x0, y0), box_size=(self.cross_length, self.cross_width)) elems += i3.Rectangle(layer=self.layer, center=(x0, y0), box_size=(self.cross_width, self.cross_length)) # Add rectangles left VERNIER elems += i3.Rectangle(layer=self.layer, center=(self.vernier_left_center[0], self.vernier_left_center[1]), box_size=(self.vernier_length, self.vernier_width)) elems += i3.Rectangle( layer=self.layer, center=(self.vernier_left_center[0], self.vernier_left_center[1] + self.vernier_period), box_size=(self.vernier_length, self.vernier_width)) elems += i3.Rectangle(layer=self.layer, center=(self.vernier_left_center[0], self.vernier_left_center[1] + 2.0 * self.vernier_period), box_size=(self.vernier_length, self.vernier_width)) elems += i3.Rectangle(layer=self.layer, center=(self.vernier_left_center[0], self.vernier_left_center[1] + 3.0 * self.vernier_period), box_size=(self.vernier_length, self.vernier_width)) elems += i3.Rectangle(layer=self.layer, center=(self.vernier_left_center[0], self.vernier_left_center[1] + 4.0 * self.vernier_period), box_size=(self.vernier_length, self.vernier_width)) elems += i3.Rectangle( layer=self.layer, center=(self.vernier_left_center[0], self.vernier_left_center[1] - self.vernier_period), box_size=(self.vernier_length, self.vernier_width)) elems += i3.Rectangle(layer=self.layer, center=(self.vernier_left_center[0], self.vernier_left_center[1] - 2.0 * self.vernier_period), box_size=(self.vernier_length, self.vernier_width)) elems += i3.Rectangle(layer=self.layer, center=(self.vernier_left_center[0], self.vernier_left_center[1] - 3.0 * self.vernier_period), box_size=(self.vernier_length, self.vernier_width)) elems += i3.Rectangle(layer=self.layer, center=(self.vernier_left_center[0], self.vernier_left_center[1] - 4.0 * self.vernier_period), box_size=(self.vernier_length, self.vernier_width)) # Add rectangles top VERNIER elems += i3.Rectangle(layer=self.layer, center=(self.vernier_top_center[0], self.vernier_top_center[1]), box_size=(self.vernier_width, self.vernier_length)) elems += i3.Rectangle( layer=self.layer, center=(self.vernier_top_center[0] + self.vernier_period, self.vernier_top_center[1]), box_size=(self.vernier_width, self.vernier_length)) elems += i3.Rectangle(layer=self.layer, center=(self.vernier_top_center[0] + 2.0 * self.vernier_period, self.vernier_top_center[1]), box_size=(self.vernier_width, self.vernier_length)) elems += i3.Rectangle(layer=self.layer, center=(self.vernier_top_center[0] + 3.0 * self.vernier_period, self.vernier_top_center[1]), box_size=(self.vernier_width, self.vernier_length)) elems += i3.Rectangle(layer=self.layer, center=(self.vernier_top_center[0] + 4.0 * self.vernier_period, self.vernier_top_center[1]), box_size=(self.vernier_width, self.vernier_length)) elems += i3.Rectangle( layer=self.layer, center=(self.vernier_top_center[0] - self.vernier_period, self.vernier_top_center[1]), box_size=(self.vernier_width, self.vernier_length)) elems += i3.Rectangle(layer=self.layer, center=(self.vernier_top_center[0] - 2.0 * self.vernier_period, self.vernier_top_center[1]), box_size=(self.vernier_width, self.vernier_length)) elems += i3.Rectangle(layer=self.layer, center=(self.vernier_top_center[0] - 3.0 * self.vernier_period, self.vernier_top_center[1]), box_size=(self.vernier_width, self.vernier_length)) elems += i3.Rectangle(layer=self.layer, center=(self.vernier_top_center[0] - 4.0 * self.vernier_period, self.vernier_top_center[1]), box_size=(self.vernier_width, self.vernier_length)) # Add TEXT elems += i3.PolygonText(layer=self.layer, coordinate=(x0, y0 - 100.0), text=self.layer_text, height=35.0) elif (self.complement == True and self.protection == False): # Add squares elems += i3.Rectangle( layer=self.layer, center=(x0 - 0.25 * self.cross_length - 0.5 * shift, y0 + 0.25 * self.cross_length + 0.5 * shift), box_size=(square_length, square_length)) elems += i3.Rectangle( layer=self.layer, center=(x0 + 0.25 * self.cross_length + 0.5 * shift, y0 + 0.25 * self.cross_length + 0.5 * shift), box_size=(square_length, square_length)) elems += i3.Rectangle( layer=self.layer, center=(x0 - 0.25 * self.cross_length - 0.5 * shift, y0 - 0.25 * self.cross_length - 0.5 * shift), box_size=(square_length, square_length)) elems += i3.Rectangle( layer=self.layer, center=(x0 + 0.25 * self.cross_length + 0.5 * shift, y0 - 0.25 * self.cross_length - 0.5 * shift), box_size=(square_length, square_length)) # Add rectangles left VERNIER elems += i3.Rectangle( layer=self.layer, center=(self.vernier_left_center[0] - self.vernier_complement_shift - 0.5 * self.vernier_complement_long_length, self.vernier_left_center[1]), box_size=(self.vernier_complement_long_length, self.vernier_complement_width)) elems += i3.Rectangle( layer=self.layer, center=(self.vernier_left_center[0] + self.vernier_complement_shift + 0.5 * self.vernier_complement_long_length, self.vernier_left_center[1]), box_size=(self.vernier_complement_long_length, self.vernier_complement_width)) elems += i3.Rectangle( layer=self.layer, center=(self.vernier_left_center[0] - self.vernier_complement_shift - 0.5 * self.vernier_complement_length, self.vernier_left_center[1] + self.vernier_complement_period), box_size=(self.vernier_complement_length, self.vernier_complement_width)) elems += i3.Rectangle( layer=self.layer, center=(self.vernier_left_center[0] + self.vernier_complement_shift + 0.5 * self.vernier_complement_length, self.vernier_left_center[1] + self.vernier_complement_period), box_size=(self.vernier_complement_length, self.vernier_complement_width)) elems += i3.Rectangle( layer=self.layer, center=(self.vernier_left_center[0] - self.vernier_complement_shift - 0.5 * self.vernier_complement_length, self.vernier_left_center[1] + 2.0 * self.vernier_complement_period), box_size=(self.vernier_complement_length, self.vernier_complement_width)) elems += i3.Rectangle( layer=self.layer, center=(self.vernier_left_center[0] + self.vernier_complement_shift + 0.5 * self.vernier_complement_length, self.vernier_left_center[1] + 2.0 * self.vernier_complement_period), box_size=(self.vernier_complement_length, self.vernier_complement_width)) elems += i3.Rectangle( layer=self.layer, center=(self.vernier_left_center[0] - self.vernier_complement_shift - 0.5 * self.vernier_complement_length, self.vernier_left_center[1] + 3.0 * self.vernier_complement_period), box_size=(self.vernier_complement_length, self.vernier_complement_width)) elems += i3.Rectangle( layer=self.layer, center=(self.vernier_left_center[0] + self.vernier_complement_shift + 0.5 * self.vernier_complement_length, self.vernier_left_center[1] + 3.0 * self.vernier_complement_period), box_size=(self.vernier_complement_length, self.vernier_complement_width)) elems += i3.Rectangle( layer=self.layer, center=(self.vernier_left_center[0] - self.vernier_complement_shift - 0.5 * self.vernier_complement_length, self.vernier_left_center[1] + 4.0 * self.vernier_complement_period), box_size=(self.vernier_complement_length, self.vernier_complement_width)) elems += i3.Rectangle( layer=self.layer, center=(self.vernier_left_center[0] + self.vernier_complement_shift + 0.5 * self.vernier_complement_length, self.vernier_left_center[1] + 4.0 * self.vernier_complement_period), box_size=(self.vernier_complement_length, self.vernier_complement_width)) elems += i3.Rectangle( layer=self.layer, center=(self.vernier_left_center[0] - self.vernier_complement_shift - 0.5 * self.vernier_complement_length, self.vernier_left_center[1] - self.vernier_complement_period), box_size=(self.vernier_complement_length, self.vernier_complement_width)) elems += i3.Rectangle( layer=self.layer, center=(self.vernier_left_center[0] + self.vernier_complement_shift + 0.5 * self.vernier_complement_length, self.vernier_left_center[1] - self.vernier_complement_period), box_size=(self.vernier_complement_length, self.vernier_complement_width)) elems += i3.Rectangle( layer=self.layer, center=(self.vernier_left_center[0] - self.vernier_complement_shift - 0.5 * self.vernier_complement_length, self.vernier_left_center[1] - 2.0 * self.vernier_complement_period), box_size=(self.vernier_complement_length, self.vernier_complement_width)) elems += i3.Rectangle( layer=self.layer, center=(self.vernier_left_center[0] + self.vernier_complement_shift + 0.5 * self.vernier_complement_length, self.vernier_left_center[1] - 2.0 * self.vernier_complement_period), box_size=(self.vernier_complement_length, self.vernier_complement_width)) elems += i3.Rectangle( layer=self.layer, center=(self.vernier_left_center[0] - self.vernier_complement_shift - 0.5 * self.vernier_complement_length, self.vernier_left_center[1] - 3.0 * self.vernier_complement_period), box_size=(self.vernier_complement_length, self.vernier_complement_width)) elems += i3.Rectangle( layer=self.layer, center=(self.vernier_left_center[0] + self.vernier_complement_shift + 0.5 * self.vernier_complement_length, self.vernier_left_center[1] - 3.0 * self.vernier_complement_period), box_size=(self.vernier_complement_length, self.vernier_complement_width)) elems += i3.Rectangle( layer=self.layer, center=(self.vernier_left_center[0] - self.vernier_complement_shift - 0.5 * self.vernier_complement_length, self.vernier_left_center[1] - 4.0 * self.vernier_complement_period), box_size=(self.vernier_complement_length, self.vernier_complement_width)) elems += i3.Rectangle( layer=self.layer, center=(self.vernier_left_center[0] + self.vernier_complement_shift + 0.5 * self.vernier_complement_length, self.vernier_left_center[1] - 4.0 * self.vernier_complement_period), box_size=(self.vernier_complement_length, self.vernier_complement_width)) # Add rectangles top VERNIER elems += i3.Rectangle( layer=self.layer, center=(self.vernier_top_center[0], self.vernier_top_center[1] - self.vernier_complement_shift - 0.5 * self.vernier_complement_long_length), box_size=(self.vernier_complement_width, self.vernier_complement_long_length)) elems += i3.Rectangle( layer=self.layer, center=(self.vernier_top_center[0], self.vernier_top_center[1] + self.vernier_complement_shift + 0.5 * self.vernier_complement_long_length), box_size=(self.vernier_complement_width, self.vernier_complement_long_length)) elems += i3.Rectangle( layer=self.layer, center=(self.vernier_top_center[0] + self.vernier_complement_period, self.vernier_top_center[1] - self.vernier_complement_shift - 0.5 * self.vernier_complement_length), box_size=(self.vernier_complement_width, self.vernier_complement_length)) elems += i3.Rectangle( layer=self.layer, center=(self.vernier_top_center[0] + self.vernier_complement_period, self.vernier_top_center[1] + self.vernier_complement_shift + 0.5 * self.vernier_complement_length), box_size=(self.vernier_complement_width, self.vernier_complement_length)) elems += i3.Rectangle( layer=self.layer, center=(self.vernier_top_center[0] + 2.0 * self.vernier_complement_period, self.vernier_top_center[1] - self.vernier_complement_shift - 0.5 * self.vernier_complement_length), box_size=(self.vernier_complement_width, self.vernier_complement_length)) elems += i3.Rectangle( layer=self.layer, center=(self.vernier_top_center[0] + 2.0 * self.vernier_complement_period, self.vernier_top_center[1] + self.vernier_complement_shift + 0.5 * self.vernier_complement_length), box_size=(self.vernier_complement_width, self.vernier_complement_length)) elems += i3.Rectangle( layer=self.layer, center=(self.vernier_top_center[0] + 3.0 * self.vernier_complement_period, self.vernier_top_center[1] - self.vernier_complement_shift - 0.5 * self.vernier_complement_length), box_size=(self.vernier_complement_width, self.vernier_complement_length)) elems += i3.Rectangle( layer=self.layer, center=(self.vernier_top_center[0] + 3.0 * self.vernier_complement_period, self.vernier_top_center[1] + self.vernier_complement_shift + 0.5 * self.vernier_complement_length), box_size=(self.vernier_complement_width, self.vernier_complement_length)) elems += i3.Rectangle( layer=self.layer, center=(self.vernier_top_center[0] + 4.0 * self.vernier_complement_period, self.vernier_top_center[1] - self.vernier_complement_shift - 0.5 * self.vernier_complement_length), box_size=(self.vernier_complement_width, self.vernier_complement_length)) elems += i3.Rectangle( layer=self.layer, center=(self.vernier_top_center[0] + 4.0 * self.vernier_complement_period, self.vernier_top_center[1] + self.vernier_complement_shift + 0.5 * self.vernier_complement_length), box_size=(self.vernier_complement_width, self.vernier_complement_length)) elems += i3.Rectangle( layer=self.layer, center=(self.vernier_top_center[0] - self.vernier_complement_period, self.vernier_top_center[1] - self.vernier_complement_shift - 0.5 * self.vernier_complement_length), box_size=(self.vernier_complement_width, self.vernier_complement_length)) elems += i3.Rectangle( layer=self.layer, center=(self.vernier_top_center[0] - self.vernier_complement_period, self.vernier_top_center[1] + self.vernier_complement_shift + 0.5 * self.vernier_complement_length), box_size=(self.vernier_complement_width, self.vernier_complement_length)) elems += i3.Rectangle( layer=self.layer, center=(self.vernier_top_center[0] - 2.0 * self.vernier_complement_period, self.vernier_top_center[1] - self.vernier_complement_shift - 0.5 * self.vernier_complement_length), box_size=(self.vernier_complement_width, self.vernier_complement_length)) elems += i3.Rectangle( layer=self.layer, center=(self.vernier_top_center[0] - 2.0 * self.vernier_complement_period, self.vernier_top_center[1] + self.vernier_complement_shift + 0.5 * self.vernier_complement_length), box_size=(self.vernier_complement_width, self.vernier_complement_length)) elems += i3.Rectangle( layer=self.layer, center=(self.vernier_top_center[0] - 3.0 * self.vernier_complement_period, self.vernier_top_center[1] - self.vernier_complement_shift - 0.5 * self.vernier_complement_length), box_size=(self.vernier_complement_width, self.vernier_complement_length)) elems += i3.Rectangle( layer=self.layer, center=(self.vernier_top_center[0] - 3.0 * self.vernier_complement_period, self.vernier_top_center[1] + self.vernier_complement_shift + 0.5 * self.vernier_complement_length), box_size=(self.vernier_complement_width, self.vernier_complement_length)) elems += i3.Rectangle( layer=self.layer, center=(self.vernier_top_center[0] - 4.0 * self.vernier_complement_period, self.vernier_top_center[1] - self.vernier_complement_shift - 0.5 * self.vernier_complement_length), box_size=(self.vernier_complement_width, self.vernier_complement_length)) elems += i3.Rectangle( layer=self.layer, center=(self.vernier_top_center[0] - 4.0 * self.vernier_complement_period, self.vernier_top_center[1] + self.vernier_complement_shift + 0.5 * self.vernier_complement_length), box_size=(self.vernier_complement_width, self.vernier_complement_length)) else: elems += i3.Rectangle(layer=self.layer, center=(x0 - 43.5, y0 + 11.5), box_size=(self.protection_length, self.protection_width)) return elems
class AlignmentMarkerSet(i3.PCell): _name_prefix = "ALIGNMENT MARKER SET" # Center of the structure position = i3.Coord2Property(default=(0.0, 0.0)) # Orientation horizontal = i3.BoolProperty(default=True) # Spacing v_spacing = i3.PositiveNumberProperty(default=320.0) h_spacing = i3.PositiveNumberProperty(default=300.0) class Layout(i3.LayoutView): def _generate_elements(self, elems): # Center of the structure (x0, y0) = self.position if self.horizontal == False: # ADD RELEASE elems += i3.SRef(reference=AlignmentMarker( layer=i3.TECH.PPLAYER.WG.TEXT, layer_text="Release"), transformation=i3.Translation( (x0 + 0.0 * self.h_spacing, y0))) elems += i3.SRef(reference=AlignmentMarker( layer=i3.TECH.PPLAYER.HFW, complement=True), transformation=i3.Translation( (x0 + 0.0 * self.h_spacing, y0))) # # ADD TETHER # elems += i3.SRef(reference=AlignmentMarker(layer=lay_island, layer_text="Tether"), # transformation=i3.Translation((x0 + 1.0 * self.h_spacing, y0))) # elems += i3.SRef(reference=AlignmentMarker(layer=lay_release, protection=True), # transformation=i3.Translation((x0 + 1.0 * self.h_spacing, y0))) # elems += i3.SRef(reference=AlignmentMarker(layer=lay_tether, complement=True), # transformation=i3.Translation((x0 + 1.0 * self.h_spacing, y0))) # # # ADD Dongbomesa # elems += i3.SRef(reference=AlignmentMarker(layer=lay_island, layer_text="Dongbomesa"), # transformation=i3.Translation((x0 + 2.0 * self.h_spacing, y0))) # elems += i3.SRef(reference=AlignmentMarker(layer=lay_release, protection=True), # transformation=i3.Translation((x0 + 2.0 * self.h_spacing, y0))) # elems += i3.SRef(reference=AlignmentMarker(layer=lay_tether, protection=True), # transformation=i3.Translation((x0 + 2.0 * self.h_spacing, y0))) # elems += i3.SRef(reference=AlignmentMarker(layer=lay_mesa, complement=True), # transformation=i3.Translation((x0 + 2.0 * self.h_spacing, y0))) else: # ADD RECESS elems += i3.SRef(reference=AlignmentMarker( layer=i3.TECH.PPLAYER.WG.TEXT, layer_text="RECESS"), transformation=i3.Translation( (x0 + 0.0 * self.h_spacing, y0))) elems += i3.SRef(reference=AlignmentMarker( layer=i3.TECH.PPLAYER.HFW, complement=True), transformation=i3.Translation( (x0 + 0.0 * self.h_spacing, y0))) # ADD AL elems += i3.SRef(reference=AlignmentMarker( layer=i3.TECH.PPLAYER.WG.TEXT, layer_text="AL"), transformation=i3.Translation( (x0, y0 - 1.0 * self.v_spacing))) elems += i3.SRef(reference=AlignmentMarker( layer=i3.TECH.PPLAYER.HFW, protection=True), transformation=i3.Translation( (x0, y0 - 1.0 * self.v_spacing))) elems += i3.SRef(reference=AlignmentMarker( layer=i3.TECH.PPLAYER.CONTACT.PILLAR, complement=True), transformation=i3.Translation( (x0, y0 - 1.0 * self.v_spacing))) # ADD SiN elems += i3.SRef(reference=AlignmentMarker( layer=i3.TECH.PPLAYER.WG.TEXT, layer_text="SiN"), transformation=i3.Translation( (x0, y0 - 2.0 * self.v_spacing))) elems += i3.SRef(reference=AlignmentMarker( layer=i3.TECH.PPLAYER.HFW, protection=True), transformation=i3.Translation( (x0, y0 - 2.0 * self.v_spacing))) elems += i3.SRef(reference=AlignmentMarker( layer=i3.TECH.PPLAYER.SIL.LINE, complement=True), transformation=i3.Translation( (x0, y0 - 2.0 * self.v_spacing))) # ADD BackUp elems += i3.SRef(reference=AlignmentMarker( layer=i3.TECH.PPLAYER.WG.TEXT, layer_text="BackUp"), transformation=i3.Translation( (x0, y0 - 3.0 * self.v_spacing))) elems += i3.SRef(reference=AlignmentMarker( layer=i3.TECH.PPLAYER.HFW, protection=True), transformation=i3.Translation( (x0, y0 - 3.0 * self.v_spacing))) # elems += i3.SRef(reference=AlignmentMarker(layer=lay_tether, complement=True), # transformation=i3.Translation((x0, y0 - 3.0 * self.v_spacing))) # RECESS adjustment according to the mask elems += i3.SRef(reference=AlignmentMarker( layer=i3.TECH.PPLAYER.NONE.DOC, protection=True), transformation=i3.Translation( (x0, y0 - 0.0 * self.v_spacing))) generated1 = i3.TECH.PPLAYER.NONE.DOC - i3.TECH.PPLAYER.HFW mapping = {generated1: i3.TECH.PPLAYER.V12.PILLAR} elems += i3.get_elements_for_generated_layers(elems, mapping) return elems
class NP_mmi12(i3.PCell): _name_prefix = "NP_" # Center of the structure position = i3.Coord2Property(default=(0.0, 0.0)) # Layer layer = i3.LayerProperty(default=i3.TECH.PPLAYER.HFW) layer_bool = i3.LayerProperty(default=i3.TECH.PPLAYER.NONE.DOC) layer2 = i3.LayerProperty(default=i3.TECH.PPLAYER.WG.TEXT) # Mesa parameters length = i3.PositiveNumberProperty(default=160.0) width = i3.PositiveNumberProperty(default=120.0) pillar = i3.BoolProperty(default=False) pocket = i3.BoolProperty(default=False) tilt = i3.BoolProperty(default=False) double = i3.BoolProperty(default=True) # Recess label label = i3.StringProperty(default="NP") class Layout(i3.LayoutView): def _generate_elements(self, elems): # Center of the structure (x0, y0) = self.position width2 = 450.0 elems += i3.Rectangle(layer=self.layer, center=(x0 + 6500 + 2000 + 2000, 600 + (1800 - width2) / 4), box_size=(3000, (1800 - width2) / 2)) elems += i3.Rectangle(layer=self.layer, center=(x0 + 6500 + 2000 + 2000, y0 + 600 + width2 + (1800 - width2) * 3 / 4), box_size=(3000, (1800 - width2) / 2)) elems += i3.SRef( reference=Interface_mmi12(pocket=self.pocket, tilt=self.tilt)) if self.pillar: self.label = "NO" for i in range(4): elems += i3.Rectangle( layer=self.layer, center=(10000 - 725 - i * 750 + 2000 + 550, 1275 + self.width / 2), box_size=(self.length, self.width)) elems += i3.Rectangle( layer=self.layer, center=(10000 - 725 - i * 750 + 2000 + 550, 1725 - self.width / 2), # change box_size=(self.length, self.width)) if self.double: elems += i3.Rectangle( layer=self.layer, center=(10000 - 725 - i * 750 + 2000 + 550 - 400, 1275 + self.width / 2), box_size=(self.length, self.width)) elems += i3.Rectangle( layer=self.layer, center=(10000 - 725 - i * 750 + 2000 + 550 - 400, 1725 - self.width / 2), # change box_size=(self.length, self.width)) if self.width > 120: self.label += "W" if self.pocket: self.label += "_WP" if self.tilt: self.label += "WT" elems += i3.PolygonText( layer=self.layer_bool, text=self.label, coordinate=(10800, 2600), # alignment=(i3.TEXT_ALIGN_LEFT, i3.TEXT_ALIGN_LEFT), font=2, height=400.0) generated1 = self.layer - self.layer_bool mapping = {generated1: self.layer} elems = i3.get_elements_for_generated_layers(elems, mapping) if self.pillar: for i in range(4): elems += i3.Rectangle( layer=self.layer2, center=(10000 - 725 - i * 750 + 2000 + 550, 1275 + self.width / 2), box_size=(self.length + 10, self.width + 10)) elems += i3.Rectangle( layer=self.layer2, center=(10000 - 725 - i * 750 + 2000 + 550, 1725 - self.width / 2), # change box_size=(self.length + 10, self.width + 10)) if self.double: elems += i3.Rectangle( layer=self.layer2, center=(10000 - 725 - i * 750 + 2000 + 550 - 400, 1275 + self.width / 2), box_size=(self.length + 10, self.width + 10)) elems += i3.Rectangle( layer=self.layer2, center=(10000 - 725 - i * 750 + 2000 + 550 - 400, 1725 - self.width / 2), # change box_size=(self.length + 10, self.width + 10)) return elems
class SiN_NP(i3.PCell): _name_prefix = "SiN_NP" # Center of the structure position = i3.Coord2Property(default=(0.0, 0.0)) # Layer layer = i3.LayerProperty(default=i3.TECH.PPLAYER.SIL.LINE) layer_bool = i3.LayerProperty(default=i3.TECH.PPLAYER.NONE.DOC) # Mesa parameters length = i3.PositiveNumberProperty(default=180.0) width = i3.PositiveNumberProperty(default=79.0) tilt = i3.PositiveNumberProperty(default=10.0) pillar = i3.BoolProperty(default=True) double = i3.BoolProperty(default=True) class Layout(i3.LayoutView): def _generate_elements(self, elems): # Center of the structure (x0, y0) = self.position elems += i3.Rectangle(layer=self.layer, center=(8750 - 15 - 10 + 5, 1500), box_size=(500 - 40, 1800 - 100)) elems += i3.Rectangle(layer=self.layer, center=(10500 - 15 - 10 + self.tilt / 2, 1500), box_size=(3000 + 50 + self.tilt, 450 - 15 * 2)) elems += i3.Rectangle(layer=self.layer, center=(8750 - 15 - 10 + 5 + 2420 - 150, 1000 - 120), box_size=(2000, 500 - 40)) # extra SiN pad # for i in range(4): # elems += i3.Rectangle(layer=self.layer, # center=( # 10000 - 725 - i * 750 + 2000 + 350, 1316+72.75), # box_size=(145, 77.5)) # elems += i3.Rectangle(layer=self.layer, center=( # 10000 - 725 - i * 750 + 2000 + 350, 1684-72.75), # change # box_size=(145, 77.5)) if self.pillar: for i in range(4): elems += i3.Rectangle( layer=self.layer_bool, center=(10000 - 725 - i * 750 + 2000 + 550, 1316 + self.width / 2 - 11.0 / 2), box_size=(self.length + 30, self.width + 30 + 11)) elems += i3.Rectangle( layer=self.layer_bool, center=(10000 - 725 - i * 750 + 2000 + 550, 1684 - self.width / 2 + 11.0 / 2), # change box_size=(self.length + 30, self.width + 30 + 11)) if self.double: elems += i3.Rectangle( layer=self.layer_bool, center=(10000 - 725 - i * 750 + 2000 + 550 - 400, 1316 + self.width / 2 - 11.0 / 2), box_size=(self.length + 30, self.width + 30 + 11)) elems += i3.Rectangle( layer=self.layer_bool, center=(10000 - 725 - i * 750 + 2000 + 550 - 400, 1684 - self.width / 2 + 11.0 / 2), # change box_size=(self.length + 30, self.width + 30 + 11)) # if self.tilt_0: # elems += i3.Rectangle(layer=self.layer, # center=(x0 + 6500 - 40 + 20 + 7.5, 2500), # box_size=(self.length + 40 + 15, self.width - 40 * 2)) # else: # elems += i3.Rectangle(layer=self.layer, # center=(x0 + 6500 - 40 + 20 + 5, 2500), # box_size=(self.length + 40 + 10, self.width - 40 * 2)) # # if self.pillar: # for i in range(7): # elems += i3.Rectangle(layer=self.layer_bool, # center=(10000 - 725 - i * 750, 1000 + (3000 - self.width) / 2 + 30), # box_size=(130, 140)) # elems += i3.Rectangle(layer=self.layer_bool, center=( # 10000 - 725 - i * 750, 1000 + (3000 - self.width) / 2 + self.width - 30), # box_size=(130, 140)) generated1 = self.layer - self.layer_bool mapping = {generated1: self.layer} elems = i3.get_elements_for_generated_layers(elems, mapping) return elems
class AL_NP(i3.PCell): _name_prefix = "AL_NP" # Center of the structure position = i3.Coord2Property(default=(0.0, 0.0)) # Layer layer = i3.LayerProperty(default=i3.TECH.PPLAYER.CONTACT.PILLAR) layer_bool = i3.LayerProperty(default=i3.TECH.PPLAYER.NONE.DOC) # Mesa parameters offset = i3.PositiveNumberProperty(default=20) # width = i3.PositiveNumberProperty(default=79) # pillar = i3.BoolProperty(default=False) reservoir = i3.BoolProperty(default=False) class Layout(i3.LayoutView): def _generate_elements(self, elems): # Center of the structure (x0, y0) = self.position # width2 = 338 + 15 + 15 elems += i3.Rectangle(layer=self.layer, center=(8750 - 15 - 10 + 5, 1500), box_size=(500 - 40, 1800 - 100)) elems += i3.Rectangle(layer=self.layer, center=(10500 - 15 - 10, 1500), box_size=(3000 + 50, 145)) elems += i3.Rectangle(layer=self.layer, center=(8750 - 15 - 10 + 5 + 2420 - 150, 1000 - 120), box_size=(2000, 500 - 40)) #extra pad elems += i3.Rectangle( layer=self.layer_bool, center=(8750 - 15 - 10 + 5 + 2420 - 150 + 998, 1000 - 120 + 620), box_size=(4, 145)) #extra shrink on the interface for i in range(4): elems += i3.Rectangle(layer=self.layer, center=(10000 - 725 - i * 750 + 2000 + 350 + self.offset, 1316 + 72.75), box_size=(145, 77.5)) elems += i3.Rectangle( layer=self.layer, center=(10000 - 725 - i * 750 + 2000 + 350 + self.offset, 1684 - 72.75), # change box_size=(145, 77.5)) # Avoid solder spill on facet elems += i3.Rectangle(layer=self.layer_bool, center=(12000 - 20, 1500), box_size=(40, 50)) elems += i3.Rectangle(layer=self.layer_bool, center=(12000 - 750 * 2, 1500), box_size=(80, 50)) elems += i3.Rectangle(layer=self.layer_bool, center=(12000 - 750 * 3, 1500), box_size=(80, 50)) elems += i3.Rectangle(layer=self.layer_bool, center=(12000 - 750 * 4, 1500), box_size=(80, 50)) # reservoir if self.reservoir: for i in range(3): elems += i3.Rectangle(layer=self.layer, center=(-750 * i + 12000 - 750, 1572.5 + 20), box_size=(149, 40)) elems += i3.Rectangle(layer=self.layer, center=(-750 * i + 12000 - 750, 1427.5 - 20), box_size=(149, 40)) elems += i3.Rectangle(layer=self.layer, center=(-750 * i + 12000 - 750, 1572.5 + 20), box_size=(149, 40)) elems += i3.Rectangle(layer=self.layer, center=(-750 * i + 12000 - 750, 1427.5 - 20), box_size=(149, 40)) elems += i3.Rectangle(layer=self.layer, center=(-750 * i + 12000 - 750, 1572.5 + 20), box_size=(149, 40)) elems += i3.Rectangle(layer=self.layer, center=(-750 * i + 12000 - 750, 1427.5 - 20), box_size=(149, 40)) elems += i3.PolygonText( layer=self.layer, text="RE", coordinate=(12000, 2600), # alignment=(i3.TEXT_ALIGN_LEFT, i3.TEXT_ALIGN_LEFT), font=2, height=400.0) # Markers bigsquare = 16.5 smallsquare = 11.5 for i in range(-3, 0, 2): elems += i3.Rectangle(layer=self.layer_bool, center=(750 * i + 12000 - 78, 1568.75), box_size=(9, 9.5)) elems += i3.Rectangle(layer=self.layer_bool, center=(750 * i + 12000 - 49.5, 1572 - 32), box_size=(9, 9)) elems += i3.Rectangle(layer=self.layer_bool, center=(750 * i + 12000 - 49.5 - 57, 1572 - 32), box_size=(9, 9)) elems += i3.Rectangle(layer=self.layer_bool, center=(750 * i + 12000 - 78, 1568.75 - 57.5), box_size=(9, 9.5)) elems += i3.Rectangle(layer=self.layer_bool, center=(750 * i + 12000 - 58.75, 1572.5 - 13.25), box_size=(smallsquare, smallsquare)) elems += i3.Rectangle(layer=self.layer_bool, center=(750 * i + 12000 - 58.75 - 38.5, 1572.5 - 13.25), box_size=(smallsquare, smallsquare)) elems += i3.Rectangle(layer=self.layer_bool, center=(750 * i + 12000 - 58.75, 1572.5 - 13.25 - 38.5), box_size=(smallsquare, smallsquare)) elems += i3.Rectangle(layer=self.layer_bool, center=(750 * i + 12000 - 58.75 - 38.5, 1572.5 - 13.25 - 38.5), box_size=(smallsquare, smallsquare)) # elems += i3.Rectangle(layer=self.layer_bool, center=(750*i+12000 - 78, 1568.75-80), box_size=(7, 7.5)) # elems += i3.Rectangle(layer=self.layer_bool, center=(750*i+12000 - 49.5, 1572 - 32-80), box_size=(7, 7)) # elems += i3.Rectangle(layer=self.layer_bool, center=(750*i+12000 - 49.5 - 57, 1572 - 32-80), box_size=(7, 7)) # elems += i3.Rectangle(layer=self.layer_bool, center=(750*i+12000 - 78, 1568.75 - 57.5-80), box_size=(7, 7.5)) # elems += i3.Rectangle(layer=self.layer_bool, center=(750*i+12000 - 58.75-2.5, 1572.5 - 13.25-80-2.5), box_size=(bigsquare, bigsquare)) # elems += i3.Rectangle(layer=self.layer_bool, center=(750*i+12000 - 58.75 - 38.5+2.5, 1572.5 - 13.25-80-2.5), # box_size=(bigsquare, bigsquare)) # elems += i3.Rectangle(layer=self.layer_bool, center=(750*i+12000 - 58.75-2.5, 1572.5 - 13.25 - 38.5-80+2.5), # box_size=(bigsquare, bigsquare)) # elems += i3.Rectangle(layer=self.layer_bool, center=(750*i+12000 - 58.75 - 38.5+2.5, 1572.5 - 13.25 - 38.5-80+2.5), # box_size=(bigsquare, bigsquare)) # elems += i3.Rectangle(layer=self.layer_bool, center=(750*i+12000 - 78-594, 1568.75), box_size=(7, 7.5)) # elems += i3.Rectangle(layer=self.layer_bool, center=(750*i+12000 - 49.5-594, 1572 - 32), box_size=(7, 7)) # elems += i3.Rectangle(layer=self.layer_bool, center=(750*i+12000 - 49.5 - 57-594, 1572 - 32), box_size=(7, 7)) # elems += i3.Rectangle(layer=self.layer_bool, center=(750*i+12000 - 78-594, 1568.75 - 57.5), box_size=(7, 7.5)) # elems += i3.Rectangle(layer=self.layer_bool, center=(750*i+12000 - 58.75-594-2.5, 1572.5 - 13.25-2.5), box_size=(bigsquare, bigsquare)) # elems += i3.Rectangle(layer=self.layer_bool, center=(750*i+12000 - 58.75 - 38.5-594+2.5, 1572.5 - 13.25-2.5), # box_size=(bigsquare, bigsquare)) # elems += i3.Rectangle(layer=self.layer_bool, center=(750*i+12000 - 58.75-594-2.5, 1572.5 - 13.25 - 38.5+2.5), # box_size=(bigsquare, bigsquare)) # elems += i3.Rectangle(layer=self.layer_bool, center=(750*i+12000 - 58.75 - 38.5-594+2.5, 1572.5 - 13.25 - 38.5+2.5), # box_size=(bigsquare, bigsquare)) elems += i3.Rectangle(layer=self.layer_bool, center=(750 * i + 12000 - 78 - 594, 1568.75 - 80), box_size=(9, 9.5)) elems += i3.Rectangle(layer=self.layer_bool, center=(750 * i + 12000 - 49.5 - 594, 1572 - 32 - 80), box_size=(9, 9)) elems += i3.Rectangle(layer=self.layer_bool, center=(750 * i + 12000 - 49.5 - 57 - 594, 1572 - 32 - 80), box_size=(9, 9)) elems += i3.Rectangle(layer=self.layer_bool, center=(750 * i + 12000 - 78 - 594, 1568.75 - 57.5 - 80), box_size=(9, 9.5)) elems += i3.Rectangle(layer=self.layer_bool, center=(750 * i + 12000 - 58.75 - 594, 1572.5 - 13.25 - 80), box_size=(smallsquare, smallsquare)) elems += i3.Rectangle(layer=self.layer_bool, center=(750 * i + 12000 - 58.75 - 38.5 - 594, 1572.5 - 13.25 - 80), box_size=(smallsquare, smallsquare)) elems += i3.Rectangle(layer=self.layer_bool, center=(750 * i + 12000 - 58.75 - 594, 1572.5 - 13.25 - 38.5 - 80), box_size=(smallsquare, smallsquare)) elems += i3.Rectangle(layer=self.layer_bool, center=(750 * i + 12000 - 58.75 - 38.5 - 594, 1572.5 - 13.25 - 38.5 - 80), box_size=(smallsquare, smallsquare)) for i in range(-2, 1, 2): # elems += i3.Rectangle(layer=self.layer_bool, center=(750*i+12000 - 78, 1568.75), box_size=(7, 7.5)) # elems += i3.Rectangle(layer=self.layer_bool, center=(750*i+12000 - 49.5, 1572-32), box_size=(7, 7)) # elems += i3.Rectangle(layer=self.layer_bool, center=(750*i+12000 - 49.5-57, 1572-32), box_size=(7, 7)) # elems += i3.Rectangle(layer=self.layer_bool, center=(750*i+12000 - 78, 1568.75-57.5), box_size=(7, 7.5)) # elems += i3.Rectangle(layer=self.layer_bool, center=(750*i+12000 - 58.75, 1572.5-13.25), box_size=(smallsquare, smallsquare)) # elems += i3.Rectangle(layer=self.layer_bool, center=(750*i+12000 - 58.75-38.5, 1572.5 - 13.25), box_size=(smallsquare, smallsquare)) # elems += i3.Rectangle(layer=self.layer_bool, center=(750*i+12000 - 58.75, 1572.5 - 13.25-38.5), box_size=(smallsquare, smallsquare)) # elems += i3.Rectangle(layer=self.layer_bool, center=(750*i+12000 - 58.75-38.5, 1572.5 - 13.25-38.5), box_size=(smallsquare, smallsquare)) elems += i3.Rectangle(layer=self.layer_bool, center=(750 * i + 12000 - 78, 1568.75 - 80), box_size=(9, 9.5)) elems += i3.Rectangle(layer=self.layer_bool, center=(750 * i + 12000 - 49.5, 1572 - 32 - 80), box_size=(9, 9)) elems += i3.Rectangle(layer=self.layer_bool, center=(750 * i + 12000 - 49.5 - 57, 1572 - 32 - 80), box_size=(9, 9)) elems += i3.Rectangle(layer=self.layer_bool, center=(750 * i + 12000 - 78, 1568.75 - 57.5 - 80), box_size=(9, 9.5)) elems += i3.Rectangle(layer=self.layer_bool, center=(750 * i + 12000 - 58.75 - 2.5, 1572.5 - 13.25 - 80 - 2.5), box_size=(bigsquare, bigsquare)) elems += i3.Rectangle(layer=self.layer_bool, center=(750 * i + 12000 - 58.75 - 38.5 + 2.5, 1572.5 - 13.25 - 80 - 2.5), box_size=(bigsquare, bigsquare)) elems += i3.Rectangle( layer=self.layer_bool, center=(750 * i + 12000 - 58.75 - 2.5, 1572.5 - 13.25 - 38.5 - 80 + 2.5), box_size=(bigsquare, bigsquare)) elems += i3.Rectangle( layer=self.layer_bool, center=(750 * i + 12000 - 58.75 - 38.5 + 2.5, 1572.5 - 13.25 - 38.5 - 80 + 2.5), box_size=(bigsquare, bigsquare)) elems += i3.Rectangle(layer=self.layer_bool, center=(750 * i + 12000 - 78 - 594, 1568.75), box_size=(9, 9.5)) elems += i3.Rectangle(layer=self.layer_bool, center=(750 * i + 12000 - 49.5 - 594, 1572 - 32), box_size=(9, 9)) elems += i3.Rectangle(layer=self.layer_bool, center=(750 * i + 12000 - 49.5 - 57 - 594, 1572 - 32), box_size=(9, 9)) elems += i3.Rectangle(layer=self.layer_bool, center=(750 * i + 12000 - 78 - 594, 1568.75 - 57.5), box_size=(9, 9.5)) elems += i3.Rectangle(layer=self.layer_bool, center=(750 * i + 12000 - 58.75 - 594 - 2.5, 1572.5 - 13.25 - 2.5), box_size=(bigsquare, bigsquare)) elems += i3.Rectangle(layer=self.layer_bool, center=(750 * i + 12000 - 58.75 - 38.5 - 594 + 2.5, 1572.5 - 13.25 - 2.5), box_size=(bigsquare, bigsquare)) elems += i3.Rectangle( layer=self.layer_bool, center=(750 * i + 12000 - 58.75 - 594 - 2.5, 1572.5 - 13.25 - 38.5 + 2.5), box_size=(bigsquare, bigsquare)) elems += i3.Rectangle( layer=self.layer_bool, center=(750 * i + 12000 - 58.75 - 38.5 - 594 + 2.5, 1572.5 - 13.25 - 38.5 + 2.5), box_size=(bigsquare, bigsquare)) # elems += i3.Rectangle(layer=self.layer_bool, center=(750*i+12000 - 78-594, 1568.75 - 80), box_size=(7, 7.5)) # elems += i3.Rectangle(layer=self.layer_bool, center=(750*i+12000 - 49.5-594, 1572 - 32 - 80), box_size=(7, 7)) # elems += i3.Rectangle(layer=self.layer_bool, center=(750*i+12000 - 49.5 - 57-594, 1572 - 32 - 80), box_size=(7, 7)) # elems += i3.Rectangle(layer=self.layer_bool, center=(750*i+12000 - 78-594, 1568.75 - 57.5 - 80), box_size=(7, 7.5)) # elems += i3.Rectangle(layer=self.layer_bool, center=(750*i+12000 - 58.75 -594, 1572.5 - 13.25 - 80 ), # box_size=(smallsquare, smallsquare)) # elems += i3.Rectangle(layer=self.layer_bool, center=(750*i+12000 - 58.75 - 38.5 -594, 1572.5 - 13.25 - 80 ), # box_size=(smallsquare, smallsquare)) # elems += i3.Rectangle(layer=self.layer_bool, center=(750*i+12000 - 58.75 -594, 1572.5 - 13.25 - 38.5 - 80 ), # box_size=(smallsquare, smallsquare)) # elems += i3.Rectangle(layer=self.layer_bool, # center=(750*i+12000 - 58.75 - 38.5 -594, 1572.5 - 13.25 - 38.5 - 80 ), # box_size=(smallsquare, smallsquare)) generated1 = self.layer - self.layer_bool mapping = {generated1: self.layer} elems = i3.get_elements_for_generated_layers(elems, mapping) return elems
class Layout(i3.LayoutView): # specified parameters used for layout, lengths of various waveguides # using some default values if standard ring shape is used bend_radius_ring = i3.PositiveNumberProperty(default=10., doc="bend radius of ring") ring_x_straight = i3.PositiveNumberProperty( default=15., doc="straight between bends in x ring") ring_y_straight = i3.PositiveNumberProperty( default=25., doc="straight between bends in y ring") external_straights = i3.PositiveNumberProperty( default=10., doc="extra straight for outside structure") external_gap = i3.PositiveNumberProperty( default=0.5, doc="gap between outside waveguides and resonator") # external_radius = i3.PositiveNumberProperty(default=bend_radius_ring, doc="radius of outside coupler") use_rounding = i3.BoolProperty(default=False, doc="use non default bending algorithm") rounding_algorithm = i3.DefinitionProperty( default=SplineRoundingAlgorithm(), doc="secondary rounding algorithm") # define the layout of the internal coupler which we SRef below def _default_resonator(self): res_layout = self.cell.resonator.get_default_view( i3.LayoutView) # Retrieve layout view following example # make the shape of the layout from the previous values. Assume (0, 0) is bottom middle!) # will do each corner for clarity # bottom_left = (-self.bend_radius_ring - self.ring_x_straight/2., 0.) # top_left = (-self.bend_radius_ring - self.ring_x_straight/2., # self.bend_radius_ring*2. + self.ring_y_straight) # top_right = (self.bend_radius_ring + self.ring_x_straight/2., # self.bend_radius_ring*2. + self.ring_y_straight) # bottom_right = (self.bend_radius_ring + self.ring_x_straight/2., 0.) # ring_shape = [bottom_left, top_left, top_right, bottom_right, bottom_left] # print ring_shape # tried to use generic round ring, but failed :P. Using ring rect instead # set the layout of the resonator. Stuck a bool for non default rounding algorithm if self.use_rounding is True: res_layout.set(bend_radius=self.bend_radius_ring, straights=(self.ring_x_straight, self.ring_y_straight), rounding_algorithm=self.rounding_algorithm) else: res_layout.set( bend_radius=self.bend_radius_ring, straights=(self.ring_x_straight, self.ring_y_straight)) # , shape=ring_shape return res_layout # now we take the resonator which was just defined and stick it in the main *get components thing def _get_components(self): resonator = i3.SRef(name="another_res", reference=self.resonator) return resonator # setting the output shape of the access waveguides using a shape defined by ports from MMI (hopefully..) def _default_wgs(self): # bring in parts from rest of PCell Layout, used to grab positions resonator = self._get_components() wg_in_cell, wg_pass_cell = self.cell.wgs wg_template = self.wg_coupler_template wg_ring_template = self.wg_ring_template # using the ring radius for the external radius external_rad = self.bend_radius_ring external_str = self.external_straights # grabbing the position of the resonator to layout the rest of the coupler properly resonator_west_side = resonator.size_info().west resonator_south_side = resonator.size_info().south resonator_core_width = wg_ring_template.core_width resonator_clad_width = wg_ring_template.cladding_width coupler_core_width = wg_template.core_width # calculate the x position for center of input coupling waveguide when coupling, and make shape x_coup_spot = resonator_west_side + resonator_clad_width/2. - resonator_core_width/2. - self.external_gap \ - coupler_core_width/2. # get bottom using the south and cladding information again bottom_left = (x_coup_spot - external_str - external_rad, resonator_south_side + resonator_clad_width / 2.) bottom_right = (x_coup_spot, resonator_south_side + resonator_clad_width / 2.) top_right = (x_coup_spot, bottom_right[1] + 2. * external_rad + self.ring_y_straight) top_left = (bottom_left[0], top_right[1]) wg_shape = [bottom_left, bottom_right, top_right, top_left] # now make the instance using this shape info wg_in_layout = wg_in_cell.get_default_view(i3.LayoutView) if self.use_rounding is True: wg_in_layout.set(trace_template=wg_template, shape=wg_shape, bend_radius=external_rad, rounding_algorithm=self.rounding_algorithm) else: wg_in_layout.set(trace_template=wg_template, shape=wg_shape, bend_radius=external_rad) wg_pass_layout = wg_pass_cell.get_default_view(i3.LayoutView) # wg_in_layout.set() return wg_in_layout, wg_pass_layout # wg_ring_layout # A few functions for grabbing waveguide parameters to determine lengths for FSR checking # def wg_lengths(self): # # grab the lengths of internal waveguides to use for calculations later # wg_in_layout, wg_pass_layout, wg_ring_layout = self.wgs # # straights_and_bends = wg_ring_layout.trace_length() # return straights_and_bends def _generate_instances(self, insts): # includes the get components and the new waveguides insts += self._get_components() wg_in_layout, wg_pass_layout = self.wgs # wg_pass_layout, wg_ring_layout insts += i3.SRef(reference=wg_in_layout, name="wg_in") # insts += i3.SRef(reference=wg_pass_layout, name="wg_pass") # insts += i3.SRef(reference=wg_ring_layout, name="wg_ring") return insts def _generate_ports(self, prts): # try to reuse the output waveguides following the example and change the names, looks good instances = self.instances prts += instances["wg_in"].ports["in"].modified_copy(name="in") prts += instances["wg_in"].ports["out"].modified_copy(name="pass") return prts
class Layout(i3.LayoutView): # specified parameters used for layout, lengths of various waveguides # using some default values if standard ring shape is used bend_radius_ring = i3.PositiveNumberProperty(default=10., doc="bend radius of ring") ring_x_straight = i3.PositiveNumberProperty( default=15., doc="straight between bends in x ring") ring_y_straight = i3.PositiveNumberProperty( default=25., doc="straight between bends in y ring") external_straights = i3.PositiveNumberProperty( default=10., doc="extra straight for outside structure") external_gap = i3.PositiveNumberProperty( default=1., doc="gap between outside waveguides and resonator") # external_radius = i3.PositiveNumberProperty(default=bend_radius_ring, doc="radius of outside coupler") rounding_algorithm = i3.DefinitionProperty( default=SplineRoundingAlgorithm(), doc="secondary rounding algorithm") # extra layouting for the CROW num_rings = i3.IntProperty(default=3, doc="number of rings") ring_gap = i3.PositiveNumberProperty(default=0.5, doc="gap between internal rings") use_gap_list = i3.BoolProperty(default=False, doc="use non default bending algorithm") ring_gap_list = i3.ListProperty( default=[], doc="list of gaps for manual swapping, default empty!") # define the layout of the internal coupler which we SRef below def _default_resonator(self): res_layout = self.cell.resonator.get_default_view( i3.LayoutView) # Retrieve layout view following example # make the shape of the layout from the previous values. Assume (0, 0) is bottom middle!) # will do each corner for clarity # bottom_left = (-self.bend_radius_ring - self.ring_x_straight/2., 0.) # top_left = (-self.bend_radius_ring - self.ring_x_straight/2., # self.bend_radius_ring*2. + self.ring_y_straight) # top_right = (self.bend_radius_ring + self.ring_x_straight/2., # self.bend_radius_ring*2. + self.ring_y_straight) # bottom_right = (self.bend_radius_ring + self.ring_x_straight/2., 0.) # ring_shape = [bottom_left, top_left, top_right, bottom_right, bottom_left] # print ring_shape # tried to use generic round ring, but failed :P. Using ring rect instead # set the layout of the resonator. Stuck a bool for non default rounding algorithm res_layout.set(bend_radius=self.bend_radius_ring, straights=(self.ring_x_straight, self.ring_y_straight), rounding_algorithm=self.rounding_algorithm) return res_layout def _dummy_resonator(self): dummy_res = i3.SRef(name="just_a_dummy", reference=self.resonator) return dummy_res # make a function for determining the distance between core size and def _resonator_size_core_to_core(self): # calls the get components function and then does math on the pulled in layout resonator = self._dummy_resonator() wg_ring_template = self.wg_ring_template # grabbing the position of the resonator to layout the rest of the coupler properly resonator_west_side = resonator.size_info().west resonator_east_side = resonator.size_info().east resonator_core_width = wg_ring_template.core_width resonator_clad_width = wg_ring_template.cladding_width resonator_x_dim = (resonator_east_side - resonator_west_side) - resonator_clad_width return resonator_x_dim # setting the output shape of the access waveguides using a shape defined by ports from MMI (hopefully..) def _default_wgs(self): # bring in parts from rest of PCell Layout, used dummy resonator to grab positions resonator = self._dummy_resonator() wg_in_cell, wg_pass_cell = self.cell.wgs wg_template = self.wg_coupler_template wg_ring_template = self.wg_ring_template # using the ring radius for the external radius external_rad = self.bend_radius_ring external_str = self.external_straights # grabbing the position of the resonator to layout the rest of the coupler properly resonator_west_side = resonator.size_info().west resonator_south_side = resonator.size_info().south resonator_core_width = wg_ring_template.core_width resonator_clad_width = wg_ring_template.cladding_width coupler_core_width = wg_template.core_width # calculate the x position for center of input coupling waveguide when coupling, and make shape x_coup_spot = resonator_west_side + resonator_clad_width/2. - resonator_core_width/2. - self.external_gap \ - coupler_core_width/2. # get bottom using the south and cladding information again bottom_left = (x_coup_spot - external_str - external_rad, resonator_south_side + resonator_clad_width / 2.) bottom_right = (x_coup_spot, resonator_south_side + resonator_clad_width / 2.) top_right = (x_coup_spot, bottom_right[1] + 2. * external_rad + self.ring_y_straight) top_left = (bottom_left[0], top_right[1]) wg_shape = [bottom_left, bottom_right, top_right, top_left] # now make the instance using this shape info wg_in_layout = wg_in_cell.get_default_view(i3.LayoutView) wg_in_layout.set(trace_template=wg_template, shape=wg_shape, bend_radius=external_rad, rounding_algorithm=self.rounding_algorithm) # other waveguide for reference, can put in shape or mirror later wg_pass_layout = wg_pass_cell.get_default_view(i3.LayoutView) # wg_in_layout.set() return wg_in_layout, wg_pass_layout # wg_ring_layout # A few functions for grabbing waveguide parameters to determine lengths for FSR checking # def wg_lengths(self): # # grab the lengths of internal waveguides to use for calculations later # wg_in_layout, wg_pass_layout, wg_ring_layout = self.wgs # # straights_and_bends = wg_ring_layout.trace_length() # return straights_and_bends # now we take the resonator and perform multiple translations for the CROW def _get_components(self): res_x_dim = self._resonator_size_core_to_core() ring_gap = self.ring_gap ring_core_width = self.wg_ring_template.core_width ring_gap_list = self.ring_gap_list shifting_list = [0.] + ring_gap_list all_components = [] # and now crank an SRef for each Ring in a loop for ring in range(self.num_rings): # will translate the original ring over to the correct position, and iterate for number of rings # use an if statement for external gap list or not. Need an error if self.use_gap_list is False: this_transform = i3.Translation( ((res_x_dim + ring_gap + ring_core_width) * ring, 0.)) this_resonator = i3.SRef(name="R_" + str(ring), reference=self.resonator, transformation=this_transform) all_components.append(this_resonator) else: # sum previous elements of the shifting list for correct relative translation total_shift = sum(shifting_list[:(ring + 1)]) this_transform = i3.Translation( ((res_x_dim + ring_core_width) * ring + total_shift, 0.)) this_resonator = i3.SRef(name="R_" + str(ring), reference=self.resonator, transformation=this_transform) all_components.append(this_resonator) return all_components def _generate_instances(self, insts): # includes the get components and the waveguides the_rings = self._get_components() insts += the_rings wg_in_layout, wg_pass_layout = self.wgs # wg_pass_layout, wg_ring_layout insts += i3.SRef(reference=wg_in_layout, name="wg_in") # ok so now I grab the last ring from the rings and use it to determine its position last_ring = the_rings[-1] east_side_ring = last_ring.size_info().east # and I get the waveguide properties for ring and coupler, to give correct outside gap ring_core_width = self.wg_ring_template.core_width ring_clad_width = self.wg_ring_template.cladding_width bus_wg_core_width = self.wg_coupler_template.core_width bus_wg_clad_width = self.wg_coupler_template.cladding_width final_x_spot = (east_side_ring - ring_clad_width/2.) + ring_core_width/2. \ + self.external_gap + bus_wg_core_width/2. # rather than making a new waveguide we can mirror the previous structure into the final position # thus we need to determine the difference in the core position of the original structure # with the *negative* position of the final x position, and then the mirror will flip it around bus_core_pos = wg_in_layout.size_info( ).east - bus_wg_clad_width / 2. # now we translate the original structure to the desired negative position, and horizontally mirror around 0 output_transformation = i3.HMirror() + i3.Translation( (-1. * (-final_x_spot - bus_core_pos), 0.)) # finally we perform the SRef on the previous layout and transform it with a new name insts += i3.SRef(reference=wg_in_layout, name="wg_out", transformation=output_transformation) return insts def _generate_ports(self, prts): # try to reuse the output waveguides following the example and change the names, looks good instances = self.instances prts += instances["wg_in"].ports["in"].modified_copy(name="in1") prts += instances["wg_in"].ports["out"].modified_copy(name="in2") prts += instances["wg_out"].ports["in"].modified_copy(name="out1") prts += instances["wg_out"].ports["out"].modified_copy(name="out2") return prts
class Layout(Bent_Coupler_Symm.Layout): # booleans for bent or not bent in1_bent = i3.BoolProperty(default=True, doc="bending in1 or not") in2_bent = i3.BoolProperty(default=False, doc="bending in2 or not") out1_bent = i3.BoolProperty(default=False, doc="bending out1 or not") out2_bent = i3.BoolProperty(default=False, doc="bending out2 or not") # define default of tapered MMI child cell def _default_coupler(self): coupler = self.cell.coupler.get_default_view( i3.LayoutView) # Retrieve layout view following example # coupler.set(coupler_spacing=1.0, coupler_length=10., trace_template=self.wg_template) return coupler # grabbing properties of child cell and setting appropriate transforms, by default do none def _get_components(self): coupler = i3.SRef(reference=self.coupler, name="coupler") return coupler # setting the output shape of the access waveguides using a shape defined by ports from MMI (hopefully..) def _default_wgs(self): # bring in parts from rest of PCell Layout, used to grab positions coupler = self._get_components() wg_in1_cell, wg_in2_cell, wg_out1_cell, wg_out2_cell = self.cell.wgs wg_template1 = self.wg_template1 wg_template2 = self.wg_template2 bend_radius = self.bend_radius # setting variable for round_alg = self.rounding_algorithm # defining bottom left waveguide, using port from MMI and bus length wg_in1_layout = wg_in1_cell.get_default_view(i3.LayoutView) in1_port_pos = coupler.ports["in1"].position in1_shape = [ in1_port_pos, (in1_port_pos[0] - bend_radius, in1_port_pos[1]), (in1_port_pos[0] - bend_radius, in1_port_pos[1] - 2. * bend_radius - self.in1_offset), (in1_port_pos[0] - 2. * bend_radius, in1_port_pos[1] - 2. * bend_radius - self.in1_offset) ] # bool section in1_shape_straight = [ in1_port_pos, (in1_port_pos[0] - 2. * bend_radius, in1_port_pos[1]) ] if self.in1_bent is False: in1_arb_shape = in1_shape_straight else: in1_arb_shape = in1_shape wg_in1_layout.set(trace_template=wg_template1, shape=in1_arb_shape, rounding_algorithm=round_alg, bend_radius=bend_radius) # repeat above for other ports, first in2 wg_in2_layout = wg_in2_cell.get_default_view(i3.LayoutView) in2_port_pos = coupler.ports["in2"].position in2_shape = [ in2_port_pos, (in2_port_pos[0] - bend_radius, in2_port_pos[1]), (in2_port_pos[0] - bend_radius, in2_port_pos[1] + 2. * bend_radius + self.in2_offset), (in2_port_pos[0] - 2. * bend_radius, in2_port_pos[1] + 2. * bend_radius + self.in2_offset) ] # bool section in2 in2_shape_straight = [ in2_port_pos, (in2_port_pos[0] - 2. * bend_radius, in2_port_pos[1]) ] if self.in2_bent is False: in2_arb_shape = in2_shape_straight else: in2_arb_shape = in2_shape wg_in2_layout.set(trace_template=wg_template2, shape=in2_arb_shape, rounding_algorithm=round_alg, bend_radius=bend_radius) # out1 wg_out1_layout = wg_out1_cell.get_default_view(i3.LayoutView) out1_port_pos = coupler.ports["out1"].position out1_shape = [ out1_port_pos, (out1_port_pos[0] + bend_radius, out1_port_pos[1]), (out1_port_pos[0] + bend_radius, out1_port_pos[1] - 2. * bend_radius - self.out1_offset), (out1_port_pos[0] + 2. * bend_radius, out1_port_pos[1] - 2. * bend_radius - self.out1_offset) ] # bool section out1 out1_shape_straight = [ out1_port_pos, (out1_port_pos[0] + 2. * bend_radius, out1_port_pos[1]) ] if self.out1_bent is False: out1_arb_shape = out1_shape_straight else: out1_arb_shape = out1_shape wg_out1_layout.set(trace_template=wg_template1, shape=out1_arb_shape, rounding_algorithm=round_alg, bend_radius=bend_radius) # and out2 wg_out2_layout = wg_out2_cell.get_default_view(i3.LayoutView) out2_port_pos = coupler.ports["out2"].position out2_shape = [ out2_port_pos, (out2_port_pos[0] + bend_radius, out2_port_pos[1]), (out2_port_pos[0] + bend_radius, out2_port_pos[1] + 2. * bend_radius + self.out2_offset), (out2_port_pos[0] + 2. * bend_radius, out2_port_pos[1] + 2. * bend_radius + self.out2_offset) ] # bool section out2 out2_shape_straight = [ out2_port_pos, (out2_port_pos[0] + 2. * bend_radius, out2_port_pos[1]) ] if self.out2_bent is False: out2_arb_shape = out2_shape_straight else: out2_arb_shape = out2_shape wg_out2_layout.set(trace_template=wg_template2, shape=out2_arb_shape, rounding_algorithm=round_alg, bend_radius=bend_radius) # returning layouts return wg_in1_layout, wg_in2_layout, wg_out1_layout, wg_out2_layout @i3.example_plot() def __example_layout(self): from technologies import silicon_photonics from picazzo3.traces.wire_wg.trace import WireWaveguideTemplate import ipkiss3.all as i3 import numpy as np from euler_rounding_algorithm import Euler90Algorithm from SplittersAndCascades import Bent_Coupler_Symm # wg_t1: waveguide template of the south arm # wg_t2: waveguide template of the north arm # define the template, set the core waveguide width wg_t1 = WireWaveguideTemplate(name="south_arm") wg_t1.Layout(core_width=2.400, cladding_width=i3.TECH.WG.CLADDING_WIDTH, core_process=i3.TECH.PROCESS.WG) wg_t2 = WireWaveguideTemplate(name="north arm") wg_t2.Layout(core_width=1.500, cladding_width=i3.TECH.WG.CLADDING_WIDTH, core_process=i3.TECH.PROCESS.WG) DC = StraightDirectionalCoupler(name="Directional coupler", trace_template1=wg_t1, trace_template2=wg_t2, coupler_length=50.0) layout_DC = DC.Layout(coupler_spacing=10.0) C = Bent_Coupler(name="modal_coupler", wg_template1=wg_t1, wg_template2=wg_t2, coupler=DC) # in1_bent...out2_bent booleans for bent control layout = C.Layout(bend_radius=30.0, in1_bent=True, in2_bent=True, out1_bent=True, out2_bent=True, rounding_algorithm=ShapeRound) layout.visualize()
class Layout(i3.LayoutView): from ipkiss.technology import get_technology TECH = get_technology() period = i3.PositiveNumberProperty(default=.3, doc="Period of sidewall grating") duty_cycle = i3.PositiveNumberProperty( default=.1, doc="Length of grating teeth (along periodic direction)") grating_amp = i3.NumberProperty( default=.01, doc= "Width/amplitude of grating teeth (normal to periodic direction)") wg_width = i3.PositiveNumberProperty( default=TECH.WG.CORE_WIDTH, doc="Width of waveguide core (if grating_amp=0 width of waveguide)" ) length = i3.PositiveNumberProperty(default=100.0, doc="Length of waveguide") # Flag, set to True to draw grating on both sides of wg. both_sides = i3.BoolProperty( default=False, doc='set to true to draw grating on both sides') def validate_properties(self): """Check whether the combination of properties is valid.""" if self.duty_cycle >= self.period: raise i3.PropertyValidationError( self, "Duty cycle is larger than/equal to the grating period", {"duty_cyle": self.duty_cycle}) return True def _generate_elements(self, elems): # Waveguide path wg_path = [(0.0, 0.0), (self.length, 0.0)] # Grating tooth path gt_path = [(0.0, 0.0), (self.duty_cycle, 0.0)] gap_cycle = self.period - self.duty_cycle numperiod = int(np.floor(self.length / self.period)) # Add waveguide core elems += i3.Path(layer=i3.TECH.PPLAYER.WG.COR, shape=wg_path, line_width=self.wg_width) # Add grating teeth if self.grating_amp > 0.0: # grating amplitude has to be non-zero ytrans = i3.Translation( (0.0, self.wg_width / 2 + self.grating_amp / 2)) for ii in range(numperiod): #Start with gap rather than tooth xtrans = i3.Translation( ((gap_cycle + ii * self.period), 0.0)) elems += i3.Path(layer=i3.TECH.PPLAYER.WG.COR, shape=gt_path, line_width=self.grating_amp, transformation=(xtrans + ytrans)) # draw bottom grating if desired if self.both_sides == True: elems += i3.Path(layer=i3.TECH.PPLAYER.WG.COR, shape=gt_path, line_width=self.grating_amp, transformation=(xtrans - ytrans)) # Add block layers import block_layers as bl block_layers = bl.layers block_widths = bl.widths for ii in range(len(block_layers)): elems += i3.Path(layer=block_layers[ii], shape=wg_path, line_width=self.wg_width + 2 * self.grating_amp + 2 * block_widths[ii]) return elems def _generate_ports(self, ports): # ports += i3.OpticalPort(name="in", position=(0.0, 0.0), angle=180.0, # trace_template=StripWgTemplate().Layout(core_width=self.wg_width)) # ports += i3.OpticalPort(name="out", position=(self.length, 0.0), angle=0.0, # trace_template=StripWgTemplate().Layout(core_width=self.wg_width)) ports += i3.OpticalPort(name="in", position=(0.0, 0.0), angle=180.0) ports += i3.OpticalPort(name="out", position=(self.length, 0.0), angle=0.0) return ports