|  | """ Generate timing summary from Vivado timing.json output. """ | 
|  | import argparse | 
|  | import json | 
|  |  | 
|  |  | 
|  | def timing_summary(timing_json): | 
|  | setups = [] | 
|  | holds = [] | 
|  | for net in timing_json: | 
|  | for ipin in net['ipins']: | 
|  | if 'setup_timing_path' in ipin and ipin['setup_timing_path' | 
|  | ]['SLACK'] != "": | 
|  | setups.append(ipin) | 
|  | if 'hold_timing_path' in ipin and ipin['hold_timing_path']['SLACK' | 
|  | ] != "": | 
|  | holds.append(ipin) | 
|  |  | 
|  | worst_setup_slack = min( | 
|  | setups, key=lambda setup: float(setup['setup_timing_path']['SLACK']) | 
|  | ) | 
|  |  | 
|  | worst_hold_slack = min( | 
|  | holds, key=lambda hold: float(hold['hold_timing_path']['SLACK']) | 
|  | ) | 
|  |  | 
|  | print( | 
|  | 'Worst setup slack: {} = {}'.format( | 
|  | worst_setup_slack['setup_timing_path']['NAME'], | 
|  | worst_setup_slack['setup_timing_path']['SLACK'] | 
|  | ) | 
|  | ) | 
|  | print( | 
|  | 'Worst hold slack: {} = {}'.format( | 
|  | worst_hold_slack['hold_timing_path']['NAME'], | 
|  | worst_hold_slack['hold_timing_path']['SLACK'] | 
|  | ) | 
|  | ) | 
|  |  | 
|  |  | 
|  | def main(): | 
|  | parser = argparse.ArgumentParser(description=__doc__) | 
|  |  | 
|  | parser.add_argument('timing_json') | 
|  |  | 
|  | args = parser.parse_args() | 
|  |  | 
|  | with open(args.timing_json) as f: | 
|  | timing_json = json.load(f) | 
|  |  | 
|  | timing_summary(timing_json) | 
|  |  | 
|  |  | 
|  | if __name__ == "__main__": | 
|  | main() |