def pll_verilog_gen(outMode,designName,genDir,outDir,formatDir,flowDir,ndrv,ncc,nfc,nstg,verilogSrcDir,buf_small,bufz,buf_big,edge_sel,dcoName,platform): if outMode=='macro' or outMode=='full': shutil.copyfile(verilogSrcDir+'FUNCTIONS.v',flowDir+'/src/FUNCTIONS.v') shutil.copyfile(verilogSrcDir+'PLL_CONTROLLER_TDC_COUNTER.v',flowDir+'/src/PLL_CONTROLLER_TDC_COUNTER.v') shutil.copyfile(verilogSrcDir+'PLL_CONTROLLER.v',flowDir+'/src/PLL_CONTROLLER.v') shutil.copyfile(verilogSrcDir+'TDC_COUNTER.v',flowDir+'/src/TDC_COUNTER.v') shutil.copyfile(verilogSrcDir+'SSC_GENERATOR.v',flowDir+'/src/SSC_GENERATOR.v') shutil.copyfile(verilogSrcDir+'dco_CC.v',flowDir+'/src/dco_CC.v') shutil.copyfile(verilogSrcDir+'dco_FC.v',flowDir+'/src/dco_FC.v') shutil.copyfile(verilogSrcDir+'synth_pll_dco_interp_'+platform+'.v',flowDir+'/src/synth_pll_dco_interp.v') shutil.copyfile(verilogSrcDir+'synth_pll_dco_outbuff_'+platform+'.v',flowDir+'/src/synth_pll_dco_outbuff.v') print(outMode,'mode: verilog sources are generated in ',flowDir,'src/') elif outMode=='verilog': shutil.copyfile(verilogSrcDir+'FUNCTIONS.v',outDir+'/FUNCTIONS.v') shutil.copyfile(verilogSrcDir+'PLL_CONTROLLER_TDC_COUNTER.v',outDir+'/PLL_CONTROLLER_TDC_COUNTER.v') shutil.copyfile(verilogSrcDir+'PLL_CONTROLLER.v',outDir+'/PLL_CONTROLLER.v') shutil.copyfile(verilogSrcDir+'TDC_COUNTER.v',outDir+'/TDC_COUNTER.v') shutil.copyfile(verilogSrcDir+'SSC_GENERATOR.v',outDir+'/SSC_GENERATOR.v') shutil.copyfile(verilogSrcDir+'dco_CC.v',outDir+'/dco_CC.v') shutil.copyfile(verilogSrcDir+'dco_FC.v',outDir+'/dco_FC.v') shutil.copyfile(verilogSrcDir+'synth_pll_dco_interp_'+platform+'.v',flowDir+'/src/synth_pll_dco_interp.v') shutil.copyfile(verilogSrcDir+'synth_pll_dco_outbuff_'+platform+'.v',flowDir+'/src/synth_pll_dco_outbuff.v') print(outMode,'mode: verilog sources are generated in ',outDir) print('verilog mode: verilog sources are generated in '+outDir) #--- generate verilog file --- r_pll_v=open(formatDir+'/form_pll_PD.v','r') nm1=txt_mds.netmap() nm1.get_net('iN',designName,None,None,None) nm1.get_net('nM',None,nstg,nstg,1) nm1.get_net('nD',None,ndrv,ndrv,1) nm1.get_net('nF',None,nfc,nfc,1) nm1.get_net('nC',None,ncc,ncc,1) nm1.get_net('dN',dcoName,None,None,None) with open(outDir+'/'+designName+'.v','w') as wvfile: lines_pll=list(r_pll_v.readlines()) for line in lines_pll: nm1.printline(line,wvfile) #--- generate verilog file --- rvfile=open(formatDir+'/form_dco.v','r') nm1=txt_mds.netmap() if edge_sel==1: nm1.get_net('IE','INCLUDE_EDGE_SEL',None,None,None) else: nm1.get_net('IE','EXCLUDE_EDGE_SEL',None,None,None) nm1.get_net('iN',dcoName,None,None,None) nm1.get_net('nM',None,nstg,nstg,1) nm1.get_net('nD',None,ndrv,ndrv,1) nm1.get_net('nF',None,nfc,nfc,1) nm1.get_net('nC',None,ncc,ncc,1) for bcnt in range (1,10): nm1.get_net('b%d'%(bcnt),buf_small,None,None,None) for zcnt in range (1,5): nm1.get_net('z%d'%(zcnt),bufz,None,None,None) nm1.get_net('B1',buf_big,None,None,None) with open(outDir+'/'+dcoName+'.v','w') as wvfile: lines_const=list(rvfile.readlines()) for line in lines_const: nm1.printline(line,wvfile)
def editPin_gen(Ndrv,Ncc,Nfc,Nstg,formatDir,wfile_name): nCC=Ncc*Nstg nFC=Nfc*Nstg nPout=Nstg*2 #rfile=open(formatDir+'/form_floorplan_test.tcl','r') #rfile=open('ignore_form_floorplan.tcl','r') rfile=open(formatDir+'/form_dco_pre_place.tcl','r') wfile=open(wfile_name,'w') #======================================================================== # Version 2 # for floor plan.tcl: spreading out the pin # this is the 2nd version, with all the edge selection spread out, # PH_P/N_out*, CLK_OUT are only concentrated in the bottom, # all other pins are spread 4-side to reduce the delay mismatch between cells #======================================================================== Nedge_start=Nstg*2 eps=int(Nstg/2) # edge_per_side per either N or P nm2=txt_mds.netmap() #--- distribute EDGE_SEL --- nm2.get_net('el',None,0,eps-1,1) nm2.get_net('eL',None,Nedge_start,Nedge_start+eps-1,1) nm2.get_net('et',None,eps,2*eps-1,1) nm2.get_net('eT',None,Nedge_start+eps,Nedge_start+2*eps-1,1) nm2.get_net('er',None,2*eps,3*eps-1,1) nm2.get_net('eR',None,Nedge_start+2*eps,Nedge_start+3*eps-1,1) #--- distribute PH_P_OUT, PH_N_OUT --- nm2.get_net('ep',None,eps*3,eps*3+int(eps/2)-1,1) nm2.get_net('en',None,Nedge_start+eps*3,Nedge_start+eps*3+int(eps/2)-1,1) nm2.get_net('po',None,0,Nstg-1,1) nm2.get_net('no',None,0,Nstg-1,1) nm2.get_net('Po',None,Nstg,2*Nstg-1,1) nm2.get_net('No',None,Nstg,2*Nstg-1,1) nm2.get_net('Ep',None,int(eps*3.5),eps*4-1,1) nm2.get_net('En',None,Nedge_start+int(eps*3.5),Nedge_start+eps*4-1,1) lines=list(rfile.readlines()) istg=0 for line in lines: if line[0:2]=='@E': nm1=txt_mds.netmap() nm1.get_net('f1','FC[',istg,istg+Nstg*(Nfc-1),Nstg) nm1.get_net('c1','CC[',istg,istg+Nstg*(Ncc-1),Nstg) nm1.printline(line,wfile) istg=istg+1 else: nm2.printline(line,wfile)
def math_model_verify(formatDir,write_model_file,CF,Cc,Cf,dm,result_exist,freq,Fmax,Fmin,Fres,Iavg,print_error): Fnom_err=[] Fmax_err=[] Fmin_err=[] Fres_err=[] Iavg_const=[] for nd in result_exist: N_fc=dm[nd][3] N_cc=dm[nd][1] N_drv=dm[nd][0] N_stg=dm[nd][2] Fmax_mdl,Fmin_mdl,Fres_mdl,Fnom_mdl,freqCoverRatio,Ctotal=spec_cal_freq(N_drv,N_cc,N_fc,N_stg,Cc,Cf,CF) Fnom_err.append(abs(Fnom_mdl-freq[nd][0][0])/freq[nd][0][0]*100) Fmax_err.append(abs(Fmax_mdl-Fmax[nd][0][0])/Fmax[nd][0][0]*100) Fmin_err.append(abs(Fmin_mdl-Fmin[nd][0][0])/Fmin[nd][0][0]*100) Fres_err.append(abs(Fres_mdl-Fres[nd][0][0])/Fres[nd][0][0]*100) #--- Iavg constant gen --- Ctotal=Cc*(N_drv+N_cc/2)+Cf*N_fc+CF*N_fc/2 Iavg_const.append(Iavg[nd][0][0]/Ctotal) # if print_error==1: # print ("N_cc= %d,N_drv=%d, Nfc= %d, Nstg=%d"%(N_cc,N_drv,N_fc,N_stg)), # print (abs(Iavg[nd][0][0])), # print (abs(Iavg[nd][0][0]/Ctotal)) Kg_mdl=1/((N_drv+N_cc)*Cc+N_fc*Cf+N_fc/2*CF) #print (Kg[nd][0][0]/Kg_mdl) #checking if Kg is okay #print (Fnom_mdl,freq[nd][0][0]) Fnom_err_mean=sum(Fnom_err)/len(Fnom_err) Fnom_err_max=max(Fnom_err) Fmax_err_mean=sum(Fmax_err)/len(Fmax_err) Fmax_err_max=max(Fmax_err) Fmin_err_mean=sum(Fmin_err)/len(Fmin_err) Fmin_err_max=max(Fmin_err) Fres_err_mean=sum(Fres_err)/len(Fres_err) Fres_err_max=max(Fres_err) Iavg_const_avg=sum(Iavg_const)/len(Iavg_const) #print (Iavg_const) Iavg_err=[] for i in Iavg_const: Iavg_err.append(abs(i-Iavg_const_avg)/abs(i)*100) Iavg_err_mean=sum(Iavg_err)/len(Iavg_err) Iavg_err_max=max(Iavg_err) if print_error==1: print ('*Model accuracy result(in percentage): Fnom_err_mean,max=%f,%f, Fmax=%f,%f, Fmin=%f,%f, Fres=%f,%f, Iavg=%f,%f'%(Fnom_err_mean,Fnom_err_max,Fmax_err_mean,Fmax_err_max,Fmin_err_mean,Fmin_err_max,Fres_err_mean,Fres_err_max,Iavg_err_mean,Iavg_err_max)) #--- write the model.json --- r_model=open(formatDir+'form_model.json','r') nm1=txt_mds.netmap() nm1.get_net('CF',None,CF,CF,1) nm1.get_net('Cc',None,Cc,Cc,1) nm1.get_net('Cf',None,Cf,Cf,1) nm1.get_net('Ic',None,abs(Iavg_const_avg),abs(Iavg_const_avg),1) with open(write_model_file,'w') as w_model: lines=list(r_model.readlines()) for line in lines: nm1.printline(line,w_model) print('model file generated: '+write_model_file) #w_model.write('Fnom_err_mean,max=%f,%f, Fmax=%f,%f, Fmin=%f,%f, Fres=%f,%f, Iavg=%f,%f'%(Fnom_err_mean,Fnom_err_max,Fmax_err_mean,Fmax_err_max,Fmin_err_mean,Fmin_err_max,Fres_err_mean,Fres_err_max,Iavg_err_mean,Iavg_err_max)) return Iavg_const
def gen_pll_prepex_wrapper(design_name, netlist_dir, format_dir, input_array, vdd): r_netlist = open(format_dir + "/ignore_form_wrapped_test_synth_pll.sp", "r") w_netlist = open(netlist_dir + "/" + "wrapped_" + design_name + ".sp", "w") lines = list(r_netlist.readlines()) netmap1 = txt_mds.netmap() #==== input_array[0]: bitwidth, [1]: flag1, [2]: flag 2, [3]: flag3, [4]: dec_val === netmap1.get_net('nd', netslit_dir, None, None, None) netmap1.get_net('dn', design_name, None, None, None) netmap1.get_net('fm', 'sp', None, None, None) netmap1.get_net('dn', design_name, None, None, None) for i in range(len(input_array)): bin_val = bin(input_array[i][4]) bin_len = len(bin_val) - 2 num_zero = input_array[i][0] - bin_len bin_fin = '0' * num_zero + bin_val[2:len(bin_val)] print("%s's bin_fin=%s" % (input_array[i][2], bin_fin)) print("%s's len(bin_fin)=%d, given length=%d" % (input_array[i][2], len(bin_fin), input_array[i][0])) netmap1.get_net(input_array[i][1], None, i * 100, i * 100 + len(bin_fin) - 1, 1) # v# netmap1.get_net(input_array[i][2], None, 0, len(bin_fin) - 1, 1) # bit# for j in range(len(bin_fin)): # print(int(bin_fin[len(bin_fin)-j-1])) netmap1.get_net(input_array[i][3], None, int(bin_fin[len(bin_fin) - j - 1]) * vdd, int(bin_fin[len(bin_fin) - j - 1]) * vdd, 1) #vdd or 0 for line in lines: netmap1.printline(line, w_netlist)
def gen_tbrf(PDK, format_dir, tbrf_dir, dm, freq, result_exist, vdd, temp): r_file = open(format_dir + "/form_tbrf_ring_osc.sp", "r") lines = list(r_file.readlines()) for nd in result_exist: N_fc = dm[nd][3] N_cc = dm[nd][1] N_drv = dm[nd][0] N_stg = dm[nd][2] N_ctrl_fc = N_stg * N_fc N_ctrl_cc = N_stg * N_cc per_tmp = 1 / freq[nd][0][0] #nominal freq, nominal temp freq_tmp = freq[nd][0][0] netmap1 = txt_mds.netmap() #35 netmap1.get_net('ff', None, freq_tmp, freq_tmp, 1) netmap1.get_net('ht', None, 50 * per_tmp, 50 * per_tmp, 1) netmap1.get_net('nd', None, N_drv, N_drv, 1) netmap1.get_net('nm', None, N_cc, N_cc, 1) netmap1.get_net('nt', 'sc', N_stg, N_stg, 1) netmap1.get_net('nf', None, N_fc, N_fc, 1) #----- only string ----------- netmap1.get_net('PK', PDK, None, None, None) #----- lateral stuffs -------- netmap1.get_net('vf', 'vf', 0, N_ctrl_fc - 1, 1) netmap1.get_net('vc', 'vc', 0, N_ctrl_cc - 1, 1) netmap1.get_net('vd', None, vdd[0], vdd[0], 1) netmap1.get_net('tm', None, temp[0], temp[0], 1) netmap1.get_net('f1', None, 'd2o', N_ctrl_fc, N_ctrl_fc // 2) netmap1.get_net('c1', None, 'd2o', N_ctrl_cc, N_ctrl_cc // 2) with open( tbrf_dir + "/tbrf_%dring%d_osc%d_fc%d.sp" % (N_drv, N_cc, N_stg, N_fc), "w") as w_file: for line in lines: netmap1.printline(line, w_file) print("tbrf nstg=%d" % (N_stg))
def tb_verilog_gen(formatDir, tbDir, relBW, Kp_o_Ki, Fref, dFf, dFc, FCW, Fbase, ndrv, ncc, nfc, nstg): Kp = relBW * Fref / dFf Ki = Kp / Kp_o_Ki nm1 = txt_mds.netmap() nm1.get_net('ns', None, nstg, nstg, 1) nm1.get_net('nc', None, ncc, ncc, 1) nm1.get_net('nf', None, nfc, nfc, 1) nm1.get_net('nd', None, ndrv, ndrv, 1) nm1.get_net('fb', None, Fbase, Fbase, 1) nm1.get_net('dc', None, dFc, dFc, 1) nm1.get_net('df', None, dFf, dFf, 1) nm1.get_net('FR', None, Fref, Fref, 1) nm1.get_net('Kp', None, Kp, Kp, 1) nm1.get_net('Ki', None, Ki, Ki, 1) nm1.get_net('FW', None, FCW, FCW, 1) nm1.get_net('CT', None, 30, 30, 1) # coarse_lock_threshold nm1.get_net('CC', None, 10, 10, 1) # coarse_lock_count nm1.get_net('FT', None, 10, 10, 1) # fine_lock_threshold nm1.get_net('FC', None, 30, 30, 1) # fine_lock_count r_TB = open(formatDir + 'form_TB_PLL_CONTROLLER_TDC_COUNTER.sv', 'r') w_TB = open(tbDir + 'TB_PLL_CONTROLLER_TDC_COUNTER.sv', 'w') lines = list(r_TB.readlines()) for line in lines: nm1.printline(line, w_TB) print('verilog testbench ready')
def gen_mkfile_v2(format_dir, hspiceDir, ncell, ndrv, nfc, nstg, rf_ready, num_core, result_exist, tech_node): r_file = open(format_dir + "/form_hspicesim.mk", "r") #w_file=open("./Makefile","w") #print (result_exist) netmap1 = txt_mds.netmap() #----- stuffs for transient sim ------- netmap1.get_net('TN', tech_node, None, None, 1) #number of core netmap1.get_net('s2', ' cd', None, None, len(ncell) - 1) #exclude ncell[0] name netmap1.get_net('tn', tech_node, None, None, len(ncell) - 1) #number of core netmap1.get_net('mp', None, num_core, num_core, 1) #number of core netmap1.get_net('md', None, ndrv[1], ndrv[1], 1) #starting from 1 since comblist[0] is name netmap1.get_net('mt', None, ncell[1], ncell[1], 1) netmap1.get_net('nt', 'sc', nstg[1], nstg[1], 1) netmap1.get_net('nf', None, nfc[1], nfc[1], 1) #----- stuffs for rf sim ------- if rf_ready == 1: if 0 in result_exist: netmap1.get_net('s1', ' cd', None, None, len(result_exist)) netmap1.get_net('rm', None, num_core, num_core, 1) #number of core netmap1.get_net('rd', None, ndrv[1], ndrv[1], 1) netmap1.get_net('mr', None, ncell[1], ncell[1], 1) netmap1.get_net('nr', 'sc', nstg[1], nstg[1], 1) netmap1.get_net('Nf', None, nfc[1], nfc[1], 1) for i in range(2, len(ncell)): #----- stuffs for transient sim ------- netmap1.add_val('mp', None, num_core, num_core, 1) #number of core netmap1.add_val('md', None, ndrv[i], ndrv[i], 1) netmap1.add_val('mt', None, ncell[i], ncell[i], 1) netmap1.add_val('nt', 'sc', nstg[i], nstg[i], 1) netmap1.add_val('nf', None, nfc[i], nfc[i], 1) #----- stuffs for rf sim ------- if rf_ready == 1: if i - 1 in result_exist: print("got net %d" % (i - 1)) netmap1.add_val('rm', None, num_core, num_core, 1) #number of core netmap1.add_val('rd', None, ndrv[i], ndrv[i], 1) netmap1.add_val('mr', None, ncell[i], ncell[i], 1) netmap1.add_val('nr', 'sc', nstg[i], nstg[i], 1) netmap1.add_val('Nf', None, nfc[i], nfc[i], 1) lines = list(r_file.readlines()) with open(hspiceDir + "/hspicesim.mk", "w") as w_file: for line in lines: if rf_ready == 1: if line[0:3] == '#@@': line = line[1:len(line)] if line[0:2] == '#1': line = line[3:len(line)] netmap1.printline(line, w_file) print(hspiceDir + 'hspicesim.mk ready')
def write_Kpn(ncell, ndrv, nfc, Kpn, Ekpn): wrkg = open("./model/%ddco_Kpn%d_val_fc%d.py" % (ndrv, ncell, nfc), "w") readf = open("./formats/form_Kpn.py", "r") lines = list(readf.readlines()) Edb = 10 * np.log10(1 + Ekpn / 100) #print ('Edb='), #print Edb Kmap = txt_mds.netmap() Kmap.get_net('Kp', None, Kpn, Kpn, 1) Kmap.get_net('Ek', None, Ekpn, Ekpn, 1) Kmap.get_net('Ed', None, float(Edb), float(Edb), 1) for line in lines: Kmap.printline(line, wrkg)
def write_K(ncell, ndrv, nfc, Kg, Kg_err, dK, idK): wrkg = open("./model/%ddco_K%d_val_fc%d.py" % (ndrv, ncell, nfc), "w") readf = open("./formats/dco_K_val.py", "r") lines = list(readf.readlines()) Kmap = txt_mds.netmap() Kmap.get_net('kg', None, Kg, Kg, 1) Kmap.get_net('ke', None, Kg_err, Kg_err, 1) Kmap.get_net('dK', None, dK[0], dK[0], 1) Kmap.get_net('iK', None, idK[0], idK[0], 1) for i in range(1, len(dK)): Kmap.add_val('dK', None, dK[i], dK[i], 1) Kmap.add_val('iK', None, idK[i], idK[i], 1) for line in lines: Kmap.printline(line, wrkg)
def outbuff_div_flow(formatDir,flowDir,bufName,platform,bleach,design): # copy scripts, src, Makefile if os.path.isdir(flowDir+'scripts')==0: shutil.copytree(formatDir+'buf_scripts',flowDir+'/scripts') shutil.copytree(formatDir+'buf_src',flowDir+'/src') shutil.copyfile(formatDir+'cadre_Makefile',flowDir+'/Makefile') #--- generate include.mk file --- rmkfile=open(formatDir+'/form_include.mk','r') nm1=txt_mds.netmap() nm1.get_net('iN',bufName,None,None,None) nm1.get_net('pf',platform,None,None,None) with open(flowDir+'include.mk','w') as wmkfile: lines_const=list(rmkfile.readlines()) for line in lines_const: nm1.printline(line,wmkfile) #--- bleach --- if bleach==1: p = sp.Popen(['make','bleach_all'], cwd=flowDir) p.wait() if design==1: #------------------------------------------- # run CADRE flow #------------------------------------------- p = sp.Popen(['make','synth'], cwd=flowDir) p.wait() p = sp.Popen(['make','design'], cwd=flowDir) p.wait() p = sp.Popen(['make','lvs'], cwd=flowDir) p.wait() p = sp.Popen(['make','drc'], cwd=flowDir) p.wait() p = sp.Popen(['make','export'], cwd=flowDir) p.wait() p = sp.Popen(['cp','results/innovus/'+'outbuff_div_cutObs.lef','export/outbuff_div.lef'], cwd=flowDir) p.wait()
def gen_mkfile_pex(formatDir, hspiceDir, hspiceResDir, tbDir, num_core, designNames, tech_node): r_file = open(formatDir + "form_pex_hspicesim.mk", "r") netmap1 = txt_mds.netmap() #----- stuffs for transient sim ------ #----- get_net is okay since it's same as add_val when the variable is already in the list ------- netmap1.get_net('TN', tech_node, None, None, 1) for designName in designNames: netmap1.get_net('s2', ' cd', None, None, 1) #exclude ncell[0] name netmap1.get_net('Rd', hspiceResDir, None, None, 1) #exclude ncell[0] name netmap1.get_net('mp', None, None, num_core, 1) #number of core netmap1.get_net('Td', tbDir, None, None, 1) #exclude ncell[0] name netmap1.get_net('dn', designName, None, None, 1) lines = list(r_file.readlines()) with open(hspiceDir + "pex_hspicesim.mk", "w") as w_file: for line in lines: netmap1.printline(line, w_file) print('pex_hspicesim.mk ready')
def gen_pll_pre_wrapper2(switch, buf, PD, raw_sp_dir, design_name, netlist_dir, format_dir, input_array, vdd): if PD == 1: if buf == 1: if switch == 0: r_netlist = open( format_dir + "/ignore_form_wrapped_test_synth_pll_buf.sp", "r") elif switch == 1: r_netlist = open( format_dir + "/ignore_form_wrapped_test_synth_pll_buf_switch.sp", "r") else: r_netlist = open( format_dir + "/ignore_form_wrapped_test_synth_pll2.sp", "r") else: r_netlist = open(format_dir + "/ignore_form_wrapped_test_synth_pll.sp", "r") #if PD==1: # r_netlist=open(format_dir+"/ignore_form_wrapped_test_synth_pll2.sp","r") # the one with VDD_DCO #else: # r_netlist=open(format_dir+"/ignore_form_wrapped_test_synth_pll.sp","r") w_netlist = open(netlist_dir + "/" + "wrapped_" + design_name + ".sp", "w") lines = list(r_netlist.readlines()) netmap1 = txt_mds.netmap() #==== input_array[0]: bitwidth, [1]: flag1, [2]: flag 2, [3]: flag3, [4]: dec_val === ### register all the inputs to netmap ### netmap1.get_net('nd', netlist_dir, None, None, None) netmap1.get_net('dn', design_name, None, None, None) netmap1.get_net('fm', 'sp', None, None, None) for i in range(len(input_array)): bin_val = bin(input_array[i][4]) bin_len = len(bin_val) - 2 num_zero = input_array[i][0] - bin_len bin_fin = '0' * num_zero + bin_val[2:len(bin_val)] print("%s's bin_fin=%s" % (input_array[i][2], bin_fin)) print("%s's len(bin_fin)=%d, given length=%d" % (input_array[i][2], len(bin_fin), input_array[i][0])) netmap1.get_net(input_array[i][1], None, i * 100, i * 100 + len(bin_fin) - 1, 1) # v# netmap1.get_net(input_array[i][2], None, 0, len(bin_fin) - 1, 1) # bit# for j in range(len(bin_fin)): # print(int(bin_fin[len(bin_fin)-j-1])) netmap1.get_net(input_array[i][3], None, int(bin_fin[len(bin_fin) - j - 1]) * vdd, int(bin_fin[len(bin_fin) - j - 1]) * vdd, 1) #vdd or 0 r_raw_netlist = open(raw_sp_dir + "/" + design_name + ".sp", "r") w_raw_netlist = open(netlist_dir + "/" + design_name + ".sp", "w") raw_lines = list(r_raw_netlist.readlines()) nm2 = txt_mds.netmap() dffchk = 0 inst_def = [] inst_start = 0 ### modify the .include file path in pex.netlist ### for line in raw_lines: if dffchk == 0: if line[8:11] == 'DFF': dffchk = 1 nm2.printline(line, w_raw_netlist) else: print('unwanted subckt def found. will be eliminated.') else: words = line.split() if len(words) > 1 and words[1] == design_name: inst_start = 1 inst_def.append(line) elif inst_start == 1 and line[0:1] == '+': inst_def.append(line) elif inst_start == 1 and line[0:1] != '+': inst_start = 0 nm2.printline(line, w_raw_netlist) ### cut out '.SUBCKT test_synth_pll2' ### inst_def_words = inst_def[0].split() inst_def_words = inst_def_words[2:len(inst_def_words)] ### write down the 'wrapped_test_synth_pll2.sp' ### for line in lines: if line[0:3] == 'xi4': line = line + '+ ' + ' '.join(inst_def_words) + '\n' netmap1.printline(line, w_netlist) for inst_def_line in inst_def[1:len(inst_def)]: netmap1.printline(inst_def_line, w_netlist) netmap1.printline('+ ' + design_name, w_netlist) else: netmap1.printline(line, w_netlist)
def gen_tb_pex(CF, Cc, Cf, PDK, finesim, tb_dir, format_dir, ncell, ndrv, nfc, nstg_start, nstg_end, nstg_step, vdd, temp, nper, design_name, sav): #===================================================== # model constants for trans simulation time calculation #===================================================== CB = Cc * (ndrv + ncell) + Cf * nfc vm1 = txt_mds.varmap() ###modify here!! vm1.get_var('ncell', ncell, ncell, 1) vm1.get_var('nstage', nstg_start, nstg_end, nstg_step) #vm1.comblist[1]=nstg vm1.get_var('ndrive', ndrv, ndrv, 1) vm1.cal_nbigcy() vm1.combinate() num_var = 1 nstg_swp = nstg_end - nstg_start + 1 N_recur = 5 * 3 * len(vdd) * len(temp) * 4 # sys.setrecursionlimit(N_recur+1) #expand the recursion limit if exceeded if len(vdd) > 1 and len(temp) > 1: vdd_min, vdd_max = txt_mds.mM(vdd) #generate function of minMax step vdd.remove(vdd_min) temp_min, temp_max = txt_mds.mM(temp) temp.remove(temp_min) elif len(vdd) == 1 and len(temp) == 1: vdd_min = vdd[0] vdd_max = vdd[0] temp_min = temp[0] temp_max = temp[0] #r_file=open("./tb_ring_osc_FC.sp","r") if finesim == 0: if sav == 0: r_file = open(format_dir + "form_pex_tb_ring_osc.sp", "r") else: r_file = open(format_dir + "form_pex_tb_ring_osc_sav.sp", "r") elif finesim == 1: r_file = open(format_dir + "form_fs_pex_tb_ring_osc.sp", "r") lines = list(r_file.readlines()) for i in range(1, len(vm1.comblist[0])): #=============================================== # transient sim time calculation #=============================================== Fmin_mdl = 1 / (CB + nfc * CF) * (ndrv) / vm1.comblist[1][i] print('estimated Fmin=%e' % (Fmin_mdl)) #per_max_mdl=vm1.comblist[1][i]*(CB+nfc*CF)/ndrv per_max_mdl = 1 / Fmin_mdl print('estimated sim_time=%e' % (per_max_mdl * 25)) TD = 00e-9 #=============================================== # writing #=============================================== L_lines = [] L_flag = 0 netmap1 = txt_mds.netmap() #35 netmap1.get_net('Ti', None, TD + per_max_mdl * 25, TD + per_max_mdl * 25, 1) netmap1.get_net('TE', None, TD + per_max_mdl * (25 + nper), TD + per_max_mdl * (25 + nper), 1) netmap1.get_net('vd', None, vdd[0], vdd[0], 1) netmap1.get_net('DN', design_name, None, None, None) #----- only string ----------- netmap1.get_net('PK', PDK, None, None, None) #=============================================== # number of control node definition for v2 #=============================================== N_ctrl_fc = vm1.comblist[1][i] * nfc N_ctrl_cc = vm1.comblist[1][i] * ncell #=============================================== # generate variable maps: FCWs to sweep # (CC,FC)=(0,0),(0,Nfc),(1,0),(Ncc//2,0) # (Ncc//2,Nfc//2),(Ncc//2,Nfc) # (Ncc,Nfc) #=============================================== vm2 = txt_mds.varmap() vm2.get_var( 'vdd', vdd[0], vdd[0], 1) #vm2.comblist[0]=vdd #???? why like this? because of get_var if len(vdd) > 1: for i in range(1, len(vdd)): vm2.add_val('vdd', vdd[i], vdd[i], 1) vm2.get_var('temp', temp[0], temp[0], 1) #vm2.comblist[1]=temp if len(temp) > 1: for i in range(1, len(temp)): vm2.add_val('temp', temp[i], temp[i], 1) vm2.cal_nbigcy() vm2.combinate() #vdd/temp combination var_list = [[[] for x in range(7)] for y in range(len(vm2.comblist[0]) - 1)] for i in range(1, len(vm2.comblist[0])): var_list[i - 1][0] = [0, 0, vm2.comblist[0][i], vm2.comblist[1][i]] var_list[i - 1][1] = [ 0, N_ctrl_fc, vm2.comblist[0][i], vm2.comblist[1][i] ] var_list[i - 1][2] = [1, 0, vm2.comblist[0][i], vm2.comblist[1][i]] var_list[i - 1][3] = [ N_ctrl_cc // 2, 0, vm2.comblist[0][i], vm2.comblist[1][i] ] var_list[i - 1][4] = [ N_ctrl_cc // 2, N_ctrl_fc // 2, vm2.comblist[0][i], vm2.comblist[1][i] ] var_list[i - 1][5] = [ N_ctrl_cc // 2, N_ctrl_fc, vm2.comblist[0][i], vm2.comblist[1][i] ] var_list[i - 1][6] = [ N_ctrl_cc, N_ctrl_fc, vm2.comblist[0][i], vm2.comblist[1][i] ] #=================================================================== # DATA table gen for parametric sweep #=================================================================== #----- lateral stuffs: names -------- netmap1.get_net('vf', 'vf', 0, N_ctrl_fc - 1, 1) #for v2 netmap1.get_net('vc', 'vc', 0, N_ctrl_cc - 1, 1) #for v2 #----- lateral stuffs: FCW values -------- with open(tb_dir + "tb_" + design_name + ".sp", "w") as w_file: for line in lines: if line[0:4] == '@L@W': line = line[2:len(line) - 1] for ivt in range(len(var_list)): for ifcw in range(len(var_list[0])): netmap2 = txt_mds.netmap() netmap2.get_net('f1', None, 'd2o', N_ctrl_fc, var_list[ivt][ifcw][1]) netmap2.get_net('c1', None, 'd2o', N_ctrl_cc, var_list[ivt][ifcw][0]) netmap2.get_net('vd', None, var_list[ivt][ifcw][2], var_list[ivt][ifcw][2], 1) netmap2.get_net('tm', None, var_list[ivt][ifcw][3], var_list[ivt][ifcw][3], 1) netmap2.printline(line, w_file) w_file.write('\n') #for j in range(1,len(vm2.comblist[0])): ## print('one line') # #print vm2.comblist[0][j] # netmap2=txt_mds.netmap() # #netmap2.get_net('f1',None,'d2o',nfc,vm2.comblist[0][j]) # netmap2.get_net('f1',None,'d2o',N_ctrl_fc,vm2.comblist[0][j]) # netmap2.get_net('c1',None,'d2o',N_ctrl_cc,vm2.comblist[1][j]) # netmap2.get_net('vd',None,vm2.comblist[2][j],vm2.comblist[2][j],1) # netmap2.get_net('tm',None,vm2.comblist[3][j],vm2.comblist[3][j],1) # netmap2.printline(line,w_file) # w_file.write('\n') else: netmap1.printline(line, w_file)
def gen_pll_pex_wrapper(switch, buf, PD, raw_pex_dir, design_name, netlist_dir, format_dir, input_array, vdd): if PD == 1: if buf == 1: if switch == 0: r_netlist = open( format_dir + "/ignore_form_wrapped_test_synth_pll_buf.sp", "r") elif switch == 1: r_netlist = open( format_dir + "/ignore_form_wrapped_test_synth_pll_buf_switch.sp", "r") else: r_netlist = open( format_dir + "/ignore_form_wrapped_test_synth_pll2.sp", "r") else: r_netlist = open(format_dir + "/ignore_form_wrapped_test_synth_pll.sp", "r") w_netlist = open(netlist_dir + "/" + "wrapped_" + design_name + ".sp", "w") lines = list(r_netlist.readlines()) netmap1 = txt_mds.netmap() ### register all the inputs to netmap ### netmap1.get_net('nd', netlist_dir, None, None, None) netmap1.get_net('dn', design_name, None, None, None) netmap1.get_net('fm', 'pex.netlist', None, None, None) for i in range(len(input_array)): bin_val = bin(input_array[i][4]) bin_len = len(bin_val) - 2 num_zero = input_array[i][0] - bin_len bin_fin = '0' * num_zero + bin_val[2:len(bin_val)] print("%s's bin_fin=%s" % (input_array[i][2], bin_fin)) print("%s's len(bin_fin)=%d, given length=%d" % (input_array[i][2], len(bin_fin), input_array[i][0])) netmap1.get_net(input_array[i][1], None, i * 100, i * 100 + len(bin_fin) - 1, 1) # v# netmap1.get_net(input_array[i][2], None, 0, len(bin_fin) - 1, 1) # bit# for j in range(len(bin_fin)): # print(int(bin_fin[len(bin_fin)-j-1])) netmap1.get_net(input_array[i][3], None, int(bin_fin[len(bin_fin) - j - 1]) * vdd, int(bin_fin[len(bin_fin) - j - 1]) * vdd, 1) #vdd or 0 r_raw_netlist = open(raw_pex_dir + "/" + design_name + ".pex.netlist", "r") w_raw_netlist = open(netlist_dir + "/" + design_name + ".pex.netlist", "w") raw_lines = list(r_raw_netlist.readlines()) nm2 = txt_mds.netmap() ### modify the .include file path in pex.netlist ### for line in raw_lines: if line[0:8] == '.include': line = '.include ' + '"./../../' + netlist_dir + line[10:len(line)] nm2.printline(line, w_raw_netlist) else: nm2.printline(line, w_raw_netlist) ### copies the first defined instant into inst_def for matching input sequence of pex.netlist### inst_def = [] inst_start = 0 for line in raw_lines: if inst_start == 1 and line[0:1] != '+': #instance def end inst_start = 0 elif line[0:7] == '.subckt': inst_start = 1 print('found subckt') inst_def.append(line) elif inst_start == 1 and line[0:1] == '+': inst_def.append(line) ### cut out '.SUBCKT test_synth_pll2' ### inst_def_words = inst_def[0].split() inst_def_words = inst_def_words[2:len(inst_def_words)] ### write down the 'wrapped_test_synth_pll2.sp' ### for line in lines: if line[0:3] == 'xi4': line = line + '+ ' + ' '.join(inst_def_words) + '\n' netmap1.printline(line, w_netlist) for inst_def_line in inst_def[1:len(inst_def)]: netmap1.printline(inst_def_line, w_netlist) netmap1.printline('+ ' + design_name, w_netlist) else: netmap1.printline(line, w_netlist)
def gen_netlist(netlist_dir, format_dir, ncell, ndrv, nfc, nstg_start, nstg_end, nstg_step, wellpin, designName): vm1 = txt_mds.varmap() vm1.get_var('ncell', ncell, ncell, 1) vm1.get_var('nstage', nstg_start, nstg_end, nstg_step) vm1.get_var('ndrv', ndrv, ndrv, 1) vm1.cal_nbigcy() vm1.combinate() for i in range(1, len(vm1.comblist[0])): if wellpin == 0: r_netlist = open(format_dir + "form_ring_osc.sp", "r") else: r_netlist = open(format_dir + "form_ring_osc_wellpin.sp", "r") lines = list(r_netlist.readlines()) nstg = vm1.comblist[1][i] #print ("ntlst nstg=%d"%(nstg)) npar = vm1.comblist[0][i] ndrv = vm1.comblist[2][i] netmap1 = txt_mds.netmap() ### enable voltages for CC,FC ### netmap1.get_net('vf', None, 0, nstg - 1, 1) netmap1.get_net('nf', None, 0, nstg - 1, 1) #netmap1.get_net('Vf','vf',None,0,nstg) netmap1.get_net('Vf', 'vf', 0, nstg - 1, 1) #for v2 netmap1.get_net('vc', None, 0, nstg - 1, 1) netmap1.get_net('nc', None, 0, nstg - 1, 1) #netmap1.get_net('Vc','vc',None,0,nstg) netmap1.get_net('Vc', 'vc', 0, nstg - 1, 1) #for v2 ###driver before last netmap1.get_net('id', None, 1, nstg - 1, 1) netmap1.get_net('Dn', 'n', 1, nstg - 1, 1) netmap1.get_net('Dp', 'p', 1, nstg - 1, 1) netmap1.get_net('dp', 'p', 2, nstg, 1) netmap1.get_net('dn', 'n', 2, nstg, 1) ###driver last netmap1.get_net('iD', None, nstg - 1, nstg - 1, 1) netmap1.get_net('DN', 'n', nstg, nstg, 1) netmap1.get_net('DP', 'p', nstg, nstg, 1) if nstg % 2 == 1: netmap1.get_net('dP', 'p', 1, 1, 1) netmap1.get_net('dN', 'n', 1, 1, 1) if nstg % 2 == 0: netmap1.get_net('dP', 'n', 1, 1, 1) netmap1.get_net('dN', 'p', 1, 1, 1) ###CC before last netmap1.get_net('ic', None, 1, nstg - 1, 1) netmap1.get_net('ni', None, 0, nstg - 2, 1) netmap1.get_net('In', 'n', 1, nstg - 1, 1) netmap1.get_net('Ip', 'p', 1, nstg - 1, 1) netmap1.get_net('Op', 'p', 2, nstg, 1) netmap1.get_net('On', 'n', 2, nstg, 1) ###CC last netmap1.get_net('IC', None, nstg - 1, nstg - 1, 1) netmap1.get_net('NI', None, nstg - 1, nstg - 1, 1) netmap1.get_net('IN', 'n', nstg, nstg, 1) netmap1.get_net('IP', 'p', nstg, nstg, 1) if nstg % 2 == 1: netmap1.get_net('OP', 'p', 1, 1, 1) netmap1.get_net('ON', 'n', 1, 1, 1) if nstg % 2 == 0: netmap1.get_net('OP', 'n', 1, 1, 1) netmap1.get_net('ON', 'p', 1, 1, 1) #-----------FC----------------- netmap1.get_net('if', None, 0, nstg - 1, 1) netmap1.get_net('fn', None, 0, nstg - 1, 1) netmap1.get_net('in', 'n', 1, nstg, 1) netmap1.get_net('ip', 'p', 1, nstg, 1) #-----------adding for parallel drv------ for ip in range(1, ndrv): netmap1.add_val('id', None, 1 + ip * nstg, (ip + 1) * nstg - 1, 1) netmap1.add_val('Dn', 'n', 1, nstg - 1, 1) netmap1.add_val('Dp', 'n', 1, nstg - 1, 1) netmap1.add_val('dp', 'n', 2, nstg, 1) netmap1.add_val('dn', 'n', 2, nstg, 1) netmap1.add_val('iD', None, (ip + 1) * nstg - 1, (ip + 1) * nstg - 1, 1) netmap1.add_val('DN', 'n', nstg, nstg, 1) netmap1.add_val('DP', 'p', nstg, nstg, 1) if nstg % 2 == 1: netmap1.add_val('dP', 'p', 1, 1, 1) netmap1.add_val('dN', 'n', 1, 1, 1) if nstg % 2 == 0: netmap1.add_val('dP', 'n', 1, 1, 1) netmap1.add_val('dN', 'p', 1, 1, 1) #-----------adding for parallel CC------ for ip in range(1, npar): #--------control voltages for CC---------- netmap1.add_val('vc', None, ip * nstg, (ip + 1) * nstg - 1, 1) netmap1.add_val('nc', None, ip * nstg, (ip + 1) * nstg - 1, 1) #netmap1.add_val('Vc','vc',None,ip,nstg) netmap1.add_val('Vc', 'vc', ip * nstg, (ip + 1) * nstg - 1, 1) #--------CC cells---------- netmap1.add_val('ic', None, 1 + ip * nstg, (ip + 1) * nstg - 1, 1) netmap1.add_val('ni', None, ip * nstg, (ip + 1) * nstg - 2, 1) netmap1.add_val('In', 'n', 1, nstg - 1, 1) netmap1.add_val('Ip', 'n', 1, nstg - 1, 1) netmap1.add_val('On', 'n', 2, nstg, 1) netmap1.add_val('Op', 'n', 2, nstg, 1) #--------CC last------------ netmap1.add_val('IC', None, (ip + 1) * nstg - 1, (ip + 1) * nstg - 1, 1) netmap1.add_val('NI', None, (ip + 1) * nstg - 1, (ip + 1) * nstg - 1, 1) netmap1.add_val('IN', 'n', nstg, nstg, 1) netmap1.add_val('IP', 'p', nstg, nstg, 1) if nstg % 2 == 1: netmap1.add_val('OP', 'p', 1, 1, 1) netmap1.add_val('ON', 'n', 1, 1, 1) if nstg % 2 == 0: netmap1.add_val('OP', 'n', 1, 1, 1) netmap1.add_val('ON', 'p', 1, 1, 1) #-----------add parallel FC------------- for ip in range(1, nfc): #----------control voltages for FC-------- netmap1.add_val('vf', None, ip * nstg, (ip + 1) * nstg - 1, 1) netmap1.add_val('nf', None, ip * nstg, (ip + 1) * nstg - 1, 1) #netmap1.add_val('Vf','vf',None,ip,nstg) netmap1.add_val('Vf', 'vf', ip * nstg, (ip + 1) * nstg - 1, 1) #for v2 #----------FC cells--------------- netmap1.add_val('if', None, ip * nstg, (ip + 1) * nstg - 1, 1) netmap1.add_val('fn', None, ip * nstg, (ip + 1) * nstg - 1, 1) netmap1.add_val('in', 'n', 1, nstg, 1) netmap1.add_val('ip', 'p', 1, nstg, 1) with open(netlist_dir + designName + ".sp", "w") as w_netlist: for line in lines: netmap1.printline(line, w_netlist)
def pdpll_flow(formatDir,flowDir,dco_flowDir,outbuff_div_flowDir,pll_name,dcoName,bleach,ndrv,ncc,nfc,nstg,W_CC,H_CC,W_FC,H_FC,synth,apr,verilogSrcDir,outbuff_div,tdc_dff,buf_small,buf_big,platform,max_r_l,min_p_rng_l,min_p_str_l,p_rng_w,p_rng_s,p2_rng_w,p2_rng_s,H_stdc): print ('#======================================================================') print ('# setting up flow directory for pdpll') print ('#======================================================================') #------------------------------------------- # flow setup #------------------------------------------- #--- copy scripts --- shutil.copyfile(formatDir+'pdpll_dc.include.tcl',flowDir+'/scripts/dc/dc.include.tcl') shutil.copyfile(formatDir+'pdpll_dc.read_design.tcl',flowDir+'/scripts/dc/dc.read_design.tcl') shutil.copyfile(formatDir+'pdpll_dc_setup.tcl',flowDir+'/scripts/dc/dc_setup.tcl') shutil.copyfile(formatDir+'pdpll_report_timing.tcl',flowDir+'/scripts/dc/report_timing.tcl') shutil.copyfile(formatDir+'dco_floorplan.tcl',flowDir+'/scripts/innovus/floorplan.tcl') shutil.copyfile(formatDir+platform+'_pdpll_power_intent.cpf',flowDir+'/scripts/innovus/power_intent.cpf') # shutil.copyfile(formatDir+'pdpll_pre_init.tcl',flowDir+'/scripts/innovus/pre_init.tcl') shutil.copyfile(formatDir+'pdpll_post_init.tcl',flowDir+'/scripts/innovus/post_init.tcl') shutil.copyfile(formatDir+'pdpll_pre_place.tcl',flowDir+'/scripts/innovus/pre_place.tcl') shutil.copyfile(formatDir+'pdpll_pre_route.tcl',flowDir+'/scripts/innovus/pre_route.tcl') shutil.copyfile(formatDir+'pdpll_post_postroute.tcl',flowDir+'/scripts/innovus/post_postroute.tcl') shutil.copyfile(formatDir+'pre_signoff.tcl',flowDir+'/scripts/innovus/pre_signoff.tcl') shutil.copyfile(formatDir+'pdpll_post_signoff.tcl',flowDir+'/scripts/innovus/post_signoff.tcl') shutil.copyfile(formatDir+'cadre_Makefile',flowDir+'/Makefile') #--- copy exports from dco --- spfiles=glob.iglob(os.path.join(dco_flowDir+'results/calibre/lvs/','*.sp')) for spfile in spfiles: if os.path.isfile(spfile): shutil.copy2(spfile,dco_flowDir+'export/'+dcoName+'.cdl') else: print('Error: cant find the '+dcoName+'.sp file in'+dco_flowDir+'results/calibre/lvs/') sys.exit(1) if os.path.isdir(flowDir+'blocks/'+dcoName+'')==0: p = sp.Popen(['mkdir','blocks/'+dcoName+''], cwd=flowDir) p.wait() dco_ex_list=['.cdl','.lef','.gds','_typ.lib'] if os.path.isdir(flowDir+'blocks/'+dcoName+'/export')==0: shutil.copytree(dco_flowDir+'export',flowDir+'blocks/'+dcoName+'/export') #--- copy exports from outbuff_div --- if outbuff_div==1: spfiles=glob.iglob(os.path.join(outbuff_div_flowDir+'results/calibre/lvs/','*.sp')) for spfile in spfiles: if os.path.isfile(spfile): shutil.copy2(spfile,outbuff_div_flowDir+'export/outbuff_div.cdl') else: print('Error: cant find the outbuff_div.sp file in '+outbuff_div_flowDir+'results/calibre/lvs/') sys.exit(1) if os.path.isdir(flowDir+'blocks/outbuff_div')==0: p = sp.Popen(['mkdir','blocks/outbuff_div'], cwd=flowDir) p.wait() if os.path.isdir(flowDir+'blocks/outbuff_div/export')==0: shutil.copytree(outbuff_div_flowDir+'export',flowDir+'blocks/outbuff_div/export') #--- generate include.mk file --- rmkfile=open(formatDir+'/form_include.mk','r') nm1=txt_mds.netmap() nm1.get_net('iN',pll_name,None,None,None) nm1.get_net('pf',platform,None,None,None) with open(flowDir+'include.mk','w') as wmkfile: lines_const=list(rmkfile.readlines()) for line in lines_const: nm1.printline(line,wmkfile) #--- bleach --- if bleach==1: p = sp.Popen(['make','bleach_all'], cwd=flowDir) p.wait() #--- generate verilog file --- rvfile=open(formatDir+'/form_pdpll.v','r') nm1=txt_mds.netmap() if outbuff_div==1: nm1.get_net('IO','INCLUDE_OUTBUFF_DIV',None,None,None) else: nm1.get_net('IO','EXCLUDE_OUTBUFF_DIV',None,None,None) nm1.get_net('iN',pll_name,None,None,None) nm1.get_net('nM',None,nstg,nstg,1) nm1.get_net('nD',None,ndrv,ndrv,1) nm1.get_net('nF',None,nfc,nfc,1) nm1.get_net('nC',None,ncc,ncc,1) nm1.get_net('dN',dcoName+'',None,None,None) for bcnt in range (1,7): nm1.get_net('b%d'%(bcnt),buf_small,None,None,None) nm1.get_net('B1',buf_big,None,None,None) nm1.get_net('df',tdc_dff,None,None,None) with open(flowDir+'src/'+pll_name+'.v','w') as wvfile: lines_const=list(rvfile.readlines()) for line in lines_const: nm1.printline(line,wvfile) #--- generate dc.filelist.tcl rflfile=open(formatDir+'/form_pdpll_dc.filelist.tcl','r') nm1=txt_mds.netmap() nm1.get_net('iN',pll_name+'.v',None,None,None) with open(flowDir+'/scripts/dc/dc.filelist.tcl','w') as wflfile: lines_const=list(rflfile.readlines()) for line in lines_const: nm1.printline(line,wflfile) #--- generate constraints.tcl rcfile=open(formatDir+'/form_pdpll_constraints.tcl','r') nm1=txt_mds.netmap() nm1.get_net('NS',None,2*nstg-1,2*nstg-1,1) nm1.get_net('nS',None,2*nstg-1,2*nstg-1,1) with open(flowDir+'/scripts/dc/constraints.tcl','w') as wcfile: lines_const=list(rcfile.readlines()) for line in lines_const: nm1.printline(line,wcfile) #--- get dco size --- dco_lef=open(flowDir+'/blocks/'+dcoName+'/export/'+dcoName+'.lef','r') lines_dco=list(dco_lef.readlines()) indco=0 for line in lines_dco: words=line.split() for word in words: if word==dcoName+'': indco=1 if indco==1 and word=='SIZE': sizes=line.split() W_dco=float(sizes[1]) H_dco=float(sizes[3]) if outbuff_div==1: #--- get outbuff_div size --- bufdiv_lef=open(flowDir+'/blocks/outbuff_div/export/outbuff_div.lef','r') lines_buf=list(bufdiv_lef.readlines()) inbuf=0 for line in lines_buf: words=line.split() for word in words: if word=='outbuff_div': inbuf=1 if inbuf==1 and word=='SIZE': sizes=line.split() W_buf=float(sizes[1]) H_buf=float(sizes[3]) elif outbuff_div==0: W_buf=0 H_buf=0 #--- run synth --- print ('#======================================================================') print('# ready for synth & apr') print ('#======================================================================') if synth==1: #------------------------------------------- # run CADRE flow #------------------------------------------- p = sp.Popen(['make','synth'], cwd=flowDir) p.wait() with open(flowDir + '/reports/dc/' + pll_name + '.mapped.area.rpt', \ 'r')as file: filedata = file.read() m = re.search('Total cell area: *([0-9.]*)', filedata) if m: A_cont = float(m.group(1)) print('estimated area after synthesis is: %e'%(A_cont)) else: print ('Synthesis Failed') #--- calculate area of the PDpll --- A_dco=W_dco*H_dco A_buf=W_buf*H_buf W_cont=int(math.ceil(math.sqrt(A_cont*1.4/5))*5) H_cont=W_cont W_pll=int(max(W_dco,W_buf)+W_cont/2) H_pll=int(H_dco+H_buf+H_cont/2) #--- generate setup.tcl rsufile=open(formatDir+'/form_setup.tcl','r') nm1=txt_mds.netmap() nm1.get_net('mr',None,max_r_l,max_r_l,1) with open(flowDir+'scripts/innovus/setup.tcl','w') as wsufile: lines_const=list(rsufile.readlines()) for line in lines_const: nm1.printline(line,wsufile) #--- generate always_source.tcl --- ralfile=open(formatDir+'/form_pdpll_always_source.tcl','r') nm1=txt_mds.netmap() nm1.get_net('ob',None,outbuff_div,outbuff_div,1) nm1.get_net('mr',None,max_r_l,max_r_l,1) nm1.get_net('rl',None,min_p_rng_l,min_p_rng_l,1) nm1.get_net('sl',None,min_p_str_l,min_p_str_l,1) nm1.get_net('rw',None,p_rng_w,p_rng_w,1) nm1.get_net('rs',None,p_rng_s,p_rng_s,1) nm1.get_net('2w',None,p2_rng_w,p2_rng_w,1) nm1.get_net('2s',None,p2_rng_s,p2_rng_s,1) nm1.get_net('CW',None,W_pll,W_pll,1) nm1.get_net('CH',None,H_pll,H_pll,1) nm1.get_net('sH',None,H_stdc,H_stdc,1) nm1.get_net('bW',None,W_buf,W_buf,1) nm1.get_net('bH',None,H_buf,H_buf,1) nm1.get_net('dW',None,W_dco,W_dco,1) nm1.get_net('dH',None,H_dco,H_dco,1) with open(flowDir+'scripts/innovus/always_source.tcl','w') as walfile: lines_const=list(ralfile.readlines()) for line in lines_const: nm1.printline(line,walfile) #--- run apr flow --- print ('#======================================================================') print('# ready for apr') print ('#======================================================================') if apr==1: p = sp.Popen(['make','design'], cwd=flowDir) p.wait() p = sp.Popen(['make','lvs'], cwd=flowDir) p.wait() p = sp.Popen(['make','drc'], cwd=flowDir) p.wait() p = sp.Popen(['make','export'], cwd=flowDir) p.wait() return W_dco, H_dco, W_pll, H_pll
def gen_dco_pex_wrapper(extDir, netlistDir, format_dir, ncc, ndrv, nfc, nstg, ninterp, designName, fc_en_type): r_netlist = open(format_dir + "/form_pex_dco.sp", "r") w_netlist = open(netlistDir + "/" + "wrapped_" + designName + ".sp", "w") lines = list(r_netlist.readlines()) netmap1 = txt_mds.netmap() ### include pex.netlist ### netmap1.get_net('dn', designName, None, None, None) ### edge_sel voltage pulses ### netmap1.get_net('ve', None, 1, nstg * 4 - 1, 1) netmap1.get_net('ES', None, 1, nstg * 4 - 1, 1) # for edge sel ### enable voltages for CC,FC ### netmap1.get_net('vf', None, 0, nfc * nstg - 1, 1) netmap1.get_net('nf', None, 0, nfc * nstg - 1, 1) netmap1.get_net('Vf', 'vf', 0, nfc * nstg - 1, 1) #for v2 netmap1.get_net('vc', None, 0, ncc * nstg - 1, 1) netmap1.get_net('nc', None, 0, ncc * nstg - 1, 1) netmap1.get_net('Vc', 'vc', 0, ncc * nstg - 1, 1) #for v2 r_raw_netlist = open(extDir + "run/" + designName + ".pex.netlist", "r") w_raw_netlist = open(netlistDir + "/" + designName + ".pex.netlist", "w") raw_lines = list(r_raw_netlist.readlines()) nm2 = txt_mds.netmap() ### modify the .include file path in pex.netlist ### for line in raw_lines: if line[0:8] == '.include': line = '.include ' + '"' + netlistDir + line[10:len( line)] #--- absolute path --- nm2.printline(line, w_raw_netlist) else: nm2.printline(line, w_raw_netlist) ### copies the first defined instant into inst_def for matching input sequence of pex.netlist### inst_def = [] inst_start = 0 for line in raw_lines: if inst_start == 1 and line[0:1] != '+': #instance def end inst_start = 0 elif line[0:7] == '.SUBCKT' or line[0:7] == '.subckt': inst_start = 1 print('found subckt') inst_def.append(line) elif inst_start == 1 and line[0:1] == '+': inst_def.append(line) ### cut out '.SUBCKT test_synth_pll2' ### inst_def_words = inst_def[0].split() inst_def_words = inst_def_words[2:len(inst_def_words)] ### write down the 'wrapped_test_synth_pll2.sp' ### for line in lines: if line[0:3] == 'xi4': line = line + '+ ' + ' '.join(inst_def_words) + '\n' netmap1.printline(line, w_netlist) for inst_def_line in inst_def[1:len(inst_def)]: netmap1.printline(inst_def_line, w_netlist) netmap1.printline('+ ' + designName, w_netlist) else: netmap1.printline(line, w_netlist) #------------------------------------------- # copy .pxi, .pex #------------------------------------------- try: shutil.copyfile(extDir + '/run/' + designName + '.pex.netlist.pxi', netlistDir + '/' + designName + '.pex.netlist.pxi') #p = sp.Popen(['cp',extDir+'/run/'+designName+'.pex.netlist.pxi',netlistDir+'/'+designName+'.pex.netlist.pxi']) #p.wait() except: shutil.copyfile( extDir + '/run/' + designName + '.pex.netlist.' + designName + '.pxi', netlistDir + '/' + designName + '.pex.netlist.' + designName + '.pxi') #p = sp.Popen(['cp',extDir+'/run/'+designName+'.pex.netlist.'+designName+'.pxi',netlistDir+'/'+designName+'.pex.netlist.'+designName+'.pxi']) #p.wait() shutil.copyfile(extDir + '/run/' + designName + '.pex.netlist.pex', netlistDir + '/' + designName + '.pex.netlist.pex')
def dco_flow(formatDir,flowDir,dcoName,bleach,ndrv,ncc,nfc,nstg,W_CC,H_CC,W_FC,H_FC,synth,apr,verilogSrcDir,platform,edge_sel,buf_small,buf_big,bufz,min_p_rng_l,min_p_str_l,p_rng_w,p_rng_s,p2_rng_w,p2_rng_s,max_r_l): print ('#======================================================================') print('# setting up flow directory for dco') print ('#======================================================================') #------------------------------------------- # flow setup #------------------------------------------- #--- copy verilog files to flowDir/src/ --- shutil.copyfile(verilogSrcDir+'dco_CC.v',flowDir+'/src/dco_CC.v') shutil.copyfile(verilogSrcDir+'dco_FC.v',flowDir+'/src/dco_FC.v') shutil.copyfile(verilogSrcDir+'synth_pll_dco_interp_'+platform+'.v',flowDir+'/src/synth_pll_dco_interp.v') shutil.copyfile(verilogSrcDir+'synth_pll_dco_outbuff_'+platform+'.v',flowDir+'/src/synth_pll_dco_outbuff.v') shutil.copyfile(verilogSrcDir+'FUNCTIONS.v',flowDir+'/src/FUNCTIONS.v') #--- copy scripts files to flowDir/scripts/ --- shutil.copyfile(formatDir+'dco_dc.include.tcl',flowDir+'/scripts/dc/dc.include.tcl') shutil.copyfile(formatDir+'dco_dc.read_design.tcl',flowDir+'/scripts/dc/dc.read_design.tcl') shutil.copyfile(formatDir+'dco_dc_setup.tcl',flowDir+'/scripts/dc/dc_setup.tcl') shutil.copyfile(formatDir+'dco_report_timing.tcl',flowDir+'/scripts/dc/report_timing.tcl') shutil.copyfile(formatDir+'dco_floorplan.tcl',flowDir+'/scripts/innovus/floorplan.tcl') shutil.copyfile(formatDir+'dco_power_intent.cpf',flowDir+'/scripts/innovus/power_intent.cpf') shutil.copyfile(formatDir+platform+'_dco_post_init.tcl',flowDir+'/scripts/innovus/post_init.tcl') shutil.copyfile(formatDir+'dco_pre_route.tcl',flowDir+'/scripts/innovus/pre_route.tcl') shutil.copyfile(formatDir+'dco_post_postroute.tcl',flowDir+'/scripts/innovus/post_postroute.tcl') shutil.copyfile(formatDir+'dco_post_signoff.tcl',flowDir+'/scripts/innovus/post_signoff.tcl') shutil.copyfile(formatDir+'pre_signoff.tcl',flowDir+'/scripts/innovus/pre_signoff.tcl') shutil.copyfile(formatDir+'cadre_Makefile',flowDir+'/Makefile') #--- generate include.mk file --- rmkfile=open(formatDir+'/form_include.mk','r') nm1=txt_mds.netmap() nm1.get_net('iN',dcoName,None,None,None) nm1.get_net('pf',platform,None,None,None) with open(flowDir+'include.mk','w') as wmkfile: lines_const=list(rmkfile.readlines()) for line in lines_const: nm1.printline(line,wmkfile) #--- bleach --- if bleach==1: p = sp.Popen(['make','bleach_all'], cwd=flowDir) p.wait() #--- generate verilog file --- rvfile=open(formatDir+'/form_dco.v','r') nm1=txt_mds.netmap() if edge_sel==1: nm1.get_net('IE','INCLUDE_EDGE_SEL',None,None,None) else: nm1.get_net('IE','EXCLUDE_EDGE_SEL',None,None,None) nm1.get_net('iN',dcoName,None,None,None) nm1.get_net('nM',None,nstg,nstg,1) nm1.get_net('nD',None,ndrv,ndrv,1) nm1.get_net('nF',None,nfc,nfc,1) nm1.get_net('nC',None,ncc,ncc,1) for bcnt in range (1,10): nm1.get_net('b%d'%(bcnt),buf_small,None,None,None) for zcnt in range (1,5): nm1.get_net('z%d'%(zcnt),bufz,None,None,None) nm1.get_net('B1',buf_big,None,None,None) with open(flowDir+'src/'+dcoName+'.v','w') as wvfile: lines_const=list(rvfile.readlines()) for line in lines_const: nm1.printline(line,wvfile) #--- generate dc.filelist.tcl rflfile=open(formatDir+'/form_dco_dc.filelist.tcl','r') nm1=txt_mds.netmap() nm1.get_net('iN',dcoName+'.v',None,None,None) with open(flowDir+'scripts/dc/dc.filelist.tcl','w') as wflfile: lines_const=list(rflfile.readlines()) for line in lines_const: nm1.printline(line,wflfile) #--- generate constraints.tcl rflfile=open(formatDir+'/form_dco_constraints.tcl','r') nm1=txt_mds.netmap() nm1.get_net('es',None,edge_sel,edge_sel,1) with open(flowDir+'scripts/dc/constraints.tcl','w') as wflfile: lines_const=list(rflfile.readlines()) for line in lines_const: nm1.printline(line,wflfile) #--- calculate area --- NCtotal=nstg*(ncc+ndrv) NFtotal=nstg*(nfc) A_dco=NCtotal*W_CC*H_CC+NFtotal*W_FC*H_FC W_dco=math.ceil(math.sqrt(A_dco)*3.0/5)*5 H_dco=math.ceil(math.sqrt(A_dco)*3.0/5)*5 #--- generate setup.tcl rsufile=open(formatDir+'/form_setup.tcl','r') nm1=txt_mds.netmap() nm1.get_net('mr',None,max_r_l,max_r_l,1) with open(flowDir+'scripts/innovus/setup.tcl','w') as wsufile: lines_const=list(rsufile.readlines()) for line in lines_const: nm1.printline(line,wsufile) #--- generate always_source.tcl ralfile=open(formatDir+'/form_dco_always_source.tcl','r') nm1=txt_mds.netmap() nm1.get_net('es',None,edge_sel,edge_sel,1) nm1.get_net('rl',None,min_p_rng_l,min_p_rng_l,1) nm1.get_net('sl',None,min_p_str_l,min_p_str_l,1) nm1.get_net('rw',None,p_rng_w,p_rng_w,1) nm1.get_net('rs',None,p_rng_s,p_rng_s,1) nm1.get_net('2w',None,p2_rng_w,p2_rng_w,1) nm1.get_net('2s',None,p2_rng_s,p2_rng_s,1) nm1.get_net('CW',None,W_dco,W_dco,1) nm1.get_net('CH',None,H_dco,H_dco,1) with open(flowDir+'scripts/innovus/always_source.tcl','w') as walfile: lines_const=list(ralfile.readlines()) for line in lines_const: nm1.printline(line,walfile) #--- generate pre_place.tcl with editPin_gen --- version=2 wfile_name=flowDir+'scripts/innovus/pre_place.tcl' editPin_gen(ndrv,ncc,nfc,nstg,formatDir,wfile_name) print ('#======================================================================') print('# ready for synth & apr') print ('#======================================================================') if synth==1: #------------------------------------------- # run CADRE flow #------------------------------------------- p = sp.Popen(['make','synth'], cwd=flowDir) p.wait() # read total estimated area of controller (it doesn't include the aux-cells) with open(flowDir + '/reports/dc/' + dcoName + '.mapped.area.rpt', \ 'r')as file: filedata = file.read() m = re.search('Total cell area: *([0-9.]*)', filedata) if m: coreCellArea = float(m.group(1)) print('estimated area after synthesis is: %e'%(coreCellArea)) else: print ('Synthesis Failed') if apr==1: p = sp.Popen(['make','design'], cwd=flowDir) p.wait() p = sp.Popen(['make','lvs'], cwd=flowDir) p.wait() p = sp.Popen(['make','drc'], cwd=flowDir) p.wait() p = sp.Popen(['make','export'], cwd=flowDir) p.wait() p = sp.Popen(['cp',dcoName+'_cutObs.lef','export/'+dcoName+'.lef'], cwd=flowDir) p.wait() return W_dco, H_dco
def gen_tb_wrapped(hspiceModel, tb_dir, format_dir, ncell, ndrv, nfc, nstg, vdd, temp, fc_en_type, sim_time, corner_lib, designName, netlistDir): #===================================================== # model constants for trans simulation time calculation #===================================================== if len(vdd) > 1 and len(temp) > 1: vdd_min, vdd_max = txt_mds.mM(vdd) #generate function of minMax step vdd.remove(vdd_min) temp_min, temp_max = txt_mds.mM(temp) temp.remove(temp_min) elif len(vdd) == 1 and len(temp) == 1: vdd_min = vdd[0] vdd_max = vdd[0] temp_min = temp[0] temp_max = temp[0] r_file = open(format_dir + "form_tb_ring_osc.sp", "r") lines = list(r_file.readlines()) #=============================================== # writing #=============================================== L_lines = [] L_flag = 0 netmap1 = txt_mds.netmap() #35 netmap1.get_net('Ti', None, sim_time, sim_time, 1) netmap1.get_net('TE', None, sim_time, sim_time, 1) netmap1.get_net('vd', None, vdd[0], vdd[0], 1) netmap1.get_net('ND', netlistDir, None, None, 1) netmap1.get_net('dn', 'wrapped_' + designName, None, None, 1) #----- only string ----------- netmap1.get_net('hm', hspiceModel, None, None, None) netmap1.get_net('cr', corner_lib, None, None, None) #=============================================== # number of control node definition for v2 #=============================================== N_ctrl_fc = nstg * nfc N_ctrl_cc = nstg * ncell #=============================================== # generate variable maps: FCWs to sweep # (CC,FC)=(0,0),(0,Nfc),(1,0),(Ncc//2,0) # (Ncc//2,Nfc//2),(Ncc//2,Nfc) # (Ncc,Nfc) #=============================================== vm2 = txt_mds.varmap() vm2.get_var( 'vdd', vdd[0], vdd[0], 1) #vm2.comblist[0]=vdd #???? why like this? because of get_var if len(vdd) > 1: for i in range(1, len(vdd)): vm2.add_val('vdd', vdd[i], vdd[i], 1) vm2.get_var('temp', temp[0], temp[0], 1) #vm2.comblist[1]=temp if len(temp) > 1: for i in range(1, len(temp)): vm2.add_val('temp', temp[i], temp[i], 1) vm2.cal_nbigcy() vm2.combinate() #vdd/temp combination var_list = [[[] for x in range(7)] for y in range(len(vm2.comblist[0]) - 1)] if fc_en_type == 1: for i in range(1, len(vm2.comblist[0])): var_list[i - 1][0] = [0, 0, vm2.comblist[0][i], vm2.comblist[1][i]] var_list[i - 1][1] = [ 0, N_ctrl_fc, vm2.comblist[0][i], vm2.comblist[1][i] ] var_list[i - 1][2] = [1, 0, vm2.comblist[0][i], vm2.comblist[1][i]] var_list[i - 1][3] = [ N_ctrl_cc // 2, 0, vm2.comblist[0][i], vm2.comblist[1][i] ] var_list[i - 1][4] = [ N_ctrl_cc // 2, N_ctrl_fc // 2, vm2.comblist[0][i], vm2.comblist[1][i] ] var_list[i - 1][5] = [ N_ctrl_cc // 2, N_ctrl_fc, vm2.comblist[0][i], vm2.comblist[1][i] ] var_list[i - 1][6] = [ N_ctrl_cc, N_ctrl_fc, vm2.comblist[0][i], vm2.comblist[1][i] ] else: for i in range(1, len(vm2.comblist[0])): var_list[i - 1][0] = [ 0, N_ctrl_fc, vm2.comblist[0][i], vm2.comblist[1][i] ] var_list[i - 1][1] = [0, 0, vm2.comblist[0][i], vm2.comblist[1][i]] var_list[i - 1][2] = [ 1, N_ctrl_fc, vm2.comblist[0][i], vm2.comblist[1][i] ] var_list[i - 1][3] = [ N_ctrl_cc // 2, N_ctrl_fc, vm2.comblist[0][i], vm2.comblist[1][i] ] var_list[i - 1][4] = [ N_ctrl_cc // 2, N_ctrl_fc // 2, vm2.comblist[0][i], vm2.comblist[1][i] ] var_list[i - 1][5] = [ N_ctrl_cc // 2, 0, vm2.comblist[0][i], vm2.comblist[1][i] ] var_list[i - 1][6] = [ N_ctrl_cc, 0, vm2.comblist[0][i], vm2.comblist[1][i] ] #=================================================================== # DATA table gen for parametric sweep #=================================================================== #----- lateral stuffs: names -------- netmap1.get_net('vf', 'vf', 0, N_ctrl_fc - 1, 1) #for v2 netmap1.get_net('vc', 'vc', 0, N_ctrl_cc - 1, 1) #for v2 #----- lateral stuffs: FCW values -------- #with open(tb_dir+"tb_%dring%d_osc%d_FC%d.sp"%(ndrv,ncell,nstg,nfc),"w") as w_file: with open(tb_dir + "tb_" + designName + ".sp", "w") as w_file: for line in lines: if line[0:4] == '@L@W': line = line[2:len(line) - 1] for ivt in range(len(var_list)): for ifcw in range(len(var_list[0])): netmap2 = txt_mds.netmap() netmap2.get_net('f1', None, 'd2o', N_ctrl_fc, var_list[ivt][ifcw][1]) netmap2.get_net('c1', None, 'd2o', N_ctrl_cc, var_list[ivt][ifcw][0]) netmap2.get_net('vd', None, var_list[ivt][ifcw][2], var_list[ivt][ifcw][2], 1) netmap2.get_net('tm', None, var_list[ivt][ifcw][3], var_list[ivt][ifcw][3], 1) netmap2.printline(line, w_file) w_file.write('\n') else: netmap1.printline(line, w_file)