示例#1
0
class EulerBend(i3.PCell):
    """ An Euler Bend for IPKISS """

    _name_prefix = "EULER_BEND"

    trace_template = i3.WaveguideTemplateProperty(
        doc="trace template for the waveguide"
    )
    def _default_trace_template(self):
        return i3.TECH.PCELLS.WG.DEFAULT

    waveguide = i3.ChildCellProperty(doc="waveguide")
    def _default_waveguide(self):
        return i3.RoundedWaveguide(trace_template=self.trace_template)

    class Layout(i3.LayoutView):
        """ Layout for the IPKISS Euler Bend """

        min_radius = i3.PositiveNumberProperty(doc="minimum Euler bend radius")
        def _default_min_radius(self):
            if self.end_point is None:
                return 10
            x, y = self.end_point
            # the final angle is twice the angle between start and finish.
            theta = 2 * np.arctan2(y, x)  
            x_final = _euler_bend_center_line_shape(R=1, theta=theta, num_points=4)[-1][0]
            return x / x_final

        end_angle = i3.PositiveNumberProperty(doc="angle (in degrees) at the end of the Euler bend.")
        def _default_end_angle(self):
            if self.end_point is None:
                return 90
            x, y = self.end_point
            return 2 * np.arctan2(y, x) * i3.RAD2DEG

        num_points = i3.PositiveNumberProperty(
            doc="resolution of the euler bend shape.",
            default=1000,
        )

        end_point = i3.Coord2Property(
            doc=(
                "(optional) coordinates of the end of the Euler bend.\n"
                "if given, this will override `min_radius` and `end_angle`."
            ),
            default=None,
        )
        
        core_width = i3.PositiveNumberProperty(
            doc="default core width of the waveguide",
            default=i3.TECH.WG.WIRE_WIDTH,
        )
        
        cladding_width = i3.PositiveNumberProperty(
            doc="default cladding width of the waveguide",
            default=i3.TECH.WG.CLADDING_WIDTH,
        )

        def _default_trace_template(self):
            trace = self.cell.trace_template.get_default_view(i3.LayoutView)
            trace.set(
                core_width=self.core_width,
                cladding_width=self.cladding_width,
            )
            return trace

        def _default_waveguide(self):
            waveguide = self.cell.waveguide.get_default_view(i3.LayoutView)
            center_line = _euler_bend_center_line_shape(
                R=self.min_radius,
                theta=self.end_angle * i3.DEG2RAD,
                num_points=self.num_points,
            )
            waveguide.set(
                shape=center_line,
                trace_template=self.trace_template,
                bend_radius=self.min_radius,
            )
            return waveguide

        def _generate_instances(self, insts):
            insts += i3.SRef(reference=self.waveguide)
            return insts
        
        def _generate_ports(self, ports):
            ports += self.waveguide.ports
            return ports
示例#2
0
class v8(PlaceAndAutoRoute):
    wg_t1 = i3.WaveguideTemplateProperty()
    wg_sm = i3.WaveguideTemplateProperty()
    mmi_trace_template = i3.WaveguideTemplateProperty()
    mmi_access_template = i3.WaveguideTemplateProperty()
    WGSM = i3.ChildCellProperty()
    widtha = i3.PositiveNumberProperty(doc="width of ports", default=15)

    mmi22 = i3.ChildCellProperty()
    WG1 = i3.ChildCellProperty()
    WG2 = i3.ChildCellProperty()
    #
    # start_id = None
    start_id = i3.PositiveNumberProperty(doc="name", default=1)
    # start_id = current_id
    param_num = 5

    def _default_links(self):
        links = [
            ("MMI1b:out2", "WGuptaper2:out"),
            ("MMI1b:out1", "WGdowntaper2:out"),
            # ("MMI1b:out","MMI1a:in"),
            ("WGuptaper:out", "MMI1b:in2"),
            ("WGdowntaper:out", "MMI1b:in1"),
            ("DWGuptaper:out", "DWGuptaper2:out"),
            ("DWGdowntaper:out", "dummy1:in"),
            ("DWGdowntaper2:out", "dummy1:out")
        ]
        return links

    def _default_child_cells(self):
        child_cells = {
            "dummy1": self.WGSM,
            "MMI1b": self.mmi22,
            "WGup": self.WG1,
            "WGdown": self.WG1,
            "WGup2": self.WG1,
            "WGdown2": self.WG1,
            "WGuptaper": self.WG2,
            "WGdowntaper": self.WG2,
            "WGuptaper2": self.WG2,
            "WGdowntaper2": self.WG2,
            "DWGup": self.WG1,
            "DWGdown": self.WG1,
            "DWGup2": self.WG1,
            "DWGdown2": self.WG1,
            "DWGuptaper": self.WG2,
            "DWGdowntaper": self.WG2,
            "DWGuptaper2": self.WG2,
            "DWGdowntaper2": self.WG2
        }
        return child_cells

    def _default_trace_template(self):
        trace_template = self.wg_sm
        return trace_template

    def _default_mmi22(self):
        mmi22 = 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.wg_sm,
        )
        return mmi22

    def _default_WG2(self):
        WG2 = WireWaveguideTransitionLinear(
            name="Dongbo{}".format(str(self.start_id)),
            start_trace_template=self.wg_t1,
            end_trace_template=self.wg_sm,
        )
        return WG2

    def _default_WG1(self):
        WG1 = i3.Waveguide(name="Dongbo{}".format(str(self.start_id + 1)),
                           trace_template=self.wg_t1)
        return WG1

    def _default_wg_t1(self):
        wg_t1 = WireWaveguideTemplate(name="port_{}".format(str(self.widtha)))
        wg_t1.Layout(core_width=self.widtha,
                     cladding_width=self.widtha + 16.0,
                     core_process=i3.TECH.PROCESS.WG)
        return wg_t1

    def _default_wg_sm(self):
        wg_sm = WireWaveguideTemplate(
            name="dongbo{}".format(str(self.start_id + 3)))
        wg_sm.Layout(core_width=3.8, cladding_width=3.8 + 16.0)
        return wg_sm

    def _default_WGSM(self):
        WGSM = i3.Waveguide(name="SM", trace_template=self.trace_template)

        return WGSM

    def _default_mmi_trace_template(self):
        mmi_trace_template = WireWaveguideTemplate(
            name="dongbo{}".format(str(self.start_id + 4)))
        mmi_trace_template.Layout(core_width=20.0,
                                  cladding_width=20.0 + 16.0)  # MMI_width
        return mmi_trace_template

    def _default_mmi_access_template(self):
        mmi_access_template = WireWaveguideTemplate(
            name="dongbo{}".format(str(self.start_id + 5)))
        mmi_access_template.Layout(core_width=9.0, cladding_width=9.0 + 16.0)
        return mmi_access_template

    class Layout(PlaceAndAutoRoute.Layout):
        length = i3.PositiveNumberProperty(doc="MMI length", default=398)

        # width = i3.PositiveNumberProperty(doc="width of ports", default=15)

        # def _default_wg_t1(self):
        #     layout_wg_t1 = self.cell.wg_t1.get_default_view(i3.LayoutView)
        #     layout_wg_t1.set(core_width=self.width,
        #                      cladding_width=self.width + 16.0,
        #                      core_process=i3.TECH.PROCESS.WG)
        #     return layout_wg_t1

        def _default_WG1(self):
            layout_WG1 = self.cell.WG1.get_default_view(i3.LayoutView)
            layout_WG1.set(shape=[(0.0, 0.0), (150.0, 0.0)])
            return layout_WG1

        def _default_WG2(self):
            layout_WG2 = self.cell.WG2.get_default_view(i3.LayoutView)
            layout_WG2.set(start_position=(150.0, 0.0),
                           end_position=(450.0, 0.0))
            return layout_WG2

        def _default_WGSM(self):
            layout_WGSM = self.cell.WGSM.get_default_view(i3.LayoutView)
            layout_WGSM.set(shape=[(0.0, 0.0), (400.0, 0.0)])
            return layout_WGSM

        def _default_mmi22(self):
            layout_mmi22 = self.cell.mmi22.get_default_view(i3.LayoutView)
            layout_mmi22.set(name="MMI22_l_{}".format(str(self.length)),
                             transition_length=200.0,
                             length=self.length,
                             trace_spacing=11.0)
            return layout_mmi22

        def _default_child_transformations(self):
            child_transformations = {
                "MMI1b": (1300, 0),
                "WGup": (0, 4000),
                "WGuptaper": (0, 4000),
                "WGdown": (0, -4000),
                "WGdowntaper": (0, -4000),
                "WGuptaper2": i3.HMirror() + i3.Translation((3000, 2000)),
                "WGdowntaper2": i3.HMirror() + i3.Translation((3000, -6000)),
                "WGup2": (2850, 2000),
                "WGdown2": (2850, -6000),
                "dummy1": (1300, -300),
                "DWGup": (0, 20900),
                "DWGuptaper": (0, 20900),
                "DWGdown": (0, -4300),
                "DWGdowntaper": (0, -4300),
                "DWGuptaper2": i3.HMirror() + i3.Translation((3000, 20900)),
                "DWGdowntaper2": i3.HMirror() + i3.Translation((3000, -6300)),
                "DWGup2": (2850, 20900),
                "DWGdown2": (2850, -6300)
            }
            return child_transformations

        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)

            return elems
示例#3
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
示例#4
0
class StraightWgLossEbeam(PlaceAndAutoRoute):
    taper = i3.ChildCellProperty()
    wg = i3.ChildCellProperty()
    wg_right = i3.ChildCellProperty()
    expanded_wg = i3.ChildCellProperty()
    trace_template = i3.WaveguideTemplateProperty()
    expanded_wg_template = i3.WaveguideTemplateProperty()
    gc_taper = i3.ChildCellProperty()
    gc_slab = i3.ChildCellProperty()
    gc_slab_template = i3.WaveguideTemplateProperty()
    wg_SM_template = i3.WaveguideTemplateProperty()
    wg_SM = i3.ChildCellProperty()
    taper_expanded_wg2wg_SM = i3.ChildCellProperty()

    wg_width = i3.PositiveNumberProperty(default=2.0)
    trench_width = i3.PositiveNumberProperty(default=3.0)
    _wg_width_indesign = i3.PositiveNumberProperty()
    expanded_wg_width = i3.PositiveNumberProperty(default=3.0)
    _expanded_wg_width_indesign = i3.PositiveNumberProperty()
    gc_slab_width = i3.PositiveNumberProperty(default=10.0)
    wg_SM_width = i3.PositiveNumberProperty(default=0.5)

    def _default__wg_width_indesign(self):
        return self.wg_width

    def _default__expanded_wg_width_indesign(self):
        return self.expanded_wg_width

    def _default_trace_template(self):
        wstart1 = PathTraceWindow(layer=i3.TECH.PPLAYER.WG.CORE,
                                  start_offset=-self.wg_width * 0.5,
                                  end_offset=self.wg_width * 0.5)
        wstart2 = PathTraceWindow(
            layer=i3.TECH.PPLAYER.WG.CLADDING,
            start_offset=-(self.wg_width + self.trench_width) * 0.5,
            end_offset=-(self.wg_width + self.trench_width) * 0.5,
            line_width=0)
        wstart3 = PathTraceWindow(
            layer=i3.TECH.PPLAYER.WG.CLADDING,
            start_offset=(self.wg_width + self.trench_width) * 0.5,
            end_offset=(self.wg_width + self.trench_width) * 0.5,
            line_width=0)
        wg_t = i3.WindowWaveguideTemplate()
        wg_t.Layout(windows=[wstart1, wstart2, wstart3])
        return wg_t

    def _default_expanded_wg_template(self):
        wstart1 = PathTraceWindow(layer=i3.TECH.PPLAYER.WG.CORE,
                                  start_offset=-self.expanded_wg_width * 0.5,
                                  end_offset=self.expanded_wg_width * 0.5)
        wstart2 = PathTraceWindow(
            layer=i3.TECH.PPLAYER.WG.CLADDING,
            start_offset=-(self.expanded_wg_width + self.trench_width) * 0.5,
            end_offset=-(self.expanded_wg_width + self.trench_width) * 0.5,
            line_width=0)
        wstart3 = PathTraceWindow(
            layer=i3.TECH.PPLAYER.WG.CLADDING,
            start_offset=(self.expanded_wg_width + self.trench_width) * 0.5,
            end_offset=(self.expanded_wg_width + self.trench_width) * 0.5,
            line_width=0)
        expanded_wg_template = i3.WindowWaveguideTemplate()
        expanded_wg_template.Layout(windows=[wstart1, wstart2, wstart3])
        return expanded_wg_template

    def _default_wg(self):
        wg = i3.RoundedWaveguide(trace_template=self.trace_template)
        return wg

    def _default_wg_right(self):
        wg_right = i3.RoundedWaveguide(trace_template=self.trace_template)
        return wg_right

    def _default_expanded_wg(self):
        expanded_wg = i3.RoundedWaveguide(
            trace_template=self.expanded_wg_template)
        return expanded_wg

    def _default_taper(self):
        taper = i3.LinearWindowWaveguideTransition(
            start_trace_template=self.trace_template,
            end_trace_template=self.expanded_wg_template)
        return taper

    def _default_gc_slab_template(self):
        wstart1 = PathTraceWindow(layer=i3.TECH.PPLAYER.WG.CORE,
                                  start_offset=-self.gc_slab_width * 0.5,
                                  end_offset=self.gc_slab_width * 0.5)
        wstart2 = PathTraceWindow(
            layer=i3.TECH.PPLAYER.WG.CLADDING,
            start_offset=-(self.gc_slab_width + self.trench_width) * 0.5,
            end_offset=-(self.gc_slab_width + self.trench_width) * 0.5,
            line_width=0)
        wstart3 = PathTraceWindow(
            layer=i3.TECH.PPLAYER.WG.CLADDING,
            start_offset=(self.gc_slab_width + self.trench_width) * 0.5,
            end_offset=(self.gc_slab_width + self.trench_width) * 0.5,
            line_width=0)
        wg_t = i3.WindowWaveguideTemplate()
        wg_t.Layout(windows=[wstart1, wstart2, wstart3])
        return wg_t

    def _default_gc_taper(self):
        taper = i3.LinearWindowWaveguideTransition(
            start_trace_template=self.wg_SM_template,
            end_trace_template=self.gc_slab_template)
        return taper

    def _default_gc_slab(self):
        slab = i3.RoundedWaveguide(trace_template=self.gc_slab_template)
        return slab

    def _default_wg_SM_template(self):
        wstart1 = PathTraceWindow(layer=i3.TECH.PPLAYER.WG.CORE,
                                  start_offset=-self.wg_SM_width * 0.5,
                                  end_offset=self.wg_SM_width * 0.5)
        wstart2 = PathTraceWindow(
            layer=i3.TECH.PPLAYER.WG.CLADDING,
            start_offset=-(self.wg_SM_width + self.trench_width) * 0.5,
            end_offset=-(self.wg_SM_width + self.trench_width) * 0.5,
            line_width=0)
        wstart3 = PathTraceWindow(
            layer=i3.TECH.PPLAYER.WG.CLADDING,
            start_offset=(self.wg_SM_width + self.trench_width) * 0.5,
            end_offset=(self.wg_SM_width + self.trench_width) * 0.5,
            line_width=0)
        wg_t = i3.WindowWaveguideTemplate()
        wg_t.Layout(windows=[wstart1, wstart2, wstart3])
        return wg_t

    def _default_wg_SM(self):
        wg = i3.RoundedWaveguide(trace_template=self.wg_SM_template)
        return wg

    def _default_taper_expanded_wg2wg_SM(self):
        taper = i3.LinearWindowWaveguideTransition(
            start_trace_template=self.expanded_wg_template,
            end_trace_template=self.wg_SM_template)
        return taper

    def _default_child_cells(self):
        child_cells = dict()
        child_cells["taper_left"] = self.taper
        child_cells["taper_right"] = self.taper
        child_cells["wg_left"] = self.wg
        child_cells["wg_right"] = self.wg_right
        child_cells["expanded_wg_left"] = self.expanded_wg
        child_cells["expanded_wg_right"] = self.expanded_wg
        child_cells[
            "taper_expanded_wg2wg_SM_left"] = self.taper_expanded_wg2wg_SM
        child_cells["wg_SM_left"] = self.wg_SM
        child_cells["wg_SM_right"] = self.wg_SM
        child_cells[
            "taper_expanded_wg2wg_SM_right"] = self.taper_expanded_wg2wg_SM
        child_cells["gc_taper_left"] = self.gc_taper
        child_cells["gc_taper_right"] = self.gc_taper
        child_cells["gc_slab_left"] = self.gc_slab
        child_cells["gc_slab_right"] = self.gc_slab
        return child_cells

    def _default_external_port_names(self):
        ports = dict()
        ports["expanded_wg_right:out"] = "in"
        ports["expanded_wg_left:out"] = "out"
        return ports

    class Layout(PlaceAndAutoRoute.Layout):
        spiral_width = i3.PositiveNumberProperty(
            doc="total width of spiral structure", default=6000.0)
        right_wg_length = i3.PositiveNumberProperty(
            doc="length of narrow wg on the right side of spiral",
            default=500.0)
        expanded_wg_length = i3.PositiveNumberProperty(default=1000.0)
        taper_length = i3.PositiveNumberProperty(default=100.0)
        bend_radius = i3.PositiveNumberProperty(default=100.0)
        gc_taper_length = i3.PositiveNumberProperty(default=300.0)
        gc_slab_length = i3.PositiveNumberProperty(default=50.0)
        wg_SM_length = i3.PositiveNumberProperty(default=50.0)

        def _default_wg(self):
            wg_lo = self.cell.wg.get_default_view(i3.LayoutView)
            wg_lo.set(shape=[(0.0, 0.0), (self.spiral_width, 0)])
            return wg_lo

        def _default_wg_right(self):
            wg_right_lo = self.cell.wg_right.get_default_view(i3.LayoutView)
            wg_right_lo.set(shape=[(0.0, 0.0), (self.right_wg_length, 0)])
            return wg_right_lo

        def _default_taper(self):
            taper_lo = self.cell.taper.get_default_view(i3.LayoutView)
            taper_lo.set(start_position=(0.0, 0.0),
                         end_position=(self.taper_length, 0.0))
            return taper_lo

        def _default_expanded_wg(self):
            expanded_wg_lo = self.cell.expanded_wg.get_default_view(
                i3.LayoutView)
            expanded_wg_lo.set(shape=[(0.0, 0.0), (self.expanded_wg_length,
                                                   0.0)])
            return expanded_wg_lo

        def _default_gc_taper(self):
            gc_taper_lo = self.cell.gc_taper.get_default_view(i3.LayoutView)
            gc_taper_lo.set(start_position=(0.0, 0.0),
                            end_position=(self.gc_taper_length, 0.0))
            return gc_taper_lo

        def _default_gc_slab(self):
            slab_lo = self.cell.gc_slab.get_default_view(i3.LayoutView)
            slab_lo.set(shape=[(0.0, 0.0), (self.gc_slab_length, 0.0)])
            return slab_lo

        def _default_wg_SM(self):
            wg_lo = self.cell.wg_SM.get_default_view(i3.LayoutView)
            wg_lo.set(shape=[(0.0, 0.0), (self.wg_SM_length, 0)])
            return wg_lo

        def _default_taper_expanded_wg2wg_SM(self):
            taper_lo = self.cell.taper_expanded_wg2wg_SM.get_default_view(
                i3.LayoutView)
            taper_lo.set(start_position=(0.0, 0.0),
                         end_position=(self.taper_length, 0.0))
            return taper_lo

        def _default_child_transformations(self):
            trans = dict()
            trans["wg_right"] = (0.0, 0.0)
            trans["taper_right"] = i3.Translation((self.right_wg_length, 0))

            start_x_expanded_wg_right = self.right_wg_length + self.taper_length
            trans["expanded_wg_right"] = i3.Translation(
                (start_x_expanded_wg_right, 0))

            start_x_taper_wg_SM2expanded_wg_right = start_x_expanded_wg_right + self.expanded_wg_length
            trans["taper_expanded_wg2wg_SM_right"] = i3.Translation(
                (start_x_taper_wg_SM2expanded_wg_right, 0.0))

            start_x_wg_SM_right = start_x_taper_wg_SM2expanded_wg_right + self.taper_length
            trans["wg_SM_right"] = i3.Translation((start_x_wg_SM_right, 0.0))

            start_x_gc_taper_right = start_x_wg_SM_right + self.wg_SM_length
            trans["gc_taper_right"] = i3.Translation(
                (start_x_gc_taper_right, 0))

            start_x_gc_slab_right = start_x_gc_taper_right + self.gc_taper_length
            trans["gc_slab_right"] = i3.Translation((start_x_gc_slab_right, 0))

            trans["wg_left"] = i3.HMirror(mirror_plane_x=0.0)
            trans["taper_left"] = i3.HMirror(
                mirror_plane_x=0.0) + i3.Translation((-self.spiral_width, 0))

            start_x_expanded_wg_left = -self.spiral_width - self.taper_length
            trans["expanded_wg_left"] = i3.HMirror(
                mirror_plane_x=0.0) + i3.Translation(
                    (start_x_expanded_wg_left, 0))

            start_x_taper_expanded_wg2wg_SM_left = start_x_expanded_wg_left - self.expanded_wg_length
            trans["taper_expanded_wg2wg_SM_left"] = i3.HMirror(
                mirror_plane_x=0.0) + i3.Translation(
                    (start_x_taper_expanded_wg2wg_SM_left, 0))

            start_x_wg_SM_left = start_x_taper_expanded_wg2wg_SM_left - self.taper_length
            trans["wg_SM_left"] = i3.HMirror(
                mirror_plane_x=0.0) + i3.Translation((start_x_wg_SM_left, 0))

            start_x_gc_taper_left = start_x_wg_SM_left - self.wg_SM_length
            trans["gc_taper_left"] = i3.HMirror(
                mirror_plane_x=0.0) + i3.Translation(
                    (start_x_gc_taper_left, 0))

            start_x_gc_slab_left = start_x_gc_taper_left - self.gc_taper_length
            trans["gc_slab_left"] = i3.HMirror(
                mirror_plane_x=0.0) + i3.Translation((start_x_gc_slab_left, 0))

            return trans

        def get_true_length(self):
            return self.spiral_width + self.right_wg_length
