| """ Generates project xray. """ |
| import argparse |
| import json |
| import prjxray.db |
| from prjxray.site_type import SitePinDirection |
| from lib.pb_type_xml import start_heterogeneous_tile, add_switchblock_locations |
| import lxml.etree as ET |
| |
| |
| def get_wires(site, site_type, unused_wires=None): |
| """Get wires related to a site""" |
| input_wires = set() |
| output_wires = set() |
| |
| drop_wires = list() |
| wires_to_drop = list() |
| if unused_wires: |
| wires_to_drop = unused_wires.split(",") |
| |
| for site_pin in site.site_pins: |
| if site_pin.name in wires_to_drop: |
| drop_wires.append(site_pin) |
| continue |
| if site_type.get_site_pin( |
| site_pin.name).direction == SitePinDirection.IN: |
| input_wires.add(site_pin.wire) |
| elif site_type.get_site_pin( |
| site_pin.name).direction == SitePinDirection.OUT: |
| output_wires.add(site_pin.wire) |
| else: |
| assert False, site_pin |
| |
| for wire in drop_wires: |
| site.site_pins.remove(wire) |
| |
| return input_wires, output_wires |
| |
| |
| def main(): |
| parser = argparse.ArgumentParser(description=__doc__) |
| |
| parser.add_argument('--db_root', required=True) |
| parser.add_argument('--part', required=True) |
| parser.add_argument('--output_directory', required=True) |
| parser.add_argument('--site_directory', required=True) |
| parser.add_argument('--tile_type', required=True) |
| parser.add_argument('--pb_types', required=True) |
| parser.add_argument('--pin_assignments', required=True) |
| parser.add_argument( |
| '--unused_wires', |
| help="Comma seperated list of site wires to exclude in this tile." |
| ) |
| |
| args = parser.parse_args() |
| |
| with open(args.pin_assignments) as f: |
| pin_assignments = json.load(f) |
| |
| db = prjxray.db.Database(args.db_root, args.part) |
| grid = db.grid() |
| tile_type = db.get_tile_type(args.tile_type) |
| |
| pb_types = args.pb_types.split(',') |
| |
| equivalent_sites_dict = dict() |
| |
| gridinfo = None |
| for tile in grid.tiles(): |
| if args.tile_type in tile: |
| gridinfo = grid.gridinfo_at_tilename(tile) |
| |
| break |
| |
| assert gridinfo |
| |
| for pb_type in pb_types: |
| try: |
| site, equivalent_sites = pb_type.split("/") |
| except ValueError: |
| site = pb_type |
| equivalent_sites = None |
| |
| equivalent_sites_dict[site] = equivalent_sites.split( |
| ':' |
| ) if equivalent_sites else [] |
| |
| sites = list() |
| |
| for site in tile_type.get_sites(): |
| site_type = db.get_site_type(site.type) |
| input_wires, output_wires = get_wires( |
| site, site_type, args.unused_wires |
| ) |
| |
| sites.append((site_type, site, input_wires, output_wires)) |
| |
| sites = sorted( |
| sites, key=lambda site: (site[1].type, int(site[1].x), int(site[1].y)) |
| ) |
| |
| tile_xml = start_heterogeneous_tile( |
| args.tile_type, |
| pin_assignments, |
| sites, |
| equivalent_sites_dict, |
| ) |
| |
| add_switchblock_locations(tile_xml) |
| |
| with open('{}/{}.tile.xml'.format(args.output_directory, |
| args.tile_type.lower()), 'w') as f: |
| tile_str = ET.tostring(tile_xml, pretty_print=True).decode('utf-8') |
| f.write(tile_str) |
| |
| |
| if __name__ == "__main__": |
| main() |