#!/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 sys, os, argparse from sdf_timing import sdfparse model_carry4 = { 'type': 'CARRY4', 'srcs': {'O5', '?X', '?X_LFF', '?X_LBOTH'}, 'out': {'CO0', 'CO1', 'CO2', 'CO3', 'O0', 'O1', 'O2', 'O3'}, 'mux': '?CY0', 'pins': { 'DI0': { 'type': 'A' }, 'DI1': { 'type': 'B' }, 'DI2': { 'type': 'C' }, 'DI3': { 'type': 'D' }, }, } def compute_delays(model, fin_name, fout_name): data = '' with open(fin_name, 'r') as f: data = f.read() sdf = sdfparse.parse(data) keys = sdf['cells'][model['type']].keys() if 'slicel'.upper() in keys: sl = 'L' elif 'slicem'.upper() in keys: sl = 'M' else: print("Unknown slice type!") return nsdf = dict() nsdf['header'] = sdf['header'] nsdf['cells'] = dict() nsdf['cells']['ROUTING_BEL'] = dict() for p in model['pins']: pin = model['pins'][p] outs = dict() for o in model['out']: outs[o] = [] res = [] cells = sdf['cells'] for src in model['srcs']: source = src.replace('?', pin['type']) _type = model['type'] + '_' + source if _type in cells.keys(): cell = cells[_type]["SLICE" + sl.upper()] for o in model['out']: iopath = 'iopath_' + p + '_' + o if iopath in cell.keys(): delay = cell[iopath]['delay_paths']['slow']['max'] outs[o].append(delay) for src in outs: s = sorted(outs[src]) for val in s: res.append(val - s[0]) delay = round(max(res), 3) muxname = str(model['mux'].replace('?', pin['type'])) rbel = nsdf['cells']['ROUTING_BEL']['SLICE' + sl.upper() + '/' + muxname] = dict() iname = 'interconnect_' + pin['type'].lower() + 'x_' + str(p).lower() rbel[iname] = dict() rbel[iname]['is_absolute'] = True rbel[iname]['to_pin_edge'] = None rbel[iname]['from_pin_edge'] = None rbel[iname]['from_pin'] = pin['type'].lower() + 'x' rbel[iname]['to_pin'] = str(p).lower() rbel[iname]['type'] = 'interconnect' rbel[iname]['is_timing_check'] = False rbel[iname]['is_timing_env'] = False paths = rbel[iname]['delay_paths'] = dict() paths['slow'] = dict() paths['slow']['min'] = delay paths['slow']['avg'] = None paths['slow']['max'] = delay paths['fast'] = dict() paths['fast']['min'] = delay paths['fast']['avg'] = None paths['fast']['max'] = delay # emit new sdfs with open(fout_name, 'w') as f: f.write(sdfparse.emit(nsdf)) def main(argv): parser = argparse.ArgumentParser( description='Tool for computing CARRY4 muxes delays') parser.add_argument( '--input', dest='inputfile', action='store', help='Input file') parser.add_argument( '--output', dest='outputfile', action='store', help='Output file') args = parser.parse_args(argv[1:]) compute_delays(model_carry4, args.inputfile, args.outputfile) if __name__ == "__main__": main(sys.argv)