示例#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=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)

    # 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 = MMI2112(name='DC_gap_2_l_' + str(dl) + str(self.length),
                           start_id=dl + self.length)
            cell.Layout(gap=self.gap_inc_vec[l], length=self.length)

            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, 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:MMI1b_out2"),
                 ("taper1:out", "ring0:MMI1a_in1"),
                 ("taper2:out", "ring0:MMI1b_in2"),
                 ("taper3:out", "ring0:MMI1a_out1"),
                 ("taper4:out", "ring0:MMI1b_out1"),
                 ("taper5:out", "ring0:MMI1a_in2"),
                 ("taper6:out", "ring1:MMI1b_out2"),
                 ("taper7:out", "ring1:MMI1a_in1"),
                 ("taper8:out", "ring1:MMI1b_in2"),
                 ("taper9:out", "ring1:MMI1a_out1"),
                 ("taper10:out", "ring1:MMI1b_out1"),
                 ("taper11:out", "ring1:MMI1a_in2"),
                 ("taper12:out", "ring2:MMI1b_out2"),
                 ("taper13:out", "ring2:MMI1a_in1"),
                 ("taper14:out", "ring2:MMI1b_in2"),
                 ("taper15:out", "ring2:MMI1a_out1"),
                 ("taper16:out", "ring2:MMI1b_out1"),
                 ("taper17:out", "ring2:MMI1a_in2"),
                 ("taper18:out", "ring3:MMI1b_out2"),
                 ("taper19:out", "ring3:MMI1a_in1"),
                 ("taper20:out", "ring3:MMI1b_in2"),
                 ("taper21:out", "ring3:MMI1a_out1"),
                 ("taper22:out", "ring3:MMI1b_out1"),
                 ("taper23:out", "ring3:MMI1a_in2")]
        return links

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

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

            trans["taper6"] = (0, 4000 + column)
            trans["taper7"] = (0, -4000 + column)
            trans["taper8"] = i3.HMirror(0) + i3.Translation(
                (3000, 3500 + column))
            trans["taper9"] = i3.HMirror(0) + i3.Translation(
                (3000, -3500 + column))
            trans["taper10"] = i3.HMirror(0) + i3.Translation(
                (3000, 1500 + column))
            trans["taper11"] = i3.HMirror(0) + i3.Translation(
                (3000, 1000 + column))
            trans["taper12"] = (0, 4000 + 2 * column)
            trans["taper13"] = (0, -4000 + 2 * column)
            trans["taper14"] = i3.HMirror(0) + i3.Translation(
                (3000, 3500 + 2 * column))
            trans["taper15"] = i3.HMirror(0) + i3.Translation(
                (3000, -3500 + 2 * column))
            trans["taper16"] = i3.HMirror(0) + i3.Translation(
                (3000, 1500 + 2 * column))
            trans["taper17"] = i3.HMirror(0) + i3.Translation(
                (3000, 1000 + 2 * column))
            trans["taper18"] = (0, 4000 + 3 * column)
            trans["taper19"] = (0, -4000 + 3 * column)
            trans["taper20"] = i3.HMirror(0) + i3.Translation(
                (3000, 3500 + 3 * column))
            trans["taper21"] = i3.HMirror(0) + i3.Translation(
                (3000, -3500 + 3 * column))
            trans["taper22"] = i3.HMirror(0) + i3.Translation(
                (3000, 1500 + 3 * column))
            trans["taper23"] = i3.HMirror(0) + i3.Translation(
                (3000, 1000 + 3 * 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.dc.name, self.cell.wg_t1.name),
            #                         coordinate=(1350.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.dc2.name, self.cell.wg_t1.name),
            #                         coordinate=(4650.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={}_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)

            return elems
示例#6
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
示例#7
0
class v8(PlaceAndAutoRoute):
    wg_t1 = i3.WaveguideTemplateProperty()
    wg_sm = i3.WaveguideTemplateProperty()
    mmi_trace_template = i3.WaveguideTemplateProperty()
    mmi_access_template = i3.WaveguideTemplateProperty()

    mmi1_12 = i3.ChildCellProperty()
    mmi1_21 = i3.ChildCellProperty()
    WG1 = i3.ChildCellProperty()
    WG2 = i3.ChildCellProperty()

    def _default_links(self):
        links = [("MMI1a:out2", "WGuptaper2:out"),
                 ("MMI1a:out1", "WGdowntaper2:out"), ("MMI1b:out", "MMI1a:in"),
                 ("WGuptaper:out", "MMI1b:in2"),
                 ("WGdowntaper:out", "MMI1b:in1")]
        return links

    def _default_child_cells(self):
        child_cells = {
            "MMI1a": self.mmi1_12,
            "MMI1b": self.mmi1_21,
            "WGup": self.WG1,
            "WGdown": self.WG1,
            "WGup2": self.WG1,
            "WGdown2": self.WG1,
            "WGuptaper": self.WG2,
            "WGdowntaper": self.WG2,
            "WGuptaper2": self.WG2,
            "WGdowntaper2": self.WG2
        }
        return child_cells

    def _default_trace_template(self):
        trace_template = self.wg_sm
        return trace_template

    def _default_mmi1_12(self):
        mmi12 = MMI1x2Tapered(
            mmi_trace_template=self.mmi_trace_template,
            input_trace_template=self.mmi_access_template,
            output_trace_template=self.mmi_access_template,
            trace_template=self.wg_sm,
        )
        return mmi12

    def _default_mmi1_21(self):
        mmi21 = MMI2x1Tapered(
            mmi_trace_template=self.mmi_trace_template,
            input_trace_template=self.mmi_access_template,
            output_trace_template=self.mmi_access_template,
            trace_template=self.wg_sm,
        )
        return mmi21

    def _default_WG2(self):
        WG2 = WireWaveguideTransitionLinear(start_trace_template=self.wg_t1,
                                            end_trace_template=self.wg_sm)
        return WG2

    def _default_WG1(self):
        WG1 = i3.Waveguide(name="Dongbo", trace_template=self.wg_t1)
        return WG1

    def _default_wg_t1(self):
        wg_t1 = WireWaveguideTemplate()
        wg_t1.Layout(core_width=15.0,
                     cladding_width=15.0 + 16.0,
                     core_process=i3.TECH.PROCESS.WG)
        return wg_t1

    def _default_wg_sm(self):
        wg_sm = WireWaveguideTemplate()
        wg_sm.Layout(core_width=3.8, cladding_width=3.8 + 16.0)
        return wg_sm

    def _default_mmi_trace_template(self):
        mmi_trace_template = WireWaveguideTemplate()
        mmi_trace_template.Layout(core_width=20.0,
                                  cladding_width=20.0 + 16.0)  # MMI_width
        return mmi_trace_template

    def _default_mmi_access_template(self):
        mmi_access_template = WireWaveguideTemplate()
        mmi_access_template.Layout(core_width=9.0, cladding_width=9.0 + 16.0)
        return mmi_access_template

    class Layout(PlaceAndAutoRoute.Layout):
        length = i3.PositiveNumberProperty(name="MMI length", default=97)

        def _default_WG1(self):
            layout_WG1 = self.cell.WG1.get_default_view(i3.LayoutView)
            layout_WG1.set(shape=[(0.0, 0.0), (150.0, 0.0)])
            return layout_WG1

        def _default_WG2(self):
            layout_WG2 = self.cell.WG2.get_default_view(i3.LayoutView)
            layout_WG2.set(start_position=(150.0, 0.0),
                           end_position=(450.0, 0.0))
            return layout_WG2

        def _default_mmi1_12(self):
            layout_mmi1_12 = self.cell.mmi1_12.get_default_view(i3.LayoutView)
            layout_mmi1_12.set(transition_length=200.0,
                               length=self.length,
                               trace_spacing=11.0)
            return layout_mmi1_12

        def _default_mmi1_21(self):
            layout_mmi1_21 = self.cell.mmi1_21.get_default_view(i3.LayoutView)
            layout_mmi1_21.set(transition_length=200.0,
                               length=self.length,
                               trace_spacing=11.0)
            return layout_mmi1_21

        def _default_child_transformations(self):
            child_transformations = {
                "MMI1a": (1887, 0),
                "MMI1b": (1300, 0),
                "WGup": (0, 4000),
                "WGuptaper": (0, 4000),
                "WGdown": (0, -4000),
                "WGdowntaper": (0, -4000),
                "WGuptaper2": i3.HMirror() + i3.Translation((3400, 4000)),
                "WGdowntaper2": i3.HMirror() + i3.Translation((3400, -4000)),
                "WGup2": (3250, 4000),
                "WGdown2": (3250, -4000)
            }
            return child_transformations

        def _default_bend_radius(self):
            bend_radius = 300
            return bend_radius
示例#8
0
class SpiralWgLossEbeam(PlaceAndAutoRoute):
    ## generate segmented FBMS line
    spiral = i3.ChildCellProperty()
    taper = i3.ChildCellProperty()
    wg = i3.ChildCellProperty()
    wg_right = i3.ChildCellProperty()
    expanded_wg = i3.ChildCellProperty()
    trace_template = i3.WaveguideTemplateProperty()
    expanded_wg_template = i3.WaveguideTemplateProperty()

    wg_width = i3.PositiveNumberProperty(default=2.0)
    trench_width = i3.PositiveNumberProperty(default=3.0)
    _wg_width_indesign = i3.PositiveNumberProperty()
    expanded_wg_width = i3.PositiveNumberProperty(default=3.0)
    _expanded_wg_width_indesign = i3.PositiveNumberProperty()
    spiral_length = i3.PositiveNumberProperty(default=10000.0)
    n_o_loops = i3.IntProperty(default=2)

    def _default__wg_width_indesign(self):
        return self.wg_width

    def _default__expanded_wg_width_indesign(self):
        return self.expanded_wg_width

    def _default_trace_template(self):
        wstart1 = PathTraceWindow(layer=i3.TECH.PPLAYER.WG.CORE,
                                  start_offset=-self.wg_width * 0.5,
                                  end_offset=self.wg_width * 0.5)
        wstart2 = PathTraceWindow(
            layer=i3.TECH.PPLAYER.WG.CLADDING,
            start_offset=-(self.wg_width + self.trench_width) * 0.5,
            end_offset=-(self.wg_width + self.trench_width) * 0.5,
            line_width=0)
        wstart3 = PathTraceWindow(
            layer=i3.TECH.PPLAYER.WG.CLADDING,
            start_offset=(self.wg_width + self.trench_width) * 0.5,
            end_offset=(self.wg_width + self.trench_width) * 0.5,
            line_width=0)
        wg_t = i3.WindowWaveguideTemplate()
        wg_t.Layout(windows=[wstart1, wstart2, wstart3])
        return wg_t

    def _default_expanded_wg_template(self):
        wstart1 = PathTraceWindow(layer=i3.TECH.PPLAYER.WG.CORE,
                                  start_offset=-self.expanded_wg_width * 0.5,
                                  end_offset=self.expanded_wg_width * 0.5)
        wstart2 = PathTraceWindow(
            layer=i3.TECH.PPLAYER.WG.CLADDING,
            start_offset=-(self.expanded_wg_width + self.trench_width) * 0.5,
            end_offset=-(self.expanded_wg_width + self.trench_width) * 0.5,
            line_width=0)
        wstart3 = PathTraceWindow(
            layer=i3.TECH.PPLAYER.WG.CLADDING,
            start_offset=(self.expanded_wg_width + self.trench_width) * 0.5,
            end_offset=(self.expanded_wg_width + self.trench_width) * 0.5,
            line_width=0)
        expanded_wg_template = i3.WindowWaveguideTemplate()
        expanded_wg_template.Layout(windows=[wstart1, wstart2, wstart3])
        return expanded_wg_template

    def _default_wg(self):
        wg = i3.RoundedWaveguide(trace_template=self.trace_template)
        return wg

    def _default_wg_right(self):
        wg_right = i3.RoundedWaveguide(trace_template=self.trace_template)
        return wg_right

    def _default_spiral(self):
        spiral = FixedLengthSpiralRounded(total_length=self.spiral_length,
                                          n_o_loops=self.n_o_loops,
                                          trace_template=self.trace_template)
        return spiral

    def _default_expanded_wg(self):
        expanded_wg = i3.RoundedWaveguide(
            trace_template=self.expanded_wg_template)
        return expanded_wg

    def _default_taper(self):
        taper = LinearWindowWaveguideTransition(
            start_trace_template=self.trace_template,
            end_trace_template=self.expanded_wg_template)
        return taper

    def _default_child_cells(self):
        child_cells = dict()
        child_cells["spiral"] = self.spiral
        child_cells["taper_left"] = self.taper
        child_cells["taper_right"] = self.taper
        child_cells["wg_left"] = self.wg
        child_cells["wg_right"] = self.wg_right
        child_cells["expanded_wg_left"] = self.expanded_wg
        child_cells["expanded_wg_right"] = self.expanded_wg
        return child_cells

    def _default_external_port_names(self):
        ports = dict()
        ports["expanded_wg_right:out"] = "in"
        ports["expanded_wg_left:out"] = "out"
        return ports

    class Layout(PlaceAndAutoRoute.Layout):
        spiral_width = i3.PositiveNumberProperty(
            doc="total width of spiral structure", default=6000.0)
        right_wg_length = i3.PositiveNumberProperty(
            doc="length of narrow wg on the right side of spiral",
            default=500.0)
        expanded_wg_length = i3.PositiveNumberProperty(default=5000.0)
        taper_length = i3.PositiveNumberProperty(default=300.0)
        bend_radius = i3.PositiveNumberProperty(default=100.0)
        gap = i3.PositiveNumberProperty(doc="distance between two trenches",
                                        default=3.0)
        _spacing_indesign = i3.PositiveNumberProperty()

        def _default__spacing_indesign(self):
            return self.gap + self.trench_width * 2 + self.wg_width

        def _default_spiral(self):
            spiral_lo = self.cell.spiral.get_default_view(i3.LayoutView)
            spiral_lo.set(incoupling_length=0,
                          bend_radius=self.bend_radius,
                          spacing=self._spacing_indesign,
                          growth_direction="H",
                          stub_direction="H")
            return spiral_lo

        def _default_wg(self):
            wg_lo = self.cell.wg.get_default_view(i3.LayoutView)
            wg_lo.set(shape=[(
                0.0,
                0.0), (self.spiral_width - self._spiral_in_out_distance(), 0)])
            return wg_lo

        def _spiral_in_out_distance(self):
            return self.spiral.ports["out"].position.x - self.spiral.ports[
                "in"].position.x

        def _default_wg_right(self):
            wg_right_lo = self.cell.wg_right.get_default_view(i3.LayoutView)
            wg_right_lo.set(shape=[(0.0, 0.0), (self.right_wg_length, 0)])
            return wg_right_lo

        def _default_taper(self):
            taper_lo = self.cell.taper.get_default_view(i3.LayoutView)
            taper_lo.set(start_position=(0.0, 0.0),
                         end_position=(self.taper_length, 0.0))
            return taper_lo

        def _default_expanded_wg(self):
            expanded_wg_lo = self.cell.expanded_wg.get_default_view(
                i3.LayoutView)
            expanded_wg_lo.set(shape=[(0.0, 0.0), (self.expanded_wg_length,
                                                   0.0)])
            return expanded_wg_lo

        def _default_child_transformations(self):
            trans = dict()
            trans["spiral"] = (-self._spiral_in_out_distance(), 0.0)
            trans["wg_right"] = (0.0, 0.0)
            trans["taper_right"] = i3.Translation((self.right_wg_length, 0))
            trans["expanded_wg_right"] = i3.Translation(
                (self.right_wg_length + self.taper_length, 0))
            trans["wg_left"] = i3.HMirror(mirror_plane_x=0.0) + i3.Translation(
                (-self._spiral_in_out_distance(), 0))
            trans["taper_left"] = i3.HMirror(
                mirror_plane_x=0.0) + i3.Translation((-self.spiral_width, 0))
            trans["expanded_wg_left"] = i3.HMirror(
                mirror_plane_x=0.0) + i3.Translation(
                    (-self.spiral_width - self.taper_length, 0))
            return trans

        def get_true_length(self):
            return self.spiral_width - self._spiral_in_out_distance(
            ) + self.right_wg_length + self.spiral_length
示例#9
0
class my_dc(PlaceAndAutoRoute):
    dc = i3.ChildCellProperty()
    dc2 = i3.ChildCellProperty()
    WG1 = i3.ChildCellProperty()
    WG2 = i3.ChildCellProperty()
    WGSM = 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,
                     core_process=i3.TECH.PROCESS.WG)
        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_wg_dc2(self):
        wg_dc2 = WireWaveguideTemplate(name="dc2_template")
        wg_dc2.Layout(core_width=2.8, cladding_width=2.8 + 16.0)
        return wg_dc2

    def _default_WG1(self):
        WG1 = i3.Waveguide(name="straight{}".format(str(self.width)),
                           trace_template=self.wg_t1)
        return WG1

    def _default_WG2(self):
        WG2 = WireWaveguideTransitionLinear(
            name="taper{}".format(str(self.width)),
            start_trace_template=self.wg_t1,
            end_trace_template=self.trace_template)
        return WG2

    def _default_WGSM(self):
        WGSM = i3.Waveguide(name="SM", trace_template=self.trace_template)

        return WGSM

    def _default_dc(self):
        dc = BendDirectionalCoupler(name="DC_gap_1.5_l_923",
                                    trace_template1=self.trace_template,
                                    coupler_length=923.0)
        dc.Layout(
            coupler_spacing=1.5 + 3.8,
            bend_radius=300.0,
            # manhattan=True,
            # straight_after_bend=600.0,
            bend_angle=90.0)
        return dc

    def _default_dc2(self):
        dc2 = BendDirectionalCoupler(name="DC_gap_2_l_888",
                                     trace_template1=self.wg_dc2,
                                     coupler_length=888.0)
        dc2.Layout(
            coupler_spacing=2 + 2.8,
            bend_radius=300.0,
            # manhattan=True,
            bend_angle=90.0)
        return dc2

    def _default_child_cells(self):
        child_cells = dict()
        for counter in range(8, 16, 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["dummy1"] = self.WGSM
        child_cells["dummy2"] = self.WGSM
        return child_cells

    def _default_links(self):
        links = [
            # ("taper0:out", "dircoup1:in2"),
            # ("taper1:out", "dircoup1:in1"),
            # ("taper2:out", "dircoup1:out2"),
            # ("taper3:out", "dircoup1:out1"),
            # ("taper4:out", "dircoup2:in2"),
            # ("taper5:out", "dircoup2:in1"),
            # ("taper6:out", "dircoup2:out2"),
            # ("taper7:out", "dircoup2:out1"),
            ("taper8:out", "taper10:out"),
            ("taper12:out", "taper14:out"),
            ("taper9:out", "dummy1:in"),
            ("taper11:out", "dummy1:out"),
            ("taper13:out", "dummy2:in"),
            ("taper15:out", "dummy2:out")
        ]
        return links

    class Layout(PlaceAndAutoRoute.Layout):
        def _default_WG1(self):
            layout_WG1 = self.cell.WG1.get_default_view(i3.LayoutView)
            layout_WG1.set(shape=[(0.0, 0.0), (150.0, 0.0)])
            return layout_WG1

        def _default_WG2(self):
            layout_WG2 = self.cell.WG2.get_default_view(i3.LayoutView)
            layout_WG2.set(start_position=(0.0, 0.0),
                           end_position=(300.0, 0.0))
            return layout_WG2

        def _default_WGSM(self):
            layout_WGSM = self.cell.WGSM.get_default_view(i3.LayoutView)
            layout_WGSM.set(shape=[(0.0, 0.0), (400.0, 0.0)])
            return layout_WGSM

        # def _default_dc(self):
        #     layout_dc = self.cell.dc.get_default_view(i3.LayoutView)
        #     layout_dc.set(coupler_spacing=2.5 + 3.8,
        #                   bend_radius=300.0,
        #                   manhattan=True,
        #                   # straight_after_bend=6.0,
        #                   bend_angle=90.0)
        #     return layout_dc

        def _default_child_transformations(self):
            trans = dict()
            # trans["dircoup1"] = (1650, 0)
            # trans["dircoup2"] = (4950, 0)
            trans["dummy1"] = (1450, -300 + 8300 * 2)
            trans["dummy2"] = (4750, -300 + 8300 * 2)
            # for counter in range(0, 8, 1):
            #     print counter
            #     trans['straight' + str(counter)] = (2000 * (counter + 1), 0)
            #     trans["taper" + str(counter)] = (0, 2000 * (counter + 1))
            # trans["straight0"] = (0, 4000)
            # trans["straight1"] = (0, -4000)
            # trans["straight2"] = (3150, 2000)
            # trans["straight3"] = (3150, -6000)
            # trans["straight4"] = (3300, 2000)
            # trans["straight5"] = (3300, -6000)
            # trans["straight6"] = (6450, 4000)
            # trans["straight7"] = (6450, -4000)
            # trans["taper0"] = (150, 4000)
            # trans["taper1"] = (150, -4000)
            # trans["taper2"] = i3.HMirror(150) + i3.Translation((2850, 2000))
            # trans["taper3"] = i3.HMirror(150) + i3.Translation((2850, -6000))
            # trans["taper4"] = (3450, 2000)
            # trans["taper5"] = (3450, -6000)
            # trans["taper6"] = i3.HMirror(150) + i3.Translation((6150, 4000))
            # trans["taper7"] = i3.HMirror(150) + i3.Translation((6150, -4000))

            trans["straight8"] = (0, 21050)
            trans["straight9"] = (0, -4150 + 8300 * 2)
            trans["straight10"] = (3150, 21050)
            trans["straight11"] = (3150, -6150 + 8300 * 2)
            trans["straight12"] = (3300, 21050)
            trans["straight13"] = (3300, -6150 + 8300 * 2)
            trans["straight14"] = (6450, 21050)
            trans["straight15"] = (6450, -4150 + 8300 * 2)
            trans["taper8"] = (150, 21050)
            trans["taper9"] = (150, -4150 + 8300 * 2)
            trans["taper10"] = i3.HMirror(150) + i3.Translation((2850, 21050))
            trans["taper11"] = i3.HMirror(150) + i3.Translation(
                (2850, -6150 + 8300 * 2))
            trans["taper12"] = (3450, 21050)
            trans["taper13"] = (3450, -6150 + 8300 * 2)
            trans["taper14"] = i3.HMirror(150) + i3.Translation((6150, 21050))
            trans["taper15"] = i3.HMirror(150) + i3.Translation(
                (6150, -4150 + 8300 * 2))

            return trans

        def _default_bend_radius(self):
            bend_radius = 300
            return bend_radius
示例#10
0
class edge(PlaceAndAutoRoute):
    wg_sm = i3.WaveguideTemplateProperty()
    mmi_trace_template = i3.WaveguideTemplateProperty()
    mmi_access_template = i3.WaveguideTemplateProperty()

    WG2 = i3.ChildCellProperty()
    narro = i3.ChildCellProperty()

    # def _default_links(self):
    #     links = [("taper:out", "taper2:out")]
    #     return links

    def _default_child_cells(self):
        child_cells = dict()
        for counter in range(0, 48, 1):  # Routing dummy
            print counter
            child_cells['edge1' + str(counter)] = self.narro
            child_cells['edge2' + str(counter)] = self.WG2

        return child_cells

    def _default_trace_template(self):
        wg_sm2 = WireWaveguideTemplate()
        wg_sm2.Layout(core_width=15, cladding_width=15 + 24.0)
        return wg_sm2

    def _default_WG2(self):
        WG2 = i3.Waveguide(name="20", trace_template=self.wg_sm)
        return WG2

    def _default_narro(self):
        WGnarrow = i3.Waveguide(name="15", trace_template=self.trace_template)
        return WGnarrow

    def _default_wg_sm(self):
        wg_sm = WireWaveguideTemplate()
        wg_sm.Layout(core_width=20, cladding_width=20 + 24.0)
        return wg_sm

    def _default_mmi_trace_template(self):
        mmi_trace_template = WireWaveguideTemplate()
        mmi_trace_template.Layout(core_width=20.0,
                                  cladding_width=20.0 + 24.0)  # MMI_width
        return mmi_trace_template

    def _default_mmi_access_template(self):
        mmi_access_template = WireWaveguideTemplate()
        mmi_access_template.Layout(core_width=9.0, cladding_width=9.0 + 24.0)
        return mmi_access_template

    class Layout(PlaceAndAutoRoute.Layout):
        length = i3.PositiveNumberProperty(doc="MMI length", default=97)

        def _default_WG2(self):
            layout_WG2 = self.cell.WG2.get_default_view(i3.LayoutView)
            layout_WG2.set(shape=[(0.0, 0.0), (300.0, 0.0)])
            return layout_WG2

        def _default_narro(self):
            layout = self.cell.narro.get_default_view(i3.LayoutView)
            layout.set(shape=[(0.0, 0.0), (300.0, 0.0)])
            return layout

        def _default_child_transformations(self):
            trans = dict()
            for counter in range(0, 24, 1):
                trans['edge1' + str(counter)] = i3.Translation(
                    translation=(-300, counter * 150))
                trans['edge2' + str(counter)] = i3.Translation(
                    translation=(-300, counter * 150 + 7500))
            for counter in range(24, 48, 1):
                trans['edge1' + str(counter)] = i3.Translation(
                    translation=(18600, counter * 150 - 2600))
                trans['edge2' + str(counter)] = i3.Translation(
                    translation=(18600, counter * 150 + 7500 - 2600))

            return trans
示例#11
0
class PhaseShifterTemplate(PhaseShifterWaveguideTemplate):
    ''' PN junction trace template with parameters to set up the implants and the contact.
    '''
    trace_template = i3.WaveguideTemplateProperty(locked=True)

    def _default_trace_template(self):
        return SiWireWaveguideTemplate(name="{}_wg_tt".format(self.name))

    class Layout(PhaseShifterWaveguideTemplate.Layout):
        core_width = i3.PositiveNumberProperty(doc="width of the core")
        p_width = i3.PositiveNumberProperty(doc="width of low dose P implant")
        p_offset = i3.NumberProperty(
            doc="offset from the center line of low dose P implant")
        n_width = i3.PositiveNumberProperty(doc="width of low dose N implant")
        n_offset = i3.NumberProperty(
            doc="offset from the center line of low dose N implant")
        high_dose_p_width = i3.PositiveNumberProperty(
            doc="width of high dose P implant")
        high_dose_p_offset = i3.NumberProperty(
            doc="offset from the center line of high dose P implant")
        high_dose_n_width = i3.PositiveNumberProperty(
            doc="width of high dose N implant")
        high_dose_n_offset = i3.NumberProperty(
            doc="offset from the center line of high dose N implant")
        con_width = i3.PositiveNumberProperty(
            doc="width of contacts etch (same on both side of the center line)"
        )
        con_p_offset = i3.NumberProperty(
            doc="offset from the center line of contacts etch on P implant")
        con_n_offset = i3.NumberProperty(
            doc="offset from the center line of contacts etch on N implant")

        def _default_core_width(self):
            return 0.45

        def _default_p_width(self):
            return 3.

        def _default_p_offset(self):
            return self.p_width / 2.

        def _default_n_width(self):
            return self.p_width

        def _default_n_offset(self):
            return -self.n_width / 2.

        def _default_high_dose_p_width(self):
            return 2.

        def _default_high_dose_p_offset(self):
            return self.p_width + self.high_dose_p_width / 2.

        def _default_high_dose_n_width(self):
            return self.high_dose_p_width

        def _default_high_dose_n_offset(self):
            return -self.high_dose_p_offset

        def _default_con_width(self):
            return self.high_dose_p_width / 2.

        def _default_con_p_offset(self):
            return self.high_dose_p_offset

        def _default_con_n_offset(self):
            return self.high_dose_n_offset

        def _default_trace_template(self):
            lv = self.cell.trace_template.get_default_view(self)
            lv.set(core_width=self.core_width)
            return lv

        def _default_trace_template_for_ports(self):
            port_tt = SiWireWaveguideTemplate(
                name="{}_wg_port_tt".format(self.name))
            port_tt_lv = port_tt.Layout(core_width=self.core_width)
            return port_tt_lv

        def _default_implant_windows(self):
            core_half_width = 0.5 * self.core_width
            p_half_width = 0.5 * self.p_width
            n_half_width = 0.5 * self.n_width
            high_dose_p_half_width = 0.5 * self.high_dose_p_width
            high_dose_n_half_width = 0.5 * self.high_dose_n_width

            p_offset = self.p_offset
            n_offset = self.n_offset
            high_dose_p_offset = self.high_dose_p_offset
            high_dose_n_offset = self.high_dose_n_offset

            windows = []
            # core
            windows.append(
                i3.PathTraceWindow(layer=i3.TECH.PPLAYER.SI,
                                   start_offset=-core_half_width,
                                   end_offset=+core_half_width))
            # low_dose_p
            windows.append(
                i3.PathTraceWindow(layer=i3.TECH.PPLAYER.P,
                                   start_offset=p_offset - p_half_width,
                                   end_offset=p_offset + p_half_width))
            # low_dose_n
            windows.append(
                i3.PathTraceWindow(layer=i3.TECH.PPLAYER.N,
                                   start_offset=n_offset - n_half_width,
                                   end_offset=n_offset + n_half_width))
            # high_dose_p
            windows.append(
                i3.PathTraceWindow(
                    layer=i3.TECH.PPLAYER.PPLUS,
                    start_offset=high_dose_p_offset - high_dose_p_half_width,
                    end_offset=high_dose_p_offset + high_dose_p_half_width))
            # high_dose_n
            windows.append(
                i3.PathTraceWindow(
                    layer=i3.TECH.PPLAYER.NPLUS,
                    start_offset=high_dose_n_offset - high_dose_n_half_width,
                    end_offset=high_dose_n_offset + high_dose_n_half_width))
            return windows

        def _default_contact_windows(self):
            con_half_width = 0.5 * self.con_width
            con_p_offset = self.con_p_offset
            con_n_offset = self.con_n_offset

            windows = []
            # Contact on P++
            windows.append(
                i3.ExtendedPathTraceWindow(
                    layer=i3.TECH.PPLAYER.CON,
                    start_offset=con_p_offset - con_half_width,
                    end_offset=con_p_offset + con_half_width,
                    extension=(-0.5, -0.5)))
            # Contact on N++
            windows.append(
                i3.ExtendedPathTraceWindow(
                    layer=i3.TECH.PPLAYER.CON,
                    start_offset=con_n_offset - con_half_width,
                    end_offset=con_n_offset + con_half_width,
                    extension=(-0.5, -0.5)))
            return windows

        def _default_metal_windows(self):
            windows = []
            return windows

        def _default_windows(self):
            windows = self.implant_windows + self.contact_windows + self.metal_windows
            return windows

    class CircuitModel(PhaseShifterWaveguideTemplate.CircuitModel):

        VpiLpi = i3.PositiveNumberProperty(
            default=1.0,
            doc="Voltage to get pi-shift for 1 cm of phase modulator [V.cm]")

        def _default_loss_dB_m(self):
            return 300.0

        def _default_neff(self):
            return 2.5

        def _default_n_g(self):
            return 4.1
示例#12
0
class v8(PlaceAndAutoRoute):
    wg_t1 = i3.WaveguideTemplateProperty()
    wg_sm = i3.WaveguideTemplateProperty()
    mmi_trace_template = i3.WaveguideTemplateProperty()
    mmi_access_template = i3.WaveguideTemplateProperty()

    widtha = i3.PositiveNumberProperty(doc="width of ports", default=15)

    mmi22 = i3.ChildCellProperty()
    WG1 = i3.ChildCellProperty()
    WG2 = i3.ChildCellProperty()

    #
    # start_id = None
    # # start_id = current_id
    # param_num= 6

    def _default_links(self):
        links = [
            ("MMI1b:out2", "WGuptaper2:out"),
            ("MMI1b:out1", "WGdowntaper2:out"),
            # ("MMI1b:out","MMI1a:in"),
            ("WGuptaper:out", "MMI1b:in2"),
            ("WGdowntaper:out", "MMI1b:in1")
        ]
        return links

    def _default_child_cells(self):
        child_cells = {
            "MMI1b": self.mmi22,
            "WGup": self.WG1,
            "WGdown": self.WG1,
            "WGup2": self.WG1,
            "WGdown2": self.WG1,
            "WGuptaper": self.WG2,
            "WGdowntaper": self.WG2,
            "WGuptaper2": self.WG2,
            "WGdowntaper2": self.WG2
        }
        return child_cells

    def _default_trace_template(self):
        trace_template = self.wg_sm
        return trace_template

    def _default_mmi22(self):
        mmi22 = 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.wg_sm,
        )
        return mmi22

    def _default_WG2(self):
        WG2 = WireWaveguideTransitionLinear(
            name="dongbo{}".format(str(np.random.randint(0, 10000))),
            start_trace_template=self.wg_t1,
            end_trace_template=self.wg_sm,
        )
        return WG2

    def _default_WG1(self):
        WG1 = i3.Waveguide(name="dongbo{}".format(
            str(np.random.randint(0, 10000))),
                           trace_template=self.wg_t1)
        return WG1

    def _default_wg_t1(self):
        wg_t1 = WireWaveguideTemplate(
            name="dongbo{}".format(str(np.random.randint(0, 10000))))
        wg_t1.Layout(core_width=self.widtha,
                     cladding_width=self.widtha + 16.0,
                     core_process=i3.TECH.PROCESS.WG)
        return wg_t1

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

    def _default_mmi_trace_template(self):
        mmi_trace_template = WireWaveguideTemplate()
        mmi_trace_template.Layout(core_width=20.0,
                                  cladding_width=20.0 + 16.0)  # MMI_width
        return mmi_trace_template

    def _default_mmi_access_template(self):
        mmi_access_template = WireWaveguideTemplate()
        mmi_access_template.Layout(core_width=9.0, cladding_width=9.0 + 16.0)
        return mmi_access_template

    class Layout(PlaceAndAutoRoute.Layout):
        length = i3.PositiveNumberProperty(doc="MMI length", default=398)

        # width = i3.PositiveNumberProperty(doc="width of ports", default=15)

        # def _default_wg_t1(self):
        #     layout_wg_t1 = self.cell.wg_t1.get_default_view(i3.LayoutView)
        #     layout_wg_t1.set(core_width=self.width,
        #                      cladding_width=self.width + 16.0,
        #                      core_process=i3.TECH.PROCESS.WG)
        #     return layout_wg_t1

        def _default_WG1(self):
            layout_WG1 = self.cell.WG1.get_default_view(i3.LayoutView)
            layout_WG1.set(shape=[(0.0, 0.0), (150.0, 0.0)])
            return layout_WG1

        def _default_WG2(self):
            layout_WG2 = self.cell.WG2.get_default_view(i3.LayoutView)
            layout_WG2.set(start_position=(150.0, 0.0),
                           end_position=(450.0, 0.0))
            return layout_WG2

        def _default_mmi22(self):
            layout_mmi22 = self.cell.mmi22.get_default_view(i3.LayoutView)
            layout_mmi22.set(transition_length=200.0,
                             length=self.length,
                             trace_spacing=11.0)
            return layout_mmi22

        def _default_child_transformations(self):
            child_transformations = {
                "MMI1b": (1300, 0),
                "WGup": (0, 4000),
                "WGuptaper": (0, 4000),
                "WGdown": (0, -4000),
                "WGdowntaper": (0, -4000),
                "WGuptaper2": i3.HMirror() + i3.Translation((3000, 2000)),
                "WGdowntaper2": i3.HMirror() + i3.Translation((3000, -6000)),
                "WGup2": (2850, 2000),
                "WGdown2": (2850, -6000)
            }
            return child_transformations

        def _default_bend_radius(self):
            bend_radius = 300
            return bend_radius
