Example #1
0
    def define_elements(self, elems):
        from ipkiss.plugins.photonics.wg.basic import WgElDefinition
        if self.extension != 0.0:
            extended_start_width = self.start_wg_definition.wg_width + (self.end_wg_definition.wg_width-self.start_wg_definition.wg_width)  * (self.extension + self.length- self.straight_extension)/self.length
        else:
            extended_start_width = self.end_wg_definition.wg_width
        end_wg_def = WgElDefinition(wg_width = extended_start_width, trench_width = self.end_wg_definition.trench_width, process = self.end_wg_definition.process)
        end_wg_def_ext = WgElDefinition(wg_width = extended_start_width+0.05, trench_width = self.end_wg_definition.trench_width-0.05, process = self.end_wg_definition.process)

        elems += WgElTaperLinear(start_position = (self.center[0] - self.extension ,self.center[1]),
                                 end_position = (self.center[0] + self.length, self.center[1]), 
                                 start_wg_def = end_wg_def,
                                 end_wg_def = self.start_wg_definition,
                                 straight_extension = (0.0, 0.0))
        if self.straight_extension > 0:
            elems += WgElTaperLinear(start_position = (self.center[0] - self.extension, self.center[1]),
                                     end_position = (self.center[0] - self.extension - self.straight_extension, self.center[1]), 
                                     start_wg_def = end_wg_def,
                                     end_wg_def = end_wg_def_ext,
                                     straight_extension = (0.0, 0.0))
   
        if self.straight_entrance > 0.0:
            elems += self.start_wg_definition(shape = [(self.center[0] + self.length ,self.center[1]), (self.center[0] + self.length + self.straight_entrance, self.center[1])])

        return elems
Example #2
0
    def define_elements(self, elems):
        # draw tip

        ## Warning: end-waveguide definition is calculated using y_spacing and tip_width, only wg-width is extracted from wg_def
        
        wg_def_stop = WgElDefinition(wg_width = self.wg_def_end.wg_width, trench_width = 0.5*(self.y_spacing-self.wg_def_end.wg_width)-1.0)
        
        elems += WgElTaperLinear(start_position = (self.tip_length + self.tip_offset, 0.0), 
                           end_position = (self.tip_offset, 0.0), 
                            start_wg_def = self.wg_def_start, 
                            end_wg_def = wg_def_stop)
        if self.extension > 0:
            wg_def = WgElDefinition(wg_width = self.wg_def_end.wg_width, trench_width = 0.5*(self.y_spacing-self.wg_def_end.wg_width)-1.0, process = self.process)
            elems += wg_def([(self.tip_offset - self.extension , 0.0), (self.tip_offset, 0.0)])
        
        #assist lines for tip
        for i in range(self.assist_lines):
            elems += Path(PPLayer(self.process, TECH.PURPOSE.LF.LINE), 
                            [(self.tip_length + self.tip_offset, 0.0 + (0.5*self.tip_start_width + (i+1)*(self.assist_width+ self.assist_spacing) - 0.5*self.assist_width)), 
                             (self.tip_offset, 0.0 + (0.5*self.tip_width + (i+1)*(self.assist_width+ self.assist_spacing) - 0.5*self.assist_width)),
                             (self.tip_offset - self.extension, 0.0 + (0.5*self.tip_width + (i+1)*(self.assist_width+ self.assist_spacing) - 0.5*self.assist_width)),
                             ], self.assist_width)
            elems += Path(PPLayer(self.process, TECH.PURPOSE.LF.LINE), 
                            [(self.tip_length +  self.tip_offset, 0.0 - (0.5*self.tip_start_width+ (i+1)*(self.assist_width+ self.assist_spacing) - 0.5*self.assist_width)), 
                            (self.tip_offset, 0.0 - (0.5*self.tip_width + (i+1)*(self.assist_width+ self.assist_spacing) - 0.5*self.assist_width)),
                            (self.tip_offset- self.extension, 0.0 - (0.5*self.tip_width + (i+1)*(self.assist_width+ self.assist_spacing) - 0.5*self.assist_width)),
                            ], self.assist_width)
        return elems
