def produce_impl(self): # fetch the parameters dbu = self.layout.dbu ly = self.layout shapes = self.cell.shapes LayerSiN = ly.layer(self.waveguide) LayerPinRecN = ly.layer(self.pinrec) LayerDevRecN = ly.layer(self.devrec) LayerTextN = ly.layer(self.text) from math import pi, cos, sin, log, sqrt from SiEPIC.utils import arc, arc_to_waveguide, points_per_circle, arc_wg x = 0 y = 0 theta = self.theta # 2*pi*r*(4*theta/360) = length + self.delta_length from SiEPIC.extend import to_itype w = to_itype(self.wg_width,dbu) length = to_itype(self.length,dbu) r = length/4/sin(theta/180.0*pi) waveguide_length = 2*pi*r*(4*theta/360.0) #arc_to_waveguide(pts, width): #arc(radius, start, stop) t = Trans(Trans.R0,x, round(y+r)) self.cell.shapes(LayerSiN).insert(arc_wg(r, w, 270., 270.+theta).transformed(t)) t = Trans(Trans.R0,round(x+length/2), round(y-r+ 2*r*(1-cos(theta/180.0*pi)))) self.cell.shapes(LayerSiN).insert(arc_wg(r, w, 90.-theta, 90.+theta).transformed(t)) t = Trans(Trans.R0,round(x+length), round(y+r)) self.cell.shapes(LayerSiN).insert(arc_wg(r, w, 270.-theta, 270).transformed(t)) # Create the pins on the waveguides, as short paths: from SiEPIC._globals import PIN_LENGTH as pin_length x = self.length / dbu t = Trans(Trans.R0, x,0) pin = Path([Point(-pin_length/2,0), Point(pin_length/2,0)], w) pin_t = pin.transformed(t) shapes(LayerPinRecN).insert(pin_t) text = Text ("pin2", t) shape = shapes(LayerPinRecN).insert(text) shape.text_size = 0.4/dbu shape.text_halign = 2 x = 0 t = Trans(Trans.R0, x,0) pin = Path([Point(pin_length/2,0), Point(-pin_length/2,0)], w) pin_t = pin.transformed(t) shapes(LayerPinRecN).insert(pin_t) text = Text ("pin1", t) shape = shapes(LayerPinRecN).insert(text) shape.text_size = 0.4/dbu # Compact model information t = Trans(Trans.R0, 0, 0) text = Text ('Lumerical_INTERCONNECT_library=Design kits/ebeam', t) shape = shapes(LayerDevRecN).insert(text) shape.text_size = 0.1/dbu t = Trans(Trans.R0, 0, w*2) text = Text ('Component=ebeam_wg_integral_1550', t) shape = shapes(LayerDevRecN).insert(text) shape.text_size = 0.1/dbu t = Trans(Trans.R0, 0, -w*2) text = Text \ ('Spice_param:wg_length=%.3fu wg_width=%.3fu' %\ (waveguide_length*dbu, self.wg_width), t ) shape = shapes(LayerDevRecN).insert(text) shape.text_size = 0.1/dbu t = Trans(Trans.R0, self.length /6, -w*2) text = Text ('dL = %.4f um' % ((waveguide_length-length)*dbu), t) shape = shapes(LayerTextN).insert(text) shape.text_size = 0.6/dbu # Create the device recognition layer -- make it 1 * wg_width away from the waveguides. box1 = Box(0, -w*3, length, w*3+(2*r*(1-cos(theta/180.0*pi)))) shapes(LayerDevRecN).insert(box1) print("SiEPIC EBeam: Waveguide_bump complete.")
def produce_impl(self): # This is the main part of the implementation: create the layout # Fixed PCell parameters port_spacing = 2000 # spacing of the two ports, determines the angle required by the s-bend. from math import pi, cos, sin, acos from SiEPIC.utils import arc_wg, arc_wg_xy from SiEPIC._globals import PIN_LENGTH # fetch the parameters dbu = self.layout.dbu ly = self.layout shapes = self.cell.shapes LayerSiN = ly.layer(self.silayer) LayerPinRecN = ly.layer(self.pinrec) LayerDevRecN = ly.layer(self.devrec) TextLayerN = ly.layer(self.textl) Lc = int(round(self.Lc / dbu)) w = int(round(self.w / dbu)) r = int(round(self.r / dbu)) g = int(round(self.g / dbu)) # Create the parallel waveguides if Lc > 0: wg1 = Box(-Lc / 2, -w / 2 + (w + g) / 2, Lc / 2, w / 2 + (w + g) / 2) shapes(LayerSiN).insert(wg1) wg1 = Box(-Lc / 2, -w / 2 - (w + g) / 2, Lc / 2, w / 2 - (w + g) / 2) shapes(LayerSiN).insert(wg1) dc_angle = acos((r - abs(port_spacing / 2)) / r) * 180 / pi # bottom S-bends self.cell.shapes(LayerSiN).insert( arc_wg_xy(Lc / 2, -r - (w + g) / 2, r, w, 90 - dc_angle, 90)) self.cell.shapes(LayerSiN).insert( arc_wg_xy(-Lc / 2, -r - (w + g) / 2, r, w, 90, 90 + dc_angle)) y_bottom = round(-2 * (1 - cos(dc_angle / 180.0 * pi)) * r) - (w + g) / 2 x_bottom = round(2 * sin(dc_angle / 180.0 * pi) * r) t = Trans(Trans.R0, -x_bottom - Lc / 2, y_bottom + r) self.cell.shapes(LayerSiN).insert( arc_wg(r, w, -90, -90 + dc_angle).transformed(t)) t = Trans(Trans.R0, x_bottom + Lc / 2, y_bottom + r) self.cell.shapes(LayerSiN).insert( arc_wg(r, w, -90 - dc_angle, -90).transformed(t)) # top S-bends self.cell.shapes(LayerSiN).insert( arc_wg_xy(Lc / 2, r + (w + g) / 2, r, w, 270, 270 + dc_angle)) self.cell.shapes(LayerSiN).insert( arc_wg_xy(-Lc / 2, r + (w + g) / 2, r, w, 270 - dc_angle, 270)) y_top = round(2 * (1 - cos(dc_angle / 180.0 * pi)) * r) + (w + g) / 2 x_top = round(2 * sin(dc_angle / 180.0 * pi) * r) t = Trans(Trans.R0, -x_top - Lc / 2, y_top - r) self.cell.shapes(LayerSiN).insert( arc_wg(r, w, 90 - dc_angle, 90).transformed(t)) t = Trans(Trans.R0, x_top + Lc / 2, y_top - r) self.cell.shapes(LayerSiN).insert( arc_wg(r, w, 90, 90 + dc_angle).transformed(t)) # Pins on the bottom waveguide side: pin = Path([ Point(-x_bottom + PIN_LENGTH / 2 - Lc / 2, y_bottom), Point(-x_bottom - PIN_LENGTH / 2 - Lc / 2, y_bottom) ], w) shapes(LayerPinRecN).insert(pin) text = Text("pin1", Trans(Trans.R0, -x_bottom - Lc / 2, y_bottom)) shape = shapes(LayerPinRecN).insert(text) shape.text_size = 0.4 / dbu pin = Path([ Point(x_bottom - PIN_LENGTH / 2 + Lc / 2, y_bottom), Point(x_bottom + PIN_LENGTH / 2 + Lc / 2, y_bottom) ], w) shapes(LayerPinRecN).insert(pin) text = Text("pin3", Trans(Trans.R0, x_bottom + Lc / 2, y_bottom)) shape = shapes(LayerPinRecN).insert(text) shape.text_size = 0.4 / dbu # Pins on the top waveguide side: pin = Path([ Point(-x_bottom + PIN_LENGTH / 2 - Lc / 2, y_top), Point(-x_bottom - PIN_LENGTH / 2 - Lc / 2, y_top) ], w) shapes(LayerPinRecN).insert(pin) text = Text("pin2", Trans(Trans.R0, -x_bottom - Lc / 2, y_top)) shape = shapes(LayerPinRecN).insert(text) shape.text_size = 0.4 / dbu pin = Path([ Point(x_bottom - PIN_LENGTH / 2 + Lc / 2, y_top), Point(x_bottom + PIN_LENGTH / 2 + Lc / 2, y_top) ], w) shapes(LayerPinRecN).insert(pin) text = Text("pin4", Trans(Trans.R0, x_bottom + Lc / 2, y_top)) shape = shapes(LayerPinRecN).insert(text) shape.text_size = 0.4 / dbu # Merge all the waveguide shapes, to avoid any small gaps layer_temp = self.layout.layer(LayerInfo(913, 0)) shapes_temp = self.cell.shapes(layer_temp) ShapeProcessor().merge(self.layout, self.cell, LayerSiN, shapes_temp, True, 0, True, True) self.cell.shapes(LayerSiN).clear() shapes_SiN = self.cell.shapes(LayerSiN) ShapeProcessor().merge(self.layout, self.cell, layer_temp, shapes_SiN, True, 0, True, True) self.cell.shapes(layer_temp).clear() # Create the device recognition layer -- make it 1 * wg_width away from the waveguides. dev = Box(-x_bottom - Lc / 2, y_bottom - w / 2 - w, x_bottom + Lc / 2, y_top + w / 2 + w) shapes(LayerDevRecN).insert(dev) # Compact model information t = Trans(Trans.R0, 0, -w) text = Text("Lumerical_INTERCONNECT_library=Design kits/ebeam_v1.2", t) shape = shapes(LayerDevRecN).insert(text) shape.text_size = r * 0.017 t = Trans(Trans.R0, 0, 0) text = Text('Component=NO_MODEL', t) shape = shapes(LayerDevRecN).insert(text) shape.text_size = r * 0.017 t = Trans(Trans.R0, 0, w) text = Text( 'Spice_param:wg_width=%.3fu gap=%.3fu radius=%.3fu Lc=%.3fu' % (w * dbu, g * dbu, r * dbu, self.Lc), t) shape = shapes(LayerDevRecN).insert(text) shape.text_size = r * 0.017 print("Done drawing the layout for - ebeam_dc: %.3f" % (self.Lc))
def produce_impl(self): # This is the main part of the implementation: create the layout from math import pi, cos, sin from SiEPIC.utils import arc_wg, arc_wg_xy from SiEPIC._globals import PIN_LENGTH # fetch the parameters dbu = self.layout.dbu ly = self.layout shapes = self.cell.shapes LayerSiN = ly.layer(self.silayer) LayerPinRecN = ly.layer(self.pinrec) LayerDevRecN = ly.layer(self.devrec) TextLayerN = ly.layer(self.textl) w = int(round(self.w / dbu)) r = int(round(self.r / dbu)) g = int(round(self.g / dbu)) Lc = int(round(self.Lc / dbu)) # draw the half-circle x = 0 y = r + w + g self.cell.shapes(LayerSiN).insert( arc_wg_xy(x - Lc / 2, y, r, w, 180, 270)) self.cell.shapes(LayerSiN).insert( arc_wg_xy(x + Lc / 2, y, r, w, 270, 360)) # Pins on the top side: pin = Path([ Point(-r - Lc / 2, y - PIN_LENGTH / 2), Point(-r - Lc / 2, y + PIN_LENGTH / 2) ], w) shapes(LayerPinRecN).insert(pin) t = Trans(Trans.R0, -r - Lc / 2, y) text = Text("pin2", t) shape = shapes(LayerPinRecN).insert(text) shape.text_size = 0.4 / dbu pin = Path([ Point(r + Lc / 2, y - PIN_LENGTH / 2), Point(r + Lc / 2, y + PIN_LENGTH / 2) ], w) shapes(LayerPinRecN).insert(pin) t = Trans(Trans.R0, r + Lc / 2, y) text = Text("pin4", t) shape = shapes(LayerPinRecN).insert(text) shape.text_size = 0.4 / dbu if Lc > 0: wg1 = Box(-Lc / 2, -w / 2 + w + g, Lc / 2, w / 2 + w + g) shapes(LayerSiN).insert(wg1) # Create the waveguide if Lc > 0: wg1 = Box(-Lc / 2, -w / 2, Lc / 2, w / 2) shapes(LayerSiN).insert(wg1) dc_angle = 30.0 self.cell.shapes(LayerSiN).insert( arc_wg_xy(Lc / 2, -r, r, w, 90 - dc_angle, 90)) self.cell.shapes(LayerSiN).insert( arc_wg_xy(-Lc / 2, -r, r, w, 90, 90 + dc_angle)) y_bottom = round(-2 * (1 - cos(dc_angle / 180.0 * pi)) * r) x_bottom = round(2 * sin(dc_angle / 180.0 * pi) * r) t = Trans(Trans.R0, -x_bottom - Lc / 2, y_bottom + r) self.cell.shapes(LayerSiN).insert( arc_wg(r, w, -90, -90 + dc_angle).transformed(t)) t = Trans(Trans.R0, x_bottom + Lc / 2, y_bottom + r) self.cell.shapes(LayerSiN).insert( arc_wg(r, w, -90 - dc_angle, -90).transformed(t)) wg1 = Box(-r - w / 2 - w - Lc / 2, y_bottom - w / 2, -x_bottom - Lc / 2, y_bottom + w / 2) shapes(LayerSiN).insert(wg1) wg1 = Box(x_bottom + Lc / 2, y_bottom - w / 2, r + w / 2 + w + Lc / 2, y_bottom + w / 2) shapes(LayerSiN).insert(wg1) # Pins on the bus waveguide side: pin = Path([ Point(-r - w / 2 - w + PIN_LENGTH / 2 - Lc / 2, y_bottom), Point(-r - w / 2 - w - PIN_LENGTH / 2 - Lc / 2, y_bottom) ], w) shapes(LayerPinRecN).insert(pin) text = Text("pin1", Trans(Trans.R0, -r - w / 2 - w - Lc / 2, y_bottom)) shape = shapes(LayerPinRecN).insert(text) shape.text_size = 0.4 / dbu pin = Path([ Point(r + w / 2 + w - PIN_LENGTH / 2 + Lc / 2, y_bottom), Point(r + w / 2 + w + PIN_LENGTH / 2 + Lc / 2, y_bottom) ], w) shapes(LayerPinRecN).insert(pin) text = Text("pin3", Trans(Trans.R0, r + w / 2 + w + Lc / 2, y_bottom)) shape = shapes(LayerPinRecN).insert(text) shape.text_size = 0.4 / dbu # Merge all the waveguide shapes, to avoid any small gaps layer_temp = self.layout.layer(LayerInfo(913, 0)) shapes_temp = self.cell.shapes(layer_temp) ShapeProcessor().merge(self.layout, self.cell, LayerSiN, shapes_temp, True, 0, True, True) self.cell.shapes(LayerSiN).clear() shapes_SiN = self.cell.shapes(LayerSiN) ShapeProcessor().merge(self.layout, self.cell, layer_temp, shapes_SiN, True, 0, True, True) self.cell.shapes(layer_temp).clear() # Create the device recognition layer -- make it 1 * wg_width away from the waveguides. dev = Box(-r - w / 2 - w - Lc / 2, y_bottom - w / 2 - w, r + w / 2 + w + Lc / 2, y) shapes(LayerDevRecN).insert(dev) # Compact model information t = Trans(Trans.R0, r / 4, 0) text = Text("Lumerical_INTERCONNECT_library=Design kits/ebeam_v1.2", t) shape = shapes(LayerDevRecN).insert(text) shape.text_size = self.r * 0.017 / dbu t = Trans(Trans.R0, r / 4, r / 4) text = Text('Component=ebeam_dc_halfring_arc_te1550', t) shape = shapes(LayerDevRecN).insert(text) shape.text_size = self.r * 0.017 / dbu t = Trans(Trans.R0, r / 4, r / 2) text = Text( 'Spice_param:wg_width=%.3fu gap=%.3fu radius=%.3fu Lc=%.3fu' % (self.w, self.g, self.r, self.Lc), t) shape = shapes(LayerDevRecN).insert(text) shape.text_size = self.r * 0.017 / dbu print("Done drawing the layout for - ebeam_dc_halfring_arc: %.3f-%g" % (self.r, self.g))
def produce(self, layout, layers, parameters, cell): """ coerce parameters (make consistent) """ self._layers = layers self.cell = cell self._param_values = parameters self.layout = layout # cell: layout cell to place the layout # LayerSiN: which layer to use # r: radius # w: waveguide width # start_angle: starting angle of the arc # stop_agnle: stopping angle of the arc # length units in dbu import math from math import pi, cos, sin from SiEPIC.utils import arc_wg # fetch the parameters dbu = self.layout.dbu ly = self.layout LayerSi = self.silayer LayerSiN = self.silayer_layer # LayerSiN = ly.layer(LayerSi) LayerPinRecN = ly.layer(self.pinrec) LayerDevRecN = ly.layer(self.devrec) from SiEPIC.extend import to_itype w = to_itype(self.wg_width, dbu) r = to_itype(self.radius, dbu) start_angle = self.start_angle stop_angle = self.stop_angle if start_angle > stop_angle: start_angle = self.stop_angle stop_angle = self.start_angle deg_to_rad = math.pi / 180.0 # draw the arc x = 0 y = 0 from SiEPIC._globals import PIN_LENGTH as pin_length self.cell.shapes(LayerSiN).insert(arc_wg(r, w, start_angle, stop_angle)) # Create the pins, as short paths: # Pin on the right side: x = r * math.cos(start_angle * deg_to_rad) y = r * math.sin(start_angle * deg_to_rad) x_pin = math.cos((90 - start_angle) * deg_to_rad) * pin_length / 2 y_pin = math.sin((90 - start_angle) * deg_to_rad) * pin_length / 2 p2 = [Point(x - x_pin, y + y_pin), Point(x + x_pin, y - y_pin)] p2c = Point(x, y) self.set_p2 = p2c self.p2 = p2c pin = Path(p2, w) self.cell.shapes(LayerPinRecN).insert(pin) t = Trans(Trans.R0, x, y) text = Text("pin2", t) shape = self.cell.shapes(LayerPinRecN).insert(text) shape.text_size = 0.4 / dbu # Pin on the left side: x = round(r * math.cos(stop_angle * deg_to_rad)) y = round(r * math.sin(stop_angle * deg_to_rad)) x_pin = math.cos((90.0 - stop_angle) * deg_to_rad) * pin_length / 2 y_pin = math.sin((90.0 - stop_angle) * deg_to_rad) * pin_length / 2 p1 = [Point(x + x_pin, y - y_pin), Point(x - x_pin, y + y_pin)] p1c = Point(x, y) self.set_p1 = p1c self.p1 = p1c pin = Path(p1, w) self.cell.shapes(LayerPinRecN).insert(pin) t = Trans(Trans.R0, x, y) text = Text("pin1", t) shape = self.cell.shapes(LayerPinRecN).insert(text) shape.text_size = 0.4 / dbu # Create the device recognition layer -- make it 1 * wg_width away from the waveguides. x = 0 y = 0 #layout_arc_wg_dbu(self.cell, LayerDevRecN, x, y, r, w*3, start_angle, stop_angle) self.cell.shapes(LayerDevRecN).insert( arc_wg(r, w * 3, start_angle, stop_angle))