Ejemplo n.º 1
0
    def produce_impl(self):
        from SiEPIC.utils import arc
        from SiEPIC.extend import to_itype

        dbu = self.layout.dbu

        layer = self.layout.layer(self.layer)
        radius = to_itype(self.radius, dbu)
        width = to_itype(self.width, dbu)

        poly = pya.Polygon(arc(radius + width / 2, 0, 360))
        hole = pya.Polygon(arc(radius - width / 2, 0, 360))
        poly.insert_hole(hole.get_points())
        self.cell.shapes(layer).insert(poly)
Ejemplo n.º 2
0
    def produce_impl(self):
        # This is the main part of the implementation: create the layout
        from math import pi, cos, sin
        from SiEPIC.extend import to_itype

        # fetch the parameters
        #    TECHNOLOGY = get_technology_by_name('GSiP')
        dbu = self.layout.dbu
        ly = self.layout
        shapes = self.cell.shapes

        LayerSi = self.silayer
        LayerSi3 = ly.layer(self.si3layer)
        LayerSiN = ly.layer(LayerSi)
        LayervlN = ly.layer(self.vllayer)
        LayermlN = ly.layer(self.mllayer)
        LayermhN = ly.layer(self.mhlayer)
        TextLayerN = ly.layer(self.textl)
        LayerPinRecN = ly.layer(self.pinrec)
        LayerDevRecN = ly.layer(self.devrec)

        # Define variables for the Modulator
        # Variables for the Si waveguide
        w = to_itype(self.w, dbu)
        r = to_itype(self.r, dbu)
        g = to_itype(self.g, dbu)
        gmon = to_itype(self.gmon, dbu)

        #Variables for the N layer
        w_1 = 2.0 / dbu  #same for N, P, N+, P+ layer
        r_n = to_itype(self.r - 1.0, dbu)

        #Variables for the VC layer
        w_vc = to_itype(4.0, dbu)
        r_vc1 = to_itype(self.r - 3.75, dbu)
        r_vc2 = to_itype(self.r + 3.75, dbu)

        #Variables for the M1 layer
        w_m1_in = r_vc1 + w_vc / 2.0 + to_itype(0.5, dbu)
        r_m1_in = r_vc1 + w_vc / 2.0 + to_itype(0.5, dbu) / 2.0
        w_m1_out = to_itype(6.0, dbu)
        r_m1_out = to_itype(self.r + 4.25, dbu)

        #Variables for the VL layer
        r_vl = w_m1_in / 2.0 - to_itype(2.1, dbu)
        w_via = to_itype(5.0, dbu)
        h_via = to_itype(5.0, dbu)

        # Variables for the SiEtch2 layer  (Slab)
        w_Si3 = w_m1_out + 2 * (r_m1_out)
        h_Si3 = w_Si3
        taper_bigend = to_itype(2, dbu)
        taper_smallend = to_itype(0.3, dbu)
        taper_length = to_itype(5, dbu)

        #Variables for the MH layer
        w_mh = to_itype(2.0, dbu)
        r_mh = r
        r_mh_in = r_mh - w_mh / 2.0

        #Define Ring centre
        x0 = r + w / 2
        y0 = r + g + w

        ######################
        # Generate the layout:

        # Create the ring resonator
        t = pya.Trans(pya.Trans.R0, (self.r + self.w / 2) / dbu,
                      (self.r + self.g + self.w) / dbu)
        pcell = ly.create_cell("Ring", "GSiP", {
            "layer": LayerSi,
            "radius": self.r,
            "width": self.w
        })
        self.cell.insert(pya.CellInstArray(pcell.cell_index(), t))

        # Create the two waveguides
        wg1 = pya.Box(x0 - (w_Si3 / 2 + taper_length), -w / 2,
                      x0 + (w_Si3 / 2 + taper_length), w / 2)
        shapes(LayerSiN).insert(wg1)
        y_offset = 2 * r + g + gmon + 2 * w
        wg2 = pya.Box(x0 - (w_Si3 / 2 + taper_length), y_offset - w / 2,
                      x0 + (w_Si3 / 2 + taper_length), y_offset + w / 2)
        shapes(LayerSiN).insert(wg2)

        #Create the SiEtch2 (Slab) layer
        boxSi3 = pya.Box(x0 - w_Si3 / 2.0, y0 - h_Si3 / 2.0, x0 + w_Si3 / 2.0,
                         y0 + h_Si3 / 2.0)
        shapes(LayerSi3).insert(boxSi3)
        pin1pts = [
            pya.Point(x0 - w_Si3 / 2.0, -taper_bigend / 2.0),
            pya.Point(x0 - w_Si3 / 2.0 - taper_length, -taper_smallend / 2.0),
            pya.Point(x0 - w_Si3 / 2.0 - taper_length, taper_smallend / 2.0),
            pya.Point(x0 - w_Si3 / 2.0, taper_bigend / 2.0)
        ]
        pin2pts = [
            pya.Point(x0 + w_Si3 / 2.0, -taper_bigend / 2.0),
            pya.Point(x0 + w_Si3 / 2.0 + taper_length, -taper_smallend / 2.0),
            pya.Point(x0 + w_Si3 / 2.0 + taper_length, taper_smallend / 2.0),
            pya.Point(x0 + w_Si3 / 2.0, +taper_bigend / 2.0)
        ]
        pin3pts = [
            pya.Point(x0 - w_Si3 / 2.0, y_offset - taper_bigend / 2.0),
            pya.Point(x0 - w_Si3 / 2.0 - taper_length,
                      y_offset - taper_smallend / 2.0),
            pya.Point(x0 - w_Si3 / 2.0 - taper_length,
                      y_offset + taper_smallend / 2.0),
            pya.Point(x0 - w_Si3 / 2.0, y_offset + taper_bigend / 2.0)
        ]
        pin4pts = [
            pya.Point(x0 + w_Si3 / 2.0, y_offset - taper_bigend / 2.0),
            pya.Point(x0 + w_Si3 / 2.0 + taper_length,
                      y_offset - taper_smallend / 2.0),
            pya.Point(x0 + w_Si3 / 2.0 + taper_length,
                      y_offset + taper_smallend / 2.0),
            pya.Point(x0 + w_Si3 / 2.0, y_offset + taper_bigend / 2.0)
        ]
        shapes(LayerSi3).insert(pya.Polygon(pin1pts))
        shapes(LayerSi3).insert(pya.Polygon(pin2pts))
        shapes(LayerSi3).insert(pya.Polygon(pin3pts))
        shapes(LayerSi3).insert(pya.Polygon(pin4pts))

        from SiEPIC.utils import arc

        # arc angles
        # doping:
        angle_min_doping = -35
        angle_max_doping = 215
        # VC contact:
        angle_min_VC = angle_min_doping + 8
        angle_max_VC = angle_max_doping - 8
        # M1:
        angle_min_M1 = angle_min_VC - 4
        angle_max_M1 = angle_max_VC + 4
        # MH:
        angle_min_MH = -75.0
        angle_max_MH = 255

        #Create the VL Layer, as well as the electrical PinRec geometries
        # heater contacts
        boxVL3 = pya.Box(
            x0 + (r_mh_in) * cos(angle_min_MH / 180 * pi) + 2.5 / dbu,
            -w / 2.0 - 10 / dbu,
            x0 + (r_mh_in) * cos(angle_min_MH / 180 * pi) + 7.5 / dbu,
            -w / 2.0 - 5 / dbu)
        shapes(LayervlN).insert(boxVL3)
        shapes(LayerPinRecN).insert(boxVL3)
        shapes(LayerPinRecN).insert(
            pya.Text(
                "elec2h2",
                pya.Trans(
                    pya.Trans.R0,
                    x0 + (r_mh_in) * cos(angle_min_MH / 180 * pi) + 5.0 / dbu,
                    -w / 2.0 - 7.5 / dbu))).text_size = 0.5 / dbu
        boxVL4 = pya.Box(
            x0 - (r_mh_in) * cos(angle_min_MH / 180 * pi) - 7.5 / dbu,
            -w / 2.0 - 10 / dbu,
            x0 - (r_mh_in) * cos(angle_min_MH / 180 * pi) - 2.5 / dbu,
            -w / 2.0 - 5 / dbu)
        shapes(LayervlN).insert(boxVL4)
        shapes(LayerPinRecN).insert(boxVL4)
        shapes(LayerPinRecN).insert(
            pya.Text(
                "elec2h1",
                pya.Trans(
                    pya.Trans.R0,
                    x0 - (r_mh_in) * cos(angle_min_MH / 180 * pi) - 5.0 / dbu,
                    -w / 2.0 - 7.5 / dbu))).text_size = 0.5 / dbu

        #Create the MH Layer
        poly = pya.Path(arc(self.r / dbu, angle_min_MH, angle_max_MH),
                        w_mh).transformed(t).simple_polygon()
        self.cell.shapes(LayermhN).insert(poly)
        boxMH1 = pya.Box(x0 + (r_mh_in) * cos(angle_min_MH / 180 * pi),
                         -w / 2.0 - 2.5 / dbu,
                         x0 + (r_mh_in) * cos(angle_min_MH / 180 * pi) + w_mh,
                         y0 + (r_mh_in) * sin(angle_min_MH / 180 * pi))
        shapes(LayermhN).insert(boxMH1)
        boxMH2 = pya.Box(x0 - (r_mh_in) * cos(angle_min_MH / 180 * pi) - w_mh,
                         -w / 2.0 - 2.5 / dbu,
                         x0 - (r_mh_in) * cos(angle_min_MH / 180 * pi),
                         y0 + (r_mh_in) * sin(angle_min_MH / 180 * pi))
        shapes(LayermhN).insert(boxMH2)
        boxMH3 = pya.Box(
            x0 + (r_mh_in) * cos(angle_min_MH / 180 * pi),
            -w / 2.0 - 12.5 / dbu,
            x0 + (r_mh_in) * cos(angle_min_MH / 180 * pi) + 10 / dbu,
            -w / 2.0 - 2.5 / dbu)
        shapes(LayermhN).insert(boxMH3)
        boxMH4 = pya.Box(
            x0 - (r_mh_in) * cos(angle_min_MH / 180 * pi) - 10 / dbu,
            -w / 2.0 - 12.5 / dbu,
            x0 - (r_mh_in) * cos(angle_min_MH / 180 * pi),
            -w / 2.0 - 2.5 / dbu)
        shapes(LayermhN).insert(boxMH4)

        # Create the pins, as short paths:
        from SiEPIC._globals import PIN_LENGTH as pin_length

        shapes(LayerPinRecN).insert(
            pya.Path([
                pya.Point(x0 - (w_Si3 / 2 + taper_length) + pin_length / 2, 0),
                pya.Point(x0 - (w_Si3 / 2 + taper_length) - pin_length / 2, 0)
            ], w))
        shapes(LayerPinRecN).insert(
            pya.Text(
                "opt1",
                pya.Trans(pya.Trans.R0, x0 - (w_Si3 / 2 + taper_length),
                          0))).text_size = 0.5 / dbu

        shapes(LayerPinRecN).insert(
            pya.Path([
                pya.Point(x0 + (w_Si3 / 2 + taper_length) - pin_length / 2, 0),
                pya.Point(x0 + (w_Si3 / 2 + taper_length) + pin_length / 2, 0)
            ], w))
        shapes(LayerPinRecN).insert(
            pya.Text(
                "opt2",
                pya.Trans(pya.Trans.R0, x0 + (w_Si3 / 2 + taper_length),
                          0))).text_size = 0.5 / dbu

        shapes(LayerPinRecN).insert(
            pya.Path([
                pya.Point(x0 - (w_Si3 / 2 + taper_length) + pin_length / 2,
                          y_offset),
                pya.Point(x0 - (w_Si3 / 2 + taper_length) - pin_length / 2,
                          y_offset)
            ], w))
        shapes(LayerPinRecN).insert(
            pya.Text(
                "opt3",
                pya.Trans(pya.Trans.R0, x0 - (w_Si3 / 2 + taper_length),
                          y_offset))).text_size = 0.5 / dbu

        shapes(LayerPinRecN).insert(
            pya.Path([
                pya.Point(x0 + (w_Si3 / 2 + taper_length) - pin_length / 2,
                          y_offset),
                pya.Point(x0 + (w_Si3 / 2 + taper_length) + pin_length / 2,
                          y_offset)
            ], w))
        shapes(LayerPinRecN).insert(
            pya.Text(
                "opt4",
                pya.Trans(pya.Trans.R0, x0 + (w_Si3 / 2 + taper_length),
                          y_offset))).text_size = 0.5 / dbu

        # Create the device recognition layer
        shapes(LayerDevRecN).insert(
            pya.Box(x0 - (w_Si3 / 2 + taper_length), -w / 2.0 - 12.5 / dbu,
                    x0 + (w_Si3 / 2 + taper_length),
                    y0 + r_m1_out + w_m1_out + h_via))

        # Compact model information
        shape = shapes(LayerDevRecN).insert(pya.Text('Lumerical_INTERCONNECT_library=Design kits/GSiP', \
          pya.Trans(pya.Trans.R0,0, 0))).text_size = 0.3/dbu
        shapes(LayerDevRecN).insert(pya.Text ('Component=Ring_Filter_DB', \
          pya.Trans(pya.Trans.R0,0, w*2))).text_size = 0.3/dbu
        shapes(LayerDevRecN).insert(pya.Text('Component_ID=%s' % self.component_ID, \
          pya.Trans(pya.Trans.R0,0, w*4))).text_size = 0.3/dbu
        shapes(LayerDevRecN).insert(pya.Text \
          ('Spice_param:radius=%.3fu wg_width=%.3fu gap=%.3fu gap_monitor=%.3fu' %\
          (self.r, self.w, self.g, self.gmon), \
          pya.Trans(pya.Trans.R0,0, -w*2) ) ).text_size = 0.3/dbu

        # Add a polygon text description
        from SiEPIC.utils import layout_pgtext
        if self.textpolygon:
            layout_pgtext(self.cell, self.textl, self.w, self.r + self.w,
                          "%.3f-%g" % (self.r, self.g), 1)