示例#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
示例#14
0
class SerpGratingArray(i3.PCell):
    """Sidewall Grating Waveguide: Waveguide with rectangular sidewall gratings
    """

    _name_prefix = "SerpGrating"

    wg_temp = i3.WaveguideTemplateProperty(
        doc=
        "Waveguide template to use for flyback waveguides, bends, and tapers")
    bend_type = i3.StringProperty(
        default="manual",
        doc=
        "String denoting type of bend to use for connecting arcs (options: 'default', 'manual')"
    )
    taper_type = i3.StringProperty(
        default="default",
        doc=
        "String denoting type of taper to use for connecting tapers (options: 'default', 'manual')"
    )
    bend = i3.ChildCellProperty(
        doc="Bend cell to use for connecting arc waveguides")
    taper_swg = i3.ChildCellProperty(
        doc=
        "Taper cell to use for taper connectors between sidewall grating waveguides and bends"
    )
    taper_flyback = i3.ChildCellProperty(
        doc=
        "Taper cell to use for taper connectors between flyback waveguides and bends"
    )
    swg = i3.ChildCellProperty(doc="Sidewall grating waveguide cell")
    flyback = i3.ChildCellProperty(doc="Flyback waveguide cell")

    def _default_wg_temp(self):
        wg_temp = StripWgTemplate(name=self.name + "_WgTemplate")
        return wg_temp

    def _default_bend(self):
        if self.bend_type is "default":
            bend = i3.Waveguide(name=self.name + "_Bend",
                                trace_template=self.wg_temp)
        else:
            from Custom_Waveguide import CustomWaveguide
            bend = CustomWaveguide(name=self.name + "_Bend")
        return bend

    def _default_taper_swg(self):
        if self.taper_type is "default":
            from Linear_Taper import LinearTaper
            taper = LinearTaper(name=self.name + "_SwgTaper")
        else:
            from Custom_Waveguide import CustomWaveguide
            taper = CustomWaveguide(name=self.name + "_SwgTaper")
        return taper

    def _default_taper_flyback(self):
        if self.taper_type is "default":
            from Linear_Taper import LinearTaper
            taper = LinearTaper(name=self.name + "_FlybackTaper")
        else:
            from Custom_Waveguide import CustomWaveguide
            taper = CustomWaveguide(name=self.name + "_FlybackTaper")
        return taper

    def _default_swg(self):
        swg = SidewallGratingWg(name=self.name + "_SidewallGratingWg")
        return swg

    def _default_flyback(self):
        flyback = i3.Waveguide(name=self.name + "_FlybackWg",
                               trace_template=self.wg_temp)
        return flyback

    # --------------------------
    # Layout
    # --------------------------
    class Layout(i3.LayoutView):
        """
        List of properties:
        period
        duty_cycle
            absolute length of the grating section, not percentage
        grating_amp
        grat_wg_width
        flyback_wg_width
        pitch
        spacing
        length
        numrows
        taper_length
        taper_path_flyback
        taper_width_flyback
        taper_path_swg
        taper_width_swg
        bend_width
        arc_path
        arc_width

        TO GENERATE CUSTOM BENDS:
            set pitch to either 16.0 or 16.516

        """

        from ipkiss.technology import get_technology
        TECH = get_technology()

        # -----------
        # Properties

        # Sidewall grating waveguide properties
        period = i3.PositiveNumberProperty(default=.3,
                                           doc="Period of sidewall grating")
        duty_cycle = i3.PositiveNumberProperty(
            default=.1,
            doc="Length of grating teeth (along periodic direction)")
        grating_amp = i3.NumberProperty(
            default=.01,
            doc=
            "Width/amplitude of grating teeth (normal to periodic direction)")
        grat_wg_width = i3.PositiveNumberProperty(
            default=1.0,
            doc=
            "Width of sidewall grating waveguide core (if grating_amp=0 width of waveguide)"
        )

        # Flyback waveguide properites
        flyback_wg_width = i3.PositiveNumberProperty(
            default=0.4, doc="Width of flyback waveguide core")

        # Grating array properties
        pitch = i3.PositiveNumberProperty(
            default=16.0,
            doc=
            "Sidewall grating pitch (center-to-center distance of sidewall grating waveguides)"
        )
        spacing = i3.PositiveNumberProperty(
            doc="Gap between sidewall grating waveguides and flyback waveguides"
        )

        def _default_spacing(self):
            spacing = (self.pitch - self.grat_wg_width -
                       self.flyback_wg_width) / 2
            return spacing

        length = i3.PositiveNumberProperty(
            default=800.0,
            doc="Length of straight (untapered) waveguide sections")
        numrows = i3.PositiveIntProperty(
            default=32,
            doc=
            "Number of sidewall grating/flyback waveguide pairs in the array")

        # Taper properties
        # Properties used for taper_type = "default"
        taper_length = i3.PositiveNumberProperty(default=10.0,
                                                 doc="Taper length")
        # Properties used for taper_type = "manual"
        taper_path_flyback = i3.NumpyArrayProperty(
            doc=
            "List of coordinates denoting the center path of the taper (bend to flyback waveguide)"
        )
        taper_width_flyback = i3.NumpyArrayProperty(
            doc=
            "List of taper widths normal to each point on the path (bend to flyback waveguide)"
        )
        taper_path_swg = i3.NumpyArrayProperty(
            doc=
            "List of coordinates denoting the center path of the taper (bend to sidewall grating waveguide)"
        )
        taper_width_swg = i3.NumpyArrayProperty(
            doc=
            "List of taper widths normal to each point on the path (bend to sidewall grating waveguide)"
        )

        # REDEFINING TAPER HERE
        # taper_swg       = i3.ViewProperty( default='', doc='Taper layout that connects grating waveguide to the bends')
        # taper_flyback   = i3.ViewProperty( default='', doc='Taper layout that connects flyback waveguide to the bends')

        # Pick grating type:
        # 'one_sidewall', 'two_sidewalls', 'nitride_vertical_top', 'nitride_vertical_bottom',
        # 'nitride_one_sidewall_top', 'nitride_one_sidewall_bottom',
        grating_type = i3.StringProperty(default='',
                                         doc='Grating type to draw')

        def _default_taper_path_flyback(self):
            #Default is a straight linear taper
            path = np.array([[0.0, 0.0], [self.taper_length, 0.0]], np.float_)
            return path

        def _default_taper_width_flyback(self):
            # Default is a straight linear taper
            widths = np.array([self.bend_width, self.flyback_wg_width],
                              np.float_)
            return widths

        def _default_taper_path_swg(self):
            #Default is a straight linear taper
            path = np.array([[0.0, 0.0], [self.taper_length, 0.0]], np.float_)
            return path

        def _default_taper_width_swg(self):
            # Default is a straight linear taper
            widths = np.array([self.bend_width, self.grat_wg_width], np.float_)
            return widths

        # Bend properties
        # Properties used for bend_type = "default"
        bend_width = i3.PositiveNumberProperty(
            default=TECH.WG.CORE_WIDTH,
            doc="Width of waveguides in bend sections")
        # Properties used for bend_type = "manual"
        arc_path = i3.NumpyArrayProperty(
            doc=
            "List of coordinates denoting the center path of the arc connectors (going from sidewall grating waveguide to flyback waveguide"
        )
        arc_width = i3.NumpyArrayProperty(
            doc=
            "List of arc widths normal to each point on the path (going from sidewall grating waveguide to flyback waveguide"
        )

        def _default_arc_path(self):
            if self.pitch == 16.0:
                #Use pregenerated adiabatic bends (TX)
                pathwidth = np.loadtxt("../nathan/bend_data/txbend.txt",
                                       np.float_)
                arc_path = pathwidth[:, :2]
            elif self.pitch == 16.516:
                # Use pregenerated adiabatic bends (RX)
                pathwidth = np.loadtxt("../nathan/bend_data/rxbend.txt",
                                       np.float_)
                arc_path = pathwidth[:, :2]
            else:
                # Default is 180 arc
                arc_path = np.zeros([181, 2], np.float_)
                bend_rad = (self.grat_wg_width / 2 + self.spacing +
                            self.flyback_wg_width / 2) / 2
                for ii in range(181):
                    angle = np.pi / 180.0 * ii
                    arc_path[ii, :] = bend_rad * np.array(
                        [-np.sin(angle), np.cos(angle)], np.float_)

            return arc_path

        def _default_arc_width(self):
            if self.pitch == 16.0:
                #Use pregenerated adiabatic bends (TX)
                pathwidth = np.loadtxt("../nathan/bend_data/txbend.txt",
                                       np.float_)
                arc_width = pathwidth[:, 2]
            elif self.pitch == 16.516:
                #Use pregenerated adiabatic bends (RX)
                pathwidth = np.loadtxt("../nathan/bend_data/rxbend.txt",
                                       np.float_)
                arc_width = pathwidth[:, 2]
            else:
                #Default is uniform width with default core_width
                arc_width = np.ones([181], np.float_)
                arc_width = arc_width * self.bend_width
            return arc_width

        def validate_properties(self):
            """Check whether the combination of properties is valid."""
            if (self.grat_wg_width + self.flyback_wg_width +
                    2 * self.spacing) != self.pitch:
                raise i3.PropertyValidationError(
                    self,
                    "Array incorrectly overspecified (pitch=/=wg_widths+spacing",
                    {"pitch": self.pitch})
            return True

        @i3.cache()
        def _get_components(self):
            # Make waveguides

            # Pick grating type:
            # 'one_sidewall', 'two_sidewalls', 'nitride_vertical_top', 'nitride_vertical_bottom',
            # 'nitride_one_sidewall_top', 'nitride_one_sidewall_bottom',

            if self.grating_type == 'one_sidewall':
                # single sidewall grating
                swg_l = self.cell.swg.get_default_view(i3.LayoutView)
                swg_l.set(period=self.period,
                          duty_cycle=self.duty_cycle,
                          grating_amp=self.grating_amp,
                          wg_width=self.grat_wg_width,
                          length=self.length,
                          both_sides=False)

            elif self.grating_type == 'two_sidewalls':
                # double sidewall grating
                swg_l = self.cell.swg.get_default_view(i3.LayoutView)
                swg_l.set(period=self.period,
                          duty_cycle=self.duty_cycle,
                          grating_amp=self.grating_amp,
                          wg_width=self.grat_wg_width,
                          length=self.length,
                          both_sides=True)

            elif self.grating_type == 'nitride_vertical_top':
                # nitride vertical grating, top layer
                swg_l = NitrideGratingWg().get_default_view(i3.LayoutView)
                swg_l.set(period=self.period,
                          duty_cycle=self.duty_cycle,
                          grating_amp=self.grating_amp,
                          wg_width=self.grat_wg_width,
                          length=self.length,
                          grating_type='vertical',
                          nitride_layer='top')

            elif self.grating_type == 'nitride_vertical_bottom':
                # nitride vertical grating, top layer
                swg_l = NitrideGratingWg().get_default_view(i3.LayoutView)
                swg_l.set(period=self.period,
                          duty_cycle=self.duty_cycle,
                          grating_amp=self.grating_amp,
                          wg_width=self.grat_wg_width,
                          length=self.length,
                          grating_type='vertical',
                          nitride_layer='bottom')

            elif self.grating_type == 'nitride_one_sidewall_top':
                # nitride vertical grating, top layer
                swg_l = NitrideGratingWg().get_default_view(i3.LayoutView)
                swg_l.set(period=self.period,
                          duty_cycle=self.duty_cycle,
                          grating_amp=self.grating_amp,
                          wg_width=self.grat_wg_width,
                          length=self.length,
                          grating_type='one_sidewall',
                          nitride_layer='top')

            elif self.grating_type == 'nitride_one_sidewall_bottom':
                # nitride vertical grating, top layer
                swg_l = NitrideGratingWg().get_default_view(i3.LayoutView)
                swg_l.set(period=self.period,
                          duty_cycle=self.duty_cycle,
                          grating_amp=self.grating_amp,
                          wg_width=self.grat_wg_width,
                          length=self.length,
                          grating_type='one_sidewall',
                          nitride_layer='bottom')

            # end making grating if statement

            # flyback and stuff
            flyback_l = self.cell.flyback.get_default_view(i3.LayoutView)
            flyback_path = [(0.0, 0.0), (self.length, 0.0)]
            wg_temp_flyback = self.cell.wg_temp.get_default_view(i3.LayoutView)
            wg_temp_flyback.set(core_width=self.flyback_wg_width)
            flyback_l.set(trace_template=wg_temp_flyback, shape=flyback_path)

            # Center-to-center distance between sidewall grating waveguide and flyback waveguide
            flyback_offset = self.grat_wg_width / 2 + self.spacing + self.flyback_wg_width / 2

            # Make bends
            bend_l = self.cell.bend.get_default_view(i3.LayoutView)
            if self.cell.bend_type is "default":
                # Default waveguide 180 arc
                bend_rad = flyback_offset / 2
                arc = i3.ShapeArc(center=(0.0, 0.0),
                                  radius=bend_rad,
                                  start_angle=89.0,
                                  end_angle=270.0)
                wg_temp_bend = self.cell.wg_temp.get_default_view(
                    i3.LayoutView)
                wg_temp_bend.set(core_width=self.bend_width)
                bend_l.set(trace_template=wg_temp_bend, shape=arc)
            else:
                # Custom bend pcell
                bend_l.set(wg_path=self.arc_path,
                           wg_width=self.arc_width,
                           start_angle=180.0,
                           end_angle=0.0)

            # Make tapers
            taper_flyback_l = self.cell.taper_flyback.get_default_view(
                i3.LayoutView)
            taper_swg_l = self.cell.taper_swg.get_default_view(i3.LayoutView)

            if self.cell.taper_type is "default":
                # Linear taper pcell
                if self.cell.bend_type is "default":
                    flyback_bend_width = self.bend_width
                    swg_bend_width = self.bend_width
                else:
                    arcsize = self.arc_width.shape
                    arclength = arcsize[0]
                    flyback_bend_width = self.arc_width[arclength - 1]
                    swg_bend_width = self.arc_width[0]

                taper_flyback_l.set(length=self.taper_length,
                                    wg_width_in=flyback_bend_width,
                                    wg_width_out=self.flyback_wg_width)
                taper_swg_l.set(length=self.taper_length,
                                wg_width_in=swg_bend_width,
                                wg_width_out=self.grat_wg_width)
            else:
                # Custom taper pcell
                taper_flyback_l.set(wg_path=self.taper_path_flyback,
                                    wg_width=self.taper_width_flyback,
                                    start_angle=0.0,
                                    end_angle=0.0)
                taper_swg_l.set(wg_path=self.taper_path_swg,
                                wg_width=self.taper_width_swg,
                                start_angle=0.0,
                                end_angle=0.0)

            return swg_l, flyback_l, bend_l, taper_swg_l, taper_flyback_l

        def _generate_instances(self, insts):
            swg_l, flyback_l, bend_l, taper_swg_l, taper_flyback_l = self._get_components(
            )

            # Hard code the tapers into here: (I hate hardcoding stuff, but no choice here)
            taper_length = 79.0  # 79 is the best according to deniz' sims
            width_etch = 4.0
            wg_width = 0.5
            taper_swg = ParabolicTaper(
                name=self.name + '_TAPER').get_default_view(i3.LayoutView)
            taper_swg.set(length=taper_length,
                          width1=wg_width,
                          width2=self.grat_wg_width,
                          width_etch=width_etch)

            taper_flyback = ParabolicTaper(
                name=self.name + '_OTHERTAPER').get_default_view(i3.LayoutView)
            taper_flyback.set(length=taper_length,
                              width1=wg_width,
                              width2=self.flyback_wg_width,
                              width_etch=width_etch)

            for ii in range(self.numrows):

                # Find component translations (for all numrows)
                t_swg = i3.Translation((0.0, ii * self.pitch))
                # t_taper_swg_w   = vector_match_transform(taper_swg_l.ports["out"], swg_l.ports['in']) + t_swg
                # t_taper_swg_e   = vector_match_transform(taper_swg_l.ports["out"], swg_l.ports['out'], mirrored=True) + t_swg
                t_taper_swg_w = vector_match_transform(
                    taper_swg.ports["right"], swg_l.ports['in']) + t_swg
                t_taper_swg_e = vector_match_transform(
                    taper_swg.ports["right"],
                    swg_l.ports['out'],
                    mirrored=True) + t_swg

                # Add grating rows + grating row tapers
                insts += i3.SRef(reference=swg_l,
                                 name="SidewallGratWg" + str(ii),
                                 transformation=t_swg)
                # insts += i3.SRef(reference=taper_swg_l, name="SwgTaper_West" + str(ii), transformation=t_taper_swg_w)
                # insts += i3.SRef(reference=taper_swg_l, name="SwgTaper_East" + str(ii), transformation=t_taper_swg_e)
                insts += i3.SRef(reference=taper_swg,
                                 name="SwgTaper_West" + str(ii),
                                 transformation=t_taper_swg_w)
                insts += i3.SRef(reference=taper_swg,
                                 name="SwgTaper_East" + str(ii),
                                 transformation=t_taper_swg_e)

                if ii < (self.numrows - 1):

                    # Find component translations (for numrows-1)
                    flyback_offset = self.grat_wg_width / 2 + self.spacing + self.flyback_wg_width / 2
                    t_flyback = i3.Translation(
                        (0.0, ii * self.pitch + flyback_offset))
                    # t_taper_flyback_w   = vector_match_transform(taper_flyback_l.ports["out"], flyback_l.ports['in']) + t_flyback
                    # t_taper_flyback_e   = vector_match_transform(taper_flyback_l.ports["out"], flyback_l.ports['out'],
                    #                                        mirrored=True) + t_flyback
                    t_taper_flyback_w   = vector_match_transform( taper_flyback.ports["right"],
                                                                  flyback_l.ports['in'] ) \
                                          + t_flyback
                    t_taper_flyback_e   = vector_match_transform( taper_flyback.ports["right"],
                                                                  flyback_l.ports['out'],
                                                                  mirrored = True ) \
                                          + t_flyback

                    # t_bend_e = i3.VMirror() + vector_match_transform(bend_l.ports['in'], taper_swg_l.ports["in"],mirrored=True) + t_taper_swg_e
                    t_bend_e = i3.VMirror() \
                               + vector_match_transform( bend_l.ports['in'],
                                                       taper_swg.ports["left"],
                                                       mirrored = True ) \
                               + t_taper_swg_e
                    t_bend_w = i3.VMirror() \
                               + vector_match_transform( bend_l.ports['out'],
                                                         taper_flyback.ports["left"] ) \
                               + t_taper_flyback_w \
                               + i3.Translation( (0.0, self.pitch) )

                    # Add instances (for numrows-1)

                    # flyback waveguide
                    insts += i3.SRef(reference=flyback_l,
                                     name="FlybackWg" + str(ii),
                                     transformation=t_flyback)

                    # flyback tapers
                    # insts += i3.SRef(   reference       = taper_flyback_l,
                    #                     name            = "FlybackTaper_West" + str(ii),
                    #                     transformation  = t_taper_flyback_w )
                    # insts += i3.SRef(   reference       = taper_flyback_l,
                    #                     name            = "FlybackTaper_East" + str(ii),
                    #                     transformation  = t_taper_flyback_e )
                    insts += i3.SRef(reference=taper_flyback,
                                     name="FlybackTaper_West" + str(ii),
                                     transformation=t_taper_flyback_w)
                    insts += i3.SRef(reference=taper_flyback,
                                     name="FlybackTaper_East" + str(ii),
                                     transformation=t_taper_flyback_e)

                    # bends
                    insts += i3.SRef(reference=bend_l,
                                     name="Bend_West" + str(ii),
                                     transformation=t_bend_w)
                    insts += i3.SRef(reference=bend_l,
                                     name="Bend_East" + str(ii),
                                     transformation=t_bend_e)

                # end if
            # end for loop

            return insts

        def _generate_ports(self, ports):
            """
            THIS NEEDS TO BE UPDATED TO REFLECT INPUT OUTPUT TAPERS
            """
            # ports += self.instances["SidewallGratWg0"].ports["in"]
            # ports += self.instances["SidewallGratWg"+str(self.numrows-1)].ports["out"]

            ports += i3.OpticalPort(name='in',
                                    position=self.instances["SwgTaper_West0"].
                                    ports["left"].position,
                                    angle=180.0)
            ports += i3.OpticalPort(
                name='out',
                position=self.instances["SwgTaper_East" +
                                        str(self.numrows -
                                            1)].ports["left"].position,
                angle=0.0)

            return ports
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
示例#16
0
class SerpGratingArray(i3.PCell):
    """Sidewall Grating Waveguide: Waveguide with rectangular sidewall gratings
    """

    _name_prefix = "SerpGrating"

    wg_temp = i3.WaveguideTemplateProperty(
        doc=
        "Waveguide template to use for flyback waveguides, bends, and tapers")
    bend_type = i3.StringProperty(
        default="manual",
        doc=
        "String denoting type of bend to use for connecting arcs (options: 'default', 'manual')"
    )
    taper_type = i3.StringProperty(
        default="default",
        doc=
        "String denoting type of taper to use for connecting tapers (options: 'default', 'manual')"
    )
    bend = i3.ChildCellProperty(
        doc="Bend cell to use for connecting arc waveguides")
    taper_swg = i3.ChildCellProperty(
        doc=
        "Taper cell to use for taper connectors between sidewall grating waveguides and bends"
    )
    taper_flyback = i3.ChildCellProperty(
        doc=
        "Taper cell to use for taper connectors between flyback waveguides and bends"
    )
    swg = i3.ChildCellProperty(doc="Sidewall grating waveguide cell")
    flyback = i3.ChildCellProperty(doc="Flyback waveguide cell")

    def _default_wg_temp(self):
        wg_temp = StripWgTemplate(name=self.name + "_WgTemplate")
        return wg_temp

    def _default_bend(self):
        if self.bend_type is "default":
            bend = i3.Waveguide(name=self.name + "_Bend",
                                trace_template=self.wg_temp)
        else:
            from Custom_Waveguide import CustomWaveguide
            bend = CustomWaveguide(name=self.name + "_Bend")
        return bend

    def _default_taper_swg(self):
        if self.taper_type is "default":
            from Linear_Taper import LinearTaper
            taper = LinearTaper(name=self.name + "_SwgTaper")
        else:
            from Custom_Waveguide import CustomWaveguide
            taper = CustomWaveguide(name=self.name + "_SwgTaper")
        return taper

    def _default_taper_flyback(self):
        if self.taper_type is "default":
            from Linear_Taper import LinearTaper
            taper = LinearTaper(name=self.name + "_FlybackTaper")
        else:
            from Custom_Waveguide import CustomWaveguide
            taper = CustomWaveguide(name=self.name + "_FlybackTaper")
        return taper

    def _default_swg(self):
        swg = SidewallGratingWg(name=self.name + "_SidewallGratingWg")
        return swg

    def _default_flyback(self):
        flyback = i3.Waveguide(name=self.name + "_FlybackWg",
                               trace_template=self.wg_temp)
        return flyback

    class Layout(i3.LayoutView):

        from ipkiss.technology import get_technology
        TECH = get_technology()

        # Sidewall grating waveguide properties
        period = i3.PositiveNumberProperty(default=.3,
                                           doc="Period of sidewall grating")
        duty_cycle = i3.PositiveNumberProperty(
            default=.1,
            doc="Length of grating teeth (along periodic direction)")
        grating_amp = i3.PositiveNumberProperty(
            default=.01,
            doc=
            "Width/amplitude of grating teeth (normal to periodic direction)")
        grat_wg_width = i3.PositiveNumberProperty(
            default=1.0,
            doc=
            "Width of sidewall grating waveguide core (if grating_amp=0 width of waveguide)"
        )

        # Flyback waveguide properites
        flyback_wg_width = i3.PositiveNumberProperty(
            default=0.4, doc="Width of flyback waveguide core")

        # Grating array properties
        pitch = i3.PositiveNumberProperty(
            default=16.0,
            doc=
            "Sidewall grating pitch (center-to-center distance of sidewall grating waveguides)"
        )
        spacing = i3.PositiveNumberProperty(
            doc="Gap between sidewall grating waveguides and flyback waveguides"
        )

        def _default_spacing(self):
            spacing = (self.pitch - self.grat_wg_width -
                       self.flyback_wg_width) / 2
            return spacing

        length = i3.PositiveNumberProperty(
            default=800.0,
            doc="Length of straight (untapered) waveguide sections")
        numrows = i3.PositiveIntProperty(
            default=32,
            doc=
            "Number of sidewall grating/flyback waveguide pairs in the array")

        # Taper properties
        # Properties used for taper_type = "default"
        taper_length = i3.PositiveNumberProperty(default=10.0,
                                                 doc="Taper length")
        # Properties used for taper_type = "manual"
        taper_path_flyback = i3.NumpyArrayProperty(
            doc=
            "List of coordinates denoting the center path of the taper (bend to flyback waveguide)"
        )
        taper_width_flyback = i3.NumpyArrayProperty(
            doc=
            "List of taper widths normal to each point on the path (bend to flyback waveguide)"
        )
        taper_path_swg = i3.NumpyArrayProperty(
            doc=
            "List of coordinates denoting the center path of the taper (bend to sidewall grating waveguide)"
        )
        taper_width_swg = i3.NumpyArrayProperty(
            doc=
            "List of taper widths normal to each point on the path (bend to sidewall grating waveguide)"
        )

        def _default_taper_path_flyback(self):
            #Default is a straight linear taper
            path = np.array([[0.0, 0.0], [self.taper_length, 0.0]], np.float_)
            return path

        def _default_taper_width_flyback(self):
            # Default is a straight linear taper
            widths = np.array([self.bend_width, self.flyback_wg_width],
                              np.float_)
            return widths

        def _default_taper_path_swg(self):
            #Default is a straight linear taper
            path = np.array([[0.0, 0.0], [self.taper_length, 0.0]], np.float_)
            return path

        def _default_taper_width_swg(self):
            # Default is a straight linear taper
            widths = np.array([self.bend_width, self.grat_wg_width], np.float_)
            return widths

        # Bend properties
        # Properties used for bend_type = "default"
        bend_width = i3.PositiveNumberProperty(
            default=TECH.WG.CORE_WIDTH,
            doc="Width of waveguides in bend sections")
        # Properties used for bend_type = "manual"
        arc_path = i3.NumpyArrayProperty(
            doc=
            "List of coordinates denoting the center path of the arc connectors (going from sidewall grating waveguide to flyback waveguide"
        )
        arc_width = i3.NumpyArrayProperty(
            doc=
            "List of arc widths normal to each point on the path (going from sidewall grating waveguide to flyback waveguide"
        )

        def _default_arc_path(self):
            if self.pitch == 16.0:
                #Use pregenerated adiabatic bends (TX)
                pathwidth = np.loadtxt("./bend_data/txbend.txt", np.float_)
                arc_path = pathwidth[:, :2]
            elif self.pitch == 16.516:
                # Use pregenerated adiabatic bends (RX)
                pathwidth = np.loadtxt("./bend_data/rxbend.txt", np.float_)
                arc_path = pathwidth[:, :2]
            else:
                # Default is 180 arc
                arc_path = np.zeros([181, 2], np.float_)
                bend_rad = (self.grat_wg_width / 2 + self.spacing +
                            self.flyback_wg_width / 2) / 2
                for ii in range(181):
                    angle = np.pi / 180.0 * ii
                    arc_path[ii, :] = bend_rad * np.array(
                        [-np.sin(angle), np.cos(angle)], np.float_)

            return arc_path

        def _default_arc_width(self):
            if self.pitch == 16.0:
                #Use pregenerated adiabatic bends (TX)
                pathwidth = np.loadtxt("./bend_data/txbend.txt", np.float_)
                arc_width = pathwidth[:, 2]
            elif self.pitch == 16.516:
                #Use pregenerated adiabatic bends (RX)
                pathwidth = np.loadtxt("./bend_data/rxbend.txt", np.float_)
                arc_width = pathwidth[:, 2]
            else:
                #Default is uniform width with default core_width
                arc_width = np.ones([181], np.float_)
                arc_width = arc_width * self.bend_width
            return arc_width

        def validate_properties(self):
            """Check whether the combination of properties is valid."""
            if (self.grat_wg_width + self.flyback_wg_width +
                    2 * self.spacing) != self.pitch:
                raise i3.PropertyValidationError(
                    self,
                    "Array incorrectly overspecified (pitch=/=wg_widths+spacing",
                    {"pitch": self.pitch})
            return True

        @i3.cache()
        def _get_components(self):
            # Make waveguides
            swg_l = self.cell.swg.get_default_view(i3.LayoutView)
            swg_l.set(period=self.period,
                      duty_cycle=self.duty_cycle,
                      grating_amp=self.grating_amp,
                      wg_width=self.grat_wg_width,
                      length=self.length)
            flyback_l = self.cell.flyback.get_default_view(i3.LayoutView)
            flyback_path = [(0.0, 0.0), (self.length, 0.0)]
            wg_temp_flyback = self.cell.wg_temp.get_default_view(i3.LayoutView)
            wg_temp_flyback.set(core_width=self.flyback_wg_width)
            flyback_l.set(trace_template=wg_temp_flyback, shape=flyback_path)

            # Center-to-center distance between sidewall grating waveguide and flyback waveguide
            flyback_offset = self.grat_wg_width / 2 + self.spacing + self.flyback_wg_width / 2

            # Make bends
            bend_l = self.cell.bend.get_default_view(i3.LayoutView)
            if self.cell.bend_type is "default":
                # Default waveguide 180 arc
                bend_rad = flyback_offset / 2
                arc = i3.ShapeArc(center=(0.0, 0.0),
                                  radius=bend_rad,
                                  start_angle=89.0,
                                  end_angle=270.0)
                wg_temp_bend = self.cell.wg_temp.get_default_view(
                    i3.LayoutView)
                wg_temp_bend.set(core_width=self.bend_width)
                bend_l.set(trace_template=wg_temp_bend, shape=arc)
            else:
                # Custom bend pcell
                bend_l.set(wg_path=self.arc_path,
                           wg_width=self.arc_width,
                           start_angle=180.0,
                           end_angle=0.0)

            # Make tapers
            taper_flyback_l = self.cell.taper_flyback.get_default_view(
                i3.LayoutView)
            taper_swg_l = self.cell.taper_swg.get_default_view(i3.LayoutView)
            if self.cell.taper_type is "default":
                # Linear taper pcell
                if self.cell.bend_type is "default":
                    flyback_bend_width = self.bend_width
                    swg_bend_width = self.bend_width
                else:
                    arcsize = self.arc_width.shape
                    arclength = arcsize[0]
                    flyback_bend_width = self.arc_width[arclength - 1]
                    swg_bend_width = self.arc_width[0]

                taper_flyback_l.set(length=self.taper_length,
                                    wg_width_in=flyback_bend_width,
                                    wg_width_out=self.flyback_wg_width)
                taper_swg_l.set(length=self.taper_length,
                                wg_width_in=swg_bend_width,
                                wg_width_out=self.grat_wg_width)
            else:
                # Custom taper pcell
                taper_flyback_l.set(wg_path=self.taper_path_flyback,
                                    wg_width=self.taper_width_flyback,
                                    start_angle=0.0,
                                    end_angle=0.0)
                taper_swg_l.set(wg_path=self.taper_path_swg,
                                wg_width=self.taper_width_swg,
                                start_angle=0.0,
                                end_angle=0.0)

            return swg_l, flyback_l, bend_l, taper_swg_l, taper_flyback_l

        def _generate_instances(self, insts):
            swg_l, flyback_l, bend_l, taper_swg_l, taper_flyback_l = self._get_components(
            )

            for ii in range(self.numrows):
                # Find component translations (for all numrows)
                t_swg = i3.Translation((0.0, ii * self.pitch))
                t_taper_swg_w = vector_match_transform(
                    taper_swg_l.ports["out"], swg_l.ports['in']) + t_swg
                t_taper_swg_e = vector_match_transform(
                    taper_swg_l.ports["out"],
                    swg_l.ports['out'],
                    mirrored=True) + t_swg
                # Add instances (for all numrows)
                insts += i3.SRef(reference=swg_l,
                                 name="SidewallGratWg" + str(ii),
                                 transformation=t_swg)
                insts += i3.SRef(reference=taper_swg_l,
                                 name="SwgTaper_West" + str(ii),
                                 transformation=t_taper_swg_w)
                insts += i3.SRef(reference=taper_swg_l,
                                 name="SwgTaper_East" + str(ii),
                                 transformation=t_taper_swg_e)
                if ii < (self.numrows - 1):
                    # Find component translations (for numrows-1)
                    flyback_offset = self.grat_wg_width / 2 + self.spacing + self.flyback_wg_width / 2
                    t_flyback = i3.Translation(
                        (0.0, ii * self.pitch + flyback_offset))
                    t_taper_flyback_w = vector_match_transform(
                        taper_flyback_l.ports["out"],
                        flyback_l.ports['in']) + t_flyback
                    t_taper_flyback_e = vector_match_transform(
                        taper_flyback_l.ports["out"],
                        flyback_l.ports['out'],
                        mirrored=True) + t_flyback
                    t_bend_e = i3.VMirror() + vector_match_transform(
                        bend_l.ports['in'],
                        taper_swg_l.ports["in"],
                        mirrored=True) + t_taper_swg_e
                    t_bend_w = i3.VMirror() + vector_match_transform(
                        bend_l.ports['out'], taper_flyback_l.ports["in"]
                    ) + t_taper_flyback_w + i3.Translation((0.0, self.pitch))
                    # Add instances (for numrows-1)
                    insts += i3.SRef(reference=flyback_l,
                                     name="FlybackWg" + str(ii),
                                     transformation=t_flyback)
                    insts += i3.SRef(reference=taper_flyback_l,
                                     name="FlybackTaper_West" + str(ii),
                                     transformation=t_taper_flyback_w)
                    insts += i3.SRef(reference=taper_flyback_l,
                                     name="FlybackTaper_East" + str(ii),
                                     transformation=t_taper_flyback_e)
                    insts += i3.SRef(reference=bend_l,
                                     name="Bend_West" + str(ii),
                                     transformation=t_bend_w)
                    insts += i3.SRef(reference=bend_l,
                                     name="Bend_East" + str(ii),
                                     transformation=t_bend_e)

            return insts

        def _generate_ports(self, ports):
            ports += self.instances["SidewallGratWg0"].ports["in"]
            ports += self.instances["SidewallGratWg" +
                                    str(self.numrows - 1)].ports["out"]
            return ports
