Esempio n. 1
0
 class Layout(WireWaveguideTemplate.Layout):
     core_process = ProcessProperty(locked=True, default=TECH.PROCESS.WG)
     core_purpose = PurposeProperty(locked=True, default=TECH.PURPOSE.CORE)
     cladding_process = ProcessProperty(locked=True, default=TECH.PROCESS.WG)
     cladding_purpose = PurposeProperty(locked=True, default=TECH.PURPOSE.CLADDING)
     core_width = PositiveNumberProperty(default=TECH.WG.CORE_WIDTH)
     cladding_width = PositiveNumberProperty(default=TECH.WG.CLADDING_WIDTH)
Esempio n. 2
0
class InvertedTaperShallow(InvertedTaper):
    process = DefinitionProperty(fdef_name = "define_process")
    
    wg_def_sh_start = WaveguideDefProperty(default = WgElDefinition(wg_width = 1.0 ,trench_width = TECH.WG.TRENCH_WIDTH))
    wg_def_sh_end = WaveguideDefProperty(default = WgElDefinition(wg_width = 0.080 ,trench_width = TECH.WG.TRENCH_WIDTH))

    deep_process = ProcessProperty(default = TECH.PROCESS.WG)
    shallow_process = ProcessProperty(default = TECH.PROCESS.FC)
    shallow_tip_width = PositiveNumberProperty(default = 0.080)
    shallow_tip_start_width = PositiveNumberProperty(default = 1.0)
    shallow_tip_length = PositiveNumberProperty(default = 150.0)


    def define_process(self):
        return self.deep_process
        
    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
            

    def define_ports(self, ports):
        wg_def = WgElDefinition(wg_width = self.shallow_tip_start_width, trench_width = self.wg_def_start.trench_width, process = self.deep_process)
        ports +=  [OpticalPort(position = (self.tip_length + self.tip_offset+ self.shallow_tip_length , 0.0), angle = 0.0, wg_definition = wg_def)]
        return ports
Esempio n. 3
0
    class Layout(rib_wg.RibWaveguideTemplate.Layout):
        core_process = ProcessProperty(
            locked=True,
            doc="Process used for the core layer of the MSN rib_old waveguide."
        )
        core_purpose = PurposeProperty(
            locked=True,
            doc="Purpose used for the core layer of the MSN rib_old waveguide."
        )
        exclusion_process = ProcessProperty(
            locked=True,
            doc=
            "Process used for the exclusion layer of the silicon wire waveguide."
        )
        exclusion_purpose = PurposeProperty(
            locked=True,
            doc=
            "Purpose used for the exclusion layer of the silicon wire waveguide."
        )
        cladding_process = ProcessProperty(
            locked=True,
            doc=
            "Process used for the cladding layer of the MSN rib_old waveguide."
        )
        cladding_purpose = PurposeProperty(
            locked=True,
            doc=
            "Purpose used for the cladding layer of the MSN rib_old waveguide."
        )
        core_width = PositiveNumberProperty(
            doc="Width of the core of the rib_old waveguide.")
        cladding_width = PositiveNumberProperty(
            doc="Cladding width of the rib_old waveguide.")

        def _default_core_process(self):
            return TECH.PROCESS.MSN

        def _default_core_purpose(self):
            return TECH.PURPOSE.DRAWING

        def _default_exclusion_process(self):
            return TECH.PROCESS.MSN

        def _default_exclusion_purpose(self):
            return TECH.PURPOSE.DRAWING

        def _default_cladding_process(self):
            return TECH.PROCESS.SHALLOW

        def _default_cladding_purpose(self):
            return TECH.PURPOSE.DRAWING

        def _default_core_width(self):
            return TECH.RIBWG.RIB_WIDTH

        def _default_cladding_width(self):
            return TECH.WIREWG.CLADDING_WIDTH