Example #3
0
    def define_elements(self, elems):
        # WG
        wg_def_stop = WgElDefinition(wg_width = self.wg_def_end.wg_width,trench_width =  self.wg_def_start.trench_width)

        shallow_tip_width = self.wg_def_sh_end.wg_width
        shallow_tip_start_width = self.wg_def_sh_start.wg_width
        elems += WgElTaperLinear(start_position = (self.shallow_tip_length + self.tip_offset + self.tip_length, 0.0), 
                            end_position = (self.tip_offset + self.tip_length, 0.0), 
                            start_wg_def = self.wg_def_start, 
                            end_wg_def = self.wg_def_end)

        # FC
        s_o_length = self.tip_offset + self.tip_length
        # draw taper to tip
        wg_def_sh_start = WgElDefinition(wg_width = self.wg_def_sh_start.wg_width+1.0, trench_width = self.wg_def_start.trench_width)
        wg_def_sh_end = WgElDefinition(wg_width = self.wg_def_sh_end.wg_width, trench_width = 0.5*(self.y_spacing-self.wg_def_sh_end.wg_width)-1.0)
        elems += WgElTaperLinear( start_position = (self.shallow_tip_length + s_o_length, 0.0),
                            end_position =  (s_o_length, 0.0), 
                            start_wg_def = wg_def_sh_start, 
                            end_wg_def = wg_def_sh_end, 
                            process = self.shallow_process)
        if self.extension > 0:
            wg_def = WgElDefinition(wg_width = self.shallow_tip_width, trench_width = 0.5*(self.y_spacing-shallow_tip_width)-1.0, process = self.shallow_process)
            elems += wg_def([(s_o_length - self.extension , 0.0), (s_o_length, 0.0)])
        #assist lines for tip
        for i in range(self.assist_lines):
            elems += Path(PPLayer(self.shallow_process, TECH.PURPOSE.LF.LINE), 
                            [(self.shallow_tip_length + s_o_length, (0.5*shallow_tip_start_width +0.5 + (i+1)*(self.assist_width+ self.assist_spacing) - 0.5*self.assist_width)), 
                             (s_o_length, + (0.5*shallow_tip_width + (i+1)*(self.assist_width+ self.assist_spacing) - 0.5*self.assist_width)),
                             (s_o_length- self.extension , + (0.5*shallow_tip_width + (i+1)*(self.assist_width+ self.assist_spacing) - 0.5*self.assist_width))
                            ], self.assist_width)
            elems += Path(PPLayer(self.shallow_process, TECH.PURPOSE.LF.LINE), 
                            [(self.shallow_tip_length + s_o_length, - (0.5*shallow_tip_start_width+0.5+ (i+1)*(self.assist_width+ self.assist_spacing) - 0.5*self.assist_width)), 
                             (s_o_length,  - (0.5*shallow_tip_width + (i+1)*(self.assist_width+ self.assist_spacing) - 0.5*self.assist_width)),
                             (s_o_length- self.extension ,  - (0.5*shallow_tip_width + (i+1)*(self.assist_width+ self.assist_spacing) - 0.5*self.assist_width))
                            ], self.assist_width)
        return elems
Example #4
0
    def define_elements(self, elems):
        # go over ports
        for i in range(len(self.struct_west_ports)):
            ip = self.struct_west_ports[i]

            # position tapers
            t_pos = (ip.position[0] - self.connect_length, self.__y_west__[i])

            T = WgElTaperLinear(start_position=t_pos,
                                end_position=(t_pos[0] - self.taper_length,
                                              t_pos[1]),
                                start_wg_def=ip.wg_definition,
                                end_wg_def=self.wg_definition)

            elems += T
            # draw straight waveguides
            elems += self.wg_definition(
                shape=[T.west_ports[0].position, (0.0, t_pos[1])])
            # generic connector between structure port and taper port
            R = RouteToWestAtY(input_port=ip,
                               y_position=T.east_ports[0].y,
                               bend_radius=self.bend_radius,
                               min_straight=self.minimum_straight,
                               rounding_algorithm=self.rounding_algorithm)
            R.end_straight += R.out_ports[0].x - T.east_ports[0].x
            elems += RouteConnectorRounded(R)
            #blocking trenches
            elems += Line(
                PPLayer(self.wg_definition.process, TECH.PURPOSE.DF.TRENCH),
                (self.block_trench_position,
                 0.5 * self.wg_definition.wg_width +
                 self.wg_definition.trench_width),
                (self.block_trench_position, 0.5 * self.y_spacing),
                self.block_trench_width)
            elems += Line(
                PPLayer(self.wg_definition.process, TECH.PURPOSE.DF.TRENCH),
                (self.block_trench_position,
                 -0.5 * self.wg_definition.wg_width -
                 self.wg_definition.trench_width),
                (self.block_trench_position, -0.5 * self.y_spacing),
                self.block_trench_width)

        for i in range(len(self.struct.east_ports)):
            op = self.struct_east_ports[i]
            # position tapers
            t_pos = (op.position[0] + self.connect_length, self.__y_east__[i])
            T = WgElTaperLinear(start_position=t_pos,
                                end_position=(t_pos[0] + self.taper_length,
                                              t_pos[1]),
                                start_wg_def=op.wg_definition,
                                end_wg_def=self.wg_definition)
            elems += T
            # draw straight waveguides
            elems += self.wg_definition(
                shape=[T.east_ports[0].position, (self.width, t_pos[1])])

            # generic connector between structure port and taper port
            R = RouteToEastAtY(input_port=ip,
                               y_position=T.west_ports[0].y,
                               bend_radius=self.bend_radius,
                               min_straight=self.minimum_straight,
                               rounding_algorithm=self.rounding_algorithm)
            R.end_straight += -R.out_ports[0].x + T.west_ports[0].x
            elems += RouteConnectorRounded(R)

        return elems