示例#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
示例#18
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()
示例#19
0
class my_dc(PlaceAndAutoRoute):
    dc = i3.ChildCellProperty()
    dc2 = i3.ChildCellProperty()
    WG1 = i3.ChildCellProperty()
    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,
                     core_process=i3.TECH.PROCESS.WG)
        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_wg_dc2(self):
        wg_dc2 = WireWaveguideTemplate(name="dc2_template")
        wg_dc2.Layout(core_width=2.8, cladding_width=2.8 + 16.0)
        return wg_dc2

    def _default_WG1(self):
        WG1 = i3.Waveguide(name="straight{}".format(str(self.width)),
                           trace_template=self.wg_t1)
        return WG1

    def _default_WG2(self):
        WG2 = WireWaveguideTransitionLinear(
            name="taper{}".format(str(self.width)),
            start_trace_template=self.wg_t1,
            end_trace_template=self.trace_template)
        return WG2

    def _default_dc(self):
        dc = BendDirectionalCoupler(name="DC_gap_1.5_l_923",
                                    trace_template1=self.trace_template,
                                    coupler_length=923.0)
        dc.Layout(
            coupler_spacing=1.5 + 3.8,
            bend_radius=300.0,
            # manhattan=True,
            # straight_after_bend=600.0,
            bend_angle=90.0)
        return dc

    def _default_dc2(self):
        dc2 = BendDirectionalCoupler(name="DC_gap_2_l_888",
                                     trace_template1=self.wg_dc2,
                                     coupler_length=888.0)
        dc2.Layout(
            coupler_spacing=2 + 2.8,
            bend_radius=300.0,
            # manhattan=True,
            bend_angle=90.0)
        return dc2

    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
        return child_cells

    def _default_links(self):
        links = [
            ("taper0:out", "dircoup1:in2"), ("taper1:out", "dircoup1:in1"),
            ("taper2:out", "dircoup1:out2"), ("taper3:out", "dircoup1:out1"),
            ("taper4:out", "dircoup2:in2"), ("taper5:out", "dircoup2:in1"),
            ("taper6:out", "dircoup2:out2"), ("taper7:out", "dircoup2:out1")
        ]
        return links

    class Layout(PlaceAndAutoRoute.Layout):
        def _default_WG1(self):
            layout_WG1 = self.cell.WG1.get_default_view(i3.LayoutView)
            layout_WG1.set(shape=[(0.0, 0.0), (150.0, 0.0)])
            return layout_WG1

        def _default_WG2(self):
            layout_WG2 = self.cell.WG2.get_default_view(i3.LayoutView)
            layout_WG2.set(start_position=(0.0, 0.0),
                           end_position=(300.0, 0.0))
            return layout_WG2

        # def _default_dc(self):
        #     layout_dc = self.cell.dc.get_default_view(i3.LayoutView)
        #     layout_dc.set(coupler_spacing=2.5 + 3.8,
        #                   bend_radius=300.0,
        #                   manhattan=True,
        #                   # straight_after_bend=6.0,
        #                   bend_angle=90.0)
        #     return layout_dc

        def _default_child_transformations(self):
            trans = dict()
            trans["dircoup1"] = (1650, 0)
            trans["dircoup2"] = (4950, 0)
            # for counter in range(0, 8, 1):
            #     print counter
            #     trans['straight' + str(counter)] = (2000 * (counter + 1), 0)
            #     trans["taper" + str(counter)] = (0, 2000 * (counter + 1))
            trans["straight0"] = (0, 4000)
            trans["straight1"] = (0, -4000)
            trans["straight2"] = (3150, 2000)
            trans["straight3"] = (3150, -6000)
            trans["straight4"] = (3300, 2000)
            trans["straight5"] = (3300, -6000)
            trans["straight6"] = (6450, 4000)
            trans["straight7"] = (6450, -4000)
            trans["taper0"] = (150, 4000)
            trans["taper1"] = (150, -4000)
            trans["taper2"] = i3.HMirror(150) + i3.Translation((2850, 2000))
            trans["taper3"] = i3.HMirror(150) + i3.Translation((2850, -6000))
            trans["taper4"] = (3450, 2000)
            trans["taper5"] = (3450, -6000)
            trans["taper6"] = i3.HMirror(150) + i3.Translation((6150, 4000))
            trans["taper7"] = i3.HMirror(150) + i3.Translation((6150, -4000))
            return trans

        def _default_bend_radius(self):
            bend_radius = 300
            return bend_radius

        # def _default_start_straight(self):
        #     start_straight = 100.0
        #     return start_straight

        def _generate_elements(self, elems):

            elems += i3.PolygonText(
                layer=i3.TECH.PPLAYER.WG.TEXT,
                text='Name={}_{}'.format(self.cell.dc.name,
                                         self.cell.wg_t1.name),
                coordinate=(1350.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.dc2.name,
                                         self.cell.wg_t1.name),
                coordinate=(4650.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={}_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)

            return elems
示例#20
0
class MMI2112(PlaceAndAutoRoute):
    wg_sm = i3.WaveguideTemplateProperty()
    mmi_trace_template = i3.WaveguideTemplateProperty()
    mmi_access_template = i3.WaveguideTemplateProperty()

    mmi1_12 = i3.ChildCellProperty()
    mmi1_21 = i3.ChildCellProperty()
    WG2 = i3.ChildCellProperty()

    # def _default_external_port_names(self):
    #     ports = dict()
    #     ports["MMI1b:in1"] = "vertical_in"
    #     ports["MMI1b:in2"] = "out"
    #     return ports

    def _default_links(self):
        links = [("taper:out", "taper2:out")]
        return links

    def _default_child_cells(self):
        child_cells = {
            "MMI1a": self.mmi1_12,
            "MMI1b": self.mmi1_21,
            "taper": self.WG2,
            "taper2": self.WG2
        }
        return child_cells

    def _default_trace_template(self):
        wg_sm2 = WireWaveguideTemplate()
        wg_sm2.Layout(core_width=3.1, cladding_width=3.1 + 16.0)
        return wg_sm2

    def _default_mmi1_12(self):
        mmi12 = MMI1x2Tapered(mmi_trace_template=self.mmi_trace_template,
                              input_trace_template=self.mmi_access_template,
                              output_trace_template=self.mmi_access_template,
                              trace_template=self.wg_sm,
                              port_labels=["out1", "out2"],
                              )

        return mmi12

    def _default_mmi1_21(self):
        mmi21 = MMI2x1Tapered(mmi_trace_template=self.mmi_trace_template,
                              input_trace_template=self.mmi_access_template,
                              output_trace_template=self.mmi_access_template,
                              trace_template=self.wg_sm,
                              port_labels=["in1", "in2"],
                              )

        return mmi21

    def _default_WG2(self):
        WG2 = WireWaveguideTransitionLinear(start_trace_template=self.mmi_access_template,
                                            end_trace_template=self.trace_template)
        return WG2

    def _default_wg_sm(self):
        wg_sm = WireWaveguideTemplate()
        wg_sm.Layout(core_width=3.8, cladding_width=3.8 + 16.0)
        return wg_sm

    def _default_mmi_trace_template(self):
        mmi_trace_template = WireWaveguideTemplate()
        mmi_trace_template.Layout(core_width=20.0, cladding_width=20.0 + 16.0)  # MMI_width
        return mmi_trace_template

    def _default_mmi_access_template(self):
        mmi_access_template = WireWaveguideTemplate()
        mmi_access_template.Layout(core_width=9.0, cladding_width=9.0 + 16.0)
        return mmi_access_template

    class Layout(PlaceAndAutoRoute.Layout):
        length = i3.PositiveNumberProperty(doc="MMI length", default=97)

        # def _default_WG1(self):
        #     layout_WG1 = self.cell.WG1.get_default_view(i3.LayoutView)
        #     layout_WG1.set(shape=[(0.0, 0.0), (150.0, 0.0)])
        #     return layout_WG1
        #
        def _default_WG2(self):
            layout_WG2 = self.cell.WG2.get_default_view(i3.LayoutView)
            layout_WG2.set(start_position=(0.0, 0.0), end_position=(200.0, 0.0))
            return layout_WG2

        def _default_mmi1_12(self):
            layout_mmi1_12 = self.cell.mmi1_12.get_default_view(i3.LayoutView)
            layout_mmi1_12.set(transition_length=200.0, length=self.length, trace_spacing=11.0)
            return layout_mmi1_12

        def _default_mmi1_21(self):
            layout_mmi1_21 = self.cell.mmi1_21.get_default_view(i3.LayoutView)
            layout_mmi1_21.set(transition_length=200.0, length=self.length, trace_spacing=11.0)
            # print layout_mmi1_21.ports['in1'].x
            return layout_mmi1_21

        def _default_child_transformations(self):
            # print self.cell.mmi1_12.get_default_view(i3.LayoutView).length
            # print self.cell.mmi1_21.get_default_view(i3.LayoutView).ports['in1'].x
            # print self.cell.mmi1_21.get_default_view(i3.LayoutView).ports['out'].x
            # a = self.cell.mmi1_21.get_default_view(i3.LayoutView).ports['out'].x - self.cell.mmi1_21.get_default_view(i3.LayoutView).ports['in1'].x
            a = self.cell.mmi1_21.get_default_view(i3.LayoutView).ports['out'].x
            child_transformations = {"MMI1a": (a + 490, 0),
                                     "taper": (a, 0),
                                     "taper2": i3.HMirror(0.0) + i3.Translation((a + 490, 0))
                                     # "WGup": (0, 4000),
                                     # "WGuptaper": (0, 4000),
                                     # "WGdown": (0, -4000),
                                     # "WGdowntaper": (0, -4000),
                                     # "WGuptaper2": i3.HMirror() + i3.Translation((3400, 4000)),
                                     # "WGdowntaper2": i3.HMirror() + i3.Translation((3400, -4000)),
                                     # "WGup2": (3250, 4000),
                                     # "WGdown2": (3250, -4000)
                                     }
            return child_transformations


# mmi1 = MMI2112()
# mmi1_layout = mmi1.Layout(length=120)
# mmi1_layout.visualize(annotate=True)
# print mmi1_layout.ports
# mmi1_layout.write_gdsii("MMI2112_V5.gds")
示例#21
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
示例#22
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
示例#23
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='spiral' + str(dl) + str(self.sm_width),
                trace_template=self.trace_template,
                n_o_loops=8,
            )
            layout = cell.Layout(
                angle_step=30,
                inner_size=[700, 1400],
                bend_radius=self.gap_inc_vec[l],
                manhattan=False,
                spacing=2 * 8 + self.sm_width + 5,
            )
            print layout.trace_length()

            MMI22_list.append(cell)

        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
        # 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", "ring1:out2"),
            # ("taper5:out", "ring1:in1"),
            # ("taper6:out", "ring1:in2"),
            # ("taper7:out", "ring1:out1"),
            #
            # ("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 = 3000
            # trans["dircoup1"] = (1650, 0)
            # trans["dircoup2"] = (4950, 0)
            # trans['mzi_22_22_0'] = (0, 0)
            trans['ring0'] = (1300, -2000)
            # trans['ring1'] = i3.VMirror(0) + i3.Translation((1300, 2000))
            trans['ring1'] = (1300 + column, -2000)
            # trans['ring2'] = (1500, 0 + 2 * column)
            # trans['ring3'] = (1500, 0 + 3 * column)

            trans["taper0"] = (0, -4000)

            trans["taper1"] = i3.HMirror(0) + i3.Translation((3000, -3500))

            trans["taper2"] = (0 + column, -3500)

            trans["taper3"] = i3.HMirror(0) + i3.Translation(
                (3000 + column, -4000))

            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.dc.name, self.cell.wg_t1.name),
            #                         coordinate=(1350.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.dc2.name, self.cell.wg_t1.name),
            #                         coordinate=(4650.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={}_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)

            return elems
