示例#1
0
class Spirals(PlaceAndAutoRoute):

    _name_prefix = 'LSpiral'

    tipo = i3.PositiveNumberProperty(doc="Number loops", default=1)

    waveguide_template = i3.DefinitionProperty(doc="Trace template used")
    R = i3.PositiveNumberProperty(default=200, doc="Radius of curvature")
    spacing = i3.PositiveNumberProperty(default=100, doc="Radius of curvature")
    n_loops = i3.IntProperty(doc="Number loops", default=2)
    n_loops_vec = i3.ListProperty(default=[4, 8])
    s_length_vec = i3.ListProperty(default=[0.0])
    Spiral_list = i3.ChildCellListProperty(
        doc="List containing the 90 degree angle child cells")
    #chip_length = i3.PositiveNumberProperty(default=2500.0, doc="Radius of curvature")
    chip_length = i3.PositiveNumberProperty(default=3000.0,
                                            doc="Radius of curvature")
    Port = i3.ChildCellProperty(doc="Used for ports")
    Port2 = i3.ChildCellProperty(doc="Used for ports")
    tlport = i3.PositiveNumberProperty(default=1000.0,
                                       doc="Transition legth to ports")
    couplingWG = i3.ChildCellProperty(doc="", locked=True)
    couplingWG_l = i3.PositiveNumberProperty(default=5000.0,
                                             doc="Length of the coupling WG ")
    tt_port = i3.TraceTemplateProperty(
        doc="Wide trace template used for the contacts")
    tt_port2 = i3.TraceTemplateProperty(
        doc="Wide trace template used for the contacts")

    #width_vec = i3.ListProperty(default=[1])
    n = i3.PositiveNumberProperty(default=1, doc="")
    width = i3.PositiveNumberProperty(default=1, doc="")
    lengths = i3.PositiveNumberProperty(default=1, doc="")

    def _default_lengths(self):
        for counter, cell in enumerate(self.s_length_vec):
            numero = counter + 1
        return numero

    #template for Autorute
    def _default_trace_template(self):
        return self.waveguide_template

    def _default_tt(self):
        return self.waveguide_template

    def _default_tt_port(self):
        tt_port = WireWaveguideTemplate()
        tt_port_layout = tt_port.Layout(core_width=10.0, cladding_width=10.0)
        return tt_port

    def _default_tt_port2(self):
        tt_port = WireWaveguideTemplate()
        tt_port_layout = tt_port.Layout(core_width=10.0, cladding_width=10.0)
        return tt_port

    def _default_Spiral_list(self):
        Spiral_list = []  # empty list
        print ' I am in _Spiral_list'
        for l, length in enumerate(self.s_length_vec):
            loops = 1
            print length

            cell = FixedLengthSpiralRounded(
                trace_template=self.waveguide_template,
                #total_length=length-self.chip_length,
                total_length=length,
                n_o_loops=loops,
                name=self.name + '_Spiral_' + str(l))

            cell.Layout(
                incoupling_length=0,
                bend_radius=self.R,
                spacing=self.spacing,
                stub_direction="H",
                growth_direction="H",
            )  #.visualize(annotate=True)
            print 'The legth of the spiral is: ', cell.total_length
            print 'Cell: ', cell.name

            Spiral_list.append(cell)

        return Spiral_list

    def _default_couplingWG(self):
        rect = i3.Waveguide(trace_template=self.tt_port)
        layout_rect = rect.Layout(shape=[(0.0, 0.0), (self.couplingWG_l, 0.0)])
        return rect

    def _default_Port(self):
        Port = AutoTransitionPorts(contents=self.couplingWG,
                                   port_labels=["in"],
                                   trace_template=self.waveguide_template)
        layout_Port = Port.Layout(
            transition_length=self.tlport)  #.visualize(annotate=True)
        return Port

    def _default_Port2(self):
        Port = AutoTransitionPorts(contents=self.couplingWG,
                                   port_labels=["in"],
                                   trace_template=self.waveguide_template)
        layout_Port = Port.Layout(
            transition_length=self.tlport)  #.visualize(annotate=True)
        return Port

    def _default_child_cells(self):
        child_cells = {
        }  # First we define the property "child_cells" as  an empty dictionary

        for counter, spiral in enumerate(
                self.Spiral_list
        ):  # the iteration starts in the first element of the list and follows element by element to the last element.

            child_cells['Spiral{}'.format(counter)] = spiral
            print spiral
            print 'name of spiral:', spiral.name
            child_cells['InPort' + str(counter)] = self.Port
            child_cells['OutPort' + str(counter)] = self.Port

            print 'child_cells:', child_cells
        return child_cells

    def _default_links(self):
        links = []
        for counter, spiral in enumerate(self.Spiral_list):
            print counter
            in_port = "Spiral{}:in".format(counter)
            out_port = "InPort{}:in".format(counter)
            links.append((in_port, out_port))
            in_port = "Spiral{}:out".format(counter)
            out_port = "OutPort{}:in".format(counter)
            links.append((in_port, out_port))

        return links

    class Layout(PlaceAndAutoRoute.Layout):
        #tipo=1

        def _default_bend_radius(self):
            return self.R

        def _default_child_transformations(self):
            d = {}
            for counter, child in enumerate(self.Spiral_list):
                ip = child.ports["in"].position
                #print self.child_cells['InPort' + str(counter)].ports["out"].position
                #print self.child_cells['OutPort' + str(counter)].ports.position
                print '----------------'
                print 'spiral length:', child.total_length
                print 'counter: ', counter
                #print ip
                op = child.ports["out"].position
                #print op

                print 'The lateral size of the spiral is', op[0] - ip[0]
                print 'The type of mask is: ', self.tipo
                print 'The number of widths is: ', self.n
                print 'The number of lengths is: ', self.lengths
                print 'The width number is: ', self.width
                print '----------------'
                iz = child.inner_size
                sx = iz[1] + 200
                #sx=1200
                if self.tipo == 1:

                    d['Spiral' + str(counter)] = i3.Translation(
                        translation=(-(op[0] - ip[0]) / 2,
                                     self.n * counter * sx))
                    d['InPort' + str(counter)] = i3.HMirror() + i3.Translation(
                        translation=(-self.chip_length / 2.0 -
                                     self.couplingWG_l, self.n * counter * sx))
                    d['OutPort' + str(counter)] = i3.Translation(
                        translation=(self.chip_length / 2.0 +
                                     self.couplingWG_l, self.n * counter * sx))
                if self.tipo == 2:
                    d['Spiral' + str(counter)] = i3.Translation(
                        translation=(-(op[0] - ip[0]) / 2,
                                     -(self.n + 0.5) * counter * sx))
                    #d['InPort' + str(counter)] = i3.HMirror()+ i3.Translation(translation=(-self.chip_length*(3/4)-self.couplingWG_l, -(self.n+0.5)*counter*sx))
                    #d['OutPort' + str(counter)] = i3.Rotation(rotation=90) + i3.Translation(translation=((op[0]-ip[0])/2+2*self.R+(((self.n+0.5)*counter+self.width)*sx/4), self.chip_length*(3/4)+(self.width+counter-(((counter+1)-1.0)%self.lengths))*sx))
                    d['InPort' + str(counter)] = i3.HMirror() + i3.Translation(
                        translation=(-self.chip_length * (1 / 2) - 2000,
                                     -(self.n + 0.5) * counter * sx))
                    d['OutPort' + str(counter)] = i3.Rotation(
                        rotation=90) + i3.Translation(translation=(
                            (op[0] - ip[0]) / 2 + 2 * self.R +
                            (((self.n + 0.5) * counter + self.width) * sx / 4),
                            3000 + self.chip_length * (3 / 4) +
                            (self.width + counter -
                             (((counter + 1) - 1.0) % self.lengths)) * sx))
                #For awg's
                #if self.tipo==2:
                #d['Spiral' + str(counter)] = i3.Translation(translation=(-(op[0]-ip[0])/2, -(self.n+0.5)*counter*sx))
                #d['InPort' + str(counter)] = i3.HMirror()+ i3.Translation(translation=(-self.chip_length*(3/4.0), -(self.n+0.5)*counter*sx))
                #d['OutPort' + str(counter)] = i3.Rotation(rotation=90) + i3.Translation(translation=((op[0]-ip[0])/2+2*self.R
                #+(((self.n+0.5)*counter+self.width)*sx/100.0)
                #, self.chip_length*(2/4.0)+
                #(self.width+counter-(((counter+1)-1.0)%self.lengths))*sx))
            return d

        # Fabio's addition
        def _generate_elements(self, elems):
            # We calculate the lengths of the 2 spirals in this pcell.
            # Note that we assume that there are exactly 2 spirals in this list.
            #assert len(self.Spiral_list) == 2
            lengths = get_lengths(self)
            iz = self.Spiral_list[0].inner_size
            sx = iz[1] + 200
            for counter, (child,
                          length) in enumerate(zip(self.Spiral_list, lengths)):
                ip = child.ports["in"].position
                op = child.ports["out"].position
                width = child.ports["in"].trace_template.core_width
                #print 'child.ports["in"].trace_template.core_width: ', child.ports["in"].trace_template.core_width

                #i3.TECH.PPLAYER.NONE.LOGOTXT   when using isipp50g
                if self.tipo == 2:
                    elems += i3.PolygonText(
                        layer=i3.TECH.PPLAYER.WG.TEXT,
                        text='Width={}_Length={}_R={}'.format(
                            width, length, self.R),
                        coordinate=((op[0] - ip[0]) / 2 - 1000.0,
                                    (self.n + 0.5) * counter * sx - 50.0),
                        alignment=(i3.TEXT_ALIGN_LEFT, i3.TEXT_ALIGN_LEFT),
                        font=2,
                        height=20.0)
                if self.tipo == 1:
                    elems += i3.PolygonText(
                        layer=i3.TECH.PPLAYER.WG.TEXT,
                        text='Width={}_Length={}_R={}'.format(
                            width, length, self.R),
                        coordinate=(-(op[0] - ip[0]) / 2 - 1000.0,
                                    -(self.n + 0.5) * counter * sx - 50.0),
                        alignment=(i3.TEXT_ALIGN_LEFT, i3.TEXT_ALIGN_LEFT),
                        font=2,
                        height=20.0)
            return elems
class SingleResonator(i3.PCell):
    """ A single resonator test class
    """
    _name_prefix = "single_resonator"

    # defining the resonator as child cell with input and output waveguides
    resonator = i3.ChildCellProperty(restriction=i3.RestrictType(i3.PCell),
                                     doc="the input resonator")

    # define waveguide template and waveguide cells
    wg_coupler_template = i3.WaveguideTemplateProperty(
        default=i3.TECH.PCELLS.WG.DEFAULT)
    wg_ring_template = i3.WaveguideTemplateProperty(
        default=i3.TECH.PCELLS.WG.DEFAULT)
    wgs = i3.ChildCellListProperty(doc="list of waveguides")

    # define default MMI for class
    def _default_resonator(self):
        """
        Internal resonator which is repeated later
        """
        resonator = RingRect(name=self.name + "_resonator",
                             ring_trace_template=self.wg_ring_template)
        return resonator

    # define rounded waveguides for the inputs and outputs of CROW
    def _default_wgs(self):
        wg_in = i3.RoundedWaveguide(name=self.name + "_wg_in",
                                    trace_template=self.wg_coupler_template)
        wg_pass = i3.RoundedWaveguide(name=self.name + "_wg_pass",
                                      trace_template=self.wg_coupler_template)
        # wg_ring = i3.RoundedWaveguide(name=self.name+"_wg_ring", trace_template=self.wg_coupler_template)
        return wg_in, wg_pass  # , wg_pass, wg_ring

    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 Netlist(i3.NetlistView):
        def _generate_terms(self, terms):
            terms += i3.OpticalTerm(name="in")
            # terms += i3.OpticalTerm(name="pass")
            return terms
class CROW_1D(i3.PCell):
    """ A single resonator test class
    """
    _name_prefix = "CROW_1D"

    # defining the resonator as child cell with input and output waveguides
    resonator = i3.ChildCellProperty(restriction=i3.RestrictType(i3.PCell),
                                     doc="the input resonator")

    # define waveguide template and waveguide cells
    wg_coupler_template = i3.WaveguideTemplateProperty(
        default=i3.TECH.PCELLS.WG.DEFAULT)
    wg_ring_template = i3.WaveguideTemplateProperty(
        default=i3.TECH.PCELLS.WG.DEFAULT)
    wgs = i3.ChildCellListProperty(doc="list of waveguides")

    # define default MMI for class
    def _default_resonator(self):
        """
        Internal resonator which is repeated later
        """
        resonator = RingRect(name=self.name + "_resonator",
                             ring_trace_template=self.wg_ring_template)
        return resonator

    # define rounded waveguides for the inputs and outputs of CROW
    def _default_wgs(self):
        wg_in = i3.RoundedWaveguide(name=self.name + "_wg_in",
                                    trace_template=self.wg_coupler_template)
        wg_pass = i3.RoundedWaveguide(name=self.name + "_wg_pass",
                                      trace_template=self.wg_coupler_template)
        # wg_ring = i3.RoundedWaveguide(name=self.name+"_wg_ring", trace_template=self.wg_coupler_template)
        return wg_in, wg_pass  # , wg_pass, wg_ring

    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 Netlist(i3.NetlistView):
        def _generate_terms(self, terms):
            terms += i3.OpticalTerm(name="in")
            # terms += i3.OpticalTerm(name="pass")
            return terms
示例#4
0
class my_dc(PlaceAndAutoRoute):
    # dc = i3.ChildCellProperty()
    # dc2 = i3.ChildCellProperty()

    DC_list = i3.ChildCellListProperty(default=[])
    gap_inc_vec = i3.ListProperty(default=[], doc="gap")
    # length = i3.PositiveNumberProperty(default=60.0, doc="Length of coupler")

    WG1 = i3.ChildCellProperty(doc="", locked=True)
    WG2 = i3.ChildCellProperty()
    wg_t1 = i3.WaveguideTemplateProperty()
    # wg_dc2 = i3.WaveguideTemplateProperty()
    width = i3.PositiveNumberProperty(doc="width of ports", default=15)
    sm_width = i3.PositiveNumberProperty(doc="width of waveguide", default=3.8)

    # start_id = i3.PositiveNumberProperty(doc="name_id", default=1)

    def _default_wg_t1(self):
        wg_t1 = WireWaveguideTemplate(name="port_{}".format(str(self.width)))
        wg_t1.Layout(
            core_width=self.width,
            cladding_width=self.width + 16,
        )
        return wg_t1

    def _default_trace_template(self):
        wg_sm = WireWaveguideTemplate(name="sm_template" + str(self.sm_width))
        wg_sm.Layout(core_width=self.sm_width,
                     cladding_width=self.sm_width + 16.0)
        return wg_sm

    def _default_WG1(self):
        WG1 = i3.Waveguide(name="straight{}".format(str(self.width)),
                           trace_template=self.wg_t1)
        WG1.Layout(shape=[(0.0, 0.0), (150.0, 0.0)])
        return WG1

    def _default_WG2(self):
        Port = AutoTransitionPorts(name="ports{}".format(str(self.sm_width)),
                                   contents=self.WG1,
                                   port_labels=["out"],
                                   trace_template=self.trace_template)
        Port.Layout(transition_length=300)  # .visualize(annotate=True)
        return Port

    def _default_DC_list(self):
        print '____________ MMI 2x2 ______________'
        MMI22_list = []

        for l, dl in enumerate(self.gap_inc_vec):
            # print 'length number ' + str(l)
            # print 'dl ' + str(dl)

            cell = DoubleSpiralRounded(
                name='R={}_width={}'.format(str(dl), str(self.sm_width)),
                trace_template=self.trace_template,
                n_o_loops=8,
            )
            layout = cell.Layout(
                angle_step=30,
                inner_size=[1400, 700],
                bend_radius=self.gap_inc_vec[l],
                manhattan=False,
                spacing=2 * 8 + self.sm_width + 5,
                stub_direction="V",
            )
            print "{}_length={}".format(str(cell.name),
                                        str(layout.trace_length()))
            # print cell.name
            # print layout.trace_length()

            MMI22_list.append(cell)

        return MMI22_list

    def _default_child_cells(self):
        child_cells = dict()
        for counter in range(0, 8, 1):
            # print counter
            # child_cells['straight' + str(counter)] = self.WG1
            child_cells['taper' + str(counter)] = self.WG2
        # child_cells["dircoup1"] = self.dc
        # child_cells["dircoup2"] = self.dc2
        # child_cells["straight"] = self.WG2

        for counter, child in enumerate(self.DC_list):
            # print 'child number' + str(counter)
            child_cells['ring' + str(counter)] = child
            # print 'child name ' + str(child.name)
            # print child
        return child_cells

    def _default_links(self):
        links = [
            ("taper0:out", "ring0:in"),
            ("taper1:out", "ring0:out"),
            ("taper2:out", "ring1:in"),
            ("taper3:out", "ring1:out"),
            ("taper4:out", "ring2:in"),
            ("taper5:out", "ring2:out"),
            ("taper6:out", "ring3:in"),
            ("taper7:out", "ring3:out"),

            # ("taper8:out", "ring2:out2"),
            # ("taper9:out", "ring2:in1"),
            # ("taper10:out", "ring2:in2"),
            # ("taper11:out", "ring2:out1"),
            # ("taper12:out", "ring3:out2"),
            # ("taper13:out", "ring3:in1"),
            # ("taper14:out", "ring3:in2"),
            # ("taper15:out", "ring3:out1"),
        ]
        return links

    class Layout(PlaceAndAutoRoute.Layout):
        def _default_child_transformations(self):
            trans = dict()
            column = 3500
            # trans["dircoup1"] = (1650, 0)
            # trans["dircoup2"] = (4950, 0)
            # trans['mzi_22_22_0'] = (0, 0)
            trans['ring0'] = (1300, -2400)
            # trans['ring1'] = i3.VMirror(0) + i3.Translation((1300, 2000))
            trans['ring1'] = (1300 + column, -2400)
            trans['ring2'] = (1300 + 2 * column, -2400)
            trans['ring3'] = (1300 + 3 * column, -2400)

            trans["taper0"] = (0, -4000)
            trans["taper1"] = i3.HMirror(0) + i3.Translation((column, -3500))
            trans["taper2"] = (0 + column, -3500)
            trans["taper3"] = i3.HMirror(0) + i3.Translation(
                (2 * column, -4000))
            trans["taper4"] = (0 + 2 * column, -4000)
            trans["taper5"] = i3.HMirror(0) + i3.Translation(
                (3 * column, -3500))
            trans["taper6"] = (0 + 3 * column, -3500)
            trans["taper7"] = i3.HMirror(0) + i3.Translation(
                (4 * column, -4000))

            return trans

        def _default_bend_radius(self):
            bend_radius = 300
            return bend_radius

        # def _default_start_straight(self):
        #     end_straight = 10
        #     return end_straight

        def _generate_elements(self, elems):
            for counter, child in enumerate(self.DC_list):
                name = child.name
                # aa = child.layout.trace_length()

                elems += i3.PolygonText(
                    layer=i3.TECH.PPLAYER.WG.TEXT,
                    text="{}".format(name),
                    # coordinate=(4650.0, 100.0),
                    alignment=(i3.TEXT_ALIGN_LEFT, i3.TEXT_ALIGN_LEFT),
                    font=2,
                    height=150.0,
                    transformation=i3.Translation(
                        (300 + 3500 * counter, -3200)))

                # elems += i3.Rectangle(layer=i3.TECH.PPLAYER.WG.TEXT,
                #                       center=(0, 0),
                #                       box_size=(500, 300))
            return elems