Ejemplo n.º 3
0
    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
        # length units in dbu

        from math import pi, cos, sin
        from SiEPIC.utils import arc, arc_to_waveguide, points_per_circle, arc_wg

        # fetch the parameters
        dbu = self.layout.dbu
        ly = self.layout
        shapes = self.cell.shapes

        LayerSi = self.silayer
        LayerSiN = self.silayer_layer
        LayerPinRecN = ly.layer(self.pinrec)
        LayerDevRecN = ly.layer(self.devrec)

        w = int(round(self.wg_width / dbu))
        r = int(round(self.radius / dbu))

        # draw the quarter-circle
        x = -r
        y = r
        # layout_arc_wg_dbu(self.cell, LayerSiN, x, y, r, w, 270, 360)
        t = Trans(Trans.R0, x, y)
        self.cell.shapes(LayerSiN).insert(
            arc_to_waveguide(arc(r, 270, 360), w).transformed(t))

        # Create the pins on the waveguides, as short paths:
        from SiEPIC._globals import PIN_LENGTH as pin_length

        # Pin on the top side:
        p2 = [Point(0, y - pin_length / 2), Point(0, y + pin_length / 2)]
        p2c = Point(0, y)
        self.set_p2 = p2c
        self.p2 = p2c
        pin = Path(p2, w)
        shapes(LayerPinRecN).insert(pin)
        t = Trans(Trans.R0, 0, y)
        text = Text("pin2", t)
        shape = shapes(LayerPinRecN).insert(text)
        shape.text_size = 0.4 / dbu

        # Pin on the left side:
        p1 = [Point(pin_length / 2 + x, 0), Point(-pin_length / 2 + x, 0)]
        p1c = Point(x, 0)
        self.set_p1 = p1c
        self.p1 = p1c
        pin = Path(p1, w)
        shapes(LayerPinRecN).insert(pin)
        t = Trans(Trans.R0, x, 0)
        text = Text("pin1", t)
        shape = shapes(LayerPinRecN).insert(text)
        shape.text_size = 0.4 / dbu

        # Create the device recognition layer -- make it 1 * wg_width away from the waveguides.
        t = Trans(Trans.R0, x, y)
        self.cell.shapes(LayerDevRecN).insert(
            arc_to_waveguide(arc(r, 270, 360), w * 3).transformed(t))
        #layout_arc_wg_dbu(self.cell, LayerDevRecN, x, y, r, w*3, 270, 360)

        # Compact model information
        t = Trans(Trans.R0, x + r / 10, 0)
        text = Text("Lumerical_INTERCONNECT_library=Design kits/EBeam", t)
        shape = shapes(LayerDevRecN).insert(text)
        shape.text_size = r / 100
        t = Trans(Trans.R0, x + r / 10, r / 4)
        text = Text('Component=ebeam_bend_1550', t)
        shape = shapes(LayerDevRecN).insert(text)
        shape.text_size = r / 100
        t = Trans(Trans.R0, x + r / 10, r / 2)
        text = Text(
            'Spice_param:radius=%.3fu wg_width=%.3fu' %
            (self.radius, self.wg_width), t)
        shape = shapes(LayerDevRecN).insert(text)
        shape.text_size = r / 100