Esempio n. 4
0
    class Layout(WindowWaveguideTemplate.Layout):

        core_process        = ProcessProperty(default=TECH.PROCESS.WG, doc="process for the waveguide core")
        core_purpose        = PurposeProperty(default=TECH.PURPOSE.LF.LINE, doc="drawing purpose for the waveguide core")
        cladding_process    = ProcessProperty(doc="process for the waveguide cladding, defaults to the core process")
        cladding_purpose    = PurposeProperty(default=TECH.PURPOSE.LF_AREA, doc="drawing purpose layer for the cladding")
        # core_width          = PositiveNumberProperty(default=TECH.WG.CORE_WIDTH)
        cladding_width      = PositiveNumberProperty(default=TECH.WG.CLADDING_WIDTH,
                                                doc="total width of the waveguide with cladding")

        def _default_cladding_process(self):
            return self.core_process

        def _default_cover_layers(self):
            # Layer for Manhattan rectangles
            return [PPLayer(self.cladding_process, self.cladding_purpose)]

        def validate_properties(self):
            if self.cladding_width < self.core_width:
                raise PropertyValidationError(
                    "The waveguide cladding should be at least of as wide as the core. core={:f}, cladding={:f}".format(
                        self.core_width, self.cladding_width))
            return True

        def _default_width(self):
            return self.cladding_width

        def _default_windows(self):

            # populate the cladding PPlayers
            clad_pp_layers_list = [
                TECH.PPLAYER.AIM.BESAMFILL,
                TECH.PPLAYER.AIM.BCAAMFILL,
                TECH.PPLAYER.AIM.BSEAMFILL,
                TECH.PPLAYER.AIM.BFNAMFILL,
                TECH.PPLAYER.AIM.BSNAMFILL,
                TECH.PPLAYER.AIM.BM1AMFILL,
                TECH.PPLAYER.AIM.BMLAMFILL,
                TECH.PPLAYER.AIM.BM2AMFILL,
                    ]

            windows = []

            # add cladding windows
            for pplayer in clad_pp_layers_list:
                windows.append(PathTraceWindow(layer=pplayer,
                                               start_offset=-0.5 * self.cladding_width,
                                               end_offset=+0.5 * self.cladding_width,
                                               shape_property_name="cladding_shape"))

            # add core layer
            windows.append(PathTraceWindow( layer           = TECH.PPLAYER.WG.COR,
                                            start_offset    = -0.5 * self.core_width,
                                            end_offset      = +0.5 * self.core_width))

            return windows
Esempio n. 5
0
class ThreePort(Structure):
    __name_prefix__ = "3PORT"
    width = PositiveNumberProperty(required=True)
    height = PositiveNumberProperty(required=True)
    wg_width = PositiveNumberProperty(default=TECH.WG.WIRE_WIDTH)
    trench_width = PositiveNumberProperty(default=TECH.WG.TRENCH_WIDTH)
    process = ProcessProperty(default=TECH.PROCESS.WG)

    # this init function is optional
    def __init__(self, **kwargs):
        # init functions should have **kwargs as last argument (to pass on arguments from subclasses)
        # and it should pass all arguments to its parent class

        # add initialization code here that should be executed BEFORE all properties are assigned
        # .....

        super(ThreePort, self).__init__(**kwargs)

        # add initialization code here that should be executed AFTER all properties are assigned
        # .....

    # method for determining the name (it is an autoname structure)
    def define_name(self):
        return "%s_W%d_H%d_W%d_T%d" % (self.__name_prefix__, self.width * 1000,
                                       self.height * 1000, self.wg_width *
                                       1000, self.trench_width * 1000)

    def define_elements(self, elems):
        # add shape elements and stuff that should only be on the waveguide layer
        elems += Rectangle(PPLayer(self.process, TECH.PURPOSE.LF.LINE),
                           (0.0, 0.0), (self.width, self.height))
        elems += Rectangle(PPLayer(self.process, TECH.PURPOSE.LF_AREA),
                           (0.0, 0.0), (self.width + 2 * self.trench_width,
                                        self.height + 2 * self.trench_width))
        return elems

    def define_ports(self, ports):
        wg_def = WgElDefinition(wg_width=self.wg_width,
                                trench_width=self.trench_width)
        ports += InOpticalPort(position=(-0.5 * self.width, 0.0),
                               wg_definition=wg_def,
                               angle=180.0)
        ports += OutOpticalPort(position=(0.0, 0.5 * self.height),
                                wg_definition=wg_def,
                                angle=90.0)
        ports += OutOpticalPort(position=(0.5 * self.width, 0.0),
                                wg_definition=wg_def,
                                angle=0.0)
        return ports
