Пример #1
0
class SimpleMMI(Coupler1x2):

    trace_template = i3.TraceTemplateProperty(doc="Trace template of the access waveguide")

    def _default_trace_template(self):
        return i3.TECH.PCELLS.WG.DEFAULT

    class Layout(i3.LayoutView):
        # properties
        width = i3.PositiveNumberProperty(default=4.0, doc="Width of the MMI section.")
        length = i3.PositiveNumberProperty(default=20.0, doc="Length of the MMI secion.")
        taper_width = i3.PositiveNumberProperty(default=1.0, doc="Width of the taper.")
        taper_length = i3.PositiveNumberProperty(default=2.0, doc="Length of the taper")
        waveguide_spacing = i3.PositiveNumberProperty(default=2.0, doc="Spacing between the waveguides.")

        # methods
        def _generate_elements(self, elems):
            elems += i3.Rectangle(layer=i3.TECH.PPLAYER.WG.CORE,
                                  center=(0.5 * self.length, 0.0),
                                  box_size=(self.length, self.width))
            elems += i3.Wedge(layer=i3.TECH.PPLAYER.WG.CORE,
                              begin_coord=(-self.taper_length, 0.0),
                              end_coord=(0.0, 0.0),
                              begin_width=self.trace_template.core_width,
                              end_width=self.taper_width
                              )
            elems += i3.Wedge(layer=i3.TECH.PPLAYER.WG.CORE,
                              begin_coord=(self.length, 0.5 * self.waveguide_spacing),
                              end_coord=(self.length + self.taper_length, 0.5 * self.waveguide_spacing),
                              begin_width=self.taper_width,
                              end_width=self.trace_template.core_width
                              )
            elems += i3.Wedge(layer=i3.TECH.PPLAYER.WG.CORE,
                              begin_coord=(self.length, -0.5 * self.waveguide_spacing),
                              end_coord=(self.length + self.taper_length, -0.5 * self.waveguide_spacing),
                              begin_width=self.taper_width,
                              end_width=self.trace_template.core_width
                              )

            elems += i3.Rectangle(layer=i3.TECH.PPLAYER.WG.CLADDING,
                                  center=(0.5 * self.length, 0.0),
                                  box_size=(self.length + 2 * self.taper_length,  self.width + 2.0)
                                  )
            return elems

        def _generate_ports(self, ports):

            ports += i3.OpticalPort(name="in", position=(-self.taper_length, 0.0), angle=180.0, trace_template=self.trace_template)
            ports += i3.OpticalPort(name="out1", position=(self.length + self.taper_length, -0.5 * self.waveguide_spacing), angle=0.0,
                                    trace_template=self.trace_template)
            ports += i3.OpticalPort(name="out2", position=(self.length + self.taper_length, +0.5 * self.waveguide_spacing), angle=0.0,
                                    trace_template=self.trace_template)

            return ports
        
        
    class CircuitModel(Coupler1x2.CircuitModel):
        pass
class Square(PlaceComponents):

	size=i3.PositiveNumberProperty(default=20.0, doc="simension of the square of aligning mark")
	separation=i3.PositiveNumberProperty(default=2.0, doc="simension of the square of aligning mark")
	square = i3.ChildCellProperty(doc="grating with pitch 1", locked=True)
        tt_square = i3.TraceTemplateProperty(doc="Wide trace template used ")
	layName = i3.StringProperty(default = 'new')
	props = i3.DictProperty()
	
	def _default_props(self):
		return AssignProcess(self.layName)
	

	def _default_tt_square(self):
		tt_w = WireWaveguideTemplate()
		tt_w.Layout(core_width=(self.size),
                    cladding_width=(self.size),
		    **self.props
                    )
		print 'ttw in Square is ', tt_w
		
		return tt_w

	def _default_square(self):
		rect=i3.Waveguide(trace_template=self.tt_square)
		layout_rect = rect.Layout(shape=[(0.0, self.size/2.0),(self.size,self.size/2.0)])
		print 'The trace template of the hline of the cross ', rect.trace_template 
		return rect
       

	def _default_child_cells(self):
		child_cells={"S1" : self.square,
                           }        

		return child_cells



	class Layout(PlaceComponents.Layout):
		def _default_child_transformations(self):

			child_transformations={
			        "S1" : i3.Translation(translation=(-(self.size*0.5),(-self.size*0.5))),
                                   }

			return child_transformations	
