# -*- coding: utf-8 -*-
"""
Created on Thu Jul 8 09:05:53 2021
@author: e022539
"""
import mypy.procedure_gdspy as ppy
import gdspy
import os
import datetime
'''定义9点'''
ll='ll';lr='lr';lc='lc';cl='cl';cc='cc';cr='cr';ul='ul';uc='uc';ur='ur'
'''
ul------uc------ur
- - -
- - -
cl------cc------cr
- - -
- - -
ll------lc------lr
'''
'''找到当前文件所在位置'''
cwd=os.getcwd()
'''设置当前文件所在位置为默认目录'''
os.chdir(cwd)
time1=datetime.datetime.now()
print('Start time: '+str(time1.strftime("%Y-%m-%d %H:%M:%S")))
'''library 置空'''
gdspy.current_library=gdspy.GdsLibrary()
'''全局变量'''
CTW=0.09
CTS=0.14
V1W=0.09
V1S=0.14
CT=ppy.cRect('CT','CT',CTW,CTW)
V1=ppy.cRect('V1','V1',V1W,V1W)
V2=ppy.cRect('V2','V2',V1W,V1W)
''''''
SA=0.2; GTexAA=0.14
AAencCT=0.02; AAencCT_Y=0.04
CTnum=2; GTencCT=0.05
GTspAA=0.05
M1S=0.18; M1W=0.5; M1L=3.5
pitch=110; padL=55
AAL=6; AAW=1; AAS=3
SNencAA=0.2; SNencGT=0.2; SPencAA=0.2; SPencGT=0.2
NWencSP=0.2
TGencAA=1; DGencAA=1
NA=['NA','Na','na','','/','\\',]
def MOS(cellname,Device,Type,W,L):
'''creat top cell'''
BORDER_L=25;BORDER_W=25
top=ppy.cRect(cellname,'BORDER',BORDER_L,BORDER_W,origin=(0,0))
'''画AA'''
AA_L=2*SA+L
AA=ppy.cRect(cellname+'_AA','AA',AA_L,W)
AA.align(None,cc,top,cc)
M1inAA_L=0.5*(2*SA+L-M1S)
M1inAA=ppy.cRect(cellname+'_M1inAA','M1',M1inAA_L,W)
M1inAA.fill(CT,CTS,CTS,AAencCT,AAencCT,fixs=True)
M1inAA.align(top,cl,AA,cl)
M1inAA.align(top,cr,AA,cr)
'''画GT'''
GTbody=ppy.cRect(cellname+'_GTbody','GT',L,W+2*GTexAA)
GTbody.align(top,cc,AA,cc)
GTlink_L=CTnum*CTW+(CTnum-1)*CTS+2*GTencCT
GTlink_W=M1S-GTspAA
GTlink=ppy.cRect(cellname+'_GTlink','GT',GTlink_L,GTlink_W)
GTlink.align(top,lc,AA,uc,0,GTspAA)
GTup=ppy.cRect(cellname+'_GTup','GT',GTlink_L,GTlink_L)
GTup.size(None,None,'M1',size=0)
GTup.fill(CT,CTS,CTS,AAencCT,AAencCT,fixs=True)
GTup.align(top,lc,GTlink,uc)
'''画pickup'''
pick=ppy.cRect(cellname+'_pick','AA',AAL,AAW)
pick.size(None,None,'M1',size=0)
pick.fill(CT,CTS,CTS,AAencCT,AAencCT,fixs=True)
pick.align(top,uc,AA,lc,0,-AAS)
'''画IMP'''
'''画NPS/PPS'''
if Type[0]=='P':
SPSN_L=GTlink_L+2*SPencGT if GTlink_L>AA_L else AA_L+2*SPencAA
SPSN_W=GTexAA+W+M1S+GTlink_L+2*SPencGT
SPSN=ppy.cRect(cellname+'_SPSN','SP',SPSN_L,SPSN_W)
elif Type[0]=='N':
SPSN_L=GTlink_L+2*SNencGT if GTlink_L>AA_L else AA_L+2*SNencAA
SPSN_W=GTexAA+W+M1S+GTlink_L+2*SNencGT
SPSN=ppy.cRect(cellname+'_SPSN','SN',SPSN_L,SPSN_W)
SPSN.align(top,cc,AA,cc,0,-0.5*GTexAA+0.5*M1S+0.5*GTlink_L)
'''画pickup IMP'''
if Type[0]=='P':
IMPpick_L=AAL+2*SNencAA
IMPpick_W=AAW+2*SNencAA
IMPpick=ppy.cRect(cellname+'_IMPpick','SN',IMPpick_L,IMPpick_W)
elif Type[0]=='N':
IMPpick_L=AAL+2*SPencAA
IMPpick_W=AAW+2*SPencAA
IMPpick=ppy.cRect(cellname+'_IMPpick','SP',IMPpick_L,IMPpick_W)
IMPpick.align(top,cc,pick,cc)
'''画SNW'''
if Type[0]=='P':
SNW_L=IMPpick_L+2*NWencSP
SNW_W=SPSN_W+IMPpick_W+AAS-GTexAA-SPencAA-SNencAA+2*NWencSP
SNW=ppy.cRect(cellname+'_IMP2','NW',SNW_L,SNW_W)
elif Type[0]=='N':
SNW=ppy.cRect(cellname+'_IMP2','NW',0,0)
SNW.align(top,cc,AA,cc,0,0.5*GTlink_L+0.5*M1S-0.5*AAS-0.5*AAW)
'''画DG和NAT'''
'''
if Device=='1.2V':
exIMP=ppy.cRect(cellname+'_exIMP','DG',0,0)
elif Device=='1.8V':
exIMP_W=GTlink_L+M1S+W+AAS+AAW+2*TGencAA
exIMP=ppy.cRect(cellname+'_exIMP','TG',exIMP_W,exIMP_W)
elif Device=='2.5V':
exIMP_W=GTlink_L+M1S+W+AAS+AAW+2*DGencAA
exIMP=ppy.cRect(cellname+'_exIMP','DG',exIMP_W,exIMP_W)
exIMP.align(top,cc,AA,cc,0,0.5*GTlink_L+0.5*M1S-0.5*AAS-0.5*AAW)
'''
'''画AA边缘的M1'''
M1lf=ppy.cRect(cellname+'_M1lf','M1',M1W,W)
M1lf.align(top,cr,AA,cl)
M1rg=ppy.cRect(cellname+'_M1rg','M1',M1W,W)
M1rg.align(top,cl,AA,cr)
'''画AA的外接M1'''
n=int(W/4) if W/2.5>1 else 1
M1link1=ppy.cRect(cellname+'_M1link1','M1',5,0.5)
M1link1lf=M1link1.array(cellname+'_M1link1lf',1,n,xspace=0,yspace=3.5)
M1link1lf.align(top,cr,M1lf,cl)
M1link1rg=M1link1.array(cellname+'_M1link1rg',1,n,xspace=0,yspace=3.5)
M1link1rg.align(top,cl,M1rg,cr)
M1link2=ppy.cRect(cellname+'_M1link2','M1',0.5*pitch-0.5*padL-5-M1W-0.5*AA_L-2,2)
M1link2lf=M1link2.array(cellname+'_M1link2lf',1,n,xspace=0,yspace=2)
M1link2lf.align(top,cr,M1lf,cl,-5,0)
M1link2rg=M1link2.array(cellname+'_M1link2rg',1,n,xspace=0,yspace=2)
M1link2rg.align(top,cl,M1rg,cr,5,0)
'''画GT的外接M1'''
GTM1=ppy.cRect(cellname+'_GTup','M1',GTlink_L,5)
GTM1.align(top,lc,GTup,uc)
'''画PIN'''
if W/2.5>1:
ppy.cRect(cellname+'_Dpin','M1',0,n*2+n*2).setpin('D','-x').align(top,cr,M1link2lf,cl)
ppy.cRect(cellname+'_Spin','M1',0,n*2+n*2).setpin('S','+x').align(top,cl,M1link2rg,cr)
elif W/2.5<=1:
ppy.cRect(cellname+'_Dpin','M1',0,2).setpin('D','-x').align(top,cr,M1link2lf,cl)
ppy.cRect(cellname+'_Spin','M1',0,2).setpin('S','+x').align(top,cl,M1link2rg,cr)
ppy.cRect(cellname+'_Gpin','M1',2,0).setpin('G','+y').align(top,lc,GTM1,uc)
ppy.cRect(cellname+'_Bpin','M1',2,0).setpin('B','-y').align(top,uc,pick,lc)
return top
top=gdspy.Cell('Sample')
A01=MOS('A01','1.8V','P',10,0.2).insert(top)
A02=MOS('A02','1.2V','P',0.12,0.06).align(top,lc,A01,uc)
A03=MOS('A03','2.5V','N',10,0.28).align(top,lc,A02,uc)
top.save('Sample.gds')
import openpyxl as xl
wb=xl.load_workbook('TK plan.xlsx',data_only=True)
sht=wb['MOS']
TKname_col='A'
cellname_col='B'
Device='C'
Type_col='D'
W_col='E'
L_col='F'
D_col='G'
G_col='H'
S_col='I'
B_col='J'
top=gdspy.Cell('top')
X=0;Y=0
tkL=2425;tkW=72
PAD55=ppy.pad(tech='55NM',cellname='PAD_55',intermetal=5,TM1=True,tkW=72,tkL=2425,padL=55,padW=55,padnum=22,pitch=110,slot=False)
for i in range(1,1000):
''' 生成TK cell,并插入一条PAD'''
if sht[cellname_col+str(i)].value=='cellname':
tkname=sht[TKname_col+str(i)].value
tk=ppy.cCell(tkname)
tk.add(PAD55)
ppy.padWord(tk,tkname,1.0)
'''开始往TK中插入device'''
for j in range(i+1,i+100):
if sht[cellname_col+str(j)].value !=None:
#print (tkname)
'''读device变量'''
'''根据变量赋值生成device'''
cellname = tkname+'_'+str(sht['B'+str(j)].value)
Device = sht['C'+str(j)].value
Type = sht['D'+str(j)].value
W = sht['E'+str(j)].value
L = sht['F'+str(j)].value
device = MOS(cellname,Device,Type,W,L)
D=sht['G'+str(j)].value
G=sht['H'+str(j)].value
S=sht['I'+str(j)].value
B=sht['J'+str(j)].value
loc=sht['G'+str(j)].value
pinset={'D':D,'G':G,'S':S,'B':B}
#print(loc,pinset)
ppy.metalLink(tk,device,linkW=2,linkS=2,location=loc,offset=['center',0],**pinset)
device.remove_Layers('BORDER')
time1=datetime.datetime.now()
#print(cellname+' done time: '+str(time1.strftime("%Y-%m-%d %H:%M:%S")))
else:
break
tk.add_rect('BORDER',tkL,tkW)
'''tk add PAD 角标'''
'''
number=['5','10','15','20']
for word in number:
ppy.padNumber(tk,word,mag=0.3,x=(int(word)-1)*tk.pitch+tk.pad1offset+tk.padL+2,y=-tk.padW/2+5)
# 在循环中添加调试信息
'''
#top.add(tk,origin=(X,Y))
Y=Y+tkW
time1=datetime.datetime.now()
print(tkname+' done time: '+str(time1.strftime("%Y-%m-%d %H:%M:%S")))
top.save('0214.gds')
gdspy.ck_sum('0214.gds','0214.txt')
time1=datetime.datetime.now()
print('End time: '+str(time1.strftime("%Y-%m-%d %H:%M:%S")))
上述程序输出Start time: 2025-08-21 13:17:30
TK01 done time: 2025-08-21 13:17:30
TK02 done time: 2025-08-21 13:17:30
3405101628 110 0214.gds
End time: 2025-08-21 13:17:30
C:\Users\e025822\AppData\Local\Continuum\anaconda3\lib\site-packages\gdspy\__init__.py:1354: RuntimeWarning: overflow encountered in double_scalars
self.length += numpy.sqrt(length**2 + axis_offset**2)