示例#24
0
class MMI2112(PlaceAndAutoRoute):
    wg_sm = i3.WaveguideTemplateProperty()
    mmi_trace_template = i3.WaveguideTemplateProperty()
    mmi_access_template = i3.WaveguideTemplateProperty()

    mmi1_12 = i3.ChildCellProperty()
    mmi1_21 = i3.ChildCellProperty()
    WG2 = i3.ChildCellProperty()

    # def _default_external_port_names(self):
    #     ports = dict()
    #     ports["MMI1b:in1"] = "vertical_in"
    #     ports["MMI1b:in2"] = "out"
    #     return ports

    def _default_links(self):
        links = [("taper:out", "taper2:out")]
        return links

    def _default_child_cells(self):
        child_cells = {
            "MMI1a": self.mmi1_12,
            "MMI1b": self.mmi1_21,
            "taper": self.WG2,
            "taper2": self.WG2
        }
        return child_cells

    def _default_trace_template(self):
        wg_sm2 = WireWaveguideTemplate()
        wg_sm2.Layout(core_width=3.1, cladding_width=3.1 + 16.0)
        return wg_sm2

    def _default_mmi1_12(self):
        mmi12 = MMI1x2Tapered(
            mmi_trace_template=self.mmi_trace_template,
            input_trace_template=self.mmi_access_template,
            output_trace_template=self.mmi_access_template,
            trace_template=self.wg_sm,
            port_labels=["out1", "out2"],
        )

        return mmi12

    def _default_mmi1_21(self):
        mmi21 = MMI2x1Tapered(
            mmi_trace_template=self.mmi_trace_template,
            input_trace_template=self.mmi_access_template,
            output_trace_template=self.mmi_access_template,
            trace_template=self.wg_sm,
            port_labels=["in1", "in2"],
        )

        return mmi21

    def _default_WG2(self):
        WG2 = WireWaveguideTransitionLinear(
            start_trace_template=self.mmi_access_template,
            end_trace_template=self.trace_template)
        return WG2

    def _default_wg_sm(self):
        wg_sm = WireWaveguideTemplate()
        wg_sm.Layout(core_width=3.8, cladding_width=3.8 + 16.0)
        return wg_sm

    def _default_mmi_trace_template(self):
        mmi_trace_template = WireWaveguideTemplate()
        mmi_trace_template.Layout(core_width=20.0,
                                  cladding_width=20.0 + 16.0)  # MMI_width
        return mmi_trace_template

    def _default_mmi_access_template(self):
        mmi_access_template = WireWaveguideTemplate()
        mmi_access_template.Layout(core_width=9.0, cladding_width=9.0 + 16.0)
        return mmi_access_template

    class Layout(PlaceAndAutoRoute.Layout):
        length = i3.PositiveNumberProperty(doc="MMI length", default=97)

        # def _default_WG1(self):
        #     layout_WG1 = self.cell.WG1.get_default_view(i3.LayoutView)
        #     layout_WG1.set(shape=[(0.0, 0.0), (150.0, 0.0)])
        #     return layout_WG1
        #
        def _default_WG2(self):
            layout_WG2 = self.cell.WG2.get_default_view(i3.LayoutView)
            layout_WG2.set(start_position=(0.0, 0.0),
                           end_position=(200.0, 0.0))
            return layout_WG2

        def _default_mmi1_12(self):
            layout_mmi1_12 = self.cell.mmi1_12.get_default_view(i3.LayoutView)
            layout_mmi1_12.set(transition_length=200.0,
                               length=self.length,
                               trace_spacing=11.0)
            return layout_mmi1_12

        def _default_mmi1_21(self):
            layout_mmi1_21 = self.cell.mmi1_21.get_default_view(i3.LayoutView)
            layout_mmi1_21.set(name="MMI2112_l_{}".format(str(self.length)),
                               transition_length=200.0,
                               length=self.length,
                               trace_spacing=11.0)
            # print layout_mmi1_21.ports['in1'].x
            return layout_mmi1_21

        def _default_child_transformations(self):
            # print self.cell.mmi1_12.get_default_view(i3.LayoutView).length
            # print self.cell.mmi1_21.get_default_view(i3.LayoutView).ports['in1'].x
            # print self.cell.mmi1_21.get_default_view(i3.LayoutView).ports['out'].x
            # a = self.cell.mmi1_21.get_default_view(i3.LayoutView).ports['out'].x - self.cell.mmi1_21.get_default_view(i3.LayoutView).ports['in1'].x
            a = self.cell.mmi1_21.get_default_view(
                i3.LayoutView).ports['out'].x
            child_transformations = {
                "MMI1a": (a + 490, 0),
                "taper": (a, 0),
                "taper2": i3.HMirror(0.0) + i3.Translation((a + 490, 0))
                # "WGup": (0, 4000),
                # "WGuptaper": (0, 4000),
                # "WGdown": (0, -4000),
                # "WGdowntaper": (0, -4000),
                # "WGuptaper2": i3.HMirror() + i3.Translation((3400, 4000)),
                # "WGdowntaper2": i3.HMirror() + i3.Translation((3400, -4000)),
                # "WGup2": (3250, 4000),
                # "WGdown2": (3250, -4000)
            }
            return child_transformations

        def _generate_elements(self, elems):

            elems += i3.PolygonText(
                layer=i3.TECH.PPLAYER.WG.TEXT,
                text='Name={}_port_20'.format(
                    self.cell.mmi1_21.get_default_view(i3.LayoutView).name),
                coordinate=(200.0, 100.0),
                alignment=(i3.TEXT_ALIGN_LEFT, i3.TEXT_ALIGN_LEFT),
                font=2,
                height=20.0)

            return elems