Пример #3
0
class SimpleMMI(i3.PCell):

    trace_template = i3.TraceTemplateProperty(
        doc="Trace template of the access waveguide")

    def _default_trace_template(self):
        return WireWaveguideTemplate()

    class Layout(i3.LayoutView):
        # properties
        width = i3.PositiveNumberProperty(default=4.0,
                                          doc="Width of the MMI section.")
        length = i3.PositiveNumberProperty(default=20.0,
                                           doc="Length of the MMI secion.")
        taper_width = i3.PositiveNumberProperty(default=1.0,
                                                doc="Width of the taper.")
        taper_length = i3.PositiveNumberProperty(default=2.0,
                                                 doc="Length of the taper")
        waveguide_spacing = i3.PositiveNumberProperty(
            default=2.0, doc="Spacing between the waveguides.")

        # methods
        def _generate_elements(self, elems):
            elems += i3.Rectangle(layer=i3.TECH.PPLAYER.WG.CORE,
                                  center=(0.5 * self.length, 0.0),
                                  box_size=(self.length, self.width))
            elems += i3.Wedge(layer=i3.TECH.PPLAYER.WG.CORE,
                              begin_coord=(-self.taper_length, 0.0),
                              end_coord=(0.0, 0.0),
                              begin_width=self.trace_template.core_width,
                              end_width=self.taper_width)
            elems += i3.Wedge(layer=i3.TECH.PPLAYER.WG.CORE,
                              begin_coord=(self.length,
                                           0.5 * self.waveguide_spacing),
                              end_coord=(self.length + self.taper_length,
                                         0.5 * self.waveguide_spacing),
                              begin_width=self.taper_width,
                              end_width=self.trace_template.core_width)
            elems += i3.Wedge(layer=i3.TECH.PPLAYER.WG.CORE,
                              begin_coord=(self.length,
                                           -0.5 * self.waveguide_spacing),
                              end_coord=(self.length + self.taper_length,
                                         -0.5 * self.waveguide_spacing),
                              begin_width=self.taper_width,
                              end_width=self.trace_template.core_width)

            elems += i3.Rectangle(
                layer=i3.TECH.PPLAYER.WG.CLADDING,
                center=(0.5 * self.length, 0.0),
                box_size=(self.length + 2 * self.taper_length,
                          self.width + 2.0))
            return elems

        def _generate_ports(self, ports):

            ports += i3.OpticalPort(name="in",
                                    position=(-self.taper_length, 0.0),
                                    angle=180.0,
                                    trace_template=self.trace_template)
            ports += i3.OpticalPort(name="out1",
                                    position=(self.length + self.taper_length,
                                              -0.5 * self.waveguide_spacing),
                                    angle=0.0,
                                    trace_template=self.trace_template)
            ports += i3.OpticalPort(name="out2",
                                    position=(self.length + self.taper_length,
                                              +0.5 * self.waveguide_spacing),
                                    angle=0.0,
                                    trace_template=self.trace_template)

            return ports

    class Netlist(i3.NetlistFromLayout):
        pass

    class CapheModelCST(CapheModelCST):
        """
        This model encapsulates all the properties of the simulation. This way we consolidate simulation settings.
        """
        def _default_start_wavelength(self):
            return 1.45e-6

        def _default_stop_wavelength(self):
            return 1.55e-6

        def _default_cells_per_wave(self):
            return 6  # 10 for more precise results

        def _default_additional_commands_path(self):
            import os
            return r"{}\additional_commands.mod".format(
                os.path.dirname(__file__))  # Extra settings set in the CST GUI

        def _default_bounding_box(self):
            si = self.extended_layout.size_info()
            w = self.layout.width
            bounding_box = [
                [si.west, si.east],  # [startx, stopx], propagation direction
                [-w / 2.0 - 0.7, +w / 2.0 + 0.7],  # [starty,stopy]
                [0.15, 0.5 + 0.22 + 0.6]
            ]  # [startz, stopz], layer direction

            return bounding_box