Example #5
0
    def define_elements(self, elems):
        super(IoFibcoupGeneric, self).define_elements(elems)
        T = HMirror()  # for east couplers
        for fc, pos, tf in self.west_fibcoups_transforms_and_positions:
            elems += SRef(fc, pos, tf)
        for fc, pos, tf in self.east_fibcoups_transforms_and_positions:
            elems += SRef(fc, pos, tf)

        #i = 0

        #for ypos in self.y_west:
        #fc = self.west_fibcoups[i%len(self.west_fibcoups)]
        #west_fibcoup_position = (self.west_fibcoup_offsets[i%len(self.west_fibcoup_offsets)], ypos - fc.east_ports[0].y)
        #elems += SRef(fc, west_fibcoup_position)
        #i+= 1

        #i = 0
        #for ypos in self.y_east:
        #fc = self.east_fibcoups[i%len(self.east_fibcoups)]
        #east_fibcoup_position = (self.width - self.east_fibcoup_offsets[i%len(self.east_fibcoup_offsets)], ypos - fc.east_ports[0].y)
        #elems += SRef(fc, east_fibcoup_position, T)
        #i+= 1

        i = 0
        west_process_match = True
        shapes = []
        wg_widths = []
        trench_widths = []
        radiuses = []
        processes = []
        # get westmost position for ports
        west = 100000000.0
        for ip in self.struct_west_ports:
            west = min(west, ip.position.x)

        for i in range(len(self.struct_west_ports)):
            west_fibcoup = self.west_fibcoups[i % len(self.west_fibcoups)]
            west_fibcoup_port = west_fibcoup.east_ports[0]
            west_fibcoup_length = west_fibcoup_port.position[
                0] + self.west_fibcoup_offsets[i %
                                               len(self.west_fibcoup_offsets)]
            west_fibcoup_width = west_fibcoup_port.wg_definition.wg_width
            west_fibcoup_trench = west_fibcoup_port.wg_definition.trench_width
            west_connect_length = self.west_connect_lengths[i % len(
                self.west_connect_lengths)]
            west_taper_length = self.west_taper_lengths[i % len(
                self.west_taper_lengths)]
            west_trench_width = self.west_trench_widths[i % len(
                self.west_trench_widths)]
            west_fibcoup_taper_length = self.west_fibcoup_taper_lengths[
                i % len(self.west_fibcoup_taper_lengths)]
            west_wg_width = self.west_wg_widths[i % len(self.west_wg_widths)]
            west_bend_radius = self.west_bend_radiuses[i % len(
                self.west_bend_radiuses)]
            west_minimum_straight = self.west_minimum_straights[i % len(
                self.west_minimum_straights)]
            west_process = west_fibcoup_port.wg_definition.process

            ip = self.struct_west_ports[i]

            if not ip.wg_definition.process == west_process:
                west_process_match = False
            # position center taper
            t_pos = (west - west_connect_length - TECH.WG.SHORT_STRAIGHT,
                     self.y_west[i])
            #small piece of waveguide at the end
            wg_def = WgElDefinition(wg_width=ip.wg_definition.wg_width,
                                    trench_width=ip.wg_definition.trench_width,
                                    process=west_process)
            W = wg_def([t_pos, (t_pos[0] + TECH.WG.SHORT_STRAIGHT, t_pos[1])])
            elems += W
            # taper to the cleave waveguide
            start_wg_def1 = WgElDefinition(
                wg_width=ip.wg_definition.wg_width,
                trench_width=ip.wg_definition.trench_width,
                process=west_process)
            end_wg_def1 = WgElDefinition(wg_width=west_wg_width,
                                         trench_width=west_trench_width,
                                         process=west_process)
            T = WgElTaperLinear(start_position=t_pos,
                                end_position=(t_pos[0] - west_taper_length,
                                              t_pos[1]),
                                start_wg_def=start_wg_def1,
                                end_wg_def=end_wg_def1)
            elems += T
            # draw cleave waveguide (the wider waveguide, connected to the grating coupler)
            wg_def = WgElDefinition(wg_width=west_wg_width,
                                    trench_width=west_trench_width,
                                    process=west_process)
            elems += wg_def([
                T.west_ports[0].position,
                (west_fibcoup_length + west_fibcoup_taper_length, t_pos[1])
            ])
            # draw fibcoup taper (between grating coupler and the cleave waveguide)
            start_wg_def2 = WgElDefinition(wg_width=west_wg_width,
                                           trench_width=west_trench_width,
                                           process=west_process)
            end_wg_def2 = WgElDefinition(wg_width=west_fibcoup_width,
                                         trench_width=west_fibcoup_trench,
                                         process=west_process)
            elems += WgElTaperLinear(start_position=(west_fibcoup_length +
                                                     west_fibcoup_taper_length,
                                                     t_pos[1]),
                                     end_position=(west_fibcoup_length,
                                                   t_pos[1]),
                                     start_wg_def=start_wg_def2,
                                     end_wg_def=end_wg_def2)
            # generic connector between structure port and taper port
            tp = W.east_ports[0]

            S = Shape(
                RouteToWestAtY(input_port=ip,
                               y_position=tp.position.y,
                               bend_radius=west_bend_radius,
                               min_straight=west_minimum_straight))
            if len(S) > 2:
                S[-2] = S[-2].translate(tp.position - S[-1])
            S[-1] = tp.position
            shapes += [S]

            wg_widths += [ip.wg_definition.wg_width]
            trench_widths += [ip.wg_definition.trench_width]
            radiuses += [west_bend_radius]
            processes += [west_process]

            #blocking trenches
            elems += Line(
                PPLayer(west_process, TECH.PURPOSE.LF_AREA),
                (self.block_trench_position,
                 t_pos[1] + 0.5 * west_wg_width + west_trench_width),
                (self.block_trench_position, t_pos[1] + 0.5 * self.y_spacing),
                self.block_trench_width)
            elems += Line(
                PPLayer(west_process, TECH.PURPOSE.LF_AREA),
                (self.block_trench_position,
                 t_pos[1] - 0.5 * west_wg_width - west_trench_width),
                (self.block_trench_position, t_pos[1] - 0.5 * self.y_spacing),
                self.block_trench_width)
        if len(self.struct_west_ports):
            if self.west_merged_waveguides:
                # TO DO: Sort this out for different processes
                elems += WgElBundleConnectRoundedGeneric(
                    shapes=shapes,
                    wg_widths=wg_widths,
                    trench_widths=trench_widths,
                    bend_radii=radiuses,
                    process=west_process)
            else:
                for (s, w, t, r, p) in zip(shapes, wg_widths, trench_widths,
                                           radiuses, processes):
                    wg_def = WgElDefinition(wg_width=w,
                                            trench_width=t,
                                            process=p)
                    connector_wg_def = WaveguidePointRoundedConnectElementDefinition(
                        wg_definition=wg_def, bend_radius=r, manhattan=False)
                    elems += connector_wg_def(shape=s)

        shapes = []
        wg_widths = []
        trench_widths = []
        radiuses = []
        processes = []

        east_process_match = True

        # get rigthmost position for ports
        east = -100000000.0
        for op in self.struct_east_ports:
            east = max(east, op.position.x)

        for i in range(len(self.struct_east_ports)):
            east_fibcoup = self.east_fibcoups[i % len(self.east_fibcoups)]
            east_fibcoup_port = east_fibcoup.east_ports[0]
            east_fibcoup_length = east_fibcoup_port.position[
                0] + self.east_fibcoup_offsets[i %
                                               len(self.east_fibcoup_offsets)]
            east_fibcoup_width = east_fibcoup_port.wg_definition.wg_width
            east_fibcoup_trench = east_fibcoup_port.wg_definition.trench_width
            east_connect_length = self.east_connect_lengths[i % len(
                self.east_connect_lengths)]
            east_taper_length = self.east_taper_lengths[i % len(
                self.east_taper_lengths)]
            east_trench_width = self.east_trench_widths[i % len(
                self.east_trench_widths)]
            east_fibcoup_taper_length = self.east_fibcoup_taper_lengths[
                i % len(self.east_fibcoup_taper_lengths)]
            east_wg_width = self.east_wg_widths[i % len(self.east_wg_widths)]
            east_bend_radius = self.east_bend_radiuses[i % len(
                self.east_bend_radiuses)]
            east_minimum_straight = self.east_minimum_straights[i % len(
                self.east_minimum_straights)]
            east_process = east_fibcoup_port.wg_definition.process

            op = self.struct_east_ports[i]
            if not op.wg_definition.process == east_process:
                east_process_match = False
            # position taper
            t_pos = (east + east_connect_length + TECH.WG.SHORT_STRAIGHT,
                     self.y_east[i])
            wg_def = WgElDefinition(wg_width=op.wg_definition.wg_width,
                                    trench_width=op.wg_definition.trench_width,
                                    process=east_process)
            W = wg_def([t_pos, (t_pos[0] - TECH.WG.SHORT_STRAIGHT, t_pos[1])])
            elems += W
            start_wg_def3 = WgElDefinition(
                wg_width=op.wg_definition.wg_width,
                trench_width=op.wg_definition.trench_width,
                process=east_process)
            end_wg_def3 = WgElDefinition(wg_width=east_wg_width,
                                         trench_width=east_trench_width,
                                         process=east_process)
            T = WgElTaperLinear(start_position=t_pos,
                                end_position=(t_pos[0] + east_taper_length,
                                              t_pos[1]),
                                start_wg_def=start_wg_def3,
                                end_wg_def=end_wg_def3)
            elems += T
            # draw cleave waveguides
            wg_def = WgElDefinition(wg_width=east_wg_width,
                                    trench_width=east_trench_width,
                                    process=east_process)
            elems += wg_def([
                T.east_ports[0].position,
                (self.width - east_fibcoup_length - east_fibcoup_taper_length,
                 t_pos[1])
            ])
            # draw fibcoup taper
            start_wg_def4 = WgElDefinition(wg_width=east_wg_width,
                                           trench_width=east_trench_width,
                                           process=east_process)
            end_wg_def4 = WgElDefinition(wg_width=east_fibcoup_width,
                                         trench_width=east_fibcoup_trench,
                                         process=east_process)
            elems += WgElTaperLinear(
                start_position=(self.width - east_fibcoup_length -
                                east_fibcoup_taper_length, t_pos[1]),
                end_position=(self.width - east_fibcoup_length, t_pos[1]),
                start_wg_def=start_wg_def4,
                end_wg_def=end_wg_def4)
            # generic connector between structure port and taper port
            tp = W.west_ports[0]

            S = Shape(
                RouteToEastAtY(input_port=op,
                               y_position=tp.position.y,
                               bend_radius=east_bend_radius,
                               min_straight=east_minimum_straight))
            if len(S) > 2:
                S[-2] = S[-2].translate(tp.position - S[-1])
            S[-1] = tp.position
            shapes += [S]

            wg_widths += [op.wg_definition.wg_width]
            trench_widths += [op.wg_definition.trench_width]
            radiuses += [east_bend_radius]
            processes += [east_process]
        if len(self.struct_east_ports):
            if self.east_merged_waveguides:
                # TODO: Correct the bundling to support multiple process layers
                elems += WgElBundleConnectRoundedGeneric(
                    shapes=shapes,
                    wg_widths=wg_widths,
                    trench_widths=trench_widths,
                    bend_radii=radiuses,
                    process=processes[0])
            else:
                for (s, w, t, r, p) in zip(shapes, wg_widths, trench_widths,
                                           radiuses, processes):
                    wg_def = WgElDefinition(wg_width=w,
                                            trench_width=t,
                                            process=p)
                    connector_wg_def = WaveguidePointRoundedConnectElementDefinition(
                        wg_definition=wg_def, bend_radius=r, manhattan=False)
                    elems += connector_wg_def(shape=s)

        if not (west_process_match and east_process_match):
            if not (west_process_match or east_process_match):
                lr = "west and east"
            elif not west_process_match:
                lr = "west"
            else:
                lr = "east"
            LOG.warning(
                "Some of the %s ports of structure %s are not on the same process layer as the %s fiber couplers"
                % (lr, self.struct.name, lr))

        return elems