示例#5
0
class my_dc(PlaceAndAutoRoute):
    # dc = i3.ChildCellProperty()
    # dc2 = i3.ChildCellProperty()

    DC_list = i3.ChildCellListProperty(default=[])
    gap_inc_vec = i3.ListProperty(default=[], doc="gap")
    length = i3.PositiveNumberProperty(default=80.0, doc="Length of coupler")

    WG1 = i3.ChildCellProperty(doc="", locked=True)
    WG2 = i3.ChildCellProperty()
    wg_t1 = i3.WaveguideTemplateProperty()
    # wg_dc2 = i3.WaveguideTemplateProperty()
    width = i3.PositiveNumberProperty(doc="width of ports", default=15)

    # start_id = i3.PositiveNumberProperty(doc="name_id", default=1)

    def _default_wg_t1(self):
        wg_t1 = WireWaveguideTemplate(name="port_{}".format(str(self.width)))
        wg_t1.Layout(
            core_width=self.width,
            cladding_width=self.width + 16,
        )
        return wg_t1

    def _default_trace_template(self):
        wg_sm = WireWaveguideTemplate(name="sm_template")
        wg_sm.Layout(core_width=3.8, cladding_width=3.8 + 16.0)
        return wg_sm

    def _default_WG1(self):
        WG1 = i3.Waveguide(name="straight{}".format(str(self.width)),
                           trace_template=self.wg_t1)
        WG1.Layout(shape=[(0.0, 0.0), (150.0, 0.0)])
        return WG1

    def _default_WG2(self):
        Port = AutoTransitionPorts(name="ports{}".format(str(self.width)),
                                   contents=self.WG1,
                                   port_labels=["out"],
                                   trace_template=self.trace_template)
        Port.Layout(transition_length=300)  # .visualize(annotate=True)
        return Port

    def _default_DC_list(self):
        print '____________ MMI 2x2 ______________'
        MMI22_list = []

        for l, dl in enumerate(self.gap_inc_vec):
            print 'length number ' + str(l)
            print 'dl ' + str(dl)

            cell = RingRectSymm180DropFilter(
                name='SR_GAP={}_L={}'.format(str(dl), str(self.length)),
                ring_trace_template=self.trace_template)
            cell.Layout(
                bend_radius=200,
                coupler_lengths=[self.length, self.length],
                coupler_radii=[300.0, 300.0],
                coupler_angles=[90.0, 90.0],
                coupler_spacings=[
                    3.8 + self.gap_inc_vec[l], 3.8 + self.gap_inc_vec[l]
                ],
                straights=(self.length, 0.0),
                # manhattan=True,
            )
            cell2 = RingRectSymmNotchFilter(
                name='ring_s' + str(dl) + str(self.length),
                ring_trace_template=self.trace_template)
            cell2.Layout(
                bend_radius=200,
                coupler_lengths=[self.length, self.length],
                coupler_radii=[300, 300],
                coupler_angles=[90.0, 90],
                coupler_spacings=[(3.8 + self.gap_inc_vec[l])],
                straights=(self.length, 0.0),
                # manhattan=True,
            )

            MMI22_list.append(cell)
            MMI22_list.append(cell2)

            print 'cell name ' + str(cell.name)
            print '__________________________'

        return MMI22_list

    def _default_child_cells(self):
        child_cells = dict()
        for counter in range(0, 24, 1):
            print counter
            # child_cells['straight' + str(counter)] = self.WG1
            child_cells['taper' + str(counter)] = self.WG2
        # child_cells["dircoup1"] = self.dc
        # child_cells["dircoup2"] = self.dc2
        # child_cells["straight"] = self.WG2

        for counter, child in enumerate(self.DC_list):
            print 'child number' + str(counter)
            child_cells['ring' + str(counter)] = child
            print 'child name ' + str(child.name)
            print child
        return child_cells

    def _default_links(self):
        links = [
            ("taper0:out", "ring0:out2"),
            ("taper1:out", "ring0:in1"),
            ("taper2:out", "ring0:in2"),
            ("taper3:out", "ring0:out1"),
            ("taper4:out", "ring1:in"),
            ("taper5:out", "ring1:out"),
            ("taper6:out", "ring2:out2"),
            ("taper7:out", "ring2:in1"),
            ("taper8:out", "ring2:in2"),
            ("taper9:out", "ring2:out1"),
            ("taper10:out", "ring3:in"),
            ("taper11:out", "ring3:out"),
            ("taper12:out", "ring4:out2"),
            ("taper13:out", "ring4:in1"),
            ("taper14:out", "ring4:in2"),
            ("taper15:out", "ring4:out1"),
            ("taper16:out", "ring5:in"),
            ("taper17:out", "ring5:out"),
            ("taper18:out", "ring6:out2"),
            ("taper19:out", "ring6:in1"),
            ("taper20:out", "ring6:in2"),
            ("taper21:out", "ring6:out1"),
            ("taper22:out", "ring7:in"),
            ("taper23:out", "ring7:out"),
        ]
        return links

    class Layout(PlaceAndAutoRoute.Layout):
        def _default_child_transformations(self):
            trans = dict()
            column = 4500
            # trans["dircoup1"] = (1650, 0)
            # trans["dircoup2"] = (4950, 0)
            # trans['mzi_22_22_0'] = (0, 0)
            trans['ring0'] = (1500, -3000)
            trans['ring4'] = (1500, -3000 + 2 * column)
            trans['ring1'] = (1500, -300)
            trans['ring5'] = (1500, -300 + 2 * column)

            trans['ring2'] = (1500, -3000 + column)
            trans['ring6'] = (1500, -3000 + 3 * column)
            trans['ring3'] = (1500, -300 + column)
            trans['ring7'] = (1500, -300 + 3 * column)

            trans["taper0"] = (0, -2100)
            trans["taper1"] = (0, -3850)
            trans["taper2"] = i3.HMirror(0) + i3.Translation((3000, -1500))
            trans["taper3"] = i3.Translation((0, -4000))
            trans["taper4"] = (0, -1950)
            trans["taper5"] = i3.HMirror(0) + i3.Translation((3000, -1350))

            trans["taper6"] = (0, -2100 + column)
            trans["taper7"] = (0, -3850 + column)
            trans["taper8"] = i3.HMirror(0) + i3.Translation(
                (3000, -1500 + column))
            trans["taper9"] = i3.Translation((0, -4000 + column))
            trans["taper10"] = (0, -1950 + column)
            trans["taper11"] = i3.HMirror(0) + i3.Translation(
                (3000, -1350 + column))
            trans["taper12"] = (0, -2100 + 2 * column)
            trans["taper13"] = (0, -3850 + 2 * column)
            trans["taper14"] = i3.HMirror(0) + i3.Translation(
                (3000, -1500 + 2 * column))
            trans["taper15"] = i3.Translation((0, -4000 + 2 * column))
            trans["taper16"] = (0, -1950 + 2 * column)
            trans["taper17"] = i3.HMirror(0) + i3.Translation(
                (3000, -1350 + 2 * column))
            trans["taper18"] = (0, -2100 + 3 * column)
            trans["taper19"] = (0, -3850 + 3 * column)
            trans["taper20"] = i3.HMirror(0) + i3.Translation(
                (3000, -1500 + 3 * column))
            trans["taper21"] = i3.Translation((0, -4000 + 3 * column))
            trans["taper22"] = (0, -1950 + 3 * column)
            trans["taper23"] = i3.HMirror(0) + i3.Translation(
                (3000, -1350 + 3 * column))

            return trans

        def _default_bend_radius(self):
            bend_radius = 300
            return bend_radius

        def _generate_elements(self, elems):
            for counter, child in enumerate(self.DC_list):
                if (counter % 2 == 0):
                    name = child.name
                    elems += i3.PolygonText(
                        layer=i3.TECH.PPLAYER.WG.TEXT,
                        text="{}".format(name[0:10]),
                        # coordinate=(4650.0, 100.0),
                        alignment=(i3.TEXT_ALIGN_LEFT, i3.TEXT_ALIGN_LEFT),
                        font=2,
                        height=200.0,
                        transformation=i3.Rotation(
                            (0.0, 0.0), -90.0) + i3.Translation(
                                (3000 - 450, -2000 + 4500 * counter / 2)))
                else:
                    elems += i3.PolygonText(
                        layer=i3.TECH.PPLAYER.WG.TEXT,
                        text="R=200_L=80",
                        alignment=(i3.TEXT_ALIGN_LEFT, i3.TEXT_ALIGN_LEFT),
                        font=2,
                        height=80.0,
                        transformation=i3.Rotation(
                            (0.0, 0.0), -90.0) + i3.Translation(
                                (3000 - 450, -2700 + 4500 * counter / 2)))

            # elems += i3.Rectangle(layer=i3.TECH.PPLAYER.WG.TEXT,
            #                       center=(0, 0),
            #                       box_size=(500, 300))
            return elems
示例#6
0
class my_dc(PlaceAndAutoRoute):
    DC_list = i3.ChildCellListProperty(default=[])
    gap_inc_vec = i3.ListProperty(default=[], doc="Length of MMI")
    WG1 = i3.ChildCellProperty(doc="", locked=True)
    WG2 = i3.ChildCellProperty()
    wg_t1 = i3.WaveguideTemplateProperty(doc="board WG")
    mmi_trace_template = i3.WaveguideTemplateProperty()
    mmi_access_template = i3.WaveguideTemplateProperty()
    width = i3.PositiveNumberProperty(doc="width of ports", default=15)

    def _default_wg_t1(self):
        wg_t1 = WireWaveguideTemplate(name="port_{}".format(str(self.width)))
        wg_t1.Layout(
            core_width=self.width,
            cladding_width=self.width + 2 * 12.0,
        )
        return wg_t1

    def _default_trace_template(self):
        wg_sm = WireWaveguideTemplate(name="sm_template")
        wg_sm.Layout(core_width=3.8, cladding_width=3.8 + 2 * 12.0)
        return wg_sm

    def _default_WG1(self):
        WG1 = i3.Waveguide(name="straight{}".format(str(self.width)),
                           trace_template=self.wg_t1)
        WG1.Layout(shape=[(0.0, 0.0), (150.0, 0.0)])
        return WG1

    def _default_WG2(self):
        Port = AutoTransitionPorts(name="ports{}".format(str(self.width)),
                                   contents=self.WG1,
                                   port_labels=["out"],
                                   trace_template=self.trace_template)
        Port.Layout(transition_length=300)  # .visualize(annotate=True)
        return Port

    def _default_mmi_trace_template(self):
        mmi_trace_template = WireWaveguideTemplate(name="MMI_tt")
        mmi_trace_template.Layout(core_width=20.0,
                                  cladding_width=20.0 + 2 * 12)  # MMI_width
        return mmi_trace_template

    def _default_mmi_access_template(self):
        mmi_access_template = WireWaveguideTemplate(name="MMI_at")
        mmi_access_template.Layout(core_width=9.0, cladding_width=9.0 + 2 * 12)
        return mmi_access_template

    def _default_DC_list(self):
        print '____________ MMI 2x2 ______________'
        MMI22_list = []

        for l, dl in enumerate(self.gap_inc_vec):
            print 'length number ' + str(l)
            print 'dl ' + str(dl)

            cell = MMI2x2Tapered(
                mmi_trace_template=self.mmi_trace_template,
                input_trace_template=self.mmi_access_template,
                output_trace_template=self.mmi_access_template,
                trace_template=self.trace_template,
            )

            cell.Layout(name="MMI22_l_{}".format(str(self.gap_inc_vec[l])),
                        transition_length=200.0,
                        length=self.gap_inc_vec[l],
                        trace_spacing=11.0)

            # cell = RingRectSymm180DropFilter(name='ring' + str(dl) + str(self.length),
            #                                  ring_trace_template=self.trace_template)
            # cell.Layout(bend_radius=200,
            #             coupler_lengths=[self.length, self.length],
            #             coupler_radii=[300.0, 300.0],
            #             coupler_angles=[90.0, 90.0],
            #             coupler_spacings=[3.8 + self.gap_inc_vec[l], 3.8 + self.gap_inc_vec[l]],
            #             straights=(self.length, 0.0),
            #             # manhattan=True,
            #             )

            MMI22_list.append(cell)

            print 'cell name ' + str(cell.name)
            print '__________________________'

        return MMI22_list

    def _default_child_cells(self):
        child_cells = dict()
        for counter in range(0, 12, 1):
            print counter
            # child_cells['straight' + str(counter)] = self.WG1
            child_cells['taper' + str(counter)] = self.WG2

        for counter, child in enumerate(self.DC_list):
            print 'child number' + str(counter)
            child_cells['ring' + str(counter)] = child
            print 'child name ' + str(child.name)
            print child
        return child_cells

    def _default_links(self):
        links = [
            ("taper0:out", "ring0:in2"),
            ("taper1:out", "ring0:in1"),
            ("taper2:out", "ring0:out2"),
            ("taper3:out", "ring0:out1"),
            ("taper4:out", "ring1:in2"),
            ("taper5:out", "ring1:in1"),
            ("taper6:out", "ring1:out2"),
            ("taper7:out", "ring1:out1"),
            ("taper8:out", "ring2:in2"),
            ("taper9:out", "ring2:in1"),
            ("taper10:out", "ring2:out2"),
            ("taper11:out", "ring2:out1"),

            # ("taper12:out", "ring3:out2"),
            # ("taper13:out", "ring3:in1"),
            # ("taper14:out", "ring3:in2"),
            # ("taper15:out", "ring3:out1"),
        ]
        return links

    class Layout(PlaceAndAutoRoute.Layout):
        def _default_child_transformations(self):
            trans = dict()
            column = 10000
            # trans["dircoup1"] = (1650, 0)
            # trans["dircoup2"] = (4950, 0)
            # trans['mzi_22_22_0'] = (0, 0)
            trans['ring0'] = (2500, 0)
            trans['ring1'] = (2500, 0 + column)
            trans['ring2'] = (2500, 0 + 2 * column)
            # trans['ring3'] = (1500, 0 + 3 * column)

            trans["taper0"] = (0, 4000)
            trans["taper1"] = (0, -4000)
            trans["taper2"] = i3.HMirror(0) + i3.Translation((5000, 2500))
            trans["taper3"] = i3.HMirror(0) + i3.Translation((5000, -2500))

            trans["taper4"] = (0, 4000 + column)
            trans["taper5"] = (0, -4000 + column)
            trans["taper6"] = i3.HMirror(0) + i3.Translation(
                (5000, 2500 + column))
            trans["taper7"] = i3.HMirror(0) + i3.Translation(
                (5000, -2500 + column))

            trans["taper8"] = (0, 4000 + 2 * column)
            trans["taper9"] = (0, -4000 + 2 * column)
            trans["taper10"] = i3.HMirror(0) + i3.Translation(
                (5000, 2500 + 2 * column))
            trans["taper11"] = i3.HMirror(0) + i3.Translation(
                (5000, -2500 + 2 * column))

            return trans

        def _default_bend_radius(self):
            bend_radius = 300
            return bend_radius

        # def _generate_elements(self, elems):
        #
        #
        #
        #     elems += i3.PolygonText(layer=i3.TECH.PPLAYER.WG.TEXT,
        #                             text='Name={}_{}'.format(self.cell.mmi22.get_default_view(i3.LayoutView).name,
        #                                                      self.cell.wg_t1.name),
        #                             coordinate=(1300.0, 100.0),
        #                             alignment=(i3.TEXT_ALIGN_LEFT, i3.TEXT_ALIGN_LEFT),
        #                             font=2,
        #                             height=20.0)
        #
        #     elems += i3.PolygonText(layer=i3.TECH.PPLAYER.WG.TEXT,
        #                             text='Name={}_{}'.format(self.cell.mmi22.get_default_view(i3.LayoutView).name,
        #                                                      self.cell.wg_t1.name),
        #                             coordinate=(-2000.0, -150.0),
        #                             alignment=(i3.TEXT_ALIGN_LEFT, i3.TEXT_ALIGN_LEFT),
        #                             font=2,
        #                             height=200.0,
        #                             transformation=i3.Rotation((0.0, 0.0), 90.0))
        #
        #     return elems

        def _generate_elements(self, elems):
            for counter, child in enumerate(self.DC_list):
                name = child.name

                elems += i3.PolygonText(
                    layer=i3.TECH.PPLAYER.WG.TEXT,
                    text="{}_{}".format(name, self.cell.wg_t1.name),
                    # coordinate=(1300.0, 100.0),
                    alignment=(i3.TEXT_ALIGN_LEFT, i3.TEXT_ALIGN_LEFT),
                    font=2,
                    height=20.0,
                    transformation=i3.Translation(
                        (2500, 100 + 10000 * counter)))

                elems += i3.PolygonText(
                    layer=i3.TECH.PPLAYER.WG.TEXT,
                    text="{}_{}".format(name, self.cell.wg_t1.name),
                    # coordinate=(-2000, -150),
                    alignment=(i3.TEXT_ALIGN_LEFT, i3.TEXT_ALIGN_LEFT),
                    font=2,
                    height=200.0,
                    transformation=i3.Rotation(
                        (0.0, 0.0), 90.0) + i3.Translation(
                            (450, -2000 + 10000 * counter)))

            return elems
class MZI_12_21(PlaceAndAutoRoute):
    _name_prefix = 'MZIs'

    delay_length = i3.PositiveNumberProperty(
        default=132.0, doc="Delay length used in the mzi")
    R = i3.PositiveNumberProperty(default=200, doc="Radius of curvature")
    #MMI12_list = i3.ChildCellListProperty(default=[])
    MMI12 = i3.ChildCellProperty(default=[])
    MMI21_list = i3.ChildCellListProperty(default=[])
    MMI22_list = i3.ChildCellListProperty(default=[])
    #MZI_12_21_list = i3.ChildCellListProperty(default=[])
    MZI_12_22_list = i3.ChildCellListProperty(default=[])
    MZI_22_22_list = i3.ChildCellListProperty(default=[])
    #MMI22_list = i3.ChildCellListProperty()
    wg_t = i3.TraceTemplateProperty(doc="trace template used")
    wg_t_MM = i3.TraceTemplateProperty(
        doc="Trace template used in the MM part")
    wg_t_port = i3.TraceTemplateProperty(
        doc="Trace template used in the ports")
    width_inc_vec = i3.ListProperty(default=[])
    length_inc_vec = i3.ListProperty(default=[])

    l_taper = i3.PositiveNumberProperty(default=200.0,
                                        doc="Length of the tapers")
    width = i3.PositiveNumberProperty(default=20.0, doc="width of MM")
    length_12 = i3.PositiveNumberProperty(default=110.0,
                                          doc="Length of MMI 1x2")
    length_22 = i3.PositiveNumberProperty(default=435.0,
                                          doc="Length of MMI 2x2")
    ts_12 = i3.PositiveNumberProperty(default=11.25, doc="trace spacing")
    #ts for 12 is 7.0 --> MM=5   ()    L12=39.0   L22=158.0
    #ts for 20 is 11 -->MM=9      (ts=11.25, MM8.75) L12=110.0, L22=435.0
    #ts for 30 is 16 -->MM=14     (ts=16.25, MM=13.75) L12=245.0, L22=980.0
    chip_length = i3.PositiveNumberProperty(default=10000.0,
                                            doc="Radius of curvature")
    Port = i3.ChildCellProperty(doc="Used for ports")
    tlport = i3.PositiveNumberProperty(default=200.0,
                                       doc="Transition legth to ports")
    couplingWG = i3.ChildCellProperty(doc="", locked=True)
    couplingWG_l = i3.PositiveNumberProperty(default=3000.0,
                                             doc="Length of the coupling WG ")
    tt_port = i3.TraceTemplateProperty(
        doc="Wide trace template used for the contacts")

    tipo = i3.PositiveNumberProperty(
        default=1,
        doc="type of out-couplers tipo==1, straight, tipo==2, 90  degree bend")

    #template for Autorute
    def _default_trace_template(self):
        return self.wg_t

    def _default_wg_t_MM(self):
        tt_w = WireWaveguideTemplate()
        tt_w.Layout(
            core_width=self.width,
            cladding_width=self.width + 2 * 8,
        )
        return tt_w

    def _default_wg_t_port(self):
        tt_w = WireWaveguideTemplate()
        tt_w.Layout(
            core_width=8.75,
            cladding_width=8.75 + 2 * 8,
        )
        return tt_w

    def _default_wg_t(self):
        tt_n = WireWaveguideTemplate()
        tt_n.Layout(
            core_width=3.3,
            cladding_width=3.3 + 2 * 8,
        )
        return tt_n

    def _default_tt_port(self):
        tt_port = WireWaveguideTemplate()
        tt_port_layout = tt_port.Layout(core_width=15.0,
                                        cladding_width=15.0 + 2 * 8)
        return tt_port

    def _default_couplingWG(self):
        rect = i3.Waveguide(trace_template=self.tt_port)
        layout_rect = rect.Layout(shape=[(0.0, 0.0), (self.couplingWG_l, 0.0)])
        return rect

    def _default_Port(self):
        Port = AutoTransitionPorts(contents=self.couplingWG,
                                   port_labels=["in"],
                                   trace_template=self.wg_t)
        layout_Port = Port.Layout(
            transition_length=self.tlport)  #.visualize(annotate=True)
        return Port

    def _default_MMI12(self):
        mmi12 = MMI1x2Tapered(
            mmi_trace_template=self.wg_t_MM,
            input_trace_template=self.wg_t_port,
            output_trace_template=self.wg_t_port,
            trace_template=self.wg_t,
            name='MMI12_w_{}_L_{}'.format(self.width, self.length_12),
        )
        mmi12.Layout(transition_length=self.l_taper,
                     length=self.length_12,
                     trace_spacing=self.ts_12)  #.visualize(annotate=True)

        return mmi12

#################################################################################

    def _default_MMI22_list(self):
        print '____________ MMI 2x2 ______________'
        MMI22_list = []

        for l, dl in enumerate(self.length_inc_vec):
            print 'length number ' + str(l)
            print 'dl ' + str(dl)
            print 'MM length ' + str(self.length_22 + dl)
            cell = MMI2x2Tapered(mmi_trace_template=self.wg_t_MM,
                                 input_trace_template=self.wg_t_port,
                                 output_trace_template=self.wg_t_port,
                                 trace_template=self.wg_t,
                                 name='MMI22_w_' + str(self.width) + '_l_' +
                                 str(self.length_22 + dl))
            cell.Layout(transition_length=self.l_taper,
                        length=self.length_22 + dl,
                        trace_spacing=self.ts_12)

            MMI22_list.append(cell)

            print 'cell name ' + str(cell.name)
            print '__________________________'

        for w, dw in enumerate(self.width_inc_vec):
            MM_w = self.width + dw
            print 'width number ' + str(w)
            print 'dw ' + str(dw)
            print 'MM width ' + str(MM_w)
            wg_t_MM_w = WireWaveguideTemplate()
            wg_t_MM_w.Layout(
                core_width=MM_w,
                cladding_width=MM_w + 2 * 8,
            )

            cell = MMI2x2Tapered(mmi_trace_template=wg_t_MM_w,
                                 input_trace_template=self.wg_t_port,
                                 output_trace_template=self.wg_t_port,
                                 trace_template=self.wg_t,
                                 name='MMI22_w_' + str(self.width + dw) +
                                 '_l_' + str(self.length_22))
            cell.Layout(transition_length=self.l_taper,
                        length=self.length_22,
                        trace_spacing=self.ts_12 +
                        dw)  #.visualize(annotate=True)
            print cell
            MMI22_list.append(cell)

            print 'cell name ' + str(cell.name)
            print '__________________________'

        print 'last MMI22 done'
        print '_ _ _ _ _ _ _ _ _ _ _ _ _ '
        return MMI22_list

    def _default_MZI_12_22_list(self):
        print '____________ MZI_1x2_2x2 ______________'
        MZI_12_22_list = []
        counter = 1
        print '____________ MZI_1x2_2x2 list ______________'
        for i, m in enumerate(self.MMI22_list):
            print 'MZI number ' + str(counter)
            cell = MZIWaveguides(name='MZI_12_22:' + str(self.MMI12.name) +
                                 str(m.name),
                                 trace_template=self.wg_t,
                                 splitter=self.MMI12,
                                 combiner=m,
                                 splitter_port_names=['out1', 'out2'],
                                 combiner_port_names=['in1', 'in2'])
            cell.Layout(
                bend_radius=self.R,
                delay_length=self.delay_length)  #.visualize(annotate=True)
            MZI_12_22_list.append(cell)
            counter = counter + 1

            print 'splitter ' + cell.splitter.name
            print 'combiner ' + cell.combiner.name

            print cell.name
            print '__________________________'

        print "Last MMI_12_22 done"
        print '_ _ _ _ _ _ _ _ _ _ _ _ _ '
        return MZI_12_22_list

    def _default_MZI_22_22_list(self):
        print '____________ MZI_2x2_2x2 ______________'
        MZI_22_22_list = []
        counter = 1
        print '____________ MZI_2x2_2x2 list ______________'
        for i, m in enumerate(self.MMI22_list):
            print 'MZI number ' + str(counter)
            cell = MZIWaveguides(name='MZI_22_22:' + str(m.name),
                                 trace_template=self.wg_t,
                                 splitter=m,
                                 combiner=m,
                                 splitter_port_names=['out1', 'out2'],
                                 combiner_port_names=['in1', 'in2'])
            cell.Layout(
                bend_radius=self.R,
                delay_length=self.delay_length)  #.visualize(annotate=True)
            MZI_22_22_list.append(cell)
            counter = counter + 1

            print 'splitter ' + cell.splitter.name
            print 'combiner ' + cell.combiner.name

            print cell.name
            print '__________________________'

        print "Last MMI_22_22 done"
        print '_ _ _ _ _ _ _ _ _ _ _ _ _ '
        return MZI_22_22_list