示例#25
0
class MMI2112(PlaceAndAutoRoute):
    wg_t1 = i3.WaveguideTemplateProperty()
    wg_sm = i3.WaveguideTemplateProperty()
    wg_sm2 = i3.WaveguideTemplateProperty()
    mmi_trace_template = i3.WaveguideTemplateProperty()
    mmi_access_template = i3.WaveguideTemplateProperty()

    mmi1_12 = i3.ChildCellProperty()
    mmi1_21 = i3.ChildCellProperty()
    # mmi1_12_taper = i3.ChildCellProperty()
    # mmi1_21_taper = i3.ChildCellProperty()
    WG1 = i3.ChildCellProperty()
    WG2 = i3.ChildCellProperty()

    length = i3.PositiveNumberProperty(doc="MMI length", default=97)

    def _default_links(self):
        links = [
            # ("MMI1a:out2", "WGuptaper2:out"),
            # ("MMI1a:out1", "WGdowntaper2:out"),
            ("MMI1b:out", "MMI1a:in"),
            # ("WGuptaper:out", "MMI1b:in2"),
            # ("WGdowntaper:out", "MMI1b:in1")
        ]
        return links

    def _default_child_cells(self):
        child_cells = {
            "MMI1a": self.mmi1_12,
            "MMI1b": self.mmi1_21,
            # "WGup": self.WG1,
            # "WGdown": self.WG1,
            # "WGup2": self.WG1,
            # "WGdown2": self.WG1,
            # "WGuptaper": self.WG2,
            # "WGdowntaper": self.WG2,
            # "WGuptaper2": self.WG2,
            # "WGdowntaper2": self.WG2
        }
        return child_cells

    def _default_trace_template(self):
        trace_template = self.wg_sm2
        return trace_template

    def _default_mmi1_12(self):
        mmi12 = MMI1x2Tapered(
            mmi_trace_template=self.mmi_trace_template,
            input_trace_template=self.mmi_access_template,
            output_trace_template=self.mmi_access_template,
            trace_template=self.wg_sm,
            port_labels=["out1", "out2"],
        )

        mmi12.Layout(transition_length=200.0,
                     length=self.length,
                     trace_spacing=11.0)

        mmi1_12_taper = AutoTransitionPorts(name="MMI12",
                                            contents=mmi12,
                                            port_labels=['in'],
                                            trace_template=self.wg_sm2)
        mmi1_12_taper.Layout(transition_length=200.0)

        return mmi1_12_taper

    # def _default_mmi1_12_taper(self):
    #     mmi1_12_taper = AutoTransitionPorts(contents=self.mmi1_12,
    #                                         port_labels=['in'],
    #                                         trace_template=self.wg_sm2)
    #     mmi1_12_taper.Layout(transition_length=200.0)
    #     return mmi1_12_taper

    def _default_mmi1_21(self):
        mmi21 = MMI2x1Tapered(
            mmi_trace_template=self.mmi_trace_template,
            input_trace_template=self.mmi_access_template,
            output_trace_template=self.mmi_access_template,
            trace_template=self.wg_sm,
            port_labels=["in1", "in2"],
        )
        mmi21.Layout(transition_length=200.0,
                     length=self.length,
                     trace_spacing=11.0)

        mmi1_12_taper = AutoTransitionPorts(name="MMI21",
                                            contents=mmi21,
                                            port_labels=['out'],
                                            trace_template=self.wg_sm2)
        mmi1_12_taper.Layout(transition_length=200.0)

        return mmi1_12_taper

    # def _default_mmi1_21_taper(self):
    #     mmi1_21_taper = AutoTransitionPorts(contents=self.mmi1_21,
    #                                         port_labels=['out'],
    #                                         trace_template=self.wg_sm2)
    #     return mmi1_21_taper

    def _default_WG2(self):
        WG2 = WireWaveguideTransitionLinear(start_trace_template=self.wg_t1,
                                            end_trace_template=self.wg_sm)
        return WG2

    def _default_WG1(self):
        WG1 = i3.Waveguide(name="Dongbo", trace_template=self.wg_t1)
        return WG1

    def _default_wg_t1(self):
        wg_t1 = WireWaveguideTemplate()
        wg_t1.Layout(core_width=15.0,
                     cladding_width=15.0 + 16.0,
                     core_process=i3.TECH.PROCESS.WG)
        return wg_t1

    def _default_wg_sm(self):
        wg_sm = WireWaveguideTemplate()
        wg_sm.Layout(core_width=3.8, cladding_width=3.8 + 16.0)
        return wg_sm

    def _default_wg_sm2(self):
        wg_sm2 = WireWaveguideTemplate()
        wg_sm2.Layout(core_width=3.1, cladding_width=3.1 + 16.0)
        return wg_sm2

    def _default_mmi_trace_template(self):
        mmi_trace_template = WireWaveguideTemplate()
        mmi_trace_template.Layout(core_width=20.0,
                                  cladding_width=20.0 + 16.0)  # MMI_width
        return mmi_trace_template

    def _default_mmi_access_template(self):
        mmi_access_template = WireWaveguideTemplate()
        mmi_access_template.Layout(core_width=9.0, cladding_width=9.0 + 16.0)
        return mmi_access_template

    # def _default_child_transformations(self):
    #     child_transformations = {"MMI1a": (500 + self.length, 0)
    #                              # "MMI1b": (1300, 0),
    #                              # "WGup": (0, 4000),
    #                              # "WGuptaper": (0, 4000),
    #                              # "WGdown": (0, -4000),
    #                              # "WGdowntaper": (0, -4000),
    #                              # "WGuptaper2": i3.HMirror() + i3.Translation((3400, 4000)),
    #                              # "WGdowntaper2": i3.HMirror() + i3.Translation((3400, -4000)),
    #                              # "WGup2": (3250, 4000),
    #                              # "WGdown2": (3250, -4000)
    #                              }
    #     return child_transformations

    class Layout(PlaceAndAutoRoute.Layout):

        # def _default_WG1(self):
        #     layout_WG1 = self.cell.WG1.get_default_view(i3.LayoutView)
        #     layout_WG1.set(shape=[(0.0, 0.0), (150.0, 0.0)])
        #     return layout_WG1
        #
        # def _default_WG2(self):
        #     layout_WG2 = self.cell.WG2.get_default_view(i3.LayoutView)
        #     layout_WG2.set(start_position=(150.0, 0.0), end_position=(450.0, 0.0))
        #     return layout_WG2

        # def _default_mmi1_12(self):
        #     layout_mmi1_12 = self.cell.mmi1_12.get_default_view(i3.LayoutView)
        #     layout_mmi1_12.set(transition_length=200.0, length=self.length, trace_spacing=11.0)
        #     return layout_mmi1_12

        # def _default_mmi1_12_taper(self):
        #     layout_mmi1_12_taper = self.cell.mmi1_12_taper.get_default_view(i3.LayoutView)
        #     layout_mmi1_12_taper.set(transition_length=200.0)
        #     return layout_mmi1_12_taper

        # def _default_mmi1_21(self):
        #     layout_mmi1_21 = self.cell.mmi1_21.get_default_view(i3.LayoutView)
        #     layout_mmi1_21.set(transition_length=200.0, length=self.length, trace_spacing=11.0)
        #     # print layout_mmi1_21.ports['in1'].x
        #     return layout_mmi1_21

        def _default_child_transformations(self):
            # print self.cell.mmi1_12.get_default_view(i3.LayoutView).length
            # print self.cell.mmi1_21.get_default_view(i3.LayoutView).ports['in1'].x
            # print self.cell.mmi1_21.get_default_view(i3.LayoutView).ports['out'].x
            a = self.cell.mmi1_21.get_default_view(
                i3.LayoutView
            ).ports['out'].x - self.cell.mmi1_21.get_default_view(
                i3.LayoutView).ports['in1'].x
            child_transformations = {
                "MMI1a": (a + 90, 0),
                # "MMI1b": (1300, 0),
                # "WGup": (0, 4000),
                # "WGuptaper": (0, 4000),
                # "WGdown": (0, -4000),
                # "WGdowntaper": (0, -4000),
                # "WGuptaper2": i3.HMirror() + i3.Translation((3400, 4000)),
                # "WGdowntaper2": i3.HMirror() + i3.Translation((3400, -4000)),
                # "WGup2": (3250, 4000),
                # "WGdown2": (3250, -4000)
            }
            return child_transformations

        def _default_bend_radius(self):
            bend_radius = 300
            return bend_radius