Ejemplo n.º 4
0
  def produce_impl(self):

    # This is the main part of the implementation: create the layout
    from math import pi, cos, sin
    from SiEPIC.extend import to_itype
    
    # fetch the parameters
#    TECHNOLOGY = get_technology_by_name('GSiP')
    dbu = self.layout.dbu
    ly = self.layout
    shapes = self.cell.shapes
    
    LayerSi3N = ly.layer(self.si3layer)
    LayerSiN = ly.layer(self.silayer)
    LayernN = ly.layer(self.nlayer)
    LayerpN = ly.layer(self.player)
    LayernpN = ly.layer(self.nplayer)
    LayerppN = ly.layer(self.pplayer)
    LayernppN = ly.layer(self.npplayer)
    LayerpppN = ly.layer(self.ppplayer)
    LayervcN = ly.layer(self.vclayer)
    Layerm1N = ly.layer(self.m1layer)
    LayervlN = ly.layer(self.vllayer)
    LayermlN = ly.layer(self.mllayer)
    LayermhN = ly.layer(self.mhlayer)
    TextLayerN = ly.layer(self.textl)
    LayerPinRecN = ly.layer(self.pinrec)
    LayerDevRecN = ly.layer(self.devrec)

    # Define variables for the Modulator
    # Variables for the Si waveguide
    w = to_itype(self.w,dbu)
    r = to_itype(self.r,dbu)
    g = to_itype(self.g,dbu)
    gmon = to_itype(self.gmon,dbu)
    
    #Variables for the N layer
    w_1 = 2.0/dbu  #same for N, P, N+, P+ layer
    r_n = to_itype(self.r - 1.0,dbu)
    
    #Variables for the P layer
    r_p = to_itype(self.r + 1.0, dbu)
     
    #Variables for the N+layer
    r_np = to_itype(self.r - 1.5,dbu)
    
    #Variables for the P+layer
    r_pp = to_itype(self.r + 1.5,dbu)

    #Variables for the N++ layer
    w_2 = to_itype(5.5,dbu)  #same for N++, P++ layer
    r_npp = to_itype(self.r - 3.75,dbu)

    #Variables for the P+layer
    r_ppp = to_itype(self.r + 3.75,dbu)

    #Variables for the VC layer
    w_vc = to_itype(4.0,dbu)
    r_vc1 = to_itype(self.r - 3.75,dbu)
    r_vc2 = to_itype(self.r + 3.75,dbu)
   
    #Variables for the M1 layer
    w_m1_in = r_vc1 + w_vc/2.0 + to_itype(0.5,dbu)
    r_m1_in = r_vc1 + w_vc/2.0 + to_itype(0.5,dbu) /2.0
    w_m1_out = to_itype(6.0,dbu)
    r_m1_out = to_itype(self.r + 4.25,dbu)
    
    #Variables for the VL layer
    #r_vl =  w_m1_in/2.0 -  2.1/dbu
    r_vl =  r_vc1 - w_vc/2.0 - to_itype(2.01,dbu)
    if r_vl < to_itype(1.42,dbu):
      r_vl = to_itype(1.42,dbu)
      w_vc = r - to_itype(1.75,dbu) - (r_vl + 2.01)
      r_vc1 = r - to_itype(1.75,dbu) - w_vc/2.0
      r_vc2 = r + to_itype(1.75,dbu) + w_vc/2.0
      w_2 = (r-w/2.0 - to_itype(0.75,dbu)) - (r_vc1 - w_vc/2.0 - 0.75) # same for N++, P++ layer
      r_npp = ((r-w/2.0 - to_itype(0.75,dbu)) + (r_vc1 - w_vc/2.0 - 0.75))/2.0
      r_ppp = 2*r - r_npp
    w_via = to_itype(5.0,dbu)
    h_via = to_itype(5.0,dbu)

    # Variables for the SiEtch2 layer  (Slab)
    w_Si3 = round(w_m1_out + 2*(r_m1_out)+ 0/dbu)
    h_Si3 = w_Si3
    taper_bigend =  to_itype(2,dbu)
    taper_smallend =  to_itype(0.3,dbu)
    taper_length =  to_itype(5,dbu)

    #Variables for the MH layer
    w_mh = to_itype(2.0,dbu)
    r_mh = r
    r_mh_in = r_mh - w_mh/2.0
    
    #Define Ring centre   
    x0 = r + w/2
    y0 = r + g + w 

    ######################
    # Generate the layout:
   
    # Create the ring resonator
    t = pya.Trans(pya.Trans.R0,x0, y0)
    pcell = ly.create_cell("Ring", "GSiP", { "layer": self.silayer, "radius": self.r, "width": self.w } )
    self.cell.insert(pya.CellInstArray(pcell.cell_index(), t))

    
    # Create the two waveguides
    wg1 = pya.Box(x0 - (w_Si3 / 2 + taper_length), -w/2, x0 + (w_Si3 / 2 + taper_length), w/2)
    shapes(LayerSiN).insert(wg1)
    y_offset = 2*r + g + gmon + 2*w
    wg2 = pya.Box(x0 - (w_Si3 / 2 + taper_length), y_offset-w/2, x0 + (w_Si3 / 2 + taper_length), y_offset+w/2)
    shapes(LayerSiN).insert(wg2)

    
    #Create the SiEtch2 (Slab) layer
    boxSi3 = pya.Box(x0-w_Si3/2.0, y0 - h_Si3/2.0, x0+w_Si3/2.0, y0 + h_Si3/2.0)
    shapes(LayerSi3N).insert(boxSi3)
    pin1pts = [pya.Point(x0-w_Si3/2.0, -taper_bigend/2.0),
               pya.Point(x0-w_Si3/2.0-taper_length,-taper_smallend/2.0),
               pya.Point(x0-w_Si3/2.0-taper_length,taper_smallend/2.0),
               pya.Point(x0-w_Si3/2.0, taper_bigend/2.0)]
    pin2pts = [pya.Point(x0+w_Si3/2.0,-taper_bigend/2.0),
               pya.Point(x0+w_Si3/2.0+taper_length,-taper_smallend/2.0),
               pya.Point(x0+w_Si3/2.0+taper_length,taper_smallend/2.0),
               pya.Point(x0+w_Si3/2.0,+taper_bigend/2.0)]
    pin3pts = [pya.Point(x0-w_Si3/2.0,y_offset-taper_bigend/2.0),
               pya.Point(x0-w_Si3/2.0-taper_length,y_offset-taper_smallend/2.0),
               pya.Point(x0-w_Si3/2.0-taper_length,y_offset+taper_smallend/2.0),
               pya.Point(x0-w_Si3/2.0,y_offset+ taper_bigend/2.0)]
    pin4pts = [pya.Point(x0+w_Si3/2.0,y_offset-taper_bigend/2.0),
               pya.Point(x0+w_Si3/2.0+taper_length,y_offset-taper_smallend/2.0),
               pya.Point(x0+w_Si3/2.0+taper_length,y_offset+taper_smallend/2.0),
               pya.Point(x0+w_Si3/2.0,y_offset+taper_bigend/2.0)]
    shapes(LayerSi3N).insert(pya.Polygon(pin1pts))
    shapes(LayerSi3N).insert(pya.Polygon(pin2pts))
    shapes(LayerSi3N).insert(pya.Polygon(pin3pts))
    shapes(LayerSi3N).insert(pya.Polygon(pin4pts))
    
    # arc angles
    # doping:
    angle_min_doping = -35
    angle_max_doping = 215
    # VC contact:
    angle_min_VC = angle_min_doping + 8
    angle_max_VC = angle_max_doping - 8
    # M1:
    angle_min_M1 = angle_min_VC - 4
    angle_max_M1 = angle_max_VC + 4
    # MH:
    angle_min_MH = -75.0
    angle_max_MH = 255

    from SiEPIC.utils import arc

    #Create the N Layer
    self.cell.shapes(LayernN).insert(pya.Path(arc(r_n, angle_min_doping, angle_max_doping), w_1).transformed(t).simple_polygon())

    #Create the P Layer
    self.cell.shapes(LayerpN).insert(pya.Path(arc(r_p, angle_min_doping, angle_max_doping), w_1).transformed(t).simple_polygon())
    
    #Create the N+ Layer
    self.cell.shapes(LayernpN).insert(pya.Path(arc(r_np, angle_min_doping, angle_max_doping), w_1).transformed(t).simple_polygon())

    #Create the P+ Layer
    self.cell.shapes(LayerppN).insert(pya.Path(arc(r_pp, angle_min_doping, angle_max_doping), w_1).transformed(t).simple_polygon())
    
    #Create the N++ Layer
    self.cell.shapes(LayernppN).insert(pya.Path(arc(r_npp, angle_min_doping, angle_max_doping), w_2).transformed(t).simple_polygon())

    #Create the P+ +Layer
    poly = pya.Path(arc(r_ppp, angle_min_doping, angle_max_doping), w_2).transformed(t).simple_polygon()
    self.cell.shapes(LayerpppN).insert(pya.Region(poly) - pya.Region(pya.Box(x0-r_ppp-w_2/2, y_offset-w/2 - 0.75/dbu, x0+r_ppp+w/2, y_offset+w/2 + 0.75/dbu)))
    
    #Create the VC Layer
    self.cell.shapes(LayervcN).insert(pya.Path(arc(r_vc1, angle_min_VC, angle_max_VC), w_vc).transformed(t).simple_polygon())

    poly = pya.Path(arc(r_vc2, angle_min_VC, angle_max_VC), w_vc).transformed(t).simple_polygon()
    self.cell.shapes(LayervcN).insert(pya.Region(poly) - pya.Region(pya.Box(x0-r_vc2-w_vc/2, y_offset-w/2 - 1.5/dbu, x0+r_vc2+w_vc/2, y_offset+w/2 + 1.5/dbu)))

        
    #Create the M1 Layer
    self.cell.shapes(Layerm1N).insert(pya.Polygon(arc(w_m1_in, angle_min_doping, angle_max_doping) + [pya.Point(0, 0)]).transformed(t))
    self.cell.shapes(Layerm1N).insert(pya.Polygon(arc(w_m1_in/2.0, 0, 360)).transformed(t))
    self.cell.shapes(Layerm1N).insert(pya.Path(arc(r_m1_out, angle_min_M1, angle_max_M1), w_m1_out).transformed(t).simple_polygon())
    boxM11 = pya.Box(x0-w_via, y0 + r_m1_out + w_m1_out-h_via, x0+w_via, y0 + r_m1_out + w_m1_out+h_via)
    shapes(Layerm1N).insert(boxM11)
    
    #Create the ML Layer
    self.cell.shapes(LayermlN).insert(pya.Polygon(arc(w_m1_in/2.0, 0, 360)).transformed(t))
    
    #Create the VL Layer, as well as the electrical PinRec geometries
    # centre contact (P, anode):
    self.cell.shapes(LayervlN).insert(pya.Polygon(arc(r_vl, 0, 360)).transformed(t))
    self.cell.shapes(LayerPinRecN).insert(pya.Polygon(arc(r_vl, 0, 360)).transformed(t))
    shapes(LayerPinRecN).insert(pya.Text ("elec1a", pya.Trans(pya.Trans.R0,x0,y0))).text_size = 0.5/dbu
    shapes(LayerPinRecN).insert(pya.Box(x0-w_via/2, y0-w_via/2, x0+w_via/2, y0+w_via/2))
    
    # top contact (N, cathode):
    boxVL1 = pya.Box(x0-w_via/2, y0 +  r_vc2 +  w_vc/2 + 2.0/dbu, x0+w_via/2, y0 + r_vc2 +  w_vc/2 + 2.0/dbu+ h_via)
    shapes(LayervlN).insert(boxVL1)
    shapes(LayerPinRecN).insert(boxVL1)
    shapes(LayerPinRecN).insert(pya.Text ("elec1c", pya.Trans(pya.Trans.R0,x0,y0 + r_vc2 +  w_vc/2 + 2.0/dbu+ h_via/2))).text_size = 0.5/dbu
    # heater contacts
    boxVL3 = pya.Box(x0+(r_mh_in)*cos(angle_min_MH/180*pi) + 2.5/dbu, -w/2.0 -  10/dbu, x0 + (r_mh_in)*cos(angle_min_MH/180*pi) + 7.5/dbu, -w/2.0 -  5/dbu)
    shapes(LayervlN).insert(boxVL3)
    shapes(LayerPinRecN).insert(boxVL3)
    shapes(LayerPinRecN).insert(pya.Text ("elec2h2", pya.Trans(pya.Trans.R0,x0+(r_mh_in)*cos(angle_min_MH/180*pi) + 5.0/dbu,-w/2.0 -  7.5/dbu))).text_size = 0.5/dbu
    boxVL4 = pya.Box(x0-(r_mh_in)*cos(angle_min_MH/180*pi)- 7.5/dbu, -w/2.0 -  10/dbu, x0 - (r_mh_in)*cos(angle_min_MH/180*pi) - 2.5/dbu, -w/2.0 -  5/dbu)
    shapes(LayervlN).insert(boxVL4)
    shapes(LayerPinRecN).insert(boxVL4)
    shapes(LayerPinRecN).insert(pya.Text ("elec2h1", pya.Trans(pya.Trans.R0,x0-(r_mh_in)*cos(angle_min_MH/180*pi) - 5.0/dbu,-w/2.0 -  7.5/dbu))).text_size = 0.5/dbu

    #Create the MH Layer
    self.cell.shapes(LayermhN).insert(pya.Path(arc(r_mh, angle_min_MH, angle_max_MH), w_mh).transformed(t).simple_polygon())
    boxMH1 = pya.Box(x0+(r_mh_in)*cos(angle_min_MH/180*pi), -w/2.0 -  2.5/dbu, x0 + (r_mh_in)*cos(angle_min_MH/180*pi) + w_mh, y0 +(r_mh_in)*sin(angle_min_MH/180*pi))
    shapes(LayermhN).insert(boxMH1)
    boxMH2 = pya.Box(x0-(r_mh_in)*cos(angle_min_MH/180*pi)  - w_mh, -w/2.0 -  2.5/dbu, x0 - (r_mh_in)*cos(angle_min_MH/180*pi), y0 +(r_mh_in)*sin(angle_min_MH/180*pi))
    shapes(LayermhN).insert(boxMH2)
    boxMH3 = pya.Box(x0+(r_mh_in)*cos(angle_min_MH/180*pi), -w/2.0 -  12.5/dbu, x0 + (r_mh_in)*cos(angle_min_MH/180*pi) + 10/dbu, -w/2.0 -  2.5/dbu)
    shapes(LayermhN).insert(boxMH3)
    boxMH4 = pya.Box(x0-(r_mh_in)*cos(angle_min_MH/180*pi)- 10/dbu, -w/2.0 -  12.5/dbu, x0 - (r_mh_in)*cos(angle_min_MH/180*pi), -w/2.0 -  2.5/dbu)
    shapes(LayermhN).insert(boxMH4)
    
    # Create the pins, as short paths:
    from SiEPIC._globals import PIN_LENGTH as pin_length
        
    shapes(LayerPinRecN).insert(pya.Path([pya.Point(x0 - (w_Si3 / 2. + taper_length) + pin_length/2., 0),
                                          pya.Point(x0 - (w_Si3 / 2. + taper_length) - pin_length/2., 0)], w))
    shapes(LayerPinRecN).insert(pya.Text("opt1", pya.Trans(pya.Trans.R0,x0 - (w_Si3 / 2. + taper_length), 0))).text_size = 0.5/dbu

    shapes(LayerPinRecN).insert(pya.Path([pya.Point(x0 + (w_Si3 / 2. + taper_length) - pin_length/2., 0),
                                          pya.Point(x0 + (w_Si3 / 2. + taper_length)           + pin_length/2., 0)], w))
    shapes(LayerPinRecN).insert(pya.Text("opt2", pya.Trans(pya.Trans.R0,x0 + (w_Si3 / 2. + taper_length), 0))).text_size = 0.5/dbu

    shapes(LayerPinRecN).insert(pya.Path([pya.Point(x0 - (w_Si3 / 2. + taper_length) + pin_length/2., y_offset),
                                          pya.Point(x0 - (w_Si3 / 2. + taper_length) - pin_length/2., y_offset)], w))
    shapes(LayerPinRecN).insert(pya.Text("opt3", pya.Trans(pya.Trans.R0,x0 - (w_Si3 / 2. + taper_length), y_offset))).text_size = 0.5/dbu

    shapes(LayerPinRecN).insert(pya.Path([pya.Point(x0 + (w_Si3 / 2. + taper_length) - pin_length/2., y_offset),
                                          pya.Point(x0 + (w_Si3 / 2. + taper_length) + pin_length/2., y_offset)], w))
    shapes(LayerPinRecN).insert(pya.Text("opt4", pya.Trans(pya.Trans.R0,x0 + (w_Si3 / 2. + taper_length), y_offset))).text_size = 0.5/dbu

    # Create the device recognition layer
    shapes(LayerDevRecN).insert(pya.Box(x0 - (w_Si3 / 2 + taper_length), -w/2.0 -  12.5/dbu, x0 + (w_Si3 / 2 + taper_length), y0 + r_m1_out + w_m1_out+h_via ))

    # Compact model information
    shape = shapes(LayerDevRecN).insert(pya.Text('Lumerical_INTERCONNECT_library=Design kits/GSiP', \
      pya.Trans(pya.Trans.R0,0, 0))).text_size = 0.3/dbu
    shapes(LayerDevRecN).insert(pya.Text('Component=Ring_Modulator_DB', \
      pya.Trans(pya.Trans.R0,0, w*2))).text_size = 0.3/dbu
    shapes(LayerDevRecN).insert(pya.Text('Component_ID=%s' % self.component_ID, \
      pya.Trans(pya.Trans.R0,0, w*4))).text_size = 0.3/dbu
    shapes(LayerDevRecN).insert(pya.Text \
      ('Spice_param:radius=%.3fu wg_width=%.3fu gap=%.3fu gap_monitor=%.3fu' %\
      (self.r, self.w, self.g, self.gmon), \
      pya.Trans(pya.Trans.R0,0, -w*2) ) ).text_size = 0.3/dbu
    
    # Add a polygon text description
    from SiEPIC.utils import layout_pgtext
    if self.textpolygon : layout_pgtext(self.cell, self.textl, self.w, self.r+self.w, "%.3f-%g" % ( self.r, self.g), 1)

    # Reference publication:
    shapes(TextLayerN).insert(pya.Text ("Ref: Raphael Dube-Demers, JLT, 2015", pya.Trans(pya.Trans.R0,x0 - (w_Si3 / 2 + taper_length), -w/2.0 -  12.5/dbu+4.0/dbu))).text_size = 0.7/dbu
    shapes(TextLayerN).insert(pya.Text ("http://dx.doi.org/10.1109/JLT.2015.2462804", pya.Trans(pya.Trans.R0,x0 - (w_Si3 / 2 + taper_length), -w/2.0 -  12.5/dbu+1.0/dbu))).text_size = 0.7/dbu