#################################################################################

    def _default_child_cells(self):
        print '____________ Child cells ______________'
        child_cells = {}

        for counter, child in enumerate(self.MZI_22_22_list):
            print 'child number' + str(counter)

            child_cells['mzi_22_22_' + str(counter)] = child
            child_cells['InPort1_' + str(counter)] = self.Port
            child_cells['OutPort1_' + str(counter)] = self.Port
            child_cells['InPort2_' + str(counter)] = self.Port
            child_cells['OutPort2_' + str(counter)] = self.Port
            print 'child name ' + str(child.name)
            print child

            #################
        for counter2, child in enumerate(self.MZI_12_22_list):
            print 'child number' + str(counter + 1 + counter2)

            child_cells['mzi_12_22_' + str(counter + 1 + counter2)] = child
            child_cells['InPort_' + str(counter + 1 + counter2)] = self.Port
            child_cells['OutPort1_' + str(counter + 1 + counter2)] = self.Port
            child_cells['OutPort2_' + str(counter + 1 + counter2)] = self.Port
            print 'child name ' + str(child.name)
            print child
            ###################

            print '__________________________'
        child_cells['InPortWG1'] = self.Port
        child_cells['OutPortWG1'] = self.Port
        child_cells['InPortWG2'] = self.Port
        child_cells['OutPortWG2'] = self.Port
        child_cells['InPortWG3'] = self.Port
        child_cells['OutPortWG3'] = self.Port

        print "Last child cell done"
        print '_ _ _ _ _ _ _ _ _ _ _ _ _ '
        return child_cells

    def _default_links(self):
        links = []
        for counter, child in enumerate(self.MZI_22_22_list):
            print counter
            in_port = "InPort1_{}:in".format(counter)
            print 'in_port', in_port
            out_port = 'mzi_22_22_{}:splitter_in1'.format(counter)
            print 'out_port', in_port
            links.append((in_port, out_port))

            in_port = "InPort2_{}:in".format(counter)
            print 'in_port', in_port
            out_port = 'mzi_22_22_{}:splitter_in2'.format(counter)
            links.append((in_port, out_port))

            out_port = "OutPort1_{}:in".format(counter)
            in_port = 'mzi_22_22_{}:combiner_out1'.format(counter)
            print 'in_port', in_port
            links.append((in_port, out_port))

            out_port = "OutPort2_{}:in".format(counter)
            in_port = 'mzi_22_22_{}:combiner_out2'.format(counter)
            print 'in_port', in_port
            links.append((in_port, out_port))

        for counter2, child in enumerate(self.MZI_12_22_list):
            out_port = "InPort_{}:in".format(counter + 1 + counter2)
            in_port = 'mzi_12_22_{}:splitter_in'.format(counter + 1 + counter2)
            links.append((in_port, out_port))

            in_port = "OutPort1_{}:in".format(counter + 1 + counter2)
            out_port = 'mzi_12_22_{}:combiner_out1'.format(counter + 1 +
                                                           counter2)
            links.append((in_port, out_port))

            in_port = "OutPort2_{}:in".format(counter + 1 + counter2)
            out_port = 'mzi_12_22_{}:combiner_out2'.format(counter + 1 +
                                                           counter2)
            links.append((in_port, out_port))
        links.append(("InPortWG1:in", "OutPortWG1:in"))
        links.append(("InPortWG2:in", "OutPortWG2:in"))
        links.append(("InPortWG3:in", "OutPortWG3:in"))
        return links

    class Layout(PlaceAndAutoRoute.Layout):
        def _default_bend_radius(self):
            return self.R

        def _default_start_straight(self):
            return 1.0

        print '____________ Layout mask ______________'

        def _default_child_transformations(self):
            d = {}
            a = 2.2
            for counter, child in enumerate(self.MZI_22_22_list):
                if self.tipo == 1:
                    d['mzi_22_22_' + str(counter)] = i3.Translation(
                        translation=((-1)**counter * 2 * self.R,
                                     counter * 5 * self.R))
                    d['InPort1_' +
                      str(counter)] = i3.HMirror() + i3.Translation(
                          translation=(-self.chip_length * 0.5,
                                       counter * 5 * self.R - 2.2 * self.R))
                    d['OutPort1_' + str(counter)] = i3.Rotation(
                        rotation=90.0) + i3.Translation(
                            translation=(self.chip_length * 0.5,
                                         counter * 5 * self.R - 2.2 * self.R))
                    d['InPort2_' +
                      str(counter)] = i3.HMirror() + i3.Translation(
                          translation=(-self.chip_length * 0.5,
                                       counter * 5 * self.R + 2.2 * self.R))
                    d['OutPort2_' + str(counter)] = i3.Rotation(
                        rotation=90.0) + i3.Translation(
                            translation=(self.chip_length * 0.5,
                                         counter * 5 * self.R + 2.2 * self.R))
                    print 'transformation ' + str(counter) + ' is ' + str(d)
                if self.tipo == 2:
                    #l_coupling=self.child_cells['Coupler'].l_coupling
                    #radius=self.child_cells['Coupler'].local_bend_radius
                    print 'R= ', self.R
                    #print 'translation port: '

                    #For w=20
                    d['mzi_22_22_' + str(counter)] = i3.Translation(
                        translation=(counter * 850 + 1200 + 1000 + 200,
                                     -counter * 5 * self.R))
                    d['InPort1_' +
                      str(counter)] = i3.HMirror() + i3.Translation(
                          translation=(-self.chip_length * 0.1,
                                       -5 * self.R * counter - a * self.R))
                    d['OutPort1_' + str(counter)] = i3.Rotation(
                        rotation=90.0) + i3.Translation(translation=(
                            self.chip_length * 0.5 + counter * 50 +
                            counter * 4 * self.R + a * self.R - 100,
                            self.couplingWG_l + self.R * a))
                    d['InPort2_' +
                      str(counter)] = i3.HMirror() + i3.Translation(
                          translation=(-self.chip_length * 0.1,
                                       -5 * self.R * counter + a * self.R))
                    d['OutPort2_' + str(counter)] = i3.Rotation(
                        rotation=90.0) + i3.Translation(
                            translation=(self.chip_length * 0.5 +
                                         counter * 50 + counter * 4 * self.R -
                                         100, self.couplingWG_l + self.R * a))

                d['InPortWG1'] = i3.HMirror() + i3.Translation(
                    translation=(-self.chip_length * 0.1, 1000.0))
                d['OutPortWG1'] = i3.Rotation(rotation=90.0) + i3.Translation(
                    translation=(self.chip_length * 0.5 - 500,
                                 self.couplingWG_l + self.R * a))
                d['InPortWG2'] = i3.HMirror() + i3.Translation(
                    translation=(-self.chip_length * 0.1, -3400 + 670))
                d['OutPortWG2'] = i3.Rotation(rotation=90.0) + i3.Translation(
                    translation=(self.chip_length * 0.5 + 2500,
                                 self.couplingWG_l + self.R * a))
                d['InPortWG3'] = i3.HMirror() + i3.Translation(
                    translation=(-self.chip_length * 0.1, -6500))
                d['OutPortWG3'] = i3.Rotation(rotation=90.0) + i3.Translation(
                    translation=(self.chip_length * 0.5 + 5600,
                                 self.couplingWG_l + self.R * a))

                ###for w=30
                #d['mzi_22_22_' + str(counter)] = i3.Translation(translation=(counter*850+1200+1000+200,-counter*5*self.R))
                #d['InPort1_'+ str(counter)] = i3.HMirror()+i3.Translation(translation=(-self.chip_length*0.1, -5*self.R*counter-a*self.R))
                #d['OutPort1_'+ str(counter)]= i3.Rotation(rotation=90.0)+i3.Translation(translation=(self.chip_length*0.5+1100+counter*50+counter*4*self.R+a*self.R-100, self.couplingWG_l+self.R*a))
                #d['InPort2_'+ str(counter)] = i3.HMirror()+i3.Translation(translation=(-self.chip_length*0.1, -5*self.R*counter+a*self.R))
                #d['OutPort2_'+ str(counter)]= i3.Rotation(rotation=90.0)+i3.Translation(translation=(self.chip_length*0.5+1100+counter*50+counter*4*self.R-100, self.couplingWG_l+self.R*a))

                #d['InPortWG1'] = i3.HMirror()+i3.Translation(translation=(-self.chip_length*0.1, 1000.0))
                #d['OutPortWG1']= i3.Rotation(rotation=90.0)+i3.Translation(translation=(self.chip_length*0.5-500+1200, self.couplingWG_l+self.R*a))
                #d['InPortWG2'] = i3.HMirror()+i3.Translation(translation=(-self.chip_length*0.1, -3400+670))
                #d['OutPortWG2']= i3.Rotation(rotation=90.0)+i3.Translation(translation=(self.chip_length*0.5+2500+1100, self.couplingWG_l+self.R*a))
                #d['InPortWG3'] = i3.HMirror()+i3.Translation(translation=(-self.chip_length*0.1, -6500))
                #d['OutPortWG3']= i3.Rotation(rotation=90.0)+i3.Translation(translation=(self.chip_length*0.5+5600+1400, self.couplingWG_l+self.R*a))
                ################
            for counter2, child in enumerate(self.MZI_12_22_list):
                if self.tipo == 1:

                    d['mzi_12_22_' +
                      str(counter + 1 + counter2)] = i3.Translation(
                          translation=((-1)**counter2 * 2 * self.R -
                                       self.length_22 + counter * 50 +
                                       counter * 4 * self.R,
                                       (counter + 1 + counter2) * 5 * self.R))
                    d['InPort_' +
                      str(counter + 1 +
                          counter2)] = i3.HMirror() + i3.Translation(
                              translation=(-self.chip_length * 0.5,
                                           (counter + 1 + counter2) * 5 *
                                           self.R))
                    d['OutPort1_' +
                      str(counter + 1 + counter2)] = i3.Translation(
                          translation=(self.chip_length * 0.5 -
                                       self.bend_radius * counter * 0.2 -
                                       a * self.R - 550,
                                       (counter + 1 + counter2) * 5 * self.R -
                                       2.2 * self.R))
                    d['OutPort2_' +
                      str(counter + 1 + counter2)] = i3.Translation(
                          translation=(self.chip_length * 0.5 -
                                       self.bend_radius * counter * 0.2 - 550,
                                       (counter + 1 + counter2) * 5 * self.R +
                                       2.2 * self.R))
                if self.tipo == 2:
                    #l_coupling=self.child_cells['Coupler'].l_coupling
                    #radius=self.child_cells['Coupler'].local_bend_radius
                    print 'R= ', self.R
                    a = 2.2
                    b = 500
                    d['mzi_12_22_' +
                      str(counter + 1 + counter2)] = i3.Translation(
                          translation=((counter + 2 + counter2) * 850 + 1200 +
                                       200 + 580 + 500,
                                       -(counter + 1 + counter2) * 5 * self.R -
                                       b))
                    d['InPort_' +
                      str(counter + 1 +
                          counter2)] = i3.HMirror() + i3.Translation(
                              translation=(-self.chip_length * 0.1,
                                           -(5 * self.R) *
                                           (counter + 1 + counter2) - b))
                    d['OutPort1_' + str(counter + 1 + counter2)] = i3.Rotation(
                        rotation=90.0) + i3.Translation(translation=(
                            self.chip_length * 0.5 +
                            (counter + 1 + counter2) * 50 + a * self.R +
                            (counter + 1 + counter2) * 4 * self.R + b,
                            self.couplingWG_l + self.R * a))
                    d['OutPort2_' + str(counter + 1 + counter2)] = i3.Rotation(
                        rotation=90.0) + i3.Translation(translation=(
                            self.chip_length * 0.5 +
                            (counter + 1 + counter2) * 50 +
                            (counter + 1 + counter2) * 4 * self.R + b,
                            self.couplingWG_l + self.R * a))

                    #d['mzi_12_22_'+ str(counter+1+counter2)] = i3.Translation(translation=((counter+2+counter2)*850+1200+200+580+1000,-(counter+1+counter2)*5*self.R-b))
                    #d['InPort_'+ str(counter+1+counter2)] = i3.HMirror()+i3.Translation(translation=(-self.chip_length*0.1, -(5*self.R)*(counter+1+counter2)-b))
                    #d['OutPort1_'+ str(counter+1+counter2)]= i3.Rotation(rotation=90.0)+i3.Translation(translation=(self.chip_length*0.5+1200+(counter+1+counter2)*50+a*self.R+(counter+1+counter2)*4*self.R+b, self.couplingWG_l+self.R*a))
                    #d['OutPort2_'+ str(counter+1+counter2)]= i3.Rotation(rotation=90.0)+i3.Translation(translation=(self.chip_length*0.5+1200+(counter+1+counter2)*50+(counter+1+counter2)*4*self.R+b,self.couplingWG_l+self.R*a))
            #################
            print '__________________________'
            print "Last layout child cell done"
            print d
            print '_ _ _ _ _ _ _ _ _ _ _ _ _ '
            return d

        def _generate_elements(self, elems):
            for counter, child in enumerate(self.MZI_22_22_list):
                name = child.name

                print name
                elems += i3.PolygonText(
                    layer=i3.TECH.PPLAYER.WG.TEXT,
                    text='Name={}_R={}_delay={}'.format(
                        name, self.R, self.delay_length),
                    coordinate=(
                        0.0,
                        -counter * 5 * self.R + 2 * self.R - 50.0  #-100
                    ),
                    alignment=(i3.TEXT_ALIGN_LEFT, i3.TEXT_ALIGN_LEFT),
                    font=2,
                    height=20.0)

                elems += i3.PolygonText(
                    layer=i3.TECH.PPLAYER.WG.TEXT,
                    text='Name={}_R={}_delay={}'.format(
                        name, self.R, self.delay_length),
                    coordinate=(
                        0.0,
                        -counter * 5 * self.R - 2 * self.R + 50.0  #-100
                    ),
                    alignment=(i3.TEXT_ALIGN_LEFT, i3.TEXT_ALIGN_LEFT),
                    font=2,
                    height=20.0)
            for counter2, child in enumerate(self.MZI_12_22_list):
                name = child.name
                print name
                elems += i3.PolygonText(
                    layer=i3.TECH.PPLAYER.WG.TEXT,
                    text='Name={}'.format(name),
                    coordinate=(
                        0.0,
                        -(counter + 1 + counter2) * 5 * self.R - 90.0 -
                        500  #-100
                    ),
                    alignment=(i3.TEXT_ALIGN_LEFT, i3.TEXT_ALIGN_LEFT),
                    font=2,
                    height=20.0)

            return elems
class GratingCoupler1Band(PlaceComponents):
	core=i3.PositiveNumberProperty(default=3.3, doc="core width")
	period=i3.PositiveNumberProperty(default=2.566, doc="core width")
	duty=i3.PositiveNumberProperty(default=0.403, doc="core width")
	nperiods=i3.PositiveNumberProperty(default=7, doc="core width")
	wg_coupler= i3.TraceTemplateProperty(doc="Wide trace template used")
	#FGC= i3.ChildCellProperty(doc="grating used")
	ctipo=i3.PositiveNumberProperty(default=1, doc="type of coupler used ctipo=1 for grating and ctipo=2 for taper")	
	coupling_l=i3.PositiveNumberProperty(default=5000, doc="length of coupling WG")	
	coupler_template= i3.TraceTemplateProperty(doc="Wide trace template used for coupler tipo2")
	waveguide_template= i3.TraceTemplateProperty(doc="Wide trace template used on routing")
	coupling_w = i3.PositiveNumberProperty(default=20, doc="width of the coupling WG")
	transition_length_coupler=i3.PositiveNumberProperty(default=300, doc="transition length of the coupler")
	Grating_list = i3.ChildCellListProperty(doc="List containing the non etched parts of gratings")
	inPort = i3.ChildCellProperty( doc="Used for ports")
	outPort = i3.ChildCellProperty( doc="Used for ports")
	incouplingWG = i3.ChildCellProperty( doc="Used for ports")
	outcouplingWG = i3.ChildCellProperty( doc="Used for ports")
	chirp=i3.NumberProperty(default=1, doc="1=chirped")
	socket_length=i3.PositiveNumberProperty(default=2.2, doc="length of coupling WG")

	layName = i3.StringProperty(default = 'waveguide')
	layNameg = i3.StringProperty(default = 'metal')
	print 'the name of the layer is', layName
	props = i3.DictProperty()	
	
	def _default_props(self):
		return AssignProcess(self.layName)

	propsg = i3.DictProperty()	
		
	def _default_propsg(self):
		return AssignProcess(self.layNameg)	 
		
	
	Lo = i3.ListProperty(default=[]) #Non etched part, illuminated during e-beam
	Le = i3.ListProperty(default=[]) #Etched part
	Loc = i3.ListProperty(default=[]) #Non etched part, illuminated during e-beam
	Lec = i3.ListProperty(default=[]) #Etched part	

	
	#def _default_transition_length(self):
		#return self.transition_length_coupler
	
	def _default_socket_length(self):
		a=sum(self.Lo)+sum(self.Le)
		#if self.chirp==1:
			#A=a=self.period * int(self.nperiods)+sum(self.Loc))
		return a
	def _default_Loc(self):
		
		#Loc=[2.175,2.122,2.07,2.016,1.963,1.908,1.854,1.798,1.743,1.687,1.63,1.573,
			    #1.515,1.457,1.398,1.339,1.279,1.219,1.158,1.096]
		Loc=self.Loc
		Loc.reverse()
		return Loc
	
	def _default_Lec(self):
			
		#Lec=[0.242,0.301,0.361,0.421,0.482,0.543,0.605,0.667,0.73,0.794,0.858,0.922, 
	             #0.988,1.054,1.12,1.187,1.255,1.323,1.392,1.462]
		Lec=self.Lec
		Lec.reverse()
		return Lec	
	
	def _default_Lo(self):
		A=[None] * int(self.nperiods)
		if self.chirp==1:
			A=[None] * int(self.nperiods+len(self.Loc))
		
		for x in range(0,int(self.nperiods)):
			A[x]=self.period*self.duty
			if self.chirp==1:
				for x in range(0,int(len(self.Loc))):
					print x
					print len(self.Loc)
					A[int(self.nperiods)+x]=self.Loc[x]
			
			print 'Lo: ',A
			
		return A	
	
	
	def _default_Le(self):
		Le=[None] * int(self.nperiods)
		if self.chirp==1:
			Le=[None] * int(self.nperiods+len(self.Loc))		
		for x in range(0,int(self.nperiods)):
			Le[x]=self.period*(1-self.duty)
			if self.chirp==1:
				for x in range(0,int(len(self.Loc))):
					Le[int(self.nperiods)+x]=self.Lec[x]			
			print 'Le: ',Le
			
		return Le	
	
	def _default_Grating_list(self):
		Grating_list = [] 
		for x in range(0,int(len(self.Lo))):
			#rect=i3.Waveguide(trace_template=self.wg_coupler)
			rect=i3.Waveguide(trace_template=self.coupler_template)
			
			#layout_rect = rect.Layout(shape=[(0.0, 0.0),(self.Lo[x],0.0)])#.visualize(annotate=True)
			layout_rect = rect.Layout(shape=[(0.0, 0.0),(self.Lo[x],0.0)])#.visualize(annotate=True)
			                          
		 		
			Grating_list.append(rect)
		return Grating_list
	
	def _default_incouplingWG(self):
		rect=i3.Waveguide(trace_template=self.wg_coupler)
		layout_rect = rect.Layout(shape=[(0.0, 0.0),(self.coupling_l,0.0)]
			                  )
		return rect	

	def _default_outcouplingWG(self):
		rect=i3.Waveguide(trace_template=self.wg_coupler)
		layout_rect = rect.Layout(shape=[(0.0, 0.0),(50+self.socket_length,0.0)]
	                                  )
		return rect	
	
	def _default_inPort(self):
		Port=AutoTransitionPorts(contents=self.incouplingWG,
			                 port_labels=["in"],
			                     trace_template=self.waveguide_template)
		layout_Port = Port.Layout(transition_length=self.transition_length_coupler)#.visualize(annotate=True)
		return Port
	
	def _default_outPort(self):
		Port=AutoTransitionPorts(contents=self.outcouplingWG,
	                                 port_labels=["in"],
	                                     trace_template=self.wg_coupler)
		layout_Port = Port.Layout(transition_length=10)#.visualize(annotate=True)
		return Port	
	
	def _default_child_cells(self):
		child_cells = {}          # First we define the property "child_cells" as  an empty dictionary
	
		for counter, pillar  in enumerate(self.Grating_list):
			child_cells['pillar{}'.format(counter)] = pillar
			
			print pillar
			print 'name of pillar:', pillar.name
			
		child_cells['InPort'] = self.inPort
		child_cells['OutPort']= self.outPort
		print 'child_cells:', child_cells
		return child_cells	
	
	def _default_props(self):
		return AssignProcess(self.layName)	

	def _default_wg_coupler(self):
		wg_coupler = WireWaveguideTemplate()
		wg_coupler.Layout(core_width=self.coupling_w, cladding_width=self.coupling_w+2*8, **self.props)
		return wg_coupler
	
	def _default_waveguide_template(self):
		wg_t = WireWaveguideTemplate()
		wg_t_layout=wg_t.Layout(core_width=self.core, cladding_width=self.core+2*8, **self.props)
				
		return wg_t

	def _default_coupler_template(self):
		wg_t = WireWaveguideTemplate()
		wg_t_layout=wg_t.Layout(core_width=self.coupling_w, cladding_width=self.coupling_w, **self.propsg)

		return wg_t	

	def _default_trace_template(self):
		return self.waveguide_template  	


	def _default_contents(self):
		return self.FGC

	def _default_port_labels(self):
		return ["out"]

	


	class Layout(PlaceComponents.Layout):

		#def _default_transition_length(self):
			#return self.transition_length_coupler
		
		def _default_child_transformations(self):
			d={}
			position=0
			for counter, child  in enumerate(self.Grating_list):
				
				d['pillar{}'.format(counter)] = i3.Translation(translation=(position, 0.0))
				position=position+self.Lo[counter]+self.Le[counter]
				print 'pillar position: ', position
				print 'counter= ', counter
				print 'Lo: ', self.Lo[counter]
				print 'Le: ', self.Le[counter]
				
			#d['InPort'] = i3.HMirror()+ i3.Translation(translation=(position+10,0))
			d['InPort'] = i3.HMirror()+ i3.Translation(translation=(self.coupling_l+self.socket_length,0))
			d['OutPort'] = i3.Translation(translation=(-50,0.0))
												   
			return d			