Пример #4
0
class MZI_12_21(PlaceAndAutoRoute):
	_name_prefix = 'MZIs'

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

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

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

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

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


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

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



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

		return mmi12



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

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

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


			MMI22_list.append(cell)                         

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


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

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


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

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

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

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

			print cell.name
			print '__________________________'

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

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

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

			print cell.name
			print '__________________________'

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


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




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

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

			child_cells['mzi_22_22_' + str(counter)] = child
			child_cells['InPort1_' + str(counter)] = self.Port
			child_cells['OutPort1_' + str(counter)]= self.Port
			child_cells['InPort2_' + str(counter)] = self.Port
			child_cells['OutPort2_' + str(counter)]= self.Port            
			print 'child name ' +str(child.name)
			print child
			
			#################
		for counter2, child  in enumerate(self.MZI_12_22_list):  
			print 'child number'+str(counter+1+counter2)

			child_cells['mzi_12_22_' + str(counter+1+counter2)] = child 
			child_cells['InPort_' + str(counter+1+counter2)] = self.Port
			child_cells['OutPort1_' + str(counter+1+counter2)]= self.Port 
			child_cells['OutPort2_' + str(counter+1+counter2)]= self.Port  
			print 'child name ' +str(child.name)
			print child            
			###################
				
			print '__________________________'
		child_cells['InPortWG1'] = self.Port
		child_cells['OutPortWG1'] = self.Port
		child_cells['InPortWG2'] = self.Port
		child_cells['OutPortWG2'] = self.Port
		child_cells['InPortWG3'] = self.Port
		child_cells['OutPortWG3'] = self.Port
		
		print "Last child cell done" 
		print '_ _ _ _ _ _ _ _ _ _ _ _ _ '
		return child_cells 		


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

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

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

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


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

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

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

	class Layout(PlaceAndAutoRoute.Layout):

		def _default_bend_radius(self):
			return self.R

		def _default_start_straight(self):
			return 1.0

		print '____________ Layout mask ______________'
		def _default_child_transformations(self):
			d={}
			a=2.2
			for counter, child in enumerate(self.MZI_22_22_list):
				if self.tipo==1:
					d['mzi_22_22_' + str(counter)] = i3.Translation(translation=((-1)**counter*2*self.R,counter*5*self.R))
					d['InPort1_' + str(counter)] = i3.HMirror()+i3.Translation(translation=(-self.chip_length*0.5, counter*5*self.R-2.2*self.R))
					d['OutPort1_' + str(counter)]= i3.Rotation(rotation=90.0)+i3.Translation(translation=(self.chip_length*0.5, counter*5*self.R-2.2*self.R))
					d['InPort2_' + str(counter)] = i3.HMirror()+i3.Translation(translation=(-self.chip_length*0.5, counter*5*self.R+2.2*self.R))
					d['OutPort2_' + str(counter)]= i3.Rotation(rotation=90.0)+i3.Translation(translation=(self.chip_length*0.5, counter*5*self.R+2.2*self.R))                    
					print 'transformation ' +str(counter) + ' is ' +str(d)
				if self.tipo==2:
					#l_coupling=self.child_cells['Coupler'].l_coupling
					#radius=self.child_cells['Coupler'].local_bend_radius
					print 'R= ',self.R
					#print 'translation port: '
					
					
					##For w=20
					d['mzi_22_22_' + str(counter)] = i3.Translation(translation=(counter*850+1200+1000+200,-counter*5*self.R))
					d['InPort1_'+ str(counter)] = i3.HMirror()+i3.Translation(translation=(1500, -5*self.R*counter-a*self.R))
					d['OutPort1_'+ str(counter)]= i3.Rotation(rotation=90.0)+i3.Translation(translation=(self.chip_length*0.5+counter*50+counter*4*self.R+a*self.R-100, self.R*a))
					d['InPort2_'+ str(counter)] = i3.HMirror()+i3.Translation(translation=(1500, -5*self.R*counter+a*self.R))
					d['OutPort2_'+ str(counter)]= i3.Rotation(rotation=90.0)+i3.Translation(translation=(self.chip_length*0.5+counter*50+counter*4*self.R-100, self.R*a)) 
					
				d['InPortWG1'] = i3.HMirror()+i3.Translation(translation=(1500, 1000.0))
				d['OutPortWG1']= i3.Rotation(rotation=90.0)+i3.Translation(translation=(self.chip_length*0.5-500, self.R*a))
				d['InPortWG2'] = i3.HMirror()+i3.Translation(translation=(1500, -3400+670))
				d['OutPortWG2']= i3.Rotation(rotation=90.0)+i3.Translation(translation=(self.chip_length*0.5+2500, self.R*a))				
				d['InPortWG3'] = i3.HMirror()+i3.Translation(translation=(1500, -6500))
				d['OutPortWG3']= i3.Rotation(rotation=90.0)+i3.Translation(translation=(self.chip_length*0.5+5600, self.R*a))				
									
				#d['mzi_22_22_' + str(counter)] = i3.Translation(translation=(counter*850+1200+1000+200,-counter*5*self.R))
				#d['InPort1_'+ str(counter)] = i3.HMirror()+i3.Translation(translation=(1500, -5*self.R*counter-a*self.R))
				#d['OutPort1_'+ str(counter)]= i3.Rotation(rotation=90.0)+i3.Translation(translation=(self.chip_length*0.5+1100+counter*50+counter*4*self.R+a*self.R-100, self.R*a))
				#d['InPort2_'+ str(counter)] = i3.HMirror()+i3.Translation(translation=(1500, -5*self.R*counter+a*self.R))
				#d['OutPort2_'+ str(counter)]= i3.Rotation(rotation=90.0)+i3.Translation(translation=(self.chip_length*0.5+1100+counter*50+counter*4*self.R-100, self.R*a)) 
				
				#d['InPortWG1'] = i3.HMirror()+i3.Translation(translation=(1500, 1000.0))
				#d['OutPortWG1']= i3.Rotation(rotation=90.0)+i3.Translation(translation=(self.chip_length*0.5-500+1200, self.R*a))
				#d['InPortWG2'] = i3.HMirror()+i3.Translation(translation=(1500, -3400+670))
				#d['OutPortWG2']= i3.Rotation(rotation=90.0)+i3.Translation(translation=(self.chip_length*0.5+2500+1100, self.R*a))				
				#d['InPortWG3'] = i3.HMirror()+i3.Translation(translation=(1500, -6500))
				#d['OutPortWG3']= i3.Rotation(rotation=90.0)+i3.Translation(translation=(self.chip_length*0.5+5600+1400, self.R*a))					
				################
			for counter2, child in enumerate(self.MZI_12_22_list):
				if self.tipo==1:
					
					d['mzi_12_22_' + str(counter+1+counter2)] = i3.Translation(translation=((-1)**counter2*2*self.R-self.length_22+counter*50+counter*4*self.R,(counter+1+counter2)*5*self.R))
					d['InPort_' + str(counter+1+counter2)] = i3.HMirror()+i3.Translation(translation=(-self.chip_length*0.5, (counter+1+counter2)*5*self.R))
					d['OutPort1_' + str(counter+1+counter2)]= i3.Translation(translation=(self.chip_length*0.5-self.bend_radius*counter*0.2-a*self.R-550, (counter+1+counter2)*5*self.R-2.2*self.R))
					d['OutPort2_' + str(counter+1+counter2)]= i3.Translation(translation=(self.chip_length*0.5-self.bend_radius*counter*0.2-550, (counter+1+counter2)*5*self.R+2.2*self.R))
				if self.tipo==2:
					#l_coupling=self.child_cells['Coupler'].l_coupling
					#radius=self.child_cells['Coupler'].local_bend_radius
					print 'R= ',self.R
					a=2.2
					b=500
					d['mzi_12_22_'+ str(counter+1+counter2)] = i3.Translation(translation=((counter+2+counter2)*850+1200+200+580,-(counter+1+counter2)*5*self.R-b))
					d['InPort_'+ str(counter+1+counter2)] = i3.HMirror()+i3.Translation(translation=(1500, -(5*self.R)*(counter+1+counter2)-b))
					d['OutPort1_'+ str(counter+1+counter2)]= i3.Rotation(rotation=90.0)+i3.Translation(translation=(self.chip_length*0.5+(counter+1+counter2)*50+a*self.R+(counter+1+counter2)*4*self.R+b, self.R*a))
					d['OutPort2_'+ str(counter+1+counter2)]= i3.Rotation(rotation=90.0)+i3.Translation(translation=(self.chip_length*0.5+(counter+1+counter2)*50+(counter+1+counter2)*4*self.R+b,self.R*a)) 
					
					#d['mzi_12_22_'+ str(counter+1+counter2)] = i3.Translation(translation=((counter+2+counter2)*850+1200+200+580+1000,-(counter+1+counter2)*5*self.R-b))
					#d['InPort_'+ str(counter+1+counter2)] = i3.HMirror()+i3.Translation(translation=(1500, -(5*self.R)*(counter+1+counter2)-b))
					#d['OutPort1_'+ str(counter+1+counter2)]= i3.Rotation(rotation=90.0)+i3.Translation(translation=(self.chip_length*0.5+1200+(counter+1+counter2)*50+a*self.R+(counter+1+counter2)*4*self.R+b, self.R*a))
					#d['OutPort2_'+ str(counter+1+counter2)]= i3.Rotation(rotation=90.0)+i3.Translation(translation=(self.chip_length*0.5+1200+(counter+1+counter2)*50+(counter+1+counter2)*4*self.R+b,self.R*a)) 							
			################
			print '__________________________'    
			print "Last layout child cell done" 
			print d
			print '_ _ _ _ _ _ _ _ _ _ _ _ _ '
			return d


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


				print name
				elems += i3.PolygonText(layer= i3.TECH.PPLAYER.WG.TEXT, text='Name={}_R={}_delay={}'.format(name, self.R, self.delay_length),

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

				                        coordinate=(0.0, -(counter+1+counter2)*5*self.R-90.0-500#-100
				                                    ),
				                        alignment=(i3.TEXT_ALIGN_LEFT, i3.TEXT_ALIGN_LEFT),
				                        font = 2,
				                        height=20.0)                      




			return elems
