| #!/usr/bin/env python3 | |
| # -*- coding: utf-8 -*- | |
| # | |
| # Copyright (C) 2017-2020 The Project X-Ray Authors. | |
| # | |
| # Use of this source code is governed by a ISC-style | |
| # license that can be found in the LICENSE file or at | |
| # https://opensource.org/licenses/ISC | |
| # | |
| # SPDX-License-Identifier: ISC | |
| import argparse | |
| import json | |
| from sdf_timing import sdfparse | |
| from sdf_timing import utils | |
| def generate_sdf(timings, sdffile): | |
| sdf_data = sdfparse.emit(timings, timescale='1ns') | |
| with open(sdffile, 'w') as fp: | |
| fp.write(sdf_data) | |
| def add_timing_paths_entry(paths, type, values): | |
| paths[type] = dict() | |
| paths[type]['min'] = values[0] | |
| paths[type]['avg'] = values[1] | |
| paths[type]['max'] = values[2] | |
| return paths | |
| def read_raw_timings(fin, site): | |
| timings = dict() | |
| timings['cells'] = dict() | |
| with open(fin, "r") as f: | |
| for line in f: | |
| raw_data = line.split() | |
| speed_model = raw_data[0] | |
| if speed_model.startswith('bel_d_'): | |
| speed_model = speed_model[6:] | |
| speed_model_split = speed_model.split('_') | |
| interconn_input = "_".join(speed_model_split[1:-1]) | |
| interconn_output = speed_model_split[-1] | |
| celltype = "ROUTING_BEL" | |
| if celltype not in timings['cells']: | |
| timings['cells'][celltype] = dict() | |
| cellsite = site + '/' + interconn_output.upper() | |
| if cellsite not in timings['cells'][celltype]: | |
| timings['cells'][celltype][cellsite] = dict() | |
| if speed_model not in timings['cells'][celltype][cellsite]: | |
| timings['cells'][celltype][cellsite][speed_model] = dict() | |
| delays = dict() | |
| # each timing entry reports 5 delays | |
| for d in range(0, 5): | |
| (t, v) = raw_data[d + 1].split(':') | |
| delays[t] = v | |
| # create entry for sdf writer | |
| iport = dict() | |
| iport['port'] = interconn_input | |
| iport['port_edge'] = None | |
| oport = dict() | |
| oport['port'] = interconn_output | |
| oport['port_edge'] = None | |
| paths = dict() | |
| paths = add_timing_paths_entry( | |
| paths, 'slow', [delays['SLOW_MIN'], None, delays['SLOW_MAX']]) | |
| paths = add_timing_paths_entry( | |
| paths, 'fast', [delays['FAST_MIN'], None, delays['FAST_MAX']]) | |
| if speed_model.endswith('diff'): | |
| iport['port'] = "_".join(speed_model_split[1:]) | |
| iport['port_edge'] = None | |
| timings['cells'][celltype][cellsite][ | |
| speed_model] = utils.add_device(iport, paths) | |
| else: | |
| timings['cells'][celltype][cellsite][ | |
| speed_model] = utils.add_interconnect(iport, oport, paths) | |
| timings['cells'][celltype][cellsite][speed_model][ | |
| 'is_absolute'] = True | |
| return timings | |
| def main(): | |
| parser = argparse.ArgumentParser() | |
| parser.add_argument('--timings', type=str, help='Raw timing input file') | |
| parser.add_argument('--sdf', type=str, help='output sdf file') | |
| parser.add_argument( | |
| '--site', type=str, help='Site of the processed timings') | |
| parser.add_argument( | |
| '--debug', type=bool, default=False, help='Enable debug json dumps') | |
| args = parser.parse_args() | |
| timings = read_raw_timings(args.timings, args.site) | |
| if args.debug: | |
| with open("debug" + args.site + ".json", 'w') as fp: | |
| json.dump(timings, fp, indent=4, sort_keys=True) | |
| generate_sdf(timings, args.sdf) | |
| if __name__ == '__main__': | |
| main() |