Esempio n. 6
0
class InvertedTaper(FiberCoupler):
    
    process = ProcessProperty(default = TECH.PROCESS.WG)
    wg_def_start = WaveguideDefProperty(default = WgElDefinition(wg_width = TECH.WG.WIRE_WIDTH,trench_width = TECH.WG.TRENCH_WIDTH))
    wg_def_end = WaveguideDefProperty(default = WgElDefinition(wg_width = 0.080 ,trench_width = 11.46))
    tip_length = PositiveNumberProperty(default = 250.0)
    tip_offset = NonNegativeNumberProperty(default = 300.0)
    nitride_clearance = NonNegativeNumberProperty(default = 50.0)
    nitride_width = PositiveNumberProperty(default = 3.0)
    y_spacing = PositiveNumberProperty(default = 25.0)
    assist_lines = IntProperty(restriction = RESTRICT_NONNEGATIVE, default = 0)
    assist_spacing = PositiveNumberProperty(default = 0.160)
    assist_width = PositiveNumberProperty(default = 0.080)
    extension = NonNegativeNumberProperty(default = 1.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

    def define_ports(self, prts):
        wg_def = WgElDefinition(wg_width = self.wg_def_start.wg_width, trench_width = self.wg_def_start.trench_width, process = self.process)
        prts +=  [OpticalPort(position = (self.tip_length + self.tip_offset, 0.0), angle = 0.0, wg_definition = wg_def)]
        return prts
Esempio n. 7
0
class NitrideInvertedTaper(InvertedTaper):
    nitride_only_length = PositiveNumberProperty(default = 300.0)
    nitride_clearance = PositiveNumberProperty(default = 50.0)
    nitride_width = PositiveNumberProperty(default = 3.0)
    nt_process = ProcessProperty(default = TECH.PROCESS.NT)
    tip_offset = DefinitionProperty(fdef_name = "define_tip_offset")

    def define_tip_offset(self):
        return self.nitride_only_length
        
    def define_elements(self, elems):
        elems += super(NitrideInvertedTaper,self).define_elements(elems)
        # WG
        elems += Line(PPLayer(self.process,TECH.PURPOSE.LF_AREA), 
                        (0.0, 0.0), (self.nitride_only_length - self.extension , 0.0), 
                        self.y_spacing)
        # NT
        elems += Line(PPLayer(self.nt_process, TECH.PURPOSE.LF.LINE), 
                        (0.0, 0.0), (self.nitride_only_length + self.tip_length + 100.0 , 0.0), 
                        self.nitride_width )
        return elems
Esempio n. 8
0
class NitrideInvertedTaperShallow(InvertedTaperShallow):
    nitride_only_length = PositiveNumberProperty(default = 300.0)
    nitride_clearance = PositiveNumberProperty(default = 50.0)
    nitride_width = PositiveNumberProperty(default = 3.0)
    nt_process = ProcessProperty(default = TECH.PROCESS.NT)


    def define_elements(self, elems):
        # WG
        elems += Line(PPLayer(self.deep_process,TECH.PURPOSE.LF_AREA), 
                        (0.0, 0.0), (self.nitride_only_length - self.extension , 0.0), 
                        self.y_spacing)
        # FC
        s_o_length = self.tip_offset + self.tip_length
        elems += Line(PPLayer(self.shallow_process, TECH.PURPOSE.LF_AREA), 
                        (0.0, 0.0), (s_o_length- self.extension , 0.0), 
                        self.y_spacing)

        # NT
        elems += Line(PPLayer(self.nt_process, TECH.PURPOSE.LF.LINE), 
                        (0.0, 0.0), (self.nitride_only_length + self.tip_length + self.shallow_tip_length + 50.0 , 0.0), 
                        self.nitride_width )
        return elems