用户工具

站点工具


vlsi:pt:fix-setup

PrimeTime Max Delay(Setup) Violation Fix

To using this script, we should using script PrimeTime Report to generate reports.

Swap Cells

Swap between different VT cells. Change HVT to LVT cells.

#! /tools/cfr/bin/python
 
import os
import sys
import re
import sets
from collections import defaultdict
 
 
def get_all_setup_rpt():
  modes =  'func mbist bisr scan merged'.split(' ')
  all_corners = 'max maxlt min minht maxrc minrc'.split(' ')
  content = ""
  for mode in modes:
    for corner in all_corners:
      #print mode, corner
      ddir = "postlayout_%s_%s" % (mode, corner)
      #setup_rpt_name = "sfvs_%s_%s_setup.rpt" % (mode, corner)
      setup_rpt_name = "zgdh_timing_setup_reg2reg_startend.rpt"
      setup_rpt = os.path.join(ddir, setup_rpt_name)
      if os.path.exists(setup_rpt):
        print "# Reading report: %s" % setup_rpt
        content += open(setup_rpt).read()
  return content
 
def get_faster_lib_cel(master):
  xp_patt = """[^LF]XP"""
  lxp_patt = """LXP"""
  new_lib_cel = ""
  if re.findall(xp_patt, master):
    new_lib_cel = 'g65fxp/' + master.replace('XP', 'FXP')
  if re.findall(lxp_patt, master):
    new_lib_cel = 'g65xp/' + master.replace('LXP', 'XP')
  return new_lib_cel
 
 
def swap_cells(setup_vio_reports):
  patt = """^([a-zA-Z0-9\[\]\/_]*)/[^/ ]*\s+\(([^ ]*)\)\s+[\.\d]+\s+[\.\d]+ \&"""
  lines = setup_vio_reports.split("\n")
  all_cmd = sets.Set()
  for line in lines:
    line = line.strip()
    if not line: continue
    instance_master = re.findall(patt, line)
    if instance_master:
      instance_master = instance_master[0]
      master = instance_master[1]
      instance = instance_master[0]
      if master == "net" or master.startswith("RR") or master.startswith("FD"): 
         pass
      else:
        new_master = get_faster_lib_cel(master)
        if new_master:
          cmd = "size_cell %s %s" % (instance, new_master)
          all_cmd.add(cmd)
        else:
          cmd = "# no change: %s %s" % (master, instance)
  return all_cmd
 
if __name__ == "__main__":
  all_setup_rpt = get_all_setup_rpt()
  #size_large_delay_cells(all_setup_paths, cell_delay_threshold=0.15)
  all_cmd = swap_cells(all_setup_rpt)
  print "\n".join(all_cmd)

Size Cells

This is not verified. More verification to do.

#! /tools/cfr/bin/python
 
import os
import sys
import re
from collections import defaultdict
 
 
def get_lib_cell_swap_dict():
  size_cell_dict = {}
  size_cell_dict['BUFM2XP']        = 'g65xp/BUFM10XPV1'
  size_cell_dict['BUFM2LXP']       = 'g65xp/BUFM10XPV1'
  size_cell_dict['BUFM3XP']        = 'g65xp/BUFM10XPV1'
  size_cell_dict['N1M1XPV1']       = 'g65xp/N1M8XPV1'
  size_cell_dict['N1M3XP']         = 'g65xp/N1M8XPV1'
  size_cell_dict['N1M05LXPV1']     = 'g65xp/N1M8XPV1'
  size_cell_dict['AO222M05XPV1']   = 'g65xp/AO222M2XPV1'
  size_cell_dict['OAI211M05XP']    = 'g65xp/OAI211M8XPV1'
  size_cell_dict['OAI211M1XPV1']   = 'g65xp/OAI211M8XPV1'
  size_cell_dict['OAI211M2XPV1']   = 'g65xp/OAI211M8XPV1'
  size_cell_dict['NR2BNM05LXPV1']  = 'g65xp/NR2ANM8XPV1'
  size_cell_dict['NR2BNM2XP']      = 'g65xp/NR2ANM8XPV1'
  size_cell_dict['OR2M05XPV1']     = 'g65xp/OR2M6XPV1'
  size_cell_dict['FA1AM05LXPV1']   = 'g65xp/FA1AM2XP'
  size_cell_dict['FA1AM1LXPV1']    = 'g65xp/FA1AM2XP'
  size_cell_dict['MUX21LM05LXP']   = 'g65xp/MUX21LM4XPV1'
  size_cell_dict['AND3M05LXPV1']   = 'g65xp/AND3M4XP'
  size_cell_dict['AOI21M05LXPV1']  = 'g65xp/AOI21M4XPV1'
  size_cell_dict['AOI22M05LXPV1']  = 'g65xp/AOI22M4XPV1'
  size_cell_dict['ENM05LXPV1']     = 'g65xp/ENM4XPV1'
  size_cell_dict['EOM05LXPV1']     = 'g65xp/EOM4XPV1'
  size_cell_dict['HA1M05LXPV1']    = 'g65xp/HA1M4XP'
  size_cell_dict['NR2M05LXPV1']    = 'g65xp/NR2M4XP'
  size_cell_dict['OR2M05LXPV1']    = 'g65xp/OR2M4XP'
  size_cell_dict['ENM075LXPV1']    = 'g65xp/ENM4XPV1'
  size_cell_dict['EOM075LXPV1']    = 'g65xp/EOM4XPV1'
  size_cell_dict['MUX21LM075LXPV1']    = 'g65xp/MUX21LM4XPV1'
  size_cell_dict['MUX21LM075XPV1']     = 'g65xp/MUX21LM4XPV1'
 
  return size_cell_dict
 
 