示例#9
0
class Bent_Coupler_Symm(i3.PCell):
    """ A coupler with symmetric bends on each of the ports. Used with generic PCell
    """
    _name_prefix = "Bent_Coupler_Symm"

    # defining MMI as child cell with input and output waveguides
    coupler = i3.ChildCellProperty(restriction=i3.RestrictType(i3.PCell))

    # define waveguide template and waveguide cells
    # for the access bent waveguides connected to the straight couple
    ## add another waveguide template
    # coupler_length = i3.PositiveNumberProperty(default=i3.TECH.WG.SHORT_STRAIGHT,
    #                                            doc="length of the directional coupler")

    wg_template1 = i3.WaveguideTemplateProperty(
        default=i3.TECH.PCELLS.WG.DEFAULT)
    wg_template2 = i3.WaveguideTemplateProperty(
        default=i3.TECH.PCELLS.WG.DEFAULT)
    # wg_template = i3.WaveguideTemplateProperty(default=i3.TECH.PCELLS.WG.DEFAULT)
    wgs = i3.ChildCellListProperty(doc="list of waveguides")

    def _default_wg_template2(self):
        return self.wg_template1

    # define default coupler for class
    # a straight directional coupler by default
    # can also insert a tapered MMI by assigning a MMI PCell
    ### pass the templates for the directional coupler
    def _default_coupler(self):
        ### waveguide templates for DC must be defined in this instantiance
        ### otherwise trace_template1 and trace_template2 will be set bundled to be equal
        coupler = StraightDirectionalCoupler(
            name=self.name + "_dir_coup", coupler_length=self.coupler_length)
        return coupler

    # define rounded waveguides for the inputs and outputs
    ## can consider for loop tp reduce the code length
    def _default_wgs(self):
        wgs = []
        name_list = ["_wg_in1", "_wg_in2", "_wg_out1", "_wg_out2"]
        template_list = [
            self.wg_template1, self.wg_template2, self.wg_template1,
            self.wg_template2
        ]
        for idx, name in enumerate(name_list):
            wg = i3.RoundedWaveguide(name=self.name + name_list[idx],
                                     trace_template=template_list[idx])
            wgs.append(wg)
        return wgs

    class Layout(i3.LayoutView):
        # specified parameters used for layout purposes
        ## coupling spacing?
        ## move to the coupler level
        bend_radius = i3.PositiveNumberProperty(
            default=10., doc="bend radius of 90 degree bends")
        in1_offset = i3.PositiveNumberProperty(
            default=10., doc="offset between 90 degree bends input 1")
        in2_offset = i3.PositiveNumberProperty(
            default=10., doc="offset between 90 degree bends input 2")
        out1_offset = i3.PositiveNumberProperty(
            default=1., doc="offset between 90 degree bends output 1")
        out2_offset = i3.PositiveNumberProperty(
            default=1., doc="offset between 90 degree bends output 2")
        rounding_algorithm = DefinitionProperty(
            default=ShapeRound,
            doc="rounding algorithm for every individual bend")

        # define default of tapered MMI child cell
        def _default_coupler(self):
            ### error to be corrected. the Child Layout view needs to point to coupler first, end get the default view
            # wg_template1 = self.wg_template1
            coupler = self.cell.coupler.get_default_view(
                i3.LayoutView)  # Retrieve layout view following examples
            ### go to upper level then to define the waveguide template, as the waveguide template of DC is NOT
            ### defined in layout level
            # self.cell.coupler.trace_template1 = self.wg_template1
            # self.cell.coupler.trace_template2 = self.wg_template2
            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()
            ## wgcell ? for loop operation
            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)
            ]

            wg_in1_layout.set(trace_template=wg_template1,
                              shape=in1_shape,
                              rounding_algorithm=round_alg,
                              bend_radius=bend_radius,
                              manhattan=True)

            # 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)
            ]

            wg_in2_layout.set(trace_template=wg_template2,
                              shape=in2_shape,
                              rounding_algorithm=round_alg,
                              bend_radius=bend_radius,
                              manhattan=True)

            # 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)
            ]

            wg_out1_layout.set(trace_template=wg_template1,
                               shape=out1_shape,
                               rounding_algorithm=round_alg,
                               bend_radius=bend_radius,
                               manhattan=True)
            # 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)
            ]

            wg_out2_layout.set(trace_template=wg_template2,
                               shape=out2_shape,
                               rounding_algorithm=round_alg,
                               bend_radius=bend_radius,
                               manhattan=True)
            # returning layouts
            return wg_in1_layout, wg_in2_layout, wg_out1_layout, wg_out2_layout

        def _generate_instances(self, insts):
            # includes the get components and the new waveguides
            insts += self._get_components()
            wg_in1_layout, wg_in2_layout, wg_out1_layout, wg_out2_layout = self.wgs

            insts += i3.SRef(reference=wg_in1_layout, name="wg_in1")
            insts += i3.SRef(reference=wg_in2_layout, name="wg_in2")
            insts += i3.SRef(reference=wg_out1_layout, name="wg_out1")
            insts += i3.SRef(reference=wg_out2_layout, name="wg_out2")
            return insts

        def _generate_ports(self, prts):
            # use output ports of all waveguides as I define shapes from the base of the coupler structure outwards
            instances = self.instances
            prts += instances["wg_in1"].ports["out"].modified_copy(name="in1")
            prts += instances["wg_in2"].ports["out"].modified_copy(name="in2")
            prts += instances["wg_out1"].ports["out"].modified_copy(
                name="out1")
            prts += instances["wg_out2"].ports["out"].modified_copy(
                name="out2")
            return prts

        ### an simple example to use Ben_Coupler_Symm class
        @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

            # set waveguide templates for
            # the north waveguide (wg_t1)
            # and the south waveguide (wg_t2)
            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)

            # set the directional coupler (can also be MMI)
            # and then pass it as an child PCell to Bend_Coupler PCell
            C = Bent_Coupler_Symmr(name="my_dircoup_2",
                                   trace_template1=wg_t1,
                                   trace_template2=wg_t2,
                                   coupler_length=20.0)
            layout = C.Layout(bend_radius=10.0,
                              straight_after_bend=6.0,
                              bend_angle=60.0)
            layout.visualize()
示例#10
0
class my_exe2(PlaceComponents):
    DC_list = i3.ChildCellListProperty(default=[])

    def _default_DC_list(self):
        MMI22_list = []

        dc1_15 = my_dc(gap_inc_vec2=[110.0, 110.0, 110.0], name="ring1")
        dc2_15 = my_dc(gap_inc_vec2=[110.0, 110.0, 110.0], name="ring2")
        MMI22_list.append(dc1_15)
        MMI22_list.append(dc2_15)
        dc1_20 = my_dc(gap_inc_vec2=[100.0, 110.0, 120.0],
                       name="ring3",
                       width=20,
                       cleave=250)
        dc2_20 = my_dc(gap_inc_vec2=[100.0, 110.0, 120.0],
                       name="ring4",
                       width=20,
                       cleave=250)

        recess0 = NP_mmi12(pillar=True,
                           pocket=False,
                           tilt=False,
                           width=133.0,
                           length=210)
        recess1 = NP_mmi12(pillar=True,
                           pocket=False,
                           tilt=False,
                           width=133.0,
                           length=210)
        recess2 = NP_mmi12(pillar=True, pocket=False, tilt=False)
        recess3 = NP_mmi12(pillar=True, pocket=False, tilt=False)
        recess4 = NP_mmi12(pillar=True, pocket=True, tilt=False)
        recess5 = NP_mmi12(pillar=True, pocket=True, tilt=False)
        recess6 = NP_mmi12(pillar=True, pocket=False, tilt=False)

        recess7 = NP_mmi12(pillar=True, pocket=False, tilt=False)
        recess8 = NP_mmi12(pillar=True, pocket=False, tilt=False)
        recess9 = NP_mmi12(pillar=True, pocket=False, tilt=False)
        recess10 = NP_mmi12(pillar=True, pocket=False, tilt=False)
        recess11 = NP_mmi12(pillar=True, pocket=True, tilt=True)
        recess12 = NP_mmi12(pillar=True, pocket=True, tilt=True)
        recess13 = NP_mmi12(pillar=True, pocket=True, tilt=False)

        recess14 = NP_mmi12(pillar=True,
                            pocket=False,
                            tilt=False,
                            width=133.0,
                            length=210,
                            double=False)
        recess15 = NP_mmi12(pillar=True,
                            pocket=False,
                            tilt=False,
                            width=133.0,
                            length=210,
                            double=False)
        recess16 = NP_mmi12(pillar=True,
                            pocket=False,
                            tilt=False,
                            double=False)
        recess17 = NP_mmi12(pillar=True,
                            pocket=False,
                            tilt=False,
                            double=False)
        recess18 = NP_mmi12(pillar=True, pocket=True, tilt=False, double=False)
        recess19 = NP_mmi12(pillar=True, pocket=True, tilt=False, double=False)
        recess20 = NP_mmi12(pillar=True,
                            pocket=False,
                            tilt=False,
                            double=False)

        recess21 = NP_mmi12(pillar=True,
                            pocket=False,
                            tilt=False,
                            double=False)
        recess22 = NP_mmi12(pillar=True,
                            pocket=False,
                            tilt=False,
                            double=False)
        recess23 = NP_mmi12(pillar=True,
                            pocket=False,
                            tilt=False,
                            double=False)
        recess24 = NP_mmi12(pillar=True,
                            pocket=False,
                            tilt=False,
                            double=False)
        recess25 = NP_mmi12(pillar=True, pocket=True, tilt=True, double=False)
        recess26 = NP_mmi12(pillar=True, pocket=True, tilt=True, double=False)
        recess27 = NP_mmi12(pillar=True, pocket=True, tilt=False, double=False)

        for i in range(0, 28, 1):
            print(i)
            _inst = locals()['recess{}'.format(i)]
            MMI22_list.append(_inst)

        MMI22_list.append(dc1_20)
        MMI22_list.append(dc2_20)
        #
        #
        Al0 = AL_NP(offset=5)
        Al1 = AL_NP(offset=5)
        Al2 = AL_NP()
        Al3 = AL_NP()
        Al4 = AL_NP()
        Al5 = AL_NP()
        Al6 = AL_NP()

        Al7 = AL_NP()
        Al8 = AL_NP()
        Al9 = AL_NP()
        Al10 = AL_NP()
        Al11 = AL_NP()
        Al12 = AL_NP()
        Al13 = AL_NP()

        Al14 = AL_NP(offset=5)
        Al15 = AL_NP(offset=5)
        Al16 = AL_NP()
        Al17 = AL_NP()
        Al18 = AL_NP()
        Al19 = AL_NP()
        Al20 = AL_NP()

        Al21 = AL_NP()
        Al22 = AL_NP()
        Al23 = AL_NP()
        Al24 = AL_NP()
        Al25 = AL_NP()
        Al26 = AL_NP()
        Al27 = AL_NP()

        for i in range(0, 28, 1):
            print(i)
            _inst = locals()['Al{}'.format(i)]
            MMI22_list.append(_inst)

        SiN0 = SiN_NP(width=92, length=210)
        SiN1 = SiN_NP(width=92, length=210)
        SiN2 = SiN_NP()
        SiN3 = SiN_NP()
        SiN4 = SiN_NP()
        SiN5 = SiN_NP()
        SiN6 = SiN_NP()
        SiN7 = SiN_NP()
        SiN8 = SiN_NP()
        SiN9 = SiN_NP()
        SiN10 = SiN_NP()
        SiN11 = SiN_NP(tilt=15)
        SiN12 = SiN_NP(tilt=15)
        SiN13 = SiN_NP()
        SiN14 = SiN_NP(width=92, length=210, double=False)
        SiN15 = SiN_NP(width=92, length=210, double=False)
        SiN16 = SiN_NP(double=False)
        SiN17 = SiN_NP(double=False)
        SiN18 = SiN_NP(double=False)
        SiN19 = SiN_NP(double=False)
        SiN20 = SiN_NP(double=False)
        SiN21 = SiN_NP(double=False)
        SiN22 = SiN_NP(double=False)
        SiN23 = SiN_NP(double=False)
        SiN24 = SiN_NP(double=False)
        SiN25 = SiN_NP(double=False, tilt=15)
        SiN26 = SiN_NP(double=False, tilt=15)
        SiN27 = SiN_NP(double=False)
        for i in range(0, 28, 1):
            print(i)
            _inst = locals()['SiN{}'.format(i)]
            MMI22_list.append(_inst)

        return MMI22_list

    def _default_child_cells(self):
        child_cells = dict()
        for counter, child in enumerate(self.DC_list):
            print 'child number' + str(counter)
            child_cells['CHILD' + str(counter)] = child
            print 'child name ' + str(child.name)
            print child
        return child_cells

    class Layout(PlaceComponents.Layout):
        def _default_child_transformations(self):
            trans = dict()
            row = 3000
            trans["CHILD0"] = (0, 0)  #MMI
            trans["CHILD1"] = i3.HMirror(1250) - i3.Translation(
                (2500, 0))  #MMI

            trans['CHILD2'] = (-14500, -3000 + row * 0)
            trans['CHILD3'] = (-14500, -3000 + row * 1)
            trans['CHILD4'] = (-14500, -3000 + row * 2)
            trans['CHILD5'] = (-14500, -3000 + row * 3)
            trans['CHILD6'] = (-14500, -3000 + row * 4)
            trans['CHILD7'] = (-14500, -3000 + row * 5)
            trans['CHILD8'] = (-14500, -3000 + row * 6)
            trans['CHILD9'] = i3.Rotation(rotation=180) + i3.Translation(
                (14500, 0 + row * 0))
            trans['CHILD10'] = i3.Rotation(rotation=180) + i3.Translation(
                (14500, 0 + row * 1))
            trans['CHILD11'] = i3.Rotation(rotation=180) + i3.Translation(
                (14500, 0 + row * 2))
            trans['CHILD12'] = i3.Rotation(rotation=180) + i3.Translation(
                (14500, 0 + row * 3))
            trans['CHILD13'] = i3.Rotation(rotation=180) + i3.Translation(
                (14500, 0 + row * 4))
            trans['CHILD14'] = i3.Rotation(rotation=180) + i3.Translation(
                (14500, 0 + row * 5))
            trans['CHILD15'] = i3.Rotation(rotation=180) + i3.Translation(
                (14500, 0 + row * 6))
            trans['CHILD16'] = (-2500, -3000 + row * 0)
            trans['CHILD17'] = (-2500, -3000 + row * 1)
            trans['CHILD18'] = (-2500, -3000 + row * 2)
            trans['CHILD19'] = (-2500, -3000 + row * 3)
            trans['CHILD20'] = (-2500, -3000 + row * 4)
            trans['CHILD21'] = (-2500, -3000 + row * 5)
            trans['CHILD22'] = (-2500, -3000 + row * 6)
            trans['CHILD23'] = i3.Rotation(rotation=180) + i3.Translation(
                (26500, 0 + row * 0))
            trans['CHILD24'] = i3.Rotation(rotation=180) + i3.Translation(
                (26500, 0 + row * 1))
            trans['CHILD25'] = i3.Rotation(rotation=180) + i3.Translation(
                (26500, 0 + row * 2))
            trans['CHILD26'] = i3.Rotation(rotation=180) + i3.Translation(
                (26500, 0 + row * 3))
            trans['CHILD27'] = i3.Rotation(rotation=180) + i3.Translation(
                (26500, 0 + row * 4))
            trans['CHILD28'] = i3.Rotation(rotation=180) + i3.Translation(
                (26500, 0 + row * 5))
            trans['CHILD29'] = i3.Rotation(rotation=180) + i3.Translation(
                (26500, 0 + row * 6))

            trans["CHILD30"] = (12000, 0)  #MMI
            trans["CHILD31"] = i3.HMirror(1250) + i3.Translation(
                (9500, 0))  #MMI

            trans['CHILD32'] = (-14500, -3000 + row * 0)
            trans['CHILD33'] = (-14500, -3000 + row * 1)
            trans['CHILD34'] = (-14500, -3000 + row * 2)
            trans['CHILD35'] = (-14500, -3000 + row * 3)
            trans['CHILD36'] = (-14500, -3000 + row * 4)
            trans['CHILD37'] = (-14500, -3000 + row * 5)
            trans['CHILD38'] = (-14500, -3000 + row * 6)
            trans['CHILD39'] = i3.Rotation(rotation=180) + i3.Translation(
                (14500, 0 + row * 0))
            trans['CHILD40'] = i3.Rotation(rotation=180) + i3.Translation(
                (14500, 0 + row * 1))
            trans['CHILD41'] = i3.Rotation(rotation=180) + i3.Translation(
                (14500, 0 + row * 2))
            trans['CHILD42'] = i3.Rotation(rotation=180) + i3.Translation(
                (14500, 0 + row * 3))
            trans['CHILD43'] = i3.Rotation(rotation=180) + i3.Translation(
                (14500, 0 + row * 4))
            trans['CHILD44'] = i3.Rotation(rotation=180) + i3.Translation(
                (14500, 0 + row * 5))
            trans['CHILD45'] = i3.Rotation(rotation=180) + i3.Translation(
                (14500, 0 + row * 6))
            trans['CHILD46'] = (-2500, -3000 + row * 0)
            trans['CHILD47'] = (-2500, -3000 + row * 1)
            trans['CHILD48'] = (-2500, -3000 + row * 2)
            trans['CHILD49'] = (-2500, -3000 + row * 3)
            trans['CHILD50'] = (-2500, -3000 + row * 4)
            trans['CHILD51'] = (-2500, -3000 + row * 5)
            trans['CHILD52'] = (-2500, -3000 + row * 6)
            trans['CHILD53'] = i3.Rotation(rotation=180) + i3.Translation(
                (26500, 0 + row * 0))
            trans['CHILD54'] = i3.Rotation(rotation=180) + i3.Translation(
                (26500, 0 + row * 1))
            trans['CHILD55'] = i3.Rotation(rotation=180) + i3.Translation(
                (26500, 0 + row * 2))
            trans['CHILD56'] = i3.Rotation(rotation=180) + i3.Translation(
                (26500, 0 + row * 3))
            trans['CHILD57'] = i3.Rotation(rotation=180) + i3.Translation(
                (26500, 0 + row * 4))
            trans['CHILD58'] = i3.Rotation(rotation=180) + i3.Translation(
                (26500, 0 + row * 5))
            trans['CHILD59'] = i3.Rotation(rotation=180) + i3.Translation(
                (26500, 0 + row * 6))

            trans['CHILD60'] = (-14500, -3000 + row * 0)
            trans['CHILD61'] = (-14500, -3000 + row * 1)
            trans['CHILD62'] = (-14500, -3000 + row * 2)
            trans['CHILD63'] = (-14500, -3000 + row * 3)
            trans['CHILD64'] = (-14500, -3000 + row * 4)
            trans['CHILD65'] = (-14500, -3000 + row * 5)
            trans['CHILD66'] = (-14500, -3000 + row * 6)
            trans['CHILD67'] = i3.Rotation(rotation=180) + i3.Translation(
                (14500, 0 + row * 0))
            trans['CHILD68'] = i3.Rotation(rotation=180) + i3.Translation(
                (14500, 0 + row * 1))
            trans['CHILD69'] = i3.Rotation(rotation=180) + i3.Translation(
                (14500, 0 + row * 2))
            trans['CHILD70'] = i3.Rotation(rotation=180) + i3.Translation(
                (14500, 0 + row * 3))
            trans['CHILD71'] = i3.Rotation(rotation=180) + i3.Translation(
                (14500, 0 + row * 4))
            trans['CHILD72'] = i3.Rotation(rotation=180) + i3.Translation(
                (14500, 0 + row * 5))
            trans['CHILD73'] = i3.Rotation(rotation=180) + i3.Translation(
                (14500, 0 + row * 6))
            trans['CHILD74'] = (-2500, -3000 + row * 0)
            trans['CHILD75'] = (-2500, -3000 + row * 1)
            trans['CHILD76'] = (-2500, -3000 + row * 2)
            trans['CHILD77'] = (-2500, -3000 + row * 3)
            trans['CHILD78'] = (-2500, -3000 + row * 4)
            trans['CHILD79'] = (-2500, -3000 + row * 5)
            trans['CHILD80'] = (-2500, -3000 + row * 6)
            trans['CHILD81'] = i3.Rotation(rotation=180) + i3.Translation(
                (26500, 0 + row * 0))
            trans['CHILD82'] = i3.Rotation(rotation=180) + i3.Translation(
                (26500, 0 + row * 1))
            trans['CHILD83'] = i3.Rotation(rotation=180) + i3.Translation(
                (26500, 0 + row * 2))
            trans['CHILD84'] = i3.Rotation(rotation=180) + i3.Translation(
                (26500, 0 + row * 3))
            trans['CHILD85'] = i3.Rotation(rotation=180) + i3.Translation(
                (26500, 0 + row * 4))
            trans['CHILD86'] = i3.Rotation(rotation=180) + i3.Translation(
                (26500, 0 + row * 5))
            trans['CHILD87'] = i3.Rotation(rotation=180) + i3.Translation(
                (26500, 0 + row * 6))
            return trans

        def _generate_elements(self, elems):
            elems += i3.Rectangle(
                layer=i3.TECH.PPLAYER.PPLUS.LINE,
                center=(0, 7500),  # change
                box_size=(190, 21000))
            elems += i3.Rectangle(
                layer=i3.TECH.PPLAYER.PPLUS.LINE,
                center=(6000, 7500),  # change
                box_size=(190, 21000))
            elems += i3.Rectangle(
                layer=i3.TECH.PPLAYER.SIL.LINE,
                center=(0, 7500),  # change
                box_size=(210, 21000))

            return elems
