#!/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 """ Generates a missing feature/bit report for LiteX design. This script is fairly fragile, because it depends on the specific observation that all of the remaining bits appear to either belong to HCLK_IOI or IOI3 tiles. A more general version of this script could be created, but that was not the point of this script. """ from fasm import parse_fasm_filename def main(): fasm_file = 'top.fasm' fasm_model = list(parse_fasm_filename(fasm_file)) unknown_bits = { 'HCLK_IOI': {}, 'IOI3': {}, } total_unknown = 0 for l in fasm_model: if l.annotations is None: continue annotations = {} for annotation in l.annotations: annotations[annotation.name] = annotation.value if 'unknown_bit' not in annotations: continue total_unknown += 1 frame, word, bit = annotations['unknown_bit'].split('_') frame = int(frame, 16) word = int(word) bit = int(bit) frame_offset = frame % 0x80 base_frame = frame - frame_offset # All remaining LiteX bits appear to be in this one IO bank, so limit # the tool this this one IO bank. assert base_frame == 0x00401580, hex(frame) SIZE = 4 INITIAL_OFFSET = -2 if word == 50: group = 'HCLK_IOI' offset = 45 elif word < 50: group = 'IOI3' offset = ((word - INITIAL_OFFSET) // SIZE) * SIZE + INITIAL_OFFSET else: group = 'IOI3' word -= 1 offset = ((word - INITIAL_OFFSET) // SIZE) * SIZE + INITIAL_OFFSET offset += 1 word += 1 bit = '{}_{:02d}'.format( frame_offset, (word - offset) * 32 + bit, ) if bit not in unknown_bits[group]: unknown_bits[group][bit] = 0 unknown_bits[group][bit] += 1 print('Total unknown bits: {}'.format(total_unknown)) for group in unknown_bits: print('Group {} (count = {}):'.format(group, len(unknown_bits[group]))) for bit in sorted(unknown_bits[group]): print(' {} (count = {})'.format(bit, unknown_bits[group][bit])) if __name__ == "__main__": main()