Пример #5
0
class Spirals(PlaceAndAutoRoute):

    _name_prefix = 'LSpiral'

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

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

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

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

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

    def _default_tt(self):
        return self.waveguide_template

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

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

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

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

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

            Spiral_list.append(cell)

        return Spiral_list

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

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

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

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

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

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

            print 'child_cells:', child_cells
        return child_cells

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

        return links

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

        def _default_bend_radius(self):
            return self.R

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

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

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

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

                #i3.TECH.PPLAYER.NONE.LOGOTXT   when using isipp50g
                if self.tipo == 2:
                    elems += i3.PolygonText(
                        layer=i3.TECH.PPLAYER.WG.TEXT,
                        text='Width={}_Length={}_R={}'.format(
                            width, length, self.R),
                        coordinate=((op[0] - ip[0]) / 2 - 1000.0,
                                    (self.n + 0.5) * counter * sx - 50.0),
                        alignment=(i3.TEXT_ALIGN_LEFT, i3.TEXT_ALIGN_LEFT),
                        font=2,
                        height=20.0)
                if self.tipo == 1:
                    elems += i3.PolygonText(
                        layer=i3.TECH.PPLAYER.WG.TEXT,
                        text='Width={}_Length={}_R={}'.format(
                            width, length, self.R),
                        coordinate=(-(op[0] - ip[0]) / 2 - 1000.0,
                                    -(self.n + 0.5) * counter * sx - 50.0),
                        alignment=(i3.TEXT_ALIGN_LEFT, i3.TEXT_ALIGN_LEFT),
                        font=2,
                        height=20.0)
            return elems
