|  | #!/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 | 
|  | ''' | 
|  | Pretty print FASM. | 
|  |  | 
|  | Sanity checks FASM against prjxray database. | 
|  | Can output canonical FASM. | 
|  | In the future may support other formatting options. | 
|  |  | 
|  | ''' | 
|  |  | 
|  | import os | 
|  | import fasm | 
|  | from prjxray import db | 
|  |  | 
|  |  | 
|  | def process_fasm(db_root, part, fasm_file, canonical): | 
|  | database = db.Database(db_root, part) | 
|  | grid = database.grid() | 
|  |  | 
|  | for fasm_line in fasm.parse_fasm_filename(fasm_file): | 
|  | if not fasm_line.set_feature: | 
|  | if not canonical: | 
|  | yield fasm_line | 
|  |  | 
|  | for feature in fasm.canonical_features(fasm_line.set_feature): | 
|  | parts = feature.feature.split('.') | 
|  | tile = parts[0] | 
|  |  | 
|  | gridinfo = grid.gridinfo_at_tilename(tile) | 
|  | tile_segbits = database.get_tile_segbits(gridinfo.tile_type) | 
|  |  | 
|  | address = 0 | 
|  | if feature.start is not None: | 
|  | address = feature.start | 
|  |  | 
|  | feature_name = '{}.{}'.format( | 
|  | gridinfo.tile_type, '.'.join(parts[1:])) | 
|  |  | 
|  | # Convert feature to bits.  If no bits are set, feature is | 
|  | # psuedo pip, and should not be output from canonical FASM. | 
|  | bits = tuple( | 
|  | tile_segbits.feature_to_bits(feature_name, address=address)) | 
|  | if len(bits) == 0 and canonical: | 
|  | continue | 
|  |  | 
|  | # In canonical output, only output the canonical features. | 
|  | if canonical: | 
|  | yield fasm.FasmLine( | 
|  | set_feature=feature, | 
|  | annotations=None, | 
|  | comment=None, | 
|  | ) | 
|  |  | 
|  | # If not in canonical mode, output original FASM line | 
|  | if not canonical: | 
|  | yield fasm_line | 
|  |  | 
|  |  | 
|  | def run(db_root, part, fasm_file, canonical): | 
|  | print( | 
|  | fasm.fasm_tuple_to_string( | 
|  | process_fasm(db_root, part, fasm_file, canonical), | 
|  | canonical=canonical)) | 
|  |  | 
|  |  | 
|  | def main(): | 
|  | import argparse | 
|  |  | 
|  | parser = argparse.ArgumentParser(description='Pretty print a FASM file.') | 
|  |  | 
|  | util.db_root_arg(parser) | 
|  | util.part_arg(parser) | 
|  | parser.add_argument('fasm_file', help='Input FASM file') | 
|  | parser.add_argument( | 
|  | '--canonical', help='Output canonical bitstream.', action='store_true') | 
|  | args = parser.parse_args() | 
|  |  | 
|  | run(args.db_root, args.part, args.fasm_file, args.canonical) | 
|  |  | 
|  |  | 
|  | if __name__ == '__main__': | 
|  | main() |