Merge All Timing Violations

#!  /tools/cfr/bin/python
 
import os
import sys
import re
from collections import defaultdict   
 
 
 
def get_all_violators():
  modes =  'func mbist bisr scan merged'.split(' ')
  corners = 'max maxlt min minht maxrc minrc'.split(' ')
  content = ""
  print "Reading reports" 
  for mode in modes:
    for corner in corners:
      #print mode, corner
      ddir = "postlayout_%s_%s" % (mode, corner)
      #file_name = "uld_eti_%s_%s_all_violators.rpt" %  (mode, corner)
      file_name = "zgdh_constraint_all_vios.rpt"
      vio_file = os.path.join(ddir, file_name)
      if os.path.exists(vio_file):
        print "  Reading file: %s" % vio_file
        content += open(os.path.join(ddir, file_name)).read()
  return content 
 
def get_hold_vio_dict(all_violators):
  patt = """min_delay/hold \('reg2reg' group\)\s+Endpoint.*?\n\n"""
  all_hold_vio = re.findall(patt, all_violators, re.DOTALL)
 
  hold_endpoints_slack_dict = defaultdict(list)
  for line in "\n".join(all_hold_vio).split("\n"):
    line = line.strip()
    if line.find("(VIOLATED") >= 0:
      fields = re.split("\s+", line)
      endpoint = fields[0]
      hold_endpoints_slack_dict[endpoint].append(fields[1])
      #slacks = hold_endpoints_slack_dict[endpoint] 
      #slacks.sort()
      #hold_endpoints_slack_dict[endpoint] = slacks
  return hold_endpoints_slack_dict
 
def get_setup_vio_dict(all_violators):
  patt = """max_delay/setup \('reg2reg' group\)\s+Endpoint.*?\n\n"""
  all_setup_vio = re.findall(patt, all_violators, re.DOTALL)
 
  setup_endpoints_slack_dict = defaultdict(list)
  for line in "\n".join(all_setup_vio).split("\n"):
    line = line.strip()
    if line.find("(VIOLATED") >= 0:
      fields = re.split("\s+", line)
      endpoint = fields[0]
      setup_endpoints_slack_dict[endpoint].append(fields[1])
      #slacks = setup_endpoints_slack_dict[endpoint] 
      #slacks.sort()
      #setup_endpoints_slack_dict[endpoint] = slacks
  return setup_endpoints_slack_dict
 
def get_sorted_vio_list(endpoint_slack_dict):
  vio_list = []
  for endpoint, slacks in endpoint_slack_dict.items():
    slacks.sort()
    slacks.reverse()
    #vio_list.append("%s, %d, %s" % (slacks[0], len(slacks), endpoint))
    vio_list.append( (slacks[0], len(slacks), endpoint))
  vio_list.sort()
  vio_list.reverse()
  #return "\n".join(vio_list)
  return(vio_list)
 
 
def __in_range_(f, min, max):
  if min < f <= max:
    return 1
  else:
    return 0
 
def get_qor_range_rpt(vio_endpoint_list):
  rpt_content = ""
  vio_list = [ float(i[0]) for i in vio_endpoint_list ]
  for step in [ 0.01, 0.1 ] :
    for i in range(0, 10):
      vio_count = sum( [ __in_range_(vio, -(i+1)*step, -i*step) for vio in vio_list ] )
      rpt_content += "%.2f ~ %.2f: %5d\n" % ( -(i+1)*step, -i*step, vio_count )
 
  rpt_content += "\n"
  #print  rpt_content
  return rpt_content
 
 
if __name__ == "__main__":
 
  dir_pt_log = 'logs'
  dir_scripts_src = 'scripts'
  dir_scripts_gen = 'scripts_pt_mcmm'
 
  all_violators = get_all_violators()
  hold_endpoints_slack_dict = get_hold_vio_dict(all_violators)
  setup_endpoints_slack_dict = get_setup_vio_dict(all_violators)
 
  hold_vio_list = get_sorted_vio_list(hold_endpoints_slack_dict)
  setup_vio_list = get_sorted_vio_list(setup_endpoints_slack_dict)
 
  setup_qor_rpt = get_qor_range_rpt(setup_vio_list)
  hold_qor_rpt = get_qor_range_rpt(hold_vio_list)
  print "\nSetup Violations:\n%s\n%s\n" % ('-'*60, setup_qor_rpt)
  print "\nHold Violations:\n%s\n%s\n" % ('-'*60, hold_qor_rpt)
 
  merged_rpt_file = 'rpt_merged_violator.rpt'
  f = open(merged_rpt_file, 'w')
  f.write("\nSetup Violator:\n\n")
  f.write(setup_qor_rpt)
  f.write("\n".join([ ", ".join([str(i) for i in t]) for t in setup_vio_list] ))
  f.write("\n\n\nHold Violator:\n\n")
  f.write(hold_qor_rpt)
  f.write("\n".join([ ", ".join([str(i) for i in t]) for t in hold_vio_list] ))
  print "Merged Violation Report Saved: %s\n" % merged_rpt_file