示例#11
0
class my_exe(PlaceComponents):
    DC_list = i3.ChildCellListProperty(default=[])

    def _default_DC_list(self):
        MMI22_list = []

        dc_10 = my_dc(gap_inc_vec=[390, 398, 406], name="ring1")
        # dc_10_layout = dc_10.Layout()
        # dc_10_layout.visualize(annotate=True)
        # dc_10_layout.write_gdsii("DC_V4.gds")
        #
        dc_15 = my_dc(gap_inc_vec=[390, 398, 406], name="ring2")
        MMI22_list.append(dc_10)
        MMI22_list.append(dc_15)

        recess0 = NP(width=338)
        recess1 = NP(width=338, pocket=True, tilt=False)
        recess2 = NP(width=338, pocket=True, tilt=True)
        recess3 = NP(pillar=True)
        recess4 = NP(pillar=True, pocket=True, tilt=False)
        recess5 = NP(pillar=True, pocket=True, tilt=True)
        recess6 = NP()
        recess7 = NP(pocket=True, tilt=False)
        recess8 = NP(width=338, pillar=True, pocket=False, tilt=False)
        recess9 = NP(width=338, pillar=True, pocket=True, tilt=False)
        recess10 = PI(pocket=False, tilt=False)
        recess11 = PI(pocket=True, tilt=False)

        for i in range(0, 12, 1):
            print(i)
            _inst = locals()['recess{}'.format(i)]
            MMI22_list.append(_inst)

        # MMI22_list.append(recess0)
        # MMI22_list.append(recess1)
        # MMI22_list.append(recess2)
        # MMI22_list.append(recess3)
        # MMI22_list.append(recess4)
        # MMI22_list.append(recess5)
        # MMI22_list.append(recess6)
        # MMI22_list.append(recess7)
        # MMI22_list.append(recess8)
        # MMI22_list.append(recess9)
        # MMI22_list.append(recess10)
        # MMI22_list.append(recess11)

        Al0 = AL_NP(width=338)
        Al1 = AL_NP(width=338)
        Al2 = AL_NP(width=338)
        Al3 = AL_NP(pillar=True)
        Al4 = AL_NP(pillar=True)
        Al5 = AL_NP(pillar=True)
        Al6 = AL_NP()
        Al7 = AL_NP()
        Al8 = AL_NP(width=338, pillar=True)
        Al9 = AL_NP(width=338, pillar=True)
        Al10 = AL_PI()
        Al11 = AL_PI()
        # _ = [Al0, Al1, Al2, Al3, Al4, Al5, Al6, Al7, Al8, Al9, Al10, Al11]
        #
        # for i in range(0,12,1):
        #     # _[i].append(i)
        #     MMI22_list.append(_[i])
        for i in range(0, 12, 1):
            print(i)
            _inst = locals()['Al{}'.format(i)]
            MMI22_list.append(_inst)

        SiN0 = SiN_NP(width=338)
        SiN1 = SiN_NP(width=338)
        SiN2 = SiN_NP(width=338, tilt_0=True)
        SiN3 = SiN_NP(pillar=True)
        SiN4 = SiN_NP(pillar=True)
        SiN5 = SiN_NP(pillar=True, tilt_0=True)
        SiN6 = SiN_NP()
        SiN7 = SiN_NP()
        SiN8 = SiN_NP(width=338, pillar=True)
        SiN9 = SiN_NP(width=338, pillar=True)
        SiN10 = SiN_PI()
        SiN11 = SiN_PI()
        for i in range(0, 12, 1):
            print(i)
            _inst = locals()['SiN{}'.format(i)]
            MMI22_list.append(_inst)

        return MMI22_list

    def _default_child_cells(self):
        child_cells = dict()
        for counter, child in enumerate(self.DC_list):
            print 'child number' + str(counter)
            child_cells['CHILD' + str(counter)] = child
            print 'child name ' + str(child.name)
            print child
        return child_cells

    class Layout(PlaceComponents.Layout):
        def _default_child_transformations(self):
            trans = dict()
            row = 5000
            trans["CHILD0"] = (0, 0)
            trans["CHILD1"] = i3.HMirror(2500) - i3.Translation((5000, 0))
            trans['CHILD2'] = (-15000, 0 + row * -1)
            trans['CHILD3'] = (-15000, 0 + row * 0)
            trans['CHILD4'] = (-15000, 0 + row * 1)
            trans['CHILD5'] = (-15000, 0 + row * 2)
            trans['CHILD6'] = (-15000, 0 + row * 3)
            trans['CHILD7'] = (-15000, 0 + row * 4)
            trans['CHILD8'] = i3.Rotation(rotation=180) + i3.Translation(
                (15000, 0 + row * 0))
            trans['CHILD9'] = i3.Rotation(rotation=180) + i3.Translation(
                (15000, 0 + row * 1))
            trans['CHILD10'] = i3.Rotation(rotation=180) + i3.Translation(
                (15000, 0 + row * 2))
            trans['CHILD11'] = i3.Rotation(rotation=180) + i3.Translation(
                (15000, 0 + row * 3))
            trans['CHILD12'] = i3.Rotation(rotation=180) + i3.Translation(
                (15000, 0 + row * 4))
            trans['CHILD13'] = i3.Rotation(rotation=180) + i3.Translation(
                (15000, 0 + row * 5))
            trans['CHILD14'] = (-15000, 0 + row * -1)
            trans['CHILD15'] = (-15000, 0 + row * 0)
            trans['CHILD16'] = (-15000, 0 + row * 1)
            trans['CHILD17'] = (-15000, 0 + row * 2)
            trans['CHILD18'] = (-15000, 0 + row * 3)
            trans['CHILD19'] = (-15000, 0 + row * 4)
            trans['CHILD20'] = i3.Rotation(rotation=180) + i3.Translation(
                (15000, 0 + row * 0))
            trans['CHILD21'] = i3.Rotation(rotation=180) + i3.Translation(
                (15000, 0 + row * 1))
            trans['CHILD22'] = i3.Rotation(rotation=180) + i3.Translation(
                (15000, 0 + row * 2))
            trans['CHILD23'] = i3.Rotation(rotation=180) + i3.Translation(
                (15000, 0 + row * 3))
            trans['CHILD24'] = i3.Rotation(rotation=180) + i3.Translation(
                (15000, 0 + row * 4))
            trans['CHILD25'] = i3.Rotation(rotation=180) + i3.Translation(
                (15000, 0 + row * 5))
            trans['CHILD26'] = (-15000, 0 + row * -1)
            trans['CHILD27'] = (-15000, 0 + row * 0)
            trans['CHILD28'] = (-15000, 0 + row * 1)
            trans['CHILD29'] = (-15000, 0 + row * 2)
            trans['CHILD30'] = (-15000, 0 + row * 3)
            trans['CHILD31'] = (-15000, 0 + row * 4)
            trans['CHILD32'] = i3.Rotation(rotation=180) + i3.Translation(
                (15000, 0 + row * 0))
            trans['CHILD33'] = i3.Rotation(rotation=180) + i3.Translation(
                (15000, 0 + row * 1))
            trans['CHILD34'] = i3.Rotation(rotation=180) + i3.Translation(
                (15000, 0 + row * 2))
            trans['CHILD35'] = i3.Rotation(rotation=180) + i3.Translation(
                (15000, 0 + row * 3))
            trans['CHILD36'] = i3.Rotation(rotation=180) + i3.Translation(
                (15000, 0 + row * 4))
            trans['CHILD37'] = i3.Rotation(rotation=180) + i3.Translation(
                (15000, 0 + row * 5))

            return trans
示例#12
0
class Mask(APAC):

    grating_coupler = i3.ChildCellProperty(doc="Grating couplers used in order")
    modulators = i3.ChildCellListProperty(doc="Modulators used")
    m_spacing = i3.ListProperty(default=[3.5, 4.0, 4.5, 5.0], doc="Metal spacings")

    def _default_grating_coupler(self):
        return FC_TE_1550()

    def _default_modulators(self):
        mods = []
        for w in self.m_spacing:
            cell = TW_MZM(name=self.name + "Modulator_{}".format(w))
            cell.Layout(modulator_length=1500,
                        metal_spacing=w)
            mods.append(cell)
        return mods

    def _default_child_cells(self):
        childs = dict()
        for cnt, mod in enumerate(self.modulators):  # Iterates over self.m_spacing and uses cnt as a counter. This is a python construct.

            childs["grating_in_{}".format(cnt)] = self.grating_coupler
            childs["mod_{}".format(cnt)] = mod
            childs["grating_out_{}".format(cnt)] = self.grating_coupler

        return childs

    def _default_connectors(self):

        conn = []
        for cnt, mod in enumerate(self.modulators):
            in_port = "grating_in_{}:out".format(cnt)
            out_port = "mod_{}:in".format(cnt)
            conn.append((in_port, out_port, wide_manhattan))

            in_port = "grating_out_{}:out".format(cnt)
            out_port = "mod_{}:out".format(cnt)
            conn.append((in_port, out_port, wide_manhattan))

        return conn

    def _default_electrical_links(self):
        el_links = []
        #shorting the ground
        for cnt, mod in enumerate(self.modulators):
            for arm_name in ["1", "5"]:
                p1 = "mod_{}:elec_right_{}".format(cnt, arm_name)
                p2 = "mod_{}:elec_right_{}".format(cnt, "3")
                el_links.append((p1, p2))
                p1 = "mod_{}:elec_left_{}".format(cnt, arm_name)
                p2 = "mod_{}:elec_left_{}".format(cnt, "3")
                el_links.append((p1, p2))


        return el_links

    def _default_external_port_names(self):
        epn = dict()

        for cnt, mod in enumerate(self.modulators):
            epn["grating_in_{}:vertical_in".format(cnt)] = "in{}".format(cnt)
            epn["grating_out_{}:vertical_in".format(cnt)] = "out{}".format(cnt)

        return epn


    def _default_propagated_electrical_ports(self):
        pp = []
        for cnt, mod in enumerate(self.modulators):
            for arm_name in [2,3,4]:
                pp.append("mod_{}_elec_right_{}".format(cnt, arm_name))
                pp.append("mod_{}_elec_left_{}".format(cnt, arm_name))

        return pp


    class Layout(APAC.Layout):

        grating_coupler_spacing = i3.PositiveNumberProperty(default=800, doc="Spacing between the grating couplers")
        center_grating_coupler_y = i3.PositiveNumberProperty(doc="Start position of the first grating coupler")

        def _default_metal1_width(self):
            return 20.0

        def _default_center_bp(self):
            return 2500 / 2.0

        def _default_center_grating_coupler_y(self):
            return 5150.0 / 2.0

        def _default_child_transformations(self):
            trans = dict()
            nw = len(self.m_spacing)
            for cnt, mod in enumerate(self.modulators):
                t = (100.0, self.center_grating_coupler_y + (-nw / 2.0 + 0.5 + cnt) * self.grating_coupler_spacing)
                trans["grating_in_{}".format(cnt)] = i3.Translation(translation=t)
                t = (2500/2.0 , self.center_grating_coupler_y + (-nw / 2.0 + 0.5 + cnt) * self.grating_coupler_spacing)
                trans["mod_{}".format(cnt)] = i3.Translation(translation=t)
                trans["grating_out_{}".format(cnt)] = i3.Rotation(rotation=180.0) + i3.Translation(translation=(2500,
                                                                                                               self.center_grating_coupler_y + (-nw / 2.0 + 0.5 + cnt) * self.grating_coupler_spacing))

            return trans

        @i3.cache()
        def _default_electrical_routes(self):
            routes = []

            for c in self.electrical_links:
                inst1, port1 = self._resolve_inst_port(c[0])
                inst2, port2 = self._resolve_inst_port(c[1])

                if "left" in port1.name:
                    r = i3.RouteManhattan(input_port=port1,
                                          output_port=port2,
                                          min_straight=100.0,
                                          angle_out=0.0,
                                          angle_in=180.0,
                                          rounding_algorithm=None)

                else:
                    r = i3.RouteManhattan(input_port=port1,
                                          output_port=port2,
                                          min_straight=100.0,
                                          angle_out=180.0,
                                          angle_in=0.0,
                                          rounding_algorithm=None)

                routes.append(r)


            return routes
示例#13
0
class _Splitter(Coupler1x2):
    """
    Abstract splitter class just places 3 waveguides. 
    """
    wg_template = i3.WaveguideTemplateProperty(doc="Waveguide template used.")
    wgs_straights = i3.ChildCellListProperty(
        doc="Childcells used for the waveguides.")

    def _default_wg_template(self):
        return WireWaveguideTemplate()

    def _default_wgs_straights(self):
        wgs = []
        for cnt in xrange(0, 3):
            wg = i3.RoundedWaveguide(trace_template=self.wg_template)
            wgs.append(wg)
        return wgs

    class Layout(i3.LayoutView):

        length_splitting_shape = i3.PositiveNumberProperty(
            default=10.0, doc="Length of the splitting section.")
        length_straights = i3.PositiveNumberProperty(
            default=0.2,
            doc="Length of the straights at the input and output.")
        spacing = i3.PositiveNumberProperty(
            default=2.0, doc="Spacing between the two output waveguides.")

        def _default_wg_template(self):
            wgt = self.cell.wg_template.get_default_view(i3.LayoutView)
            return wgt

        def _default_wgs_straights(self):
            wgs_cells = self.cell.wgs_straights
            wgs_layout = []

            for wgc in wgs_cells:
                wg_layout = wgc.get_default_view(i3.LayoutView)
                wg_layout.set(shape=i3.Shape(
                    points=[(0, 0), (self.length_straights, 0)]))
                wgs_layout.append(wg_layout)

            return wgs_layout

        def _generate_instances(self, insts):

            insts += i3.SRef(reference=self.wgs_straights[0], name="in")
            insts += i3.SRef(
                reference=self.wgs_straights[1],
                name="out1",
                position=(self.length_straights + self.length_splitting_shape,
                          -self.spacing / 2))
            insts += i3.SRef(
                reference=self.wgs_straights[2],
                name="out2",
                position=(self.length_straights + self.length_splitting_shape,
                          +self.spacing / 2))

            return insts

        def _get_cladding_elem(self):

            shape_cladding = i3.Shape(
                points=[(self.length_straights, self.wg_template.width / 2),
                        (self.length_straights + self.length_splitting_shape,
                         self.spacing / 2 + self.wg_template.width / 2)])

            shape_cladding_m = i3.Shape(
                points=[(self.length_straights, -self.wg_template.width / 2),
                        (self.length_straights + self.length_splitting_shape,
                         -self.spacing / 2 - self.wg_template.width / 2)])

            shape_elem = shape_cladding + shape_cladding_m.reversed()

            elem = i3.Boundary(layer=self.wg_template.windows[1].layer,
                               shape=shape_elem)
            return elem

        def _generate_ports(self, ports):
            ports += self.instances["in"].ports["in"]
            ports += self.instances["out1"].ports["out"].modified_copy(
                name="out1")
            ports += self.instances["out2"].ports["out"].modified_copy(
                name="out2")
            return ports

        def _get_splitting_elem(self):
            raise NotImplementedError(
                "This is an abstract class in which _get_splitting_elem was not implemented."
            )

        def _generate_elements(self, elems):
            elems += self._get_splitting_elem()
            elems += self._get_cladding_elem()
            return elems

    class CapheModelCST(CapheModelCST):
        """
        CapheModel based on a CST simulation
        """
        def _default_additional_commands_path(self):
            return r"{}\simulation_files\additional_commands.mod".format(
                os.path.dirname(__file__))

    class CapheModel(Coupler1x2.CapheModel):
        """
        Simple Analytic CapheModel
        """
        pass
class AlignmentMark(i3.PCell):
    """
    Alignment mark between two process layers.
    """
    
    # List of Vernier scales and crosses for a basecell. They are locked properties and defined by default functions
    verniers = i3.ChildCellListProperty(locked=True, doc="Vernier scales")
    cross_marks = i3.ChildCellListProperty(locked=True, doc="Cross Marks")

    _name_prefix = "ALIGNMENT_MARKER" 

    def _default_verniers(self):
        vern_1 = VernierScale()        
        vern_2 = VernierScale()
        return [vern_1, vern_2]

    def _default_cross_marks(self):
        # Dark Cross on layer 1
        dark_cross = CrossMark()        
        # Open Cross on layer 1 
        open_cross = CrossMark()
        
        return [dark_cross, open_cross]

    class Layout(i3.LayoutView):
        """
        Alignment mark layout view.
        """

        # Specify two layers on which markers are drawn
        process1 = i3.ProcessProperty(default=i3.TECH.PPLAYER.CH2.TRENCH)#i3.TECH.PROCESS.CHANNEL_1, doc="Process Layer 1")  #was i3.TECH.PROCESS.WG
        process2 = i3.ProcessProperty(default=i3.TECH.PPLAYER.CH1.TRENCH)#i3.TECH.PROCESS.CHANNEL_2, doc="Process Layer 2")

        # Properties of crosses
        dark_cross_bar_width = i3.PositiveNumberProperty(default=30, doc="width of the dark cross")
        open_cross_bar_width = i3.PositiveNumberProperty(default=40, doc="width of the open cross")
        cross_boundary_width = i3.PositiveNumberProperty(default=150, doc="width of the cross boundary box")
    
        # Basic properties of Vernier scales
        vern_spacing_short = i3.PositiveNumberProperty(default=18, doc="spacing between bars of shorter vernier scale")
        vern_spacing_long = i3.PositiveNumberProperty(default=18.5, doc="spacing between bars of longer vernier scale")
        vern_number_of_bar = i3.IntProperty(default=13, doc="the number of vernier bars")
    
        # Detailed properties of Vernier scales
        vern_bar_length = i3.PositiveNumberProperty(default=30, doc="length of the shortest bars on the scale")
        vern_bar_extra_length = i3.PositiveNumberProperty(default=10, doc="extra length of the central bar")
        vern_bar_width = i3.PositiveNumberProperty(default=5, doc="width of a single bar")

        # Separation between Vernier scales and Crosses section
        vern_cross_spacing = i3.PositiveNumberProperty(default=30,
                                      doc="Distance between cross box and closest edge of scales")

        # Separation between 2 scales of 2 layers
        vern_layer_gap = i3.NonNegativeNumberProperty(default=0.0, doc="gap between 2 scales of 2 layers on alignment")

        def _default_verniers(self):
            vern_1 = self.cell.verniers[0].Layout(spacing=self.vern_spacing_long,
                                                number_of_bars=self.vern_number_of_bar,
                                                bar_length=self.vern_bar_length,
                                                bar_extra_length=self.vern_bar_extra_length,
                                                bar_width=self.vern_bar_width)#,
                                                #process=self.process1)
                                                
            vern_2 = self.cell.verniers[1].Layout(spacing=self.vern_spacing_short,
                                                number_of_bars=self.vern_number_of_bar,
                                                bar_length=self.vern_bar_length,
                                                bar_extra_length=self.vern_bar_extra_length,
                                                bar_width=self.vern_bar_width)#,
                                                #process=self.process2)

            return [vern_1, vern_2]

    
        def _default_cross_marks(self):
            # Dark Cross on layer 1
            dark_cross = self.cell.cross_marks[0].Layout(inversion=False, 
                                                         cross_bar_width=self.dark_cross_bar_width,
                                                         cross_boundary_width=self.cross_boundary_width)#,
                                                         #process=self.process1)

            open_cross = self.cell.cross_marks[1].Layout(inversion=True, 
                                                         cross_bar_width=self.open_cross_bar_width,
                                                         cross_boundary_width=self.cross_boundary_width)#,
                                                         #process=self.process2)
            return [dark_cross, open_cross]

        def _generate_instances(self, insts):
            insts += i3.SRef(reference=self.cross_marks[0])
            insts += i3.SRef(reference=self.cross_marks[1])
            
            vern_1_horz_trans = i3.VMirror() + \
                                i3.Translation((0, -self.cross_boundary_width * 0.5 - self.vern_cross_spacing -
                                                (self.vern_bar_length + self.vern_bar_extra_length) - self.vern_layer_gap))            
            
            insts += i3.SRef(reference=self.verniers[0], transformation=vern_1_horz_trans)           
            
            vern_2_horz_trans = i3.Translation((0, -self.cross_boundary_width * 0.5 - self.vern_cross_spacing -
                                                (self.vern_bar_length + self.vern_bar_extra_length)))        
            
            insts += i3.SRef(reference=self.verniers[1], transformation=vern_2_horz_trans) 

            vern_1_vert_trans = i3.Rotation(rotation=90) + \
                                i3.Translation((-self.cross_boundary_width*0.5 - 
                                                self.vern_cross_spacing -
                                                (self.vern_bar_length + self.vern_bar_extra_length) -
                                                self.vern_layer_gap,
                                                0))
                                
            insts += i3.SRef(reference=self.verniers[0], transformation=vern_1_vert_trans)  
            
            vern_2_vert_trans = i3.Rotation(rotation=270) + \
                                i3.Translation((-self.cross_boundary_width*0.5 -
                                                (self.vern_bar_length + self.vern_bar_extra_length) -
                                                self.vern_cross_spacing, 0))                    
            insts += i3.SRef(reference=self.verniers[1], transformation=vern_2_vert_trans)  
            
            return insts