示例#26
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
示例#27
0
class MMI2112(PlaceAndAutoRoute):
    wg_sm = i3.WaveguideTemplateProperty()
    mmi_trace_template = i3.WaveguideTemplateProperty()
    mmi_access_template = i3.WaveguideTemplateProperty()

    mmi1_12 = i3.ChildCellProperty()
    mmi1_21 = i3.ChildCellProperty()
    WG2 = i3.ChildCellProperty()

    def _default_links(self):
        links = [("taper:out", "taper2:out")]
        return links

    def _default_child_cells(self):
        child_cells = {
            "MMI1a": self.mmi1_12,
            "MMI1b": self.mmi1_21,
            "taper": self.WG2,
            "taper2": self.WG2
        }
        return child_cells

    def _default_trace_template(self):
        wg_sm2 = WireWaveguideTemplate()
        wg_sm2.Layout(core_width=3.1, cladding_width=3.1 + 24.0)
        return wg_sm2

    def _default_mmi1_12(self):
        mmi12 = MMI1x2Tapered(mmi_trace_template=self.mmi_trace_template,
                              input_trace_template=self.mmi_access_template,
                              output_trace_template=self.mmi_access_template,
                              trace_template=self.wg_sm,
                              port_labels=["out1", "out2"],
                              )

        return mmi12

    def _default_mmi1_21(self):
        mmi21 = MMI2x1Tapered(mmi_trace_template=self.mmi_trace_template,
                              input_trace_template=self.mmi_access_template,
                              output_trace_template=self.mmi_access_template,
                              trace_template=self.wg_sm,
                              port_labels=["in1", "in2"],
                              )

        return mmi21

    def _default_WG2(self):
        WG2 = WireWaveguideTransitionLinear(start_trace_template=self.mmi_access_template,
                                            end_trace_template=self.trace_template)
        return WG2

    def _default_wg_sm(self):
        wg_sm = WireWaveguideTemplate()
        wg_sm.Layout(core_width=3.8, cladding_width=3.8 + 24.0)
        return wg_sm

    def _default_mmi_trace_template(self):
        mmi_trace_template = WireWaveguideTemplate()
        mmi_trace_template.Layout(core_width=20.0, cladding_width=20.0 + 24.0)  # MMI_width
        return mmi_trace_template

    def _default_mmi_access_template(self):
        mmi_access_template = WireWaveguideTemplate()
        mmi_access_template.Layout(core_width=9.0, cladding_width=9.0 + 24.0)
        return mmi_access_template

    class Layout(PlaceAndAutoRoute.Layout):
        length = i3.PositiveNumberProperty(doc="MMI length", default=97)

        def _default_WG2(self):
            layout_WG2 = self.cell.WG2.get_default_view(i3.LayoutView)
            layout_WG2.set(start_position=(0.0, 0.0), end_position=(200.0, 0.0))
            return layout_WG2

        def _default_mmi1_12(self):
            layout_mmi1_12 = self.cell.mmi1_12.get_default_view(i3.LayoutView)
            layout_mmi1_12.set(transition_length=200.0, length=self.length, trace_spacing=11.0)
            return layout_mmi1_12

        def _default_mmi1_21(self):
            layout_mmi1_21 = self.cell.mmi1_21.get_default_view(i3.LayoutView)
            layout_mmi1_21.set(name="MMI2112_l_{}".format(str(self.length)), transition_length=200.0,
                               length=self.length, trace_spacing=11.0)
            # print layout_mmi1_21.ports['in1'].x
            return layout_mmi1_21

        def _default_child_transformations(self):
            a = self.cell.mmi1_21.get_default_view(i3.LayoutView).ports['out'].x
            child_transformations = {"MMI1a": (a + 490, 0),
                                     "taper": (a, 0),
                                     "taper2": i3.HMirror(0.0) + i3.Translation((a + 490, 0))

                                     }
            return child_transformations
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
示例#29
0
class v9(PlaceAndAutoRoute):
    wg_t1 = i3.WaveguideTemplateProperty()
    wg_sm = i3.WaveguideTemplateProperty()
    mmi_trace_template = i3.WaveguideTemplateProperty()
    mmi_access_template = i3.WaveguideTemplateProperty()
    length2 = i3.PositiveNumberProperty(doc="MMI2 length", default=97)
    mmi22 = i3.ChildCellProperty()
    WG1 = i3.ChildCellProperty()
    WG2 = i3.ChildCellProperty()

    def _default_links(self):
        links = [
            ("MMI1b:MMI1a_out2", "WGuptaper2:out"),
            ("MMI1b:MMI1a_out1", "WGdowntaper2:out"),
            # ("MMI1b:out","MMI1a:in"),
            ("WGuptaper:out", "MMI1b:MMI1b_in2"),
            ("WGdowntaper:out", "MMI1b:MMI1b_in1")
        ]
        return links

    def _default_child_cells(self):
        child_cells = {
            "MMI1b": self.mmi22,
            "WGup": self.WG1,
            "WGdown": self.WG1,
            "WGup2": self.WG1,
            "WGdown2": self.WG1,
            "WGuptaper": self.WG2,
            "WGdowntaper": self.WG2,
            "WGuptaper2": self.WG2,
            "WGdowntaper2": self.WG2
        }
        return child_cells

    def _default_trace_template(self):
        trace_template = self.wg_sm
        return trace_template

    def _default_mmi22(self):
        mmi22 = MMI2112(length=self.length2)
        # mmi22 = MMI2112()
        return mmi22

    def _default_WG2(self):
        WG2 = WireWaveguideTransitionLinear(start_trace_template=self.wg_t1,
                                            end_trace_template=self.wg_sm)
        return WG2

    def _default_WG1(self):
        WG1 = i3.Waveguide(name="Dongbo", trace_template=self.wg_t1)
        return WG1

    def _default_wg_t1(self):
        wg_t1 = WireWaveguideTemplate()
        wg_t1.Layout(core_width=15.0,
                     cladding_width=15.0 + 16.0,
                     core_process=i3.TECH.PROCESS.WG)
        return wg_t1

    def _default_wg_sm(self):
        wg_sm = WireWaveguideTemplate()
        wg_sm.Layout(core_width=3.8, cladding_width=3.8 + 16.0)
        return wg_sm

    def _default_mmi_trace_template(self):
        mmi_trace_template = WireWaveguideTemplate()
        mmi_trace_template.Layout(core_width=20.0,
                                  cladding_width=20.0 + 16.0)  # MMI_width
        return mmi_trace_template

    def _default_mmi_access_template(self):
        mmi_access_template = WireWaveguideTemplate()
        mmi_access_template.Layout(core_width=9.0, cladding_width=9.0 + 16.0)
        return mmi_access_template

    class Layout(PlaceAndAutoRoute.Layout):

        # length2 = i3.PositiveNumberProperty(doc="MMI2 length", default=97)

        def _default_WG1(self):
            layout_WG1 = self.cell.WG1.get_default_view(i3.LayoutView)
            layout_WG1.set(shape=[(0.0, 0.0), (150.0, 0.0)])
            return layout_WG1

        def _default_WG2(self):
            layout_WG2 = self.cell.WG2.get_default_view(i3.LayoutView)
            layout_WG2.set(start_position=(150.0, 0.0),
                           end_position=(450.0, 0.0))
            return layout_WG2

        # def _default_mmi22(self):
        #     # layout_mmi22 = self.cell.mmi22.get_default_view(i3.LayoutView)
        #     self.cell.mmi22.length = self.length2
        #     layout_mmi22 = self.cell.mmi22.get_default_view(i3.LayoutView)
        #     return layout_mmi22

        def _default_child_transformations(self):
            child_transformations = {
                "MMI1b": (1300, 0),
                "WGup": (0, 4000),
                "WGuptaper": (0, 4000),
                "WGdown": (0, -4000),
                "WGdowntaper": (0, -4000),
                "WGuptaper2": i3.HMirror() + i3.Translation((3300, 2000)),
                "WGdowntaper2": i3.HMirror() + i3.Translation((3300, -6000)),
                "WGup2": (3150, 2000),
                "WGdown2": (3150, -6000)
            }
            return child_transformations

        def _default_bend_radius(self):
            bend_radius = 300
            return bend_radius