def get_slack_from_path(timing_path):
  patt="""slack \(VIOLATED\)\s+(-?[\d\.]+)"""
  slacks = re.findall(patt, timing_path, re.DOTALL)
  slack = 0
  if slacks:
    slack = float(slacks[0])
  return slack
 
def get_all_setup_paths():
  modes =  'func mbist bisr scan merged'.split(' ')
  all_corners = 'max maxlt min minht maxrc minrc'.split(' ')
  content = ""
  for mode in modes:
    for corner in all_corners:
      #print mode, corner
      ddir = "postlayout_%s_%s" % (mode, corner)
      #setup_rpt_name = "sfvs_%s_%s_setup.rpt" % (mode, corner)
      setup_rpt_name = "zgdh_timing_setup_reg2reg_startend.rpt"
      setup_rpt = os.path.join(ddir, setup_rpt_name)
      if os.path.exists(setup_rpt):
        print "# Reading report: %s" % setup_rpt
        content += open(setup_rpt).read()
  timing_paths = content.split('Startpoint')
  new_timing_paths = []
  for p in timing_paths:
    if p.strip():
      new_timing_paths.append( 'Startpoint'+p )
  return new_timing_paths
 
 
def get_large_delay_cells(all_setup_vio_rpt, delay_threshold = 0.10):
  cell_delay_dic = defaultdict(list)
  patt = """^([a-zA-Z0-9\[\]\/_]*)/[^/ ]*\s+\(([^ ]*)\)\s+[\.\d]+\s+([\.\d]+)"""
  for line in all_setup_vio_rpt.split("\n"):
    line = line.strip()
    if not line: continue
    instance_masters = re.findall(patt, line)
    if instance_masters:
      master = instance_masters[0][1]
      instance = instance_masters[0][0]
      if master == "net" or master.startswith("RR") or master.startswith("FD"): 
         pass
      else:
        cell_delay =  float(instance_masters[0][2])
        if cell_delay >= delay_threshold:
          #print instance_masters
          cell_delay_dic[master].append(instance_masters[0][2])
  return cell_delay_dic
 
 
def size_large_delay_cells(setup_paths, setup_slack_threshold = -0.10, cell_delay_threshold = 0.20):
  instance_masters_uniq = {}
  fix_cmd_icc = ""
  lib_cell_swap_dict = get_lib_cell_swap_dict()
  for setup_path in all_setup_paths:
    all_instance_masters = get_sizing_instances(setup_path, setup_slack_threshold, cell_delay_threshold)
    for im in all_instance_masters:
      instance = im[0]
      master   = im[1]
      print "#", im
      instance_masters_uniq[instance] = master
  for instance, master in instance_masters_uniq.items():
    print "# %s %s " % (instance, master)
    dest_cell = lib_cell_swap_dict.get(master, "")
    if dest_cell:
      #fix_cmd_icc += "size_cell %s %s\n" % (instance, dest_cell)
      print "size_cell %s %s" % (instance, dest_cell)
    else:
      print "#-#-# No predefined: %s, %s" % (master, instance)
    print
 
 
def get_sizing_instances(setup_path, setup_slack_threshold = -0.10, cell_delay_threshold = 0.10):
  cell_delay_dic = defaultdict(list)
  patt = """^([a-zA-Z0-9\[\]\/_]*)/[^/ ]*\s+\(([^ ]*)\)\s+[\.\d]+\s+([\.\d]+) \&"""
  setup_slack = get_slack_from_path(setup_path)
  all_sizing_instance_masters = []
  instance_master = None
  if setup_slack > setup_slack_threshold:
    pass
  else:
    for line in setup_path.split("\n"):
      line = line.strip()
      if not line: continue
      instance_master = re.findall(patt, line)
      if instance_master:
        instance_master = instance_master[0]
        master = instance_master[1]
        instance = instance_master[0]
        if master == "net" or master.startswith("RR") or master.startswith("FD"): 
           pass
        else:
          cell_delay =  float(instance_master[2])
          if cell_delay >= cell_delay_threshold:
            #print "#-- ", instance_master
            all_sizing_instance_masters.append(instance_master)
  return all_sizing_instance_masters
 
 
if __name__ == "__main__":
  patt = """^([a-zA-Z0-9\[\]\/_]*)/[^/ ]*\s+\(([^ ]*)\)\s+[\.\d]+\s+([\.\d]+)"""
  all_setup_paths = get_all_setup_paths()
  size_large_delay_cells(all_setup_paths, cell_delay_threshold=0.15)
 
 
#  lib_cell_swap_dict = get_lib_cell_swap_dict()
#  large_delay_cells_dict = get_large_delay_cells(all_setup_vio_paths)
#  for key, v in  large_delay_cells_dict.items():
#    v.sort
#    print  v[-1], len(v), key
#  print size_large_delay_cells(all_setup_vio_paths)
vlsi/pt/fix-setup.txt · 最后更改: 2011/06/29 02:22 (外部编辑)