示例#15
0
class Spirals_w(PlaceComponents):
    Spirals_w_list = i3.ChildCellListProperty(
        doc="List containing the different routed masks")
    width_vec = i3.ListProperty(default=[10000.0, 20000.0])
    s_length_vec = i3.ListProperty(default=[50000.0])
    n = i3.PositiveNumberProperty(default=1, doc="Radius of curvature")
    tipo = i3.PositiveNumberProperty(default=1, doc="Radius of curvature")

    def _default_n(self):
        for counter, cell in enumerate(self.width_vec):
            numero = counter + 1
            #print 'number of legths: ', self.n
        return numero

    def _default_Spirals_w_list(self):
        Spirals_w_list = []

        for w, width in enumerate(self.width_vec):
            print 'The core width is: ', width
            wg_t = WireWaveguideTemplate()
            wg_t.Layout(
                core_width=width,
                cladding_width=width,
            )
            Spirals_w_list.append(
                Spirals(s_length_vec=self.s_length_vec,
                        waveguide_template=wg_t,
                        tipo=self.tipo,
                        width=w + 1,
                        n=self.n,
                        name='Spirals_w_' +
                        str(width))  #.Layout(local_mbend_radius = radius)
            )
        return Spirals_w_list

    def _default_child_cells(self):
        child_cells = {}

        for counter, width in enumerate(self.Spirals_w_list):

            child_cells['Spirals{}'.format(counter)] = width

            print 'child_cells:', child_cells
        return child_cells

    class Layout(PlaceComponents.Layout):
        def _default_child_transformations(self):
            d = {}
            for counter, child in enumerate(self.child_cells):
                # We get the layoutview of the childcell
                spiral = self.child_cells[child].get_default_view(self)
                isz_0 = spiral.instances['Spiral0'].reference.inner_size
                sx = isz_0[1] + 200
                print 'sx = ', sx
                #print("inner_size = {}".format(isz_0, isz_1))

                number = self.n
                if self.tipo == 1:
                    d['Spirals' + str(counter)] = i3.Translation(
                        translation=(0.0, (counter) *
                                     sx))  #+i3.HMirror()+i3.VMirror()
                if self.tipo == 2:
                    d['Spirals' + str(counter)] = i3.Translation(translation=(
                        0.0, -(counter) * sx)) + i3.HMirror() + i3.VMirror()

            return d
示例#16
0
class my_MMI2112(PlaceAndAutoRoute):
    DC_list = i3.ChildCellListProperty(default=[])
    gap_inc_vec = i3.ListProperty(default=[], doc="Length of MMI")
    WG1 = i3.ChildCellProperty(doc="", locked=True)
    WG2 = i3.ChildCellProperty()
    wg_t1 = i3.WaveguideTemplateProperty(doc="board WG")
    mmi_trace_template = i3.WaveguideTemplateProperty()
    mmi_access_template = i3.WaveguideTemplateProperty()
    width = i3.PositiveNumberProperty(doc="width of ports", default=15)

    def _default_wg_t1(self):
        wg_t1 = WireWaveguideTemplate(name="port_{}".format(str(self.width)))
        wg_t1.Layout(
            core_width=self.width,
            cladding_width=self.width + 2 * 12.0,
        )
        return wg_t1

    def _default_trace_template(self):
        wg_sm = WireWaveguideTemplate(name="sm_template")
        wg_sm.Layout(core_width=3.8, cladding_width=3.8 + 2 * 12.0)
        return wg_sm

    def _default_WG1(self):
        WG1 = i3.Waveguide(name="straight{}".format(str(self.width)),
                           trace_template=self.wg_t1)
        WG1.Layout(shape=[(0.0, 0.0), (150.0, 0.0)])
        return WG1

    def _default_WG2(self):
        Port = AutoTransitionPorts(name="ports{}".format(str(self.width)),
                                   contents=self.WG1,
                                   port_labels=["out"],
                                   trace_template=self.trace_template)
        Port.Layout(transition_length=300)  # .visualize(annotate=True)
        return Port

    def _default_mmi_trace_template(self):
        mmi_trace_template = WireWaveguideTemplate(name="MMI_tt")
        mmi_trace_template.Layout(core_width=20.0,
                                  cladding_width=20.0 + 2 * 12)  # MMI_width
        return mmi_trace_template

    def _default_mmi_access_template(self):
        mmi_access_template = WireWaveguideTemplate(name="MMI_at")
        mmi_access_template.Layout(core_width=9.0, cladding_width=9.0 + 2 * 12)
        return mmi_access_template

    def _default_DC_list(self):
        print '____________ MMI 2x2 ______________'
        MMI22_list = []

        for l, dl in enumerate(self.gap_inc_vec):
            print 'length number ' + str(l)
            print 'dl ' + str(dl)

            cell = MMI2112()

            cell.Layout(name="MMI2112_l_{}".format(str(self.gap_inc_vec[l])),
                        length=self.gap_inc_vec[l])

            # cell = RingRectSymm180DropFilter(name='ring' + str(dl) + str(self.length),
            #                                  ring_trace_template=self.trace_template)
            # cell.Layout(bend_radius=200,
            #             coupler_lengths=[self.length, self.length],
            #             coupler_radii=[300.0, 300.0],
            #             coupler_angles=[90.0, 90.0],
            #             coupler_spacings=[3.8 + self.gap_inc_vec[l], 3.8 + self.gap_inc_vec[l]],
            #             straights=(self.length, 0.0),
            #             # manhattan=True,
            #             )

            MMI22_list.append(cell)

            print 'cell name ' + str(cell.name)
            print '__________________________'

        return MMI22_list

    def _default_child_cells(self):
        child_cells = dict()
        for counter in range(0, 12, 1):
            print counter
            # child_cells['straight' + str(counter)] = self.WG1
            child_cells['taper' + str(counter)] = self.WG2

        for counter, child in enumerate(self.DC_list):
            print 'child number' + str(counter)
            child_cells['ring' + str(counter)] = child
            print 'child name ' + str(child.name)
            print child
        return child_cells

    def _default_links(self):
        links = [
            ("taper0:out", "ring0:MMI1b_in2"),
            ("taper1:out", "ring0:MMI1b_in1"),
            ("taper2:out", "ring0:MMI1a_out2"),
            ("taper3:out", "ring0:MMI1a_out1"),
            ("taper4:out", "ring1:MMI1b_in2"),
            ("taper5:out", "ring1:MMI1b_in1"),
            ("taper6:out", "ring1:MMI1a_out2"),
            ("taper7:out", "ring1:MMI1a_out1"),
            ("taper8:out", "ring2:MMI1b_in2"),
            ("taper9:out", "ring2:MMI1b_in1"),
            ("taper10:out", "ring2:MMI1a_out2"),
            ("taper11:out", "ring2:MMI1a_out1"),
        ]
        return links

    class Layout(PlaceAndAutoRoute.Layout):
        def _default_child_transformations(self):
            trans = dict()
            column = 10000
            # trans["dircoup1"] = (1650, 0)
            # trans["dircoup2"] = (4950, 0)
            # trans['mzi_22_22_0'] = (0, 0)
            trans['ring0'] = (2500, 0)
            trans['ring1'] = (2500, 0 + column)
            trans['ring2'] = (2500, 0 + 2 * column)
            # trans['ring3'] = (1500, 0 + 3 * column)

            trans["taper0"] = (0, 4000)
            trans["taper1"] = (0, -4000)
            trans["taper2"] = i3.HMirror(0) + i3.Translation((5000, 2500))
            trans["taper3"] = i3.HMirror(0) + i3.Translation((5000, -2500))

            trans["taper4"] = (0, 4000 + column)
            trans["taper5"] = (0, -4000 + column)
            trans["taper6"] = i3.HMirror(0) + i3.Translation(
                (5000, 2500 + column))
            trans["taper7"] = i3.HMirror(0) + i3.Translation(
                (5000, -2500 + column))

            trans["taper8"] = (0, 4000 + 2 * column)
            trans["taper9"] = (0, -4000 + 2 * column)
            trans["taper10"] = i3.HMirror(0) + i3.Translation(
                (5000, 2500 + 2 * column))
            trans["taper11"] = i3.HMirror(0) + i3.Translation(
                (5000, -2500 + 2 * column))

            return trans

        def _default_bend_radius(self):
            bend_radius = 300
            return bend_radius
