StarRC AutoScript

#! /opt/xfce-4.4.2/bin/python
 
import os
import re
import sys
import optparse
 
run_cmd_patt = """#! /bin/csh -f
# Notes:
#  1) customize LSF queue 'userEnterQ' and memory resource 'X000'
#  2) if NUM_PARTS is changed in the xtcmd file then also adjust
#      a: number of slave processes launched to NUM_PARTS-1
#      b: the RHS of '$c==<val>' to NUM_PARTS-1
 
bsub -J %s_xtgdh -q priority -R "rusage[mem=10000]"  "StarXtract -clean %s"
 
# Wait for master process to begin before launching slaves
# sleep 60
# bsub -J xcw125gdh -q int -R "select[osname=='redhat'&&oslevel=='4'] && rusage[mem=4000]"  "StarXtract -clean ramplus_top_cworst_125.xtcmd"
# bsub -J xcw125gdh -q int -R "select[osname=='redhat'&&oslevel=='4'] && rusage[mem=4000]"  "StarXtract -clean ramplus_top_cworst_125.xtcmd"
# bsub -J xcw125gdh -q int -R "select[osname=='redhat'&&oslevel=='4'] && rusage[mem=4000]"  "StarXtract -clean ramplus_top_cworst_125.xtcmd"
"""
 
cfg_template = """
[global]
* Star-RCXT Command File 
* Used to extract parasitics from ICC/Milkyway database and write a parastic netlist file.
* Generated by utility lsiStar.rca (rev 1.13, dated Mon Apr 19 19:07:32 2010 $)
* Command file generated on Tue May 25 17:39:42 CST 2010
 
* MILKYWAY_DATABASE: %s
* BLOCK: %s
* TCAD_GRD_FILE: %s
* MAPPING_FILE:  %s
SKIP_CELLS: *
* OPERATING_TEMPERATURE: %s
NETLIST_FORMAT: SPEF
NETLIST_COMPRESS_COMMAND: gzip
* NETLIST_FILE:  %s
COUPLE_TO_GROUND: NO
EXTRACT_VIA_CAPS: YES
NETLIST_TYPE: RCc *
COUPLING_ABS_THRESHOLD: 3e-15
COUPLING_REL_THRESHOLD: 0.03
NETLIST_NAME_MAP: YES
NETLIST_CAPACITANCE_UNIT: 1e-15
EXTRACTION: RC
NETLIST_REMOVE_LOOPS: NO
PROCESS_CORNER: MAX
REDUCTION_MAX_DELAY_ERROR: 5.0e-13
METAL_FILL_POLYGON_HANDLING: FLOATING
MILKYWAY_ADDITIONAL_VIEWS: FILL
METAL_FILL_GDS_FILE: 
* GDS_LAYER_MAP_FILE: %s
NUM_PARTS: 1
NETLIST_INPUT_DRIVERS: YES
REDUCTION: NO_EXTRA_LOOPS
NETLIST_CONNECT_OPENS: *
POWER_EXTRACT: NO
STAR_DIRECTORY: ramplus_top_cworst_125
MODE: 400
SHORT_PINS: YES
INTRANET_CAPS: NO
DENSITY_BASED_THICKNESS: YES
 
MILKYWAY_DATABASE:   /home/IPRAMPLUS_F/users/dongu/release/ramplus_top
BLOCK:   ramplus_top
MAPPING_FILE:  /tools/fip40.3-preqa/lsi40nm_3.0/tsmc_cln40g/shared/synopsys/star/lsi40_6+2.starxt_map
GDS_LAYER_MAP_FILE:  /tools/fip40.3-preqa/lsi40nm_3.0/tsmc_cln40g/shared/synopsys/star/lsi40_6+2.fillgds_map
 
[wc]
TCAD_GRD_FILE: /tools/fip40.3-preqa/lsi40nm_3.0/tsmc_cln40g/shared/synopsys/star/lsi40_6+2_cworst.nxtgrd
OPERATING_TEMPERATURE: 125
NETLIST_FILE:  /home/IPRAMPLUS_F/users/dongu/release/post_layout/ramplus_top_cworst_125.spef.gz
 
[wclt]
TCAD_GRD_FILE: /tools/fip40.3-preqa/lsi40nm_3.0/tsmc_cln40g/shared/synopsys/star/lsi40_6+2_cworst.nxtgrd
OPERATING_TEMPERATURE: -40
NETLIST_FILE:  /home/IPRAMPLUS_F/users/dongu/release/post_layout/ramplus_top_cworst_m40.spef.gz
 
[bc]
TCAD_GRD_FILE: /tools/fip40.3-preqa/lsi40nm_3.0/tsmc_cln40g/shared/synopsys/star/lsi40_6+2_cbest.nxtgrd
OPERATING_TEMPERATURE: -40
NETLIST_FILE:   /home/IPRAMPLUS_F/users/dongu/release/post_layout/ramplus_top_cbest_m40.spef.gz
 
[bcht]
TCAD_GRD_FILE: /tools/fip40.3-preqa/lsi40nm_3.0/tsmc_cln40g/shared/synopsys/star/lsi40_6+2_cbest.nxtgrd
OPERATING_TEMPERATURE: 125
NETLIST_FILE:   /home/IPRAMPLUS_F/users/dongu/release/post_layout/ramplus_top_cbest_125.spef.gz
"""
 
