| #!/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() |