示例#17
0
class my_dc(PlaceAndAutoRoute):
    DC_list = i3.ChildCellListProperty(default=[])
    MMI_list = i3.ChildCellListProperty(default=[])
    gap_inc_vec = i3.ListProperty(default=[], doc="Length of MMI")
    length_inc_vec = i3.ListProperty(default=[], doc="length of MMI2112")
    WG1 = i3.ChildCellProperty(doc="", locked=True)
    WG2 = i3.ChildCellProperty()
    WG3 = i3.ChildCellProperty(
        doc="dummy SM waveguide")  # define this to guide route
    wg_t1 = i3.WaveguideTemplateProperty(doc="board WG")
    wg_dc = i3.WaveguideTemplateProperty(doc="dc WG")
    mmi_trace_template = i3.WaveguideTemplateProperty()
    mmi_access_template = i3.WaveguideTemplateProperty()
    width = i3.PositiveNumberProperty(doc="width of ports", default=15)

    def _default_wg_t1(self):
        wg_t1 = WireWaveguideTemplate(name="port_{}".format(str(self.width)))
        wg_t1.Layout(
            core_width=self.width,
            cladding_width=self.width + 2 * 12.0,
        )
        return wg_t1

    def _default_wg_dc(self):
        wg_t1 = WireWaveguideTemplate(name="dc")
        wg_t1.Layout(
            core_width=2.8,
            cladding_width=2.8 + 2 * 12.0,
        )
        return wg_t1

    def _default_trace_template(self):
        wg_sm = WireWaveguideTemplate(name="sm_template")
        wg_sm.Layout(core_width=3.8, cladding_width=3.8 + 2 * 12.0)
        return wg_sm

    def _default_WG1(self):
        wg1 = i3.Waveguide(name="straight{}".format(str(self.width)),
                           trace_template=self.wg_t1)
        wg1.Layout(shape=[(0.0, 0.0), (150.0, 0.0)])
        return wg1

    def _default_WG3(self):
        wg3 = i3.Waveguide(name="route", trace_template=self.trace_template)
        wg3.Layout(shape=[(0.0, 0.0), (1.0, 0.0)])
        return wg3

    def _default_WG2(self):
        Port = AutoTransitionPorts(name="ports{}".format(str(self.width)),
                                   contents=self.WG1,
                                   port_labels=["out"],
                                   trace_template=self.trace_template)
        Port.Layout(transition_length=300)  # .visualize(annotate=True)
        return Port

    def _default_mmi_trace_template(self):
        mmi_trace_template = WireWaveguideTemplate(name="MMI_tt")
        mmi_trace_template.Layout(core_width=20.0,
                                  cladding_width=20.0 + 2 * 12)  # MMI_width
        return mmi_trace_template

    def _default_mmi_access_template(self):
        mmi_access_template = WireWaveguideTemplate(name="MMI_at")
        mmi_access_template.Layout(core_width=9.0, cladding_width=9.0 + 2 * 12)
        return mmi_access_template

    def _default_DC_list(self):
        print '____________ MMI 2x2 ______________'
        MMI22_list = []

        for l, dl in enumerate(self.gap_inc_vec):
            print 'length number ' + str(l)
            print 'dl ' + str(dl)

            cell = MMI2x2Tapered(
                mmi_trace_template=self.mmi_trace_template,
                input_trace_template=self.mmi_access_template,
                output_trace_template=self.mmi_access_template,
                trace_template=self.trace_template,
            )

            cell.Layout(name="MMI22_l_{}".format(str(self.gap_inc_vec[l])),
                        transition_length=200.0,
                        length=self.gap_inc_vec[l],
                        trace_spacing=11.0)

            MMI22_list.append(cell)

            print 'cell name ' + str(cell.name)
            print '__________________________'

        return MMI22_list

    def _default_MMI_list(self):
        print '____________ MMI 2112 ______________'
        MMI2112_list = []

        for l, dl in enumerate(self.length_inc_vec):
            print 'length number ' + str(l)
            print 'dl ' + str(dl)

            cell = MMI2112()

            cell.Layout(name="MMI2112_l_{}".format(str(
                self.length_inc_vec[l])),
                        length=self.length_inc_vec[l])

            MMI2112_list.append(cell)
            print 'cell name ' + str(cell.name)

        return MMI2112_list

    def _default_child_cells(self):
        child_cells = dict()
        for counter in range(0, 16, 1):
            print counter
            child_cells['straight1' + str(counter)] = self.WG3

        for counter in range(0, 24, 1):
            child_cells['taper_in' + str(counter)] = self.WG2

        for counter in range(0, 24, 1):
            # child_cells['straight2' + str(counter)] = self.WG3
            child_cells['taper_out' + str(counter)] = self.WG2

        for counter in range(0, 16, 1):
            child_cells['straight2' + str(counter)] = self.WG3

        for counter, child in enumerate(self.DC_list):
            print 'child number' + str(counter)
            child_cells['ring' + str(counter)] = child
            print 'child name ' + str(child.name)
            print child

        for counter, child in enumerate(self.MMI_list):
            print 'child number' + str(counter)
            child_cells['mmi' + str(counter)] = child
            print 'child name ' + str(child.name)
            print child

        child = SBendDirectionalCoupler(name="dc3",
                                        trace_template1=self.trace_template,
                                        coupler_length=923)
        child.Layout(
            coupler_spacing=1.5 + 3.8,
            straight_after_bend=970,
            # bend_angle=30.0,
            bend_angles1=(20, 20),
            bend_angles2=(40, 40),
            bend_radius=100)
        child_cells['dc3'] = child

        child = SBendDirectionalCoupler(name="dc2",
                                        trace_template1=self.wg_dc,
                                        coupler_length=888)
        child.Layout(
            coupler_spacing=2 + 2.8,
            straight_after_bend=860,
            # bend_angle=30.0,
            bend_angles1=(20, 20),
            bend_angles2=(40, 40),
            bend_radius=100,
            # manhattan=True,
        )
        child_cells['dc2'] = child

        child = SBendDirectionalCoupler(name="dc1",
                                        trace_template1=self.wg_dc,
                                        coupler_length=868)
        child.Layout(
            coupler_spacing=2 + 2.8,
            straight_after_bend=750,
            # bend_angle=30.0,
            bend_angles1=(20, 20),
            bend_angles2=(40, 40),
            bend_radius=100,
            # manhattan=True,
        )
        child_cells['dc1'] = child

        child = SBendDirectionalCoupler(name="dc4",
                                        trace_template1=self.trace_template,
                                        coupler_length=923)
        child.Layout(
            coupler_spacing=100 + 3.8,
            straight_after_bend=1150,
            # bend_angle=30.0,
            bend_angles1=(1, 1),
            bend_angles2=(40, 40),
            bend_radius=100)
        child_cells['dc4'] = child

        return child_cells

    def _default_links(self):
        links = []
        for counter in range(0, 10, 1):
            # in_port = "Spiral{}:in".format(counter)
            in_port = "taper_in{}:out".format(counter)
            # links.append((in_port, out_port))
            # in_port = "Spiral{}:out".format(counter)
            out_port = "straight1{}:in".format(counter)
            links.append((in_port, out_port))

            in_port = "taper_out{}:out".format(counter)
            # links.append((in_port, out_port))
            # in_port = "Spiral{}:out".format(counter)
            out_port = "straight2{}:out".format(counter)
            links.append((in_port, out_port))

            # for counter in range(0, 11, 1):
            if counter % 2 == 0:
                i_port = "straight1{}:out".format(counter)
                o_port = "ring{}:in1".format(counter // 2)
                links.append((i_port, o_port))
                i_port = "straight2{}:in".format(counter)
                o_port = "ring{}:out1".format(counter // 2)
                links.append((i_port, o_port))
            else:
                ii_port = "straight1{}:out".format(counter)
                oo_port = "ring{}:in2".format(counter // 2)
                links.append((ii_port, oo_port))

                ii_port = "straight2{}:in".format(counter)
                oo_port = "ring{}:out2".format(counter // 2)
                links.append((ii_port, oo_port))

        for counter in range(10, 16, 1):
            # in_port = "Spiral{}:in".format(counter)
            in_port = "taper_in{}:out".format(counter)
            # links.append((in_port, out_port))
            # in_port = "Spiral{}:out".format(counter)
            out_port = "straight1{}:in".format(counter)
            links.append((in_port, out_port))

            in_port = "taper_out{}:out".format(counter)
            # links.append((in_port, out_port))
            # in_port = "Spiral{}:out".format(counter)
            out_port = "straight2{}:out".format(counter)
            links.append((in_port, out_port))

            if counter % 2 == 0:
                i_port = "straight1{}:out".format(counter)
                o_port = "mmi{}:MMI1b_in1".format((counter - 10) // 2)
                links.append((i_port, o_port))
                i_port = "straight2{}:in".format(counter)
                o_port = "mmi{}:MMI1a_out1".format((counter - 10) // 2)
                links.append((i_port, o_port))
            else:
                ii_port = "straight1{}:out".format(counter)
                oo_port = "mmi{}:MMI1b_in2".format((counter - 10) // 2)
                links.append((ii_port, oo_port))

                ii_port = "straight2{}:in".format(counter)
                oo_port = "mmi{}:MMI1a_out2".format((counter - 10) // 2)
                links.append((ii_port, oo_port))

        links.append(("taper_in16:out", "dc1:in1")),
        links.append(("taper_in17:out", "dc1:in2")),
        links.append(("taper_out16:out", "dc1:out1")),
        links.append(("taper_out17:out", "dc1:out2")),
        links.append(("taper_in18:out", "dc2:in1")),
        links.append(("taper_in19:out", "dc2:in2")),
        links.append(("taper_out18:out", "dc2:out1")),
        links.append(("taper_out19:out", "dc2:out2")),
        links.append(("taper_in20:out", "dc3:in1")),
        links.append(("taper_in21:out", "dc3:in2")),
        links.append(("taper_out20:out", "dc3:out1")),
        links.append(("taper_out21:out", "dc3:out2")),
        links.append(("taper_in22:out", "dc4:in1")),
        links.append(("taper_in23:out", "dc4:in2")),
        links.append(("taper_out22:out", "dc4:out1")),
        links.append(("taper_out23:out", "dc4:out2")),
        # links.append(
        #     ("taper_in0:out", "ring0:in2"),
        #     ("taper_in1:out", "ring0:in1"),
        #     # ("taper_in2:out", "ring0:out2"),
        #     # ("taper_in3:out", "ring0:out1"),
        #
        #     ("taper_in2:out", "ring1:in2"),
        #     ("taper_in3:out", "ring1:in1"),
        #     # ("taper6:out", "ring1:out2"),
        #     # ("taper7:out", "ring1:out1"),
        #     #
        #     ("taper_in4:out", "ring2:in2"),
        #     ("taper_in5:out", "ring2:in1"),
        #     # ("taper10:out", "ring2:out2"),
        #     # ("taper11:out", "ring2:out1"),
        #     ("taper_in6:out", "ring3:in2"),
        #     ("taper_in7:out", "ring3:in1"),
        #     ("taper_in8:out", "ring4:in2"),
        #     ("taper_in9:out", "ring4:in1"),
        #
        # )
        return links

    class Layout(PlaceAndAutoRoute.Layout):
        def _default_child_transformations(self):
            trans = dict()
            column = 150
            # a = self.cell.mmi1_21.get_default_view(i3.LayoutView).ports['out'].x
            for counter in range(0, 24, 1):
                trans['taper_in' + str(counter)] = i3.Translation(
                    translation=(0, counter * column))
                trans['taper_out' +
                      str(counter)] = i3.HMirror(0) + i3.Translation(
                          translation=(6000, 1000 + counter * column))
                # trans['straight1' + str(counter)] = i3.Translation(
                #     translation=(1490 - counter * 30, 1670 + counter * 150), rotation=90)
                # trans['straight2']

            # trans["dircoup1"] = (1650, 0)
            # trans["dircoup2"] = (4950, 0)
            # trans['mzi_22_22_0'] = (0, 0)
            for counter in range(0, 5, 1):
                trans['ring' + str(counter)] = i3.Translation(
                    translation=(3000, 5000 + counter * column / 1.5))

            for counter in range(0, 3, 1):
                trans['mmi' + str(counter)] = i3.Translation(
                    translation=(3000, 5500 + counter * column / 1.5))

            trans['dc1'] = i3.Translation((3000 + 200, 5800))
            trans['dc2'] = i3.Translation((3000 + 200, 5950))
            trans['dc3'] = i3.Translation((3000 + 200, 6100))
            trans['dc4'] = i3.Translation((3000 + 200, 6300))

            for counter, child in enumerate(self.DC_list):
                a = (child.ports['in1'].x, child.ports['in1'].y)
                b = (child.ports['in2'].x, child.ports['in2'].y)
                c = (child.ports['out1'].x, child.ports['out1'].y)
                d = (child.ports['out2'].x, child.ports['out2'].y)
                n = counter * 2
                m = counter * 2 + 1
                trans['straight1' + str(n)] = i3.Translation(
                    translation=a) + i3.Translation(translation=(
                        3000, 5000 + counter * column / 1.5)) + i3.Translation(
                            (-2 - 50 * n, 0))
                trans['straight1' + str(m)] = i3.Translation(
                    translation=b) + i3.Translation(translation=(
                        3000, 5000 + counter * column / 1.5)) + i3.Translation(
                            (-2 - 50 * m, 0))
                trans['straight2' + str(n)] = i3.Translation(
                    translation=c) + i3.Translation(translation=(
                        3000, 5000 + counter * column / 1.5)) + i3.Translation(
                            (2 + 50 * n, 0))
                trans['straight2' + str(m)] = i3.Translation(
                    translation=d) + i3.Translation(translation=(
                        3000, 5000 + counter * column / 1.5)) + i3.Translation(
                            (2 + 50 * m, 0))
                print a, b

            for counter, child in enumerate(self.MMI_list):
                a = (child.ports['MMI1b_in1'].x, child.ports['MMI1b_in1'].y)
                b = (child.ports['MMI1b_in2'].x, child.ports['MMI1b_in2'].y)
                c = (child.ports['MMI1a_out1'].x, child.ports['MMI1a_out1'].y)
                d = (child.ports['MMI1a_out2'].x, child.ports['MMI1a_out2'].y)
                n = 10 + counter * 2
                m = 10 + counter * 2 + 1
                trans['straight1' + str(n)] = i3.Translation(
                    translation=a) + i3.Translation(translation=(
                        3000, 5500 + counter * column / 1.5)) + i3.Translation(
                            (-2 - 50 * n, 0))
                trans['straight1' + str(m)] = i3.Translation(
                    translation=b) + i3.Translation(translation=(
                        3000, 5500 + counter * column / 1.5)) + i3.Translation(
                            (-2 - 50 * m, 0))
                trans['straight2' + str(n)] = i3.Translation(
                    translation=c) + i3.Translation(translation=(
                        3000, 5500 + counter * column / 1.5)) + i3.Translation(
                            (2 + 50 * n - 250, 0))
                trans['straight2' + str(m)] = i3.Translation(
                    translation=d) + i3.Translation(translation=(
                        3000, 5500 + counter * column / 1.5)) + i3.Translation(
                            (2 + 50 * m - 250, 0))
                print a, b

            # trans['ring0'] = (2000, 2000)
            # trans['ring1'] = (2000, 2000 + column)
            # trans['ring2'] = (2000, 2000 + 2 * column)
            # trans['ring3'] = (2000, 2000 + 3 * column)
            # trans['ring4'] = (2000, 2000 + 4 * column)
            # trans['ring0'] = (2000, 2000)
            # trans['ring1'] = (2000, 2000 + column)
            # trans['ring2'] = (2000, 2000 + 2 * column)
            # trans['ring3'] = (2000, 2000 + 3 * column)
            # trans['ring4'] = (2000, 2000 + 4 * column)
            # trans["taper0"] = (0, 4000)
            # trans["taper1"] = (0, -4000)
            # trans["taper2"] = i3.HMirror(0) + i3.Translation((5000, 2500))
            # trans["taper3"] = i3.HMirror(0) + i3.Translation((5000, -2500))
            #
            # trans["taper4"] = (0, 4000 + column)
            # trans["taper5"] = (0, -4000 + column)
            # trans["taper6"] = i3.HMirror(0) + i3.Translation((5000, 2500 + column))
            # trans["taper7"] = i3.HMirror(0) + i3.Translation((5000, -2500 + column))
            #
            # trans["taper8"] = (0, 4000 + 2 * column)
            # trans["taper9"] = (0, -4000 + 2 * column)
            # trans["taper10"] = i3.HMirror(0) + i3.Translation((5000, 2500 + 2 * column))
            # trans["taper11"] = i3.HMirror(0) + i3.Translation((5000, -2500 + 2 * column))

            return trans

        def _default_bend_radius(self):
            bend_radius = 300
            return bend_radius

        def _generate_elements(self, elems):
            for counter in range(0, 24, 1):
                elems += i3.PolygonText(
                    layer=i3.TECH.PPLAYER.WG.TEXT,
                    text="{}".format(str(counter)),
                    # coordinate=(1300.0, 100.0),
                    # alignment=(i3.TEXT_ALIGN_LEFT, i3.TEXT_ALIGN_LEFT),
                    font=2,
                    height=70.0,
                    transformation=i3.Translation((300, 100 + 150 * counter)))
                elems += i3.PolygonText(
                    layer=i3.TECH.PPLAYER.WG.TEXT,
                    text="{}".format(str(counter)),
                    # coordinate=(1300.0, 100.0),
                    # alignment=(i3.TEXT_ALIGN_LEFT, i3.TEXT_ALIGN_LEFT),
                    font=2,
                    height=70.0,
                    transformation=i3.Translation(
                        (5700, 1100 + 150 * counter)))

            return elems
class CircuitOfBlocks(microfluidics.PlaceAndAutoRoute):
    """Parametric cell with several traps, which are stacked vertically (Parallel) or horizontally (Series)
    """
    #_name_prefix = "circuitOfTraps"
    type = i3.NumberProperty(default=0)  #  0 Paralell 1 Series
    block_distance = i3.NumberProperty(default=400.)  #distance betwn traps
    block_with_tee = i3.ChildCellListProperty(
    )  #  Generating traps with Tee from Child Cell List Property
    trace_template = microfluidics.ChannelTemplateProperty(
        default=microfluidics.ShortChannelTemplate())
    n_blocks_x = i3.PositiveIntProperty(default=30)
    n_blocks_y = i3.PositiveIntProperty(default=30)
    x_footprint = i3.PositiveIntProperty(default=1000)
    y_footprint = i3.PositiveIntProperty(default=1000)

    def _default_child_cells(self):
        return {
            "blk_w_tee{}".format(cnt): self.block_with_tee[cnt]
            for cnt in range(self.n_blocks_x * self.n_blocks_y)
        }

    def _default_links(self):
        links = []
        bx = self.n_blocks_x

        ########################
        #############   PARALLEL
        if self.type == 0:
            for cntx in range(0, self.n_blocks_x):
                # self connection at the top -bypass
                top = self.n_blocks_y * self.n_blocks_x - self.n_blocks_x + cntx
                links.append(("blk_w_tee{}:in2".format(top),
                              "blk_w_tee{}:out2".format(top)))
                # connecting bottom to top
                for cnty in range(0, self.n_blocks_y - 1):
                    links.append(
                        ("blk_w_tee{}:in2".format(cnty * bx + cntx),
                         "blk_w_tee{}:in1".format((cnty + 1) * bx + cntx)))
                    links.append(
                        ("blk_w_tee{}:out2".format(cnty * bx + cntx),
                         "blk_w_tee{}:out1".format((cnty + 1) * bx + cntx)))

            #interconnecting horizontally
            if self.n_blocks_x > 1:
                for cntd in range(0, self.n_blocks_x - 1):
                    links.append(("blk_w_tee{}:out1".format(cntd),
                                  "blk_w_tee{}:in1".format(cntd + 1)))
        ########  END PARALLEL #################

        ########################
        #############   SERIES
        if self.type == 1:  # series
            #all by-pass, each object
            for cnt in range(0,
                             self.n_blocks_y * self.n_blocks_x):  #all bypass
                links.append(("blk_w_tee{}:in2".format(cnt),
                              "blk_w_tee{}:out2".format(cnt)))

            #all interconnecting horizontally
            if self.n_blocks_x > 1:
                for cnty in range(0, self.n_blocks_y):
                    for cntd in range(0, (self.n_blocks_x - 1)):
                        links.append(
                            ("blk_w_tee{}:out1".format(cnty * bx + cntd),
                             "blk_w_tee{}:in1".format(cnty * bx + cntd + 1)))

            #left connections
            for cntd in range(1, (self.n_blocks_y - 1), 2):
                #links.append(("blk_w_tee{}:in1".format(cntd * bx), "blk_w_tee{}:in1".format((cntd+1) * bx)))
                links.append(("blk_w_tee{}:in1".format(
                    (cntd + 1) * bx), "blk_w_tee{}:in1".format(cntd * bx)))

            #right connections
            for cntd in range(1, (self.n_blocks_y), 2):
                links.append(("blk_w_tee{}:out1".format(cntd * bx - 1),
                              "blk_w_tee{}:out1".format((cntd + 1) * bx - 1)))

        ########  END SERIES #################

        return links

    def _default_block_with_tee(
            self):  # Generating traps from Child Cell List Property
        tee1 = TeeSimple()
        tee1.Layout(tee_length=(200.0))
        my_block = CellTrapSimple()
        my_block.Layout(cell_trap_length=300.0)
        return [
            TrapWithTees(
                name="blk_w_tee_{}".format(cnt),
                trap=my_block,
                tee=tee1,
            ) for cnt in range(self.n_blocks_x * self.n_blocks_y)
        ]

    class Layout(microfluidics.PlaceAndAutoRoute.Layout):
        def _default_child_transformations(self):

            # generate grid
            x = np.linspace(0, self.cell.x_footprint, self.cell.n_blocks_x)
            y = np.linspace(0, self.cell.y_footprint, self.cell.n_blocks_y)

            # generate positions
            from functions.position_coordinates import generate_positions
            coords = generate_positions(x, y, self.type)

            return {
                "blk_w_tee{}".format(cnt): i3.Translation(coords[cnt])
                for cnt in range(self.n_blocks_x * self.n_blocks_y)
            }

        def _generate_ports(self, ports):
            # Add ports
            if self.type == 0:
                ports += i3.expose_ports(
                    self.instances, {
                        'blk_w_tee0:in1': 'in1',
                        'blk_w_tee{}:out1'.format(self.n_blocks_x - 1): 'out1'
                    })

            if self.type == 1:
                if self.n_blocks_y % 2 == 0:
                    ports += i3.expose_ports(
                        self.instances,
                        {
                            'blk_w_tee0:in1':
                            'in1',
                            'blk_w_tee{}:in1'.format(self.n_blocks_x * self.n_blocks_y - self.n_blocks_x):
                            'out1'  # last left
                        })
                else:
                    ports += i3.expose_ports(
                        self.instances,
                        {
                            'blk_w_tee0:in1':
                            'in1',
                            'blk_w_tee{}:out1'.format(self.n_blocks_x * self.n_blocks_y - 1):
                            'out1'  # last right
                        })

            return ports
示例#19
0
class my_dc(PlaceAndAutoRoute):
    DC_list = i3.ChildCellListProperty(default=[])
    # gap_inc_vec = i3.ListProperty(default=[], doc="Length of MMI")
    gap_inc_vec2 = i3.ListProperty(default=[], doc="length of 12mmi")
    WG1 = i3.ChildCellProperty(doc="", locked=True)
    WG2 = i3.ChildCellProperty()
    wg_t1 = i3.WaveguideTemplateProperty(doc="board WG")
    mmi_trace_template = i3.WaveguideTemplateProperty()
    mmi_access_template = i3.WaveguideTemplateProperty()
    width = i3.PositiveNumberProperty(doc="width of ports", default=15)
    cleave = i3.PositiveNumberProperty(doc="tolerance", default=150)

    def _default_wg_t1(self):
        wg_t1 = WireWaveguideTemplate(name="port_{}".format(str(self.width)))
        wg_t1.Layout(
            core_width=self.width,
            cladding_width=self.width + 2 * 12.0,
        )
        return wg_t1

    def _default_trace_template(self):
        wg_sm = WireWaveguideTemplate(name="sm_template")
        wg_sm.Layout(core_width=3.8, cladding_width=3.8 + 2 * 12.0)
        return wg_sm

    def _default_WG1(self):
        WG1 = i3.Waveguide(name="straight{}_{}".format(str(self.width),
                                                       str(self.cleave)),
                           trace_template=self.wg_t1)
        WG1.Layout(shape=[(0.0, 0.0), (self.cleave, 0.0)])
        return WG1

    def _default_WG2(self):
        Port = AutoTransitionPorts(name="ports{}_{}".format(
            str(self.width), str(self.cleave)),
                                   contents=self.WG1,
                                   port_labels=["out"],
                                   trace_template=self.trace_template)
        Port.Layout(transition_length=300)  # .visualize(annotate=True)
        return Port

    def _default_mmi_trace_template(self):
        mmi_trace_template = WireWaveguideTemplate(name="MMI_tt")
        mmi_trace_template.Layout(core_width=20.0,
                                  cladding_width=20.0 + 2 * 12)  # MMI_width
        return mmi_trace_template

    def _default_mmi_access_template(self):
        mmi_access_template = WireWaveguideTemplate(name="MMI_at")
        mmi_access_template.Layout(core_width=9.0, cladding_width=9.0 + 2 * 12)
        return mmi_access_template

    def _default_DC_list(self):
        print '____________ MMI 2x2 ______________'
        MMI22_list = []

        # cell = MMI2x2Tapered(mmi_trace_template=self.mmi_trace_template,
        #                      input_trace_template=self.mmi_access_template,
        #                      output_trace_template=self.mmi_access_template,
        #                      trace_template=self.trace_template,
        #                      )
        #
        # cell.Layout(name="MMI22_l_430", transition_length=200.0,
        #             length=430, trace_spacing=11.0
        #             )
        #
        # MMI22_list.append(cell)
        #
        # print 'cell name ' + str(cell.name)
        # print '__________________________'

        for l, dl in enumerate(self.gap_inc_vec2):
            print 'length number ' + str(l)
            print 'dl ' + str(dl)

            cell = MMI2112()

            cell.Layout(name="MMI2112_l_{}".format(str(self.gap_inc_vec2[l])),
                        length=self.gap_inc_vec2[l])

            MMI22_list.append(cell)

            print 'cell name ' + str(cell.name)
            print '__________________________'

        return MMI22_list

    def _default_child_cells(self):
        child_cells = dict()
        for counter in range(0, 11, 1):
            print counter
            # child_cells['straight' + str(counter)] = self.WG1
            child_cells['taper' + str(counter)] = self.WG2

        for counter, child in enumerate(self.DC_list):
            print 'child number' + str(counter)
            child_cells['ring' + str(counter)] = child
            print 'child name ' + str(child.name)
            print child
        return child_cells

    def _default_links(self):
        links = [
            # ("taper0:out", "ring0:in2"),
            # ("taper1:out", "ring0:in1"),
            # ("taper2:out", "ring0:out2"),
            # ("taper3:out", "ring0:out1"),
            ("taper0:out", "ring0:narrow_in"),
            ("taper1:out", "ring0:MMI1a_out1"),
            ("taper2:out", "ring0:MMI1a_out2"),
            ("taper3:out", "ring1:narrow_in"),
            ("taper4:out", "ring1:MMI1a_out1"),
            ("taper5:out", "ring1:MMI1a_out2"),
            ("taper6:out", "ring2:narrow_in"),
            ("taper7:out", "ring2:MMI1a_out1"),
            ("taper8:out", "ring2:MMI1a_out2"),
            ("taper9:out", "taper10:out")
        ]
        return links

    class Layout(PlaceAndAutoRoute.Layout):
        def _default_child_transformations(self):
            trans = dict()
            column = 6000
            trans['ring0'] = (600, 0)
            trans['ring1'] = (600, 1 * column)
            trans['ring2'] = (600, 2 * column)
            # trans['ring3'] = (1300, 8000 + 2 * column )

            trans["taper0"] = (0, 0)
            trans["taper1"] = i3.HMirror(0) + i3.Translation((2500, -1500))
            trans["taper2"] = i3.HMirror(0) + i3.Translation((2500, 1500))

            trans["taper3"] = (0, 1 * column)
            trans["taper4"] = i3.HMirror(0) + i3.Translation(
                (2500, -1500 + 1 * column))
            trans["taper5"] = i3.HMirror(0) + i3.Translation(
                (2500, 1500 + 1 * column))

            trans["taper6"] = (0, 2 * column)
            trans["taper7"] = i3.HMirror(0) + i3.Translation(
                (2500, -1500 + 2 * column))
            trans["taper8"] = i3.HMirror(0) + i3.Translation(
                (2500, 1500 + 2 * column))

            trans["taper9"] = (0, 3800 + 2 * column)

            trans["taper10"] = i3.HMirror(0) + i3.Translation(
                (2500, -1500 + 3 * column))
            # trans["taper11"] = i3.HMirror(0) + i3.Translation((3000, 6500+ 2 * column))
            # trans["taper12"] = i3.HMirror(0) + i3.Translation((3000, 9500+ 2 * column))

            return trans

        def _default_bend_radius(self):
            bend_radius = 300
            return bend_radius

        def _generate_elements(self, elems):
            for counter, child in enumerate(self.DC_list):
                name = child.name

                elems += i3.PolygonText(
                    layer=i3.TECH.PPLAYER.WG.TEXT,
                    text="{}_{}".format(name, self.cell.wg_t1.name),
                    # coordinate=(1300.0, 100.0),
                    alignment=(i3.TEXT_ALIGN_LEFT, i3.TEXT_ALIGN_LEFT),
                    font=2,
                    height=30.0,
                    transformation=i3.Translation((600, 100 + 6000 * counter)))
                for i in range(1, 8, 1):
                    elems += i3.PolygonText(
                        layer=i3.TECH.PPLAYER.WG.TEXT,
                        text="{}".format(i),
                        coordinate=(400, -4400 + 3000 * i),
                        font=2,
                        height=200.0,
                    )
                for j in range(-1, 2, 1):
                    for i in range(0, 4, 1):
                        elems += i3.Rectangle(layer=i3.TECH.PPLAYER.WG.TEXT,
                                              center=(100 + j * 6000,
                                                      -3000 + 100 + 6000 * i),
                                              box_size=(100, 100))
                        elems += i3.Rectangle(layer=i3.TECH.PPLAYER.WG.TEXT,
                                              center=(100 + j * 6000,
                                                      -3000 - 100 + 6000 * i),
                                              box_size=(100, 100))
                    elems += i3.Rectangle(layer=i3.TECH.PPLAYER.WG.TEXT,
                                          center=(100 + j * 6000, -3000 + 100 +
                                                  6000 * 3 + 3000),
                                          box_size=(100, 100))
                    elems += i3.Rectangle(layer=i3.TECH.PPLAYER.WG.TEXT,
                                          center=(100 + j * 6000, -3000 - 100 +
                                                  6000 * 3 + 3000),
                                          box_size=(100, 100))
                elems += i3.Rectangle(layer=i3.TECH.PPLAYER.WG.TEXT,
                                      center=(300,
                                              -3000 + 100 + 6000 * 3 + 3000),
                                      box_size=(100, 100))
                elems += i3.Rectangle(layer=i3.TECH.PPLAYER.WG.TEXT,
                                      center=(300, -3000 - 100),
                                      box_size=(100, 100))

            return elems
示例#20
0
class my_dc3(PlaceAndAutoRoute):
    DC_list = i3.ChildCellListProperty(default=[])
    gap_inc_vec = i3.ListProperty(default=[], doc="Length of MMI")
    WG1 = i3.ChildCellProperty(doc="", locked=True)
    WG2 = i3.ChildCellProperty()
    wg_t1 = i3.WaveguideTemplateProperty(doc="board WG")
    mmi_trace_template = i3.WaveguideTemplateProperty()
    mmi_access_template = i3.WaveguideTemplateProperty()
    width = i3.PositiveNumberProperty(doc="width of ports", default=15)

    def _default_wg_t1(self):
        wg_t1 = WireWaveguideTemplate(name="port_{}".format(str(self.width)))
        wg_t1.Layout(core_width=self.width,
                     cladding_width=self.width + 2 * 12.0,
                     )
        return wg_t1

    def _default_trace_template(self):
        wg_sm = WireWaveguideTemplate(name="sm_template")
        wg_sm.Layout(core_width=3.8, cladding_width=3.8 + 2 * 12.0)
        return wg_sm

    def _default_WG1(self):
        WG1 = i3.Waveguide(name="straight{}".format(str(self.width)), trace_template=self.wg_t1)
        WG1.Layout(shape=[(0.0, 0.0), (150.0, 0.0)])
        return WG1

    def _default_WG2(self):
        Port = AutoTransitionPorts(
            name="ports{}".format(str(self.width)),
            contents=self.WG1,
            port_labels=["out"],
            trace_template=self.trace_template)
        Port.Layout(transition_length=300)  # .visualize(annotate=True)
        return Port

    def _default_mmi_trace_template(self):
        mmi_trace_template = WireWaveguideTemplate(name="MMI_tt")
        mmi_trace_template.Layout(core_width=20.0, cladding_width=20.0 + 2 * 12)  # MMI_width
        return mmi_trace_template

    def _default_mmi_access_template(self):
        mmi_access_template = WireWaveguideTemplate(name="MMI_at")
        mmi_access_template.Layout(core_width=9.0, cladding_width=9.0 + 2 * 12)
        return mmi_access_template

    def _default_DC_list(self):
        print '____________ MMI 2x2 ______________'
        MMI22_list = []

        for l, dl in enumerate(self.gap_inc_vec):
            print 'length number ' + str(l)
            print 'dl ' + str(dl)

            cell = MMI2x2Tapered(mmi_trace_template=self.mmi_trace_template,
                                 input_trace_template=self.mmi_access_template,
                                 output_trace_template=self.mmi_access_template,
                                 trace_template=self.trace_template,
                                 )

            cell.Layout(name="MMI22_l_{}".format(str(self.gap_inc_vec[l])), transition_length=200.0,
                        length=self.gap_inc_vec[l], trace_spacing=11.0
                        )

            MMI22_list.append(cell)

            print 'cell name ' + str(cell.name)
            print '__________________________'

        return MMI22_list

    def _default_child_cells(self):
        child_cells = dict()
        for counter in range(0, 4, 1):
            print counter
            # child_cells['straight' + str(counter)] = self.WG1
            child_cells['taper' + str(counter)] = self.WG2

        for counter, child in enumerate(self.DC_list):
            print 'child number' + str(counter)
            child_cells['ring' + str(counter)] = child
            print 'child name ' + str(child.name)
            print child
        return child_cells

    def _default_links(self):
        links = [
            ("taper0:out", "ring0:in2"),
            ("taper1:out", "ring0:in1"),
            ("taper2:out", "ring0:out2"),
            ("taper3:out", "ring0:out1"),

        ]
        return links

    class Layout(PlaceAndAutoRoute.Layout):

        def _default_child_transformations(self):
            trans = dict()
            column = 10000
            # trans["dircoup1"] = (1650, 0)
            # trans["dircoup2"] = (4950, 0)
            # trans['mzi_22_22_0'] = (0, 0)
            trans['ring0'] = (1500, 0)
            # trans['ring1'] = (2500, 0 + column)
            # trans['ring2'] = (2500, 0 + 2 * column)
            # trans['ring3'] = (1500, 0 + 3 * column)

            trans["taper0"] = (0, 2500)
            trans["taper1"] = (0, -2500)
            trans["taper2"] = i3.Rotation(rotation=-90) + i3.Translation((2500, 5000))
            trans["taper3"] = i3.HMirror(0) + i3.Translation((4000, -5.5))


            return trans

        def _default_bend_radius(self):
            bend_radius = 300
            return bend_radius

        def _generate_elements(self, elems):
            for counter, child in enumerate(self.DC_list):
                name = child.name

                # elems += i3.PolygonText(layer=i3.TECH.PPLAYER.WG.TEXT,
                #                         text="{}_{}".format(name, self.cell.wg_t1.name),
                #                         # coordinate=(1300.0, 100.0),
                #                         alignment=(i3.TEXT_ALIGN_LEFT, i3.TEXT_ALIGN_LEFT),
                #                         font=2,
                #                         height=20.0,
                #                         transformation=i3.Translation((1500, 100 + 10000 * counter))
                #                         )

                # elems += i3.PolygonText(layer=i3.TECH.PPLAYER.WG.TEXT,
                #                         text="{} {}".format(name, self.cell.wg_t1.name),
                #                         # coordinate=(-2000, -150),
                #                         alignment=(i3.TEXT_ALIGN_LEFT, i3.TEXT_ALIGN_LEFT),
                #                         font=2,
                #                         height=200.0,
                #                         transformation=i3.Rotation((0.0, 0.0), 90.0)
                #                                        + i3.Translation((450+2900, -2000 + 10000 * counter))
                #                         )
                # for j in range (-1,2,1):
                #     for i in range(0,4,1):
                #         elems += i3.Rectangle(layer=i3.TECH.PPLAYER.WG.TEXT, center=(
                #                     100+j*6000, -3000+100+10000*i),box_size=(100, 100))
                #         elems += i3.Rectangle(layer=i3.TECH.PPLAYER.WG.TEXT, center=(
                #             100+j*6000, -3000 - 100 + 10000 * i), box_size=(100, 100))
                #     elems += i3.Rectangle(layer=i3.TECH.PPLAYER.WG.TEXT, center=(
                #         100+j*6000, -3000 + 100 + 6000 * 3+3000), box_size=(100, 100))
                #     elems += i3.Rectangle(layer=i3.TECH.PPLAYER.WG.TEXT, center=(
                #         100+j*6000, -3000 - 100 + 6000 * 3+3000), box_size=(100, 100))
                # elems += i3.Rectangle(layer=i3.TECH.PPLAYER.WG.TEXT, center=(
                #     300, -3000 + 100 + 6000 * 3 + 3000), box_size=(100, 100))
                # elems += i3.Rectangle(layer=i3.TECH.PPLAYER.WG.TEXT, center=(
                #     300, -3000 - 100 ), box_size=(100, 100))

            return elems
示例#21
0
class my_exe2(PlaceComponents):
    DC_list = i3.ChildCellListProperty(default=[])

    def _default_DC_list(self):
        MMI22_list = []

        dc_10 = my_dc(gap_inc_vec2=[110.0, 110.0, 110], name="ring1")
        # dc_10_layout = dc_10.Layout()
        # dc_10_layout.visualize(annotate=True)
        # dc_10_layout.write_gdsii("DC_V4.gds")
        #
        dc_15 = my_dc(gap_inc_vec2=[110.0, 110.0, 110], name="ring2")
        MMI22_list.append(dc_10)
        MMI22_list.append(dc_15)

        recess0 = NP(width=338, pocket=True, tilt=True)
        recess1 = NP(pillar=True)
        recess2 = NP_mmi12(width=330, pillar=True, pocket=False, tilt=False)
        recess3 = NP_mmi12(width=330, pillar=True, pocket=False, tilt=False)
        recess4 = NP_mmi12(width=330, pillar=True, pocket=True, tilt=False)
        recess5 = NP_mmi12(width=330, pillar=True, pocket=True, tilt=False)
        recess6 = NP_mmi12(width=330, pillar=True, pocket=True, tilt=True)
        recess7 = NP_mmi12(width=330, pillar=True, pocket=True, tilt=True)

        recess8 = NP(width=338, pillar=True, pocket=False, tilt=False)
        recess9 = NP(width=338, pillar=True, pocket=True, tilt=False)
        recess10 = NP_mmi12(width=338, pillar=True, pocket=False, tilt=False)
        recess11 = NP_mmi12(width=338, pillar=True, pocket=False, tilt=False)
        recess12 = NP_mmi12(width=338, pillar=True, pocket=True, tilt=False)
        recess13 = NP_mmi12(width=338, pillar=True, pocket=True, tilt=False)
        recess14 = NP_mmi12(width=338, pillar=True, pocket=True, tilt=True)
        recess15 = NP_mmi12(width=338, pillar=True, pocket=True, tilt=True)

        for i in range(0, 16, 1):
            print(i)
            _inst = locals()['recess{}'.format(i)]
            MMI22_list.append(_inst)

        #
        #
        # Al0 = AL_NP(width=338)
        # Al1 = AL_NP(width=338)
        # Al2 = AL_NP(width=338)
        # Al3 = AL_NP(pillar=True)
        # Al4 = AL_NP(pillar=True)
        # Al5 = AL_NP(pillar=True)
        # Al6 = AL_NP()
        # Al7 = AL_NP()
        # Al8 = AL_NP(width=338, pillar=True)
        # Al9 = AL_NP(width=338, pillar=True)
        # Al10 = AL_PI()
        # Al11 = AL_PI()
        #
        # for i in range(0, 12, 1):
        #     print(i)
        #     _inst = locals()['Al{}'.format(i)]
        #     MMI22_list.append(_inst)

        # SiN0 = SiN_NP(width=338)
        # SiN1 = SiN_NP(width=338)
        # SiN2 = SiN_NP(width=338, tilt_0=True)
        # SiN3 = SiN_NP(pillar=True)
        # SiN4 = SiN_NP(pillar=True)
        # SiN5 = SiN_NP(pillar=True, tilt_0=True)
        # SiN6 = SiN_NP()
        # SiN7 = SiN_NP()
        # SiN8 = SiN_NP(width=338, pillar=True)
        # SiN9 = SiN_NP(width=338, pillar=True)
        # SiN10 = SiN_PI()
        # SiN11 = SiN_PI()
        # for i in range(0, 12, 1):
        #     print(i)
        #     _inst = locals()['SiN{}'.format(i)]
        #     MMI22_list.append(_inst)

        return MMI22_list

    def _default_child_cells(self):
        child_cells = dict()
        for counter, child in enumerate(self.DC_list):
            print 'child number' + str(counter)
            child_cells['CHILD' + str(counter)] = child
            print 'child name ' + str(child.name)
            print child
        return child_cells

    class Layout(PlaceComponents.Layout):
        def _default_child_transformations(self):
            trans = dict()
            row = 3000
            trans["CHILD0"] = (0, 0)
            trans["CHILD1"] = i3.HMirror(2500) - i3.Translation((5000, 0))
            trans['CHILD2'] = (-15000, -5000)
            trans['CHILD3'] = (-15000, 0)
            trans['CHILD4'] = (-15000, 2000 + row * 1)
            trans['CHILD5'] = (-15000, 2000 + row * 2)
            trans['CHILD6'] = (-15000, 2000 + row * 3)
            trans['CHILD7'] = (-15000, 2000 + row * 4)
            trans['CHILD8'] = (-15000, 2000 + row * 5)
            trans['CHILD9'] = (-15000, 2000 + row * 6)
            trans['CHILD10'] = i3.Rotation(rotation=180) + i3.Translation(
                (15000, 0))
            trans['CHILD11'] = i3.Rotation(rotation=180) + i3.Translation(
                (15000, 5000))
            trans['CHILD12'] = i3.Rotation(rotation=180) + i3.Translation(
                (15000, 5000 + row * 1))
            trans['CHILD13'] = i3.Rotation(rotation=180) + i3.Translation(
                (15000, 5000 + row * 2))
            trans['CHILD14'] = i3.Rotation(rotation=180) + i3.Translation(
                (15000, 5000 + row * 3))
            trans['CHILD15'] = i3.Rotation(rotation=180) + i3.Translation(
                (15000, 5000 + row * 4))
            trans['CHILD16'] = i3.Rotation(rotation=180) + i3.Translation(
                (15000, 5000 + row * 5))
            trans['CHILD17'] = i3.Rotation(rotation=180) + i3.Translation(
                (15000, 5000 + row * 6))

            # trans['CHILD14'] = (-15000, 0 + row * -1)
            # trans['CHILD15'] = (-15000, 0 + row * 0)
            # trans['CHILD16'] = (-15000, 0 + row * 1)
            # trans['CHILD17'] = (-15000, 0 + row * 2)
            # trans['CHILD18'] = (-15000, 0 + row * 3)
            # trans['CHILD19'] = (-15000, 0 + row * 4)
            # trans['CHILD20'] = i3.Rotation(rotation=180) + i3.Translation((15000, 0 + row * 0))
            # trans['CHILD21'] = i3.Rotation(rotation=180) + i3.Translation((15000, 0 + row * 1))
            # trans['CHILD22'] = i3.Rotation(rotation=180) + i3.Translation((15000, 0 + row * 2))
            # trans['CHILD23'] = i3.Rotation(rotation=180) + i3.Translation((15000, 0 + row * 3))
            # trans['CHILD24'] = i3.Rotation(rotation=180) + i3.Translation((15000, 0 + row * 4))
            # trans['CHILD25'] = i3.Rotation(rotation=180) + i3.Translation((15000, 0 + row * 5))

            return trans

        def _generate_elements(self, elems):
            elems += i3.Rectangle(
                layer=i3.TECH.PPLAYER.NONE.DOC,
                center=(0, 9000),  # change
                box_size=(200, 28000))

            # generated1 = i3.TECH.PPLAYER.HFW - i3.TECH.PPLAYER.NONE.DOC
            # mapping = {generated1: i3.TECH.PPLAYER.HFW}
            # elems = i3.get_elements_for_generated_layers(elems, mapping)
            return elems
示例#22
0
class Lspiral(PlaceAndAutoRoute):
    rectV_list = i3.ChildCellListProperty(default=[])
    rectH_list = i3.ChildCellListProperty(default=[])
    gap_inc_vec = i3.ListProperty(default=[], doc="Length of MMI")
    gap_inc_vec2 = i3.ListProperty(default=[], doc="length of 12mmi")
    WG1 = i3.ChildCellProperty(doc="", locked=True)
    WG2 = i3.ChildCellProperty()
    wg_t1 = i3.WaveguideTemplateProperty(doc="board WG")
    wg_t2 = i3.WaveguideTemplateProperty(doc="change WG")
    # mmi_trace_template = i3.WaveguideTemplateProperty()
    # mmi_access_template = i3.WaveguideTemplateProperty()
    width = i3.PositiveNumberProperty(doc="width of ports", default=15)
    # cleave = i3.PositiveNumberProperty(doc="tolerance", default=150)
    offset = i3.NumberProperty(doc="count", default=0)

    def _default_wg_t1(self):
        wg_t1 = WireWaveguideTemplate(name="port20")
        wg_t1.Layout(
            core_width=20,
            cladding_width=20 + 2 * 12.0,
        )
        return wg_t1

    def _default_wg_t2(self):
        wg_t2 = WireWaveguideTemplate(
            name="port_{}_{}".format(str(self.width), str(self.offset)))
        wg_t2.Layout(
            core_width=self.width,
            cladding_width=self.width + 2 * 12.0,
        )
        return wg_t2

    def _default_trace_template(self):
        wg_sm = WireWaveguideTemplate(name="sm_template")
        wg_sm.Layout(core_width=3.8, cladding_width=3.8 + 2 * 12.0)
        return wg_sm

    def _default_WG1(self):
        WG1 = i3.Waveguide(name="straight{}".format(str(self.width)),
                           trace_template=self.wg_t1)
        WG1.Layout(shape=[(-200.0, 0.0), (600.0, 0.0)])
        return WG1

    def _default_WG2(self):
        Port = AutoTransitionPorts(name="ports{}".format(str(self.width)),
                                   contents=self.WG1,
                                   port_labels=["out"],
                                   trace_template=self.wg_t2)
        Port.Layout(transition_length=300)  # .visualize(annotate=True)
        return Port

    # def _default_mmi_trace_template(self):
    #     mmi_trace_template = WireWaveguideTemplate(name="MMI_tt")
    #     mmi_trace_template.Layout(core_width=20.0, cladding_width=20.0 + 2 * 12)  # MMI_width
    #     return mmi_trace_template
    #
    # def _default_mmi_access_template(self):
    #     mmi_access_template = WireWaveguideTemplate(name="MMI_at")
    #     mmi_access_template.Layout(core_width=9.0, cladding_width=9.0 + 2 * 12)
    #     return mmi_access_template

    def _default_rectH_list(self):

        MMI22_list = []
        for l in range(0, 5, 1):

            cell = i3.Waveguide(name="rectH{}_{}".format(
                str(l), str(self.offset)),
                                trace_template=self.wg_t2)
            cell.Layout(shape=[(0.0, 0.0), (17000 - 4000 * l, 0.0)])
            # cell = i3.Waveguide(name="rectV{}".format(str(l)),
            #                     trace_template=self.wg_t2)
            # cell.Layout(shape=[(18000 - 4000 * l, 0.0), (0.0, 0.0)])

            MMI22_list.append(cell)

        return MMI22_list

    def _default_rectV_list(self):
        print '____________ MMI 2x2 ______________'
        MMI22_list2 = []
        for l in range(0, 5, 1):

            # cell = i3.Waveguide(name="rectH{}".format(str(l)),
            #                    trace_template=self.wg_t2)
            # cell.Layout(shape=[(0.0, 0.0), (18000-4000*l, 0.0)])
            cell = i3.Waveguide(name="rectV{}_{}".format(
                str(l), str(self.offset)),
                                trace_template=self.wg_t2)
            cell.Layout(shape=[(0.0, 0.0), (0.0, -1000 - 4000 * l)])

            MMI22_list2.append(cell)

        return MMI22_list2

    def _default_child_cells(self):
        child_cells = dict()
        for counter in range(0, 5, 1):
            print counter
            # child_cells['straight' + str(counter)] = self.WG1
            child_cells['taperH' + str(counter)] = self.WG2
            child_cells['taperV' + str(counter)] = self.WG2

        for counter, child in enumerate(self.rectH_list):
            print 'child number' + str(counter)
            child_cells['recH' + str(counter)] = child
            print 'child name ' + str(child.name)

        for counter, child in enumerate(self.rectV_list):
            print 'child number' + str(counter)
            child_cells['recV' + str(counter)] = child
            print 'child name ' + str(child.name)

        return child_cells

    def _default_links(self):
        links = [
            ("recH0:out", "recV4:out"),
            ("recH1:out", "recV3:out"),
            ("recH2:out", "recV2:out"),
            ("recH3:out", "recV1:out"),
            ("recH4:out", "recV0:out"),
        ]
        return links

    class Layout(PlaceAndAutoRoute.Layout):
        def _default_child_transformations(self):
            trans = dict()
            column = 4000
            # trans['ring0'] = (600, 0)
            # trans['ring1'] = (600, 1 * column)
            # trans['ring2'] = (600, 2 * column)
            # # trans['ring3'] = (1300, 8000 + 2 * column )

            for i in range(0, 5, 1):
                trans["taperH{}".format(i)] = (0,
                                               column * i + 100 * self.offset)
                trans["taperV{}".format(i)] = i3.Rotation(
                    rotation=-90) + i3.Translation(
                        (4000 + column * i - 100 * self.offset, 20000))
                trans["recH{}".format(i)] = (900,
                                             column * i + 100 * self.offset)
                trans["recV{}".format(i)] = (4000 + column * i -
                                             100 * self.offset, 20000 - 900)
            # trans["taper0"] = (0, 0)
            # trans["taper1"] = i3.HMirror(0) + i3.Translation((2500, -1500))
            # trans["taper2"] = i3.HMirror(0) + i3.Translation((2500, 1500))
            #
            # trans["taper3"] = (0, 1 * column)
            # trans["taper4"] = i3.HMirror(0) + i3.Translation((2500, -1500 + 1 * column))
            #
            # trans["taper5"] = i3.HMirror(0) + i3.Translation((2500, 1500 + 1 * column))
            #
            # trans["taper6"] = (0, 2 * column)
            # trans["taper7"] = i3.HMirror(0) + i3.Translation((2500, -1500 + 2 * column))
            # trans["taper8"] = i3.HMirror(0) + i3.Translation((2500, 1500 + 2 * column))
            #
            # trans["taper9"] = (0, 3800 + 2 * column)
            #
            # trans["taper10"] = i3.HMirror(0) + i3.Translation((2500, -1500 + 3 * column))
            # # trans["taper11"] = i3.HMirror(0) + i3.Translation((3000, 6500+ 2 * column))
            # # trans["taper12"] = i3.HMirror(0) + i3.Translation((3000, 9500+ 2 * column))

            return trans

        def _default_bend_radius(self):
            bend_radius = 500
            return bend_radius

        def _generate_elements(self, elems):

            for i in range(0, 5, 1):
                elems += i3.PolygonText(
                    layer=i3.TECH.PPLAYER.WG.TEXT,
                    text="WITDH={}_length={}*2_R=500".format(
                        str(self.width), 17000 - 4000 * i),
                    coordinate=(900, 55 + 4000 * i + 100 * self.offset),
                    font=2,
                    height=20.0,
                )
                for j in range(0, 13, 1):
                    elems += i3.PolygonText(
                        layer=i3.TECH.PPLAYER.WG.TEXT,
                        text="{}_{}".format(str(i), str(j)),
                        coordinate=(550, 63 + 4000 * i + 100 * j),
                        font=2,
                        height=30.0,
                    )
                    elems += i3.PolygonText(
                        layer=i3.TECH.PPLAYER.WG.TEXT,
                        text="{}_{}".format(str(i), str(j)),
                        # coordinate=(),
                        font=2,
                        height=30.0,
                        transformation=i3.Rotation(rotation=-90) +
                        i3.Translation(
                            (20000 - 4000 * i - 100 * j + 63, 20000 - 550)),
                    )
            for i in range(0, 6, 1):
                elems += i3.Rectangle(layer=i3.TECH.PPLAYER.WG.TEXT,
                                      center=(100, 4000 * i - 1000 + 700),
                                      box_size=(100, 100))
                elems += i3.Rectangle(layer=i3.TECH.PPLAYER.WG.TEXT,
                                      center=(300, 4000 * i - 1000 + 700),
                                      box_size=(100, 100))
                elems += i3.Rectangle(layer=i3.TECH.PPLAYER.WG.TEXT,
                                      center=(4000 * i + 300, 19700),
                                      box_size=(100, 100))
                elems += i3.Rectangle(layer=i3.TECH.PPLAYER.WG.TEXT,
                                      center=(4000 * i + 300, 19900),
                                      box_size=(100, 100))
            elems += i3.Rectangle(layer=i3.TECH.PPLAYER.WG.TEXT,
                                  center=(100, 19900),
                                  box_size=(100, 100))
            elems += i3.Rectangle(layer=i3.TECH.PPLAYER.WG.TEXT,
                                  center=(-100, 19900),
                                  box_size=(100, 100))
            elems += i3.Rectangle(layer=i3.TECH.PPLAYER.WG.TEXT,
                                  center=(500, 19900),
                                  box_size=(100, 100))
            elems += i3.Rectangle(layer=i3.TECH.PPLAYER.WG.TEXT,
                                  center=(100, 19500),
                                  box_size=(100, 100))
            elems += i3.Rectangle(layer=i3.TECH.PPLAYER.WG.TEXT,
                                  center=(100, 20100),
                                  box_size=(100, 100))
            elems += i3.Rectangle(layer=i3.TECH.PPLAYER.WG.TEXT,
                                  center=(-100, -500),
                                  box_size=(100, 100))
            elems += i3.Rectangle(layer=i3.TECH.PPLAYER.WG.TEXT,
                                  center=(100, -500),
                                  box_size=(100, 100))
            elems += i3.Rectangle(layer=i3.TECH.PPLAYER.WG.TEXT,
                                  center=(300, -500),
                                  box_size=(100, 100))
            elems += i3.Rectangle(layer=i3.TECH.PPLAYER.WG.TEXT,
                                  center=(500, -500),
                                  box_size=(100, 100))
            elems += i3.Rectangle(layer=i3.TECH.PPLAYER.WG.TEXT,
                                  center=(20500, 19500),
                                  box_size=(100, 100))
            elems += i3.Rectangle(layer=i3.TECH.PPLAYER.WG.TEXT,
                                  center=(20500, 19700),
                                  box_size=(100, 100))
            elems += i3.Rectangle(layer=i3.TECH.PPLAYER.WG.TEXT,
                                  center=(20500, 19900),
                                  box_size=(100, 100))
            elems += i3.Rectangle(layer=i3.TECH.PPLAYER.WG.TEXT,
                                  center=(20500, 20100),
                                  box_size=(100, 100))

            return elems