Ejemplo n.º 5
0
  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, arc_xy

    # fetch the parameters
    dbu = self.layout.dbu
    ly = self.layout
    shapes = self.cell.shapes
    
    LayerSi = self.silayer
    LayerSiN = ly.layer(LayerSi)
    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+0.35/dbu+g
#    layout_arc_wg_dbu(self.cell, LayerSiN, x-Lc/2, y, r, w, 180, 270)
    #layout_arc_wg_dbu(self.cell, LayerSiN, x+Lc/2, y, r, 0.2/dbu, 270, 360)

    t = Trans(Trans.R0,x+Lc/2, y)
    self.cell.shapes(LayerSiN).insert(Path(arc(r, 270, 360),0.2/dbu).transformed(t).simple_polygon())

    # Draw 500 to 200 nm polygon
    pts = []
    pts.append(Point.from_dpoint(DPoint(0/dbu, (-0.35+0.6)/dbu)))
    pts.append(Point.from_dpoint(DPoint(0/dbu, (-0.85+0.6)/dbu)))
    pts.append(Point.from_dpoint(DPoint(-10/dbu, (-0.55+0.6)/dbu)))
    pts.append(Point.from_dpoint(DPoint(-10/dbu, (-0.35+0.6)/dbu)))
    polygon = Polygon(pts)
    shapes(LayerSiN).insert(polygon)

    # Create the top left 1/2 waveguide
    wg1 = Box(-10/dbu, (-0.35+0.6+0.3)/dbu, 0, (-0.55+0.6+0.3)/dbu)
    shapes(LayerSiN).insert(wg1)

    
    # Create the pins, as short paths:
    from SiEPIC._globals import PIN_LENGTH 
 
    # Create the waveguide
    wg1 = Box(0, -w/2, r+w/2+w+Lc/2, w/2)
    shapes(LayerSiN).insert(wg1)

    # Pins on the bus waveguide side:
    pin = Path([Point(-10.1/dbu, (-0.35+0.6+0.05)/dbu), Point(-9.9/dbu, (-0.35+0.6+0.05)/dbu)], w)
    shapes(LayerPinRecN).insert(pin)
    t = Trans(Trans.R0, -10/dbu, (-0.35+0.6+0.05)/dbu)
    text = Text ("pin1", t)
    shape = shapes(LayerPinRecN).insert(text)
    shape.text_size = 0.4/dbu

    pin = Path([Point(r+w/2+w-PIN_LENGTH/2+Lc/2, 0), Point(r+w/2+w+PIN_LENGTH/2+Lc/2, 0)], w)
    shapes(LayerPinRecN).insert(pin)
    t = Trans(Trans.R0, r+w/2+w+Lc/2, 0)
    text = Text ("pin2", t)
    shape = shapes(LayerPinRecN).insert(text)
    shape.text_size = 0.4/dbu

    # Create the device recognition layer -- make it 1 * wg_width away from the waveguides.
    dev = Box(-10/dbu, -w/2-w, r+w/2+w+Lc/2, y )
    shapes(LayerDevRecN).insert(dev)

    print("Done drawing the layout for - strip_to_slot: %.3f-%g" % ( self.r, self.g) )