def gen_template():
  template_file = "autoxtract.cfg.template"
  if os.path.exists(template_file):
    print "configure template file exists: %s\nPlease check the file!" % template_file
  else:
    open(template_file, 'w').write(cfg_template)
    print "configure template file generated: %s\nPlese modify it based on your design" % template_file
  print
 
 
def read_cfg(cfg_file):
  xtcmd_dic = {}
  if not os.path.exists( cfg_file):
    print "cfg file not exists: %s" % cfg_file
    return
  lines = open(cfg_file).readlines()
  group = ""
  for line in lines:
    line = line.strip()
    if not line: continue
    patt = """\[(.*)\]"""
    section =  re.findall(patt, line)
    if section:
      group = "".join(section)
      group = group.strip()
      if not group in xtcmd_dic.keys():
        xtcmd_dic[group] = ""
    else:
      xtcmd_dic[group] += line + '\n'
 
  return xtcmd_dic
 
 
def save_xtcmd_file(xtcmd_dic, num_cpu=1):
  run_all_cmd = "#! /bin/csh -f\n"
 
  for corner, value in xtcmd_dic.items():
    if corner == 'global': continue
    print "Corner: %s" % corner
 
    # xt cmd 
    if not os.path.exists(corner): os.makedirs(corner)
    xtcmd = ""
    xtcmd += "\n\n" + "*"*30 + " global setting " + "*"*30 + "\n\n"
    xtcmd += xtcmd_dic['global']
    xtcmd += "\n\n" + "*"*30 + " setting for %s " % corner + "*"*30 + "\n\n"
    xtcmd += value
    xtcmd += "\n\n" + "*"*30 + " setting for parts " + "*"*30 + "\n\n"
    xtcmd += "NUM_PARTS: %d\n" % num_cpu
 
    xtcmd_file_name = "star_rc.xtcmd"
    open( os.path.join(corner,xtcmd_file_name), 'w').write(xtcmd)
    print "Save xtcmd file %s" % os.path.join(corner,xtcmd_file_name)
 
    # run file 
    queue = 'priority'
    run_cmd_patt = """bsub -P autoxt -J atxt_%s -q %s -R "select[osname=='redhat'&&oslevel=='4'] && rusage[mem=10000]"  "StarXtract -clean %s  %s "\n"""
    run_cmd = "#! /bin/csh -f\n"
    for i in range(0, num_cpu):
      tee_cmd = " | tee run-%d-%d.log; touch starrc-%d-%d.done" % (i+1, num_cpu, i+1, num_cpu)
      run_cmd += run_cmd_patt % ( corner, queue, xtcmd_file_name, tee_cmd)
      if i == 0 and num_cpu > 1 : run_cmd += "\n# Wait for master process to begin before launching slaves \nsleep 60\n"
      #else: run_cmd += "\nsleep 5\n"
      run_cmd += "\n"
    run_file = "run.csh"
    runcmd_file_name =  os.path.join(corner, run_file)
    open(runcmd_file_name, 'w').write(run_cmd)
    os.system("chmod +x %s" % runcmd_file_name)
    print "Save run cmd file %s" % runcmd_file_name
 
    # kick off script
    corner_dir = os.path.join(os.getcwd(), corner)
    run_all_cmd += "cd %s\n" % corner_dir
    run_all_cmd += "./%s \n\n" % run_file
    print 
 
 
  #kick off file
  run_all_cmd += "cd %s" % os.getcwd()
  kick_off_file = "sub_jobs.csh"
  open(kick_off_file, 'w').write(run_all_cmd)
  os.system("chmod +x %s" % kick_off_file)
  print "Kick off file saved: %s" % kick_off_file
  print
 
if __name__ == "__main__":
  #
  parser = optparse.OptionParser()
  parser.add_option("-n", "--num_cpu", dest="num_cpu", type="int",
                    help="cpu number to run extraction, default 1", metavar="NUM_CPU")
 
  parser.add_option("-f", "--file", dest="cfg_file",
                    help="star rc configure file", metavar="FILE")
 
  parser.add_option("-c", "--create_temp", dest="gen_temp", action="store_true",
                    help="create cfg template file" )
 
  (options, args) = parser.parse_args()
  if options.gen_temp:
    gen_template()
    sys.exit(0)
  if not options.num_cpu:  num_cpu = 1
  else: num_cpu = int(options.num_cpu)
  if not options.cfg_file:
    print "Please Specify configure file by -f"
    print "You can use option -c to create a template file"
    print
    sys.exit(0)
  else:
    cfg_file = options.cfg_file
 
  #print num_cpu
  #cfg_file = "auto_starrc.cfg"
  xtcmd_dic = read_cfg ( cfg_file )
  save_xtcmd_file(xtcmd_dic, num_cpu)