def mzi(length=1000, sep=50): with nd.Cell(hashme=True) as mziBB: eopm = eopm_dc(length=length, pads=True, sep=40) mmi_left = mmi2x2_dp().put('lc') deep.sbend(offset=sep).put(mmi_left.pin['b0']) eopm_top = eopm.put() deep.sbend(offset=-sep).put() mmi_right = mmi2x2_dp().put() deep.sbend(offset=-sep).put(mmi_left.pin['b1']) eopm_bot = eopm.put(flip=True) deep.sbend(offset=sep).put() nd.Pin('a0', pin=mmi_left.pin['a0']).put() nd.Pin('a1', pin=mmi_left.pin['a1']).put() nd.Pin('b0', pin=mmi_right.pin['b0']).put() nd.Pin('b1', pin=mmi_right.pin['b1']).put() nd.Pin('c0', pin=eopm_top.pin['c0']).put() nd.Pin('c1', pin=eopm_top.pin['c1']).put() nd.Pin('d0', pin=eopm_bot.pin['c0']).put() nd.Pin('d1', pin=eopm_bot.pin['c1']).put() pdk.put_stub() bb_length, y, a = nd.diff(mziBB.pin['a0'], mziBB.pin['b0']) pdk.put_boundingbox('org', length=abs(bb_length), width=2*sep+428) return mziBB
def abb_eopm_dc(length=750, contacts=2): """Create an electro-optic phase modulator cell. Args: length (float): length of the modulator section in um Returns: Cell: eopm element """ width = 60 with nd.Cell(hashme=True) as C: nd.Pin(name='a0', xs='Deep', width=wdeep).put(0, 0, 180) nd.Pin(name='b0', xs='Deep', width=wdeep).put(length, 0, 0) # x-positions of pads: L = 0.5*(length - wmetdc) xpos = [] if contacts > 1: for n in range(contacts): xpos.append(0.5*wmetdc + L*2*n/(contacts-1)) elif contacts == 1: xpos = [0.5*length] elif contacts == 0: pass for n, x in enumerate(xpos): pinname = 'c'+str(n) p1 = nd.Pin(name=pinname, xs='MetalDC', width=wmetdc).put(x, 0, 90) nd.put_stub(pinname) #nd.Pin(name='c0', xs='MetalDC', width=wmetdc).put(0.5*length, 5.0, 90) pdk.put_stub(['a0', 'b0', 'c0']) pdk.put_boundingbox('org', length, width, align='lc') icons.icon_strt(length, width, bufx=0, bufy=10, layer='MetalDCIcon').put('cc', 0, 'cc') icons.icon_strt(length, width, bufx=10, bufy=-8, layer='DeepIcon').put('cc', 0, 'cc') return C
def dbr_laser(Ldbr1=50, Ldbr2=500, Lsoa=750, Lpm=70): """Create a parametrized dbr laser building block.""" Liso = 20 with nd.Cell(hashme=True) as laser: #create an isolation cell for reuse iso = isolation_act(length=Liso) #draw the laser s2a1 = s2a().put(0) iso.put() dbr1 = dbr(length=Ldbr1).put() iso.put() soa1 = soa(length=Lsoa).put() iso.put() phase1 = phase_shifter(length=Lpm).put() iso.put() dbr2 = dbr(length=Ldbr2).put() iso.put() a2s1 = a2s().put() # add pins to the laser building block nd.Pin('a0', pin=s2a1.pin['a0']).put() nd.Pin('b0', pin=a2s1.pin['b0']).put() nd.Pin('c0', pin=dbr1.pin['c0']).put() nd.Pin('c1', pin=soa1.pin['c0']).put() nd.Pin('c2', pin=phase1.pin['c0']).put() nd.Pin('c3', pin=dbr2.pin['c0']).put() pdk.put_stub() length, y, a = nd.diff(laser.pin['a0'], laser.pin['b0']) pdk.put_boundingbox('org', length=abs(length), width=200, align='lb', move=(0, -30, 0)) return laser
def isolation(length=length): """Create a p-isolation cell. Args: length (float): length of the isolation section in um Returns: Cell: isolation element """ bb_width = 20 with nd.Cell(hashme=True) as C: nd.Pin(name='a0', xs=xs, width=width).put(0, 0, 180) nd.Pin(name='b0', xs=xs, width=width).put(length, 0, 0) pdk.put_stub() pdk.put_boundingbox('org', length, bb_width) icons.icon_strt(length, bb_width, bufx=4, bufy=-8, layer=layer).put('cc', 0, 'cc') return C
def phase_shifter(length=100): """Create a current injection phase shifting cell. Args: length (float): length of phase section in um Returns: Cell: phase-shifter element """ width = 200 h = -70 with nd.Cell(hashme=True) as C: nd.Pin(name='a0', xs='Active', width=wact).put(0, h, 180) nd.Pin(name='b0', xs='Active', width=wact).put(length, h, 0) nd.Pin(name='c0', xs='MetalDC', width=wmetdc).put(0.5*length, 5.0, 90) pdk.put_stub(['a0', 'b0', 'c0']) pdk.put_boundingbox('org', length, width, align='lc') icons.icon_strt(length, width, bufx=0, bufy=10, layer='MetalDCIcon').put('cc', 0, 'cc') icons.icon_strt(length, width, bufx=10, bufy=-8, layer='ActiveIcon').put('cc', 0, h, 'cc') return C
def dbr(length=100, pitch=0.250, duty_cycle=0.5): """Create a DBR cell. Args: length (float): length of DBR section in um pitch (float): pitch (full period) of dbr in um duty_cycle (float): duty cycle of grating (default = 0.5) Returns: Cell: dbr element """ width = 200 h = -70 icon = icons.Tp_icon_grating('ActiveIcon') with nd.Cell(hashme=True) as C: nd.Pin(name='a0', xs='Active', width=wact).put(0, h, 180) nd.Pin(name='b0', xs='Active', width=wact).put(length, h, 0) nd.Pin(name='c0', xs='MetalDC', width=wmetdc).put(0.5*length, 5.0, 90) pdk.put_stub(['a0', 'b0', 'c0']) pdk.put_boundingbox('org', length, width, align='lc') icons.icon_strt(length, width, bufx=0, bufy=10, layer='MetalDCIcon').put('cc', 0, 'cc') icons.icon_strt(length, width, bufx=10, bufy=-8, layer='ActiveIcon').put('cc', 0, h, 'cc') icon(length, width, bufx=5, bufy=-40).put('cc', 0, h, 'cc') return C
def soa(length=100, pad=True): """Create a SOA cell. Args: length (float): length of gain section in um Returns: Cell: SOA element """ if pad: width = 200 else: width = 50 h = -70 with nd.Cell(hashme=True) as C: nd.Pin(name='a0', xs='Active', width=wact).put(0, h, 180) nd.Pin(name='b0', xs='Active', width=wact).put(length, h, 0) nd.Pin(name='c0', xs='MetalDC', width=wmetdc).put(0.5*length, 5.0, 90) pdk.put_stub(['a0', 'b0', 'c0']) pdk.put_boundingbox('org', length, width, align='lc') icons.icon_strt(length, width, bufx=0, bufy=10, layer='MetalDCIcon').put('cc', 0, 'cc') icons.icon_strt(length, width, bufx=10, bufy=-8, layer='ActiveIcon').put('cc', 0, h, 'cc') return C
#============================================================================== with nd.Cell('awg1x4') as awg1x4: awg = nd.load_gds( filename= os.path.join(dir_path, 'gdsBB', 'AWG_1x4.gds'), cellname='awg', newcellname='demo_awg', layermap={1:3}) awg.put() nd.Pin('a0', xs='Deep', width=wdeep).put((9.184851e-016, -5, -90)) nd.Pin('b0', xs='Deep', width=wdeep).put((273.63575, -4.5798919, -85.569401)) nd.Pin('b1', xs='Deep', width=wdeep).put((269.89849, -4.9532407, -88.523134)) nd.Pin('b2', xs='Deep', width=wdeep).put((266.1423, -4.9532407, -91.476866)) nd.Pin('b3', xs='Deep', width=wdeep).put((262.40504, -4.5798919, -94.430599)) pdk.put_stub(['a0', 'b0', 'b1', 'b2', 'b3']) #BBfunctioncalls.append('awg1x4') BBcells = [eval(F) for F in BBfunctioncalls] #============================================================================== # Create groups to provide a structure to put building blocks (BB) under. # This is optional, though useful in navigation BBs. #============================================================================== bb_connectors = pdk.Functional_group() #: inter-connectors bb_transitions = pdk.Functional_group() #: xsection transistions bb_splitters = pdk.Functional_group() #: power splitter and combiners bb_combiners = pdk.Functional_group() #: power splitter and combiners bb_amplifiers = pdk.Functional_group() #: SOAs