示例#30
0
class tapered_GratingCoupler_extension(PlaceAndAutoRoute):
    gc = i3.ChildCellProperty()
    tapered_gc = i3.ChildCellProperty()
    wg_socket = i3.WaveguideTemplateProperty()
    wg = i3.ChildCellProperty()

    def _default_trace_template(self):
        wg_t = WireWaveguideTemplate()
        wg_t.Layout(core_width=0.8, cladding_width=6.8)
        return wg_t

    def _default_wg(self):
        wg = i3.RoundedWaveguide(trace_template=self.trace_template)
        return wg


    def _default_wg_socket(self):
        wg_socket = WireWaveguideTemplate()
        wg_socket.Layout(core_width=12.0, cladding_width=18.0)
        return wg_socket

    def _default_gc(self):
        gc = UniformLineGrating(trace_template=self.wg_socket)
        return gc

    def _default_tapered_gc(self):
        tapered_gc = AutoTransitionPorts(contents=self.gc, trace_template=self.trace_template, port_labels=["out"])
        return tapered_gc

    def _default_child_cells(self):
        child_cells = dict()
        child_cells["tapered_gc"] = self.tapered_gc
        child_cells["wg"] = self.wg
        return child_cells

    def _default_links(self):
        links = [("tapered_gc:out", "wg:in")]
        return links

    def _default_external_port_names(self):
        ports = dict()
        ports["tapered_gc:vertical_in"] = "vertical_in"
        ports["wg:out"] = "out"
        return ports

    class Layout(PlaceAndAutoRoute.Layout):

        period = i3.PositiveNumberProperty(doc="period of grating", default=0.95)
        n_o_periods = i3.PositiveIntProperty(doc="number of periods of grating", default=16)
        line_width = i3.PositiveNumberProperty(doc="width of the grating")
        line_length = i3.PositiveNumberProperty(doc="length of the grating", default=13.0)
        socket_length = i3.PositiveNumberProperty(doc="length of socket")
        # transition_length = i3.PositiveNumberProperty(doc="length of the taper")
        transition_length = i3.PositiveNumberProperty(doc="taper length", default=100.0)
        extension_length = i3.PositiveNumberProperty(doc="extra straight length", default=100.0)

        def _default_line_width(self):
            return self.period * 0.5

        def _default_socket_length(self):
            return self.period * self.n_o_periods + 2.0

        def _default_gc(self):
            gc_lo = self.cell.gc.get_default_view(i3.LayoutView)
            gc_lo.set(period=self.period, n_o_periods=self.n_o_periods, line_width=self.line_width, line_length=self.line_length)
            return gc_lo

        def _default_tapered_gc(self):
            tapered_gc_lo = self.cell.tapered_gc.get_default_view(i3.LayoutView)
            tapered_gc_lo.set(transition_length=self.transition_length)
            return tapered_gc_lo

        def _default_wg(self):
            wg_lo = self.cell.wg.get_default_view(i3.LayoutView)
            wg_lo.set(shape=[(0.0, 0.0), (self.extension_length, 0.0)])
            return wg_lo

        def _default_child_transformations(self):
            trans = dict()
            trans["tapered_gc"] = (0, 0)
            trans["wg"] = i3.Translation(self.tapered_gc.ports["out"].position) + i3.Translation((10, 0))
            return trans