Пример #6
0
class Spirals(PlaceAndAutoRoute):

    _name_prefix = 'LSpiral'

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

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

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

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

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

    def _default_tt(self):
        return self.waveguide_template

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

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

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

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

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

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

            print 'child_cells:', child_cells
        return child_cells

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

        return links

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

        def _default_bend_radius(self):
            return self.R

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

                #print 'spiral length:', child.total_length
                print 'counter: ', counter
                print 'self.n = ', self.n
                print 'self.width: ', self.width
                #print 'sx: ', sx

                if self.tipo == 1:
                    sx = 70
                    a = 0.5
                    print 2 * (22362 * 0.5 - self.couplingWG_l)
                    print 'tipo = ', self.tipo

                    #d['Spiral' + str(counter)] = i3.Translation(translation=(-(op[0]-ip[0])/2, self.n*counter*sx))
                    #d['InPort' + str(counter)] = i3.HMirror()+ i3.Translation(translation=(-self.chip_length*0.5, (self.n+a)*counter*sx))
                    #d['OutPort' + str(counter)] = i3.Translation(translation=(self.chip_length*0.5, (self.n+a)*counter*sx))

                    d['InPort' + str(counter)] = i3.HMirror() + i3.Translation(
                        translation=(-22362 * 0.5 + self.couplingWG_l,
                                     (self.n + a) * counter * sx))
                    d['OutPort' + str(counter)] = i3.Translation(
                        translation=(22362 * 0.5 - self.couplingWG_l,
                                     (self.n + a) * counter * sx))

                #if self.tipo==2:
                #d['Spiral' + str(counter)] = i3.Translation(translation=(-(op[0]-ip[0])/2, -(self.n+0.5)*counter*sx))
                #d['InPort' + str(counter)] = i3.HMirror()+ i3.Translation(translation=(-self.chip_length*(3/4)-self.couplingWG_l, -(self.n+0.5)*counter*sx))
                #d['OutPort' + str(counter)] = i3.Rotation(rotation=90) + i3.Translation(translation=((op[0]-ip[0])/2+2*self.R+(((self.n+0.5)*counter+self.width)*sx/4), self.chip_length*(3/4)+(self.width+counter-(((counter+1)-1.0)%self.lengths))*sx))
                if self.tipo == 2:
                    sx = 100
                    #d['Spiral' + str(counter)] = i3.Translation(translation=(-(op[0]-ip[0])/2, -(self.n+1)*counter*sx))
                    a = 7.0
                    print 'increment of length between waveguides of same width: ', (
                        self.n + a) * 1 * sx + ((self.n + a) * 1 + 0) * sx
                    print 'increment of length between waveguides of same length group: ', (
                        self.n + a) * 0 * sx + (
                            (self.n + a) * 0 + self.width) * sx

                    d['InPort' + str(counter)] = i3.HMirror() + i3.Translation(
                        translation=(0.0 - self.chip_length * 0.5,
                                     -(self.n + a) * counter * sx))
                    d['OutPort' + str(counter)] = i3.Rotation(
                        rotation=90) + i3.Translation(translation=(
                            (((self.n + a) * counter + self.width) * sx),
                            self.chip_length * 0.5 +
                            (self.width + counter -
                             (((counter + 1) - 1.0) % self.lengths)) * sx))

            return d

        # Fabio's addition
        def _generate_elements(self, elems):
            # We calculate the lengths of the 2 spirals in this pcell.
            # Note that we assume that there are exactly 2 spirals in this list.
            #assert len(self.Spiral_list) == 2
            lengths = get_lengths(self)[0]
            print lengths
            Link = get_lengths(self)[1]
            print Link
            if self.tipo == 1:

                sx = 70
                for counter, (child, length) in enumerate(
                        zip(self.s_length_vec, lengths)):
                    #ip= child.ports["in"].position
                    #op= child.ports["out"].position

                    width = Link.trace_template.core_width
                    #print 'child.ports["in"].trace_template.core_width: ', child.ports["in"].trace_template.core_width
                    a = 0.5
                    #i3.TECH.PPLAYER.NONE.LOGOTXT   when using isipp50g
                    elems += i3.PolygonText(
                        layer=i3.TECH.PPLAYER.WG.TEXT,
                        text='Width={}'.format(width, ),
                        coordinate=(-self.chip_length * 0.5 + 2 * self.tlport,
                                    (self.n + a) * counter * sx - 15.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='Width={}'.format(width, ),
                        coordinate=(0.0, (self.n + a) * counter * sx - 15.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='Width={}'.format(width, ),
                        coordinate=(self.chip_length * 0.5 - 2 * self.tlport,
                                    (self.n + a) * counter * sx - 15.0),
                        alignment=(i3.TEXT_ALIGN_LEFT, i3.TEXT_ALIGN_LEFT),
                        font=2,
                        height=20.0)

            if self.tipo == 2:
                sx = 100
                for counter, (child, length) in enumerate(
                        zip(self.s_length_vec, lengths)):
                    #ip= child.ports["in"].position
                    #op= child.ports["out"].position

                    width = Link.trace_template.core_width
                    #print 'child.ports["in"].trace_template.core_width: ', child.ports["in"].trace_template.core_width
                    a = 7.0
                    #i3.TECH.PPLAYER.NONE.LOGOTXT   when using isipp50g
                    elems += i3.PolygonText(
                        layer=i3.TECH.PPLAYER.WG.TEXT,
                        text='Width={}_Length={}_R={}'.format(
                            width, length, self.R),
                        coordinate=(-1500,
                                    -(self.n + a) * counter * sx - 55.0),
                        alignment=(i3.TEXT_ALIGN_LEFT, i3.TEXT_ALIGN_LEFT),
                        font=2,
                        height=20.0)
            return elems
Пример #7
0
class MMI(i3.PCell):
    """
    MMI with a variable number of inputs and outputs with variable width and length of the taper.
    """
    n_inputs = i3.PositiveIntProperty(default=1, doc="Number of inputs")
    n_outputs = i3.PositiveIntProperty(default=2, doc="Number of outputs")
    trace_template = i3.TraceTemplateProperty(doc="Trace template at the ports")

    def _default_trace_template(self):
        return SiWireWaveguideTemplate(name=self.name + "tt")

    class Layout(i3.LayoutView):

        length = i3.PositiveNumberProperty(default=25.0, doc="Length of the mmi.")
        width = i3.PositiveNumberProperty(default=5.0, doc="Width of core layer at center of the mmi.")
        transistion_length = i3.PositiveNumberProperty(default=5.0, doc="Length of the tapers.")
        wg_spacing_in = i3.NonNegativeNumberProperty(default=2.0,
                                                     doc="Center to center distance between the waveguides at the input.")
        wg_spacing_out = i3.NonNegativeNumberProperty(default=2.0,
                                                      doc="Center to center distance between the waveguides at the output.")
        taper_width = i3.PositiveNumberProperty(default=1.0,
                                                doc="Width of the core of the taper of the access waveguides of the mmi.")

        @i3.cache()
        def _get_input_taper_coords(self):
            # coordinates of the input tapers [(taper1_begin, taper1_end), (taper2_begin, taper2_end), ...]
            base_y = - (self.n_inputs - 1) * self.wg_spacing_in / 2.0
            taper_coords = [
                [(0, base_y + cnt * self.wg_spacing_in), (-self.transistion_length, base_y + cnt * self.wg_spacing_in)]
                for cnt in range(self.n_inputs)]

            return taper_coords

        @i3.cache()
        def _get_output_taper_coords(self):
            # coordinates of the output tapers [(taper1_begin, taper1_end), (taper2_begin, taper2_end), ...]
            base_y = - (self.n_outputs - 1) * self.wg_spacing_out / 2.0
            taper_coords = [[(self.length, base_y + cnt * self.wg_spacing_out),
                             (self.length + self.transistion_length, base_y + cnt * self.wg_spacing_out)]
                            for cnt in range(self.n_outputs)]

            return taper_coords

        def _generate_elements(self, elems):
            layer_core = self.trace_template.core_layer
            # mmi core
            elems += i3.Rectangle(layer=layer_core, center=(+self.length / 2.0, 0.0),
                                  box_size=(self.length, self.width))
            # input wedges
            for bc, ec in self._get_input_taper_coords():
                elems += i3.Wedge(layer_core, begin_coord=bc, end_coord=ec, begin_width=self.taper_width,
                                  end_width=self.trace_template.core_width)
            for bc, ec in self._get_output_taper_coords():
                elems += i3.Wedge(layer_core, begin_coord=bc, end_coord=ec, begin_width=self.taper_width,
                                  end_width=self.trace_template.core_width)
            return elems

        def _generate_ports(self, ports):

            for cnt, coords in enumerate(self._get_input_taper_coords(), 1):
                ports += i3.OpticalPort(name="in{}".format(cnt), position=coords[1], angle=180.0,
                                        trace_template=self.trace_template)

            for cnt, coords in enumerate(self._get_output_taper_coords(), 1):
                ports += i3.OpticalPort(name="out{}".format(cnt), position=coords[1], angle=0.0,
                                        trace_template=self.trace_template)

            return ports

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

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

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

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

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

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

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

		return wg_t	

	def _default_trace_template(self):
		return self.waveguide_template  	


	def _default_contents(self):
		return self.FGC

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

	


	class Layout(PlaceComponents.Layout):

		#def _default_transition_length(self):
			#return self.transition_length_coupler
		
		def _default_child_transformations(self):
			d={}
			position=0
			for counter, child  in enumerate(self.Grating_list):
				
				d['pillar{}'.format(counter)] = i3.Translation(translation=(position, 0.0))
				position=position+self.Lo[counter]+self.Le[counter]
				print 'pillar position: ', position
				print 'counter= ', counter
				print 'Lo: ', self.Lo[counter]
				print 'Le: ', self.Le[counter]
				
			#d['InPort'] = i3.HMirror()+ i3.Translation(translation=(position+10,0))
			d['InPort'] = i3.HMirror()+ i3.Translation(translation=(self.coupling_l+self.socket_length,0))
			d['OutPort'] = i3.Translation(translation=(-50,0.0))
												   
			return d			
class AligningMarks(PlaceComponents):

	tt_cross = i3.TraceTemplateProperty(doc="Wide trace template used for the contact pads")
	hline = i3.ChildCellProperty(doc="Horizontal line", locked=True)
	vline = i3.ChildCellProperty(doc="Vertical", locked=True)
	square = i3.ChildCellProperty(doc="Vertical", locked=True)
	size=i3.PositiveNumberProperty(default=250.0, doc="bigger dimension of aligning mark")
	width=i3.PositiveNumberProperty(default=20.0, doc="smaller dimension of aligning mark")
	#Pitch1=i3.PositiveNumberProperty(default=2.0, doc="pitch grating 1")	
	separation=i3.NumberProperty(default=100.0, doc="separation between cross and gratings")

	#dc=i3.PositiveNumberProperty(default=0.47, doc="duty cycle") 
	
	layName = i3.StringProperty(default = 'metal2')
	props = i3.DictProperty()	
			
		
	def _default_props(self):
		return AssignProcess(self.layName)		

	def _default_tt_cross(self):
		tt_w = WireWaveguideTemplate()
		tt_w.Layout(core_width=(self.width),
                    cladding_width=(self.width),
		    **self.props
                        )

		return tt_w

	def _default_hline(self):
		rect=i3.Waveguide(trace_template=self.tt_cross)
		layout_rect = rect.Layout(shape=[(0.0, self.size/2.0),(self.size,self.size/2.0)])
		print 'The trace template of the hline of the cross ', rect.trace_template 
		return rect  

	def _default_vline(self):
		rect=i3.Waveguide(trace_template=self.tt_cross)
		layout_rect = rect.Layout(shape=[(self.size/2.0, 0.0),(self.size/2.0,self.size)])
		print 'The trace template of the vline of the cross ', rect.trace_template 
		                          
			
		return rect  

	def _default_square(self):
		#square=Square(size=self.width, layName=self.layName)
		square=Square(size=self.width, layName='metal')
		#square.Layout().visualize()
		return square

	def _default_child_cells(self):
		child_cells={"S1" : self.square,
                     "S2" : self.square,
                     "S3" : self.square,
                     "S4" : self.square,
                     "V"  : self.vline,
                     "H"  : self.hline
                     }        

		return child_cells    

	class Layout(PlaceComponents.Layout):

		def _default_child_transformations(self):

			child_transformations={"S1" : i3.Translation(translation=(-(self.width+5.0),(self.width+5.0))),
			                       "S2" : i3.Translation(translation=((self.width+5.0),(self.width+5.0))),
			                       "S3" : i3.Translation(translation=(-(self.width+5.0),-(self.width+5.0))), 
			                       "S4" : i3.Translation(translation=((self.width+5.0),-(self.width+5.0))), 
			                       "V"  : i3.Translation(translation=(0.0, 0.0))+ i3.Translation(translation=(-(self.size)/2.0,-(self.size)/2.0)),
			                       "H"  : i3.Translation(translation=(0.0, 0.0))+ i3.Translation(translation=(-(self.size)/2.0,-(self.size)/2.0))				           
                                 }   


			return child_transformations
Пример #10
0
class DirectionalCoupler(i3.PCell):
    trace_template = i3.TraceTemplateProperty(
        doc="Trace template used for directional coupler")

    def _default_trace_template(self):
        return SiWireWaveguideTemplate()

    class Layout(i3.LayoutView):
        spacing = i3.PositiveNumberProperty(
            default=0.2, doc="Spacing between the waveguides", locked=True)
        bend_radius = i3.PositiveNumberProperty(
            default=10.0,
            doc="Bend radius of the directional coupler",
            locked=True)

        def _generate_instances(self, insts):
            delta = self.trace_template.core_width + self.spacing
            bend_radius = self.bend_radius
            coupler_length = self.cell.get_default_view(
                i3.CircuitModelView).coupler_length

            shape = i3.Shape([
                (-coupler_length / 2.0 - bend_radius, bend_radius),
                (-coupler_length / 2.0 - bend_radius, 0.0),
                (-coupler_length / 2.0, 0.0), (coupler_length / 2.0, 0.0),
                (coupler_length / 2.0 + bend_radius, 0.0),
                (coupler_length / 2.0 + bend_radius, bend_radius)
            ])

            wg = i3.RoundedWaveguide(name=self.name + "_wg",
                                     trace_template=self.trace_template)
            wg_layout = wg.Layout(shape=shape)

            insts += i3.SRef(reference=wg_layout,
                             name="wav_top",
                             position=(0, delta / 2.0))

            insts += i3.SRef(reference=wg_layout,
                             name="wav_bot",
                             transformation=i3.VMirror() +
                             i3.Translation(translation=(0, -delta / 2.0)))
            return insts

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

            return ports

    class CircuitModel(i3.CircuitModelView):
        coupler_length = i3.PositiveNumberProperty(
            doc=
            "Length of the straight section of the directional coupler, calculated from the power coupling",
            locked=True)
        power_coupling_factor = i3.FractionProperty(
            default=0.5, doc="Fraction of the field coupling")
        delta_n_eff = i3.NumberProperty(
            doc="Difference between even and odd mode of the dc")
        coupling_at_zero_length = i3.NonNegativeNumberProperty(
            default=0.03,
            doc="Field coupling for a zero length coupling",
            locked=True)
        center_wavelength = i3.PositiveNumberProperty(
            doc="Reference wavelength for all parameters", locked=True)

        def _default_center_wavelength(self):
            return self.trace_template.center_wavelength

        def _default_delta_n_eff(self):
            return 0.04

        def _default_coupler_length(self):
            L = (self.center_wavelength *
                 np.arcsin(self.power_coupling_factor**0.5) /
                 (np.pi * self.delta_n_eff) - self.center_wavelength *
                 np.arcsin(self.coupling_at_zero_length) /
                 (np.pi * self.delta_n_eff))

            return L

        def _generate_model(self):
            trace_length = self.layout_view.instances[
                'wav_top'].reference.trace_length()
            non_coupling_length = (trace_length - self.coupler_length)

            return DirCoupModel(
                delta_n=self.delta_n_eff,
                n_avg=self.trace_template.n_eff,
                coupler_length=self.coupler_length,
                non_coupling_length=non_coupling_length,
                coupling_at_zero_length=self.coupling_at_zero_length,
                center_wavelength=self.center_wavelength)

    class Netlist(i3.NetlistFromLayout):
        pass