#!/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
""" Sanity checks FASM output from IOB fuzzer.
The IOB fuzzer is fairly complicated, and it's output is hard to verify by
inspected.  For this reason, check_results.py was written to compare the
specimen's generated and their FASM output.  The FASM output does pose a
chicken and egg issue.  The test procedure is a follows:

1. Build the database (e.g. make -j<N> run)
2. Build the database again (e.g. make -j<N> run)
3. Run check_results.py

The second time that the database is run, the FASM files in the specimen's
will have the bits documented by fuzzer.

"""
import argparse
import os
import os.path
from prjxray import verilog
import json
import generate


def process_parts(parts):
    if len(parts) == 0:
        return

    if parts[-1] == 'IN_ONLY':
        yield 'type', ['IBUF', 'IBUFDS']

    if len(parts) > 2 and parts[-2] == 'SLEW':
        yield 'SLEW', verilog.quote(parts[-1])

    if parts[0] == 'PULLTYPE':
        yield 'PULLTYPE', verilog.quote(parts[1])

    if len(parts) > 1 and parts[1] == 'IN':
        yield 'IOSTANDARDS', parts[0].split('_')
        yield 'IN', True

    if len(parts) > 1 and parts[1] == 'IN_DIFF':
        yield 'IOSTANDARDS', parts[0].split('_')
        yield 'IN_DIFF', True

    if len(parts) > 1 and parts[1] == 'DRIVE':
        yield 'IOSTANDARDS', parts[0].split('_')

        if parts[2] == 'I_FIXED':
            yield 'DRIVES', [None]
        else:
            yield 'DRIVES', parts[2].split('_')


def create_sites_from_fasm(fasm_file):
    sites = {}

    diff_tiles = set()

    with open(fasm_file) as f:
        for l in f:
            if 'IOB33' not in l:
                continue

            parts = l.strip().split('.')
            tile = parts[0]
            site = parts[1]

            if 'OUT_DIFF' == site:
                diff_tiles.add(tile)
                continue

            if (tile, site) not in sites:
                sites[(tile, site)] = {
                    'tile': tile,
                    'site_key': site,
                }

            if len(parts) > 3 and 'IN_DIFF' == parts[3]:
                diff_tiles.add(tile)

            for key, value in process_parts(parts[2:]):
                sites[(tile, site)][key] = value

    for key in sites:
        if 'type' not in sites[key]:
            if 'IOSTANDARDS' not in sites[key]:
                sites[key]['type'] = [None]
            else:
                assert 'IOSTANDARDS' in sites[key], sites[key]
                assert 'DRIVES' in sites[key], sites[key]

                if 'IN' in sites[key]:
                    sites[key]['type'] = ['IOBUF', 'IOBUF_INTERMDISABLE']
                else:
                    sites[key]['type'] = [
                        "OBUF",
                        "OBUFDS",
                        "OBUFTDS",
                        "OBUFDS_DUAL_BUF",
                        "OBUFTDS_DUAL_BUF",
                    ]

    return sites, diff_tiles


def process_specimen(fasm_file, params_json):
    sites, diff_tiles = create_sites_from_fasm(fasm_file)

    with open(params_json) as f:
        params = json.load(f)

    count = 0
    for p in params['tiles']:
        tile = p['tile']
        for site in p['site'].split(' '):
            site_y = int(site[site.find('Y') + 1:]) % 2

            if generate.skip_broken_tiles(p):
                continue

            site_key = 'IOB_Y{}'.format(site_y)

            if (tile, site_key) not in sites:
                assert p['type'] is None, p
                continue

            site_from_fasm = sites[(tile, site_key)]

            if site_y == 0 or tile not in diff_tiles:
                assert p['type'] in site_from_fasm['type'], (
                    tile, site_key, p['type'], site_from_fasm['type'])
            else:
                # Y1 on DIFF tiles is always none.
                assert p['type'] is None, p

            if p['type'] is None:
                continue

            assert 'PULLTYPE' in p, p
            assert 'PULLTYPE' in site_from_fasm, site_from_fasm

            if verilog.unquote(p['PULLTYPE']) == '':
                # Default is None.
                pulltype = verilog.quote('NONE')
            else:
                pulltype = p['PULLTYPE']

            assert pulltype == site_from_fasm['PULLTYPE'], (
                tile, site_key, p, site_from_fasm)

            assert 'IOSTANDARDS' in site_from_fasm, (tile, site)

            iostandard = verilog.unquote(p['IOSTANDARD'])
            if iostandard.startswith('DIFF_'):
                iostandard = iostandard[5:]

            assert iostandard in site_from_fasm['IOSTANDARDS'], (
                p['IOSTANDARD'],
                site_from_fasm['IOSTANDARDS'],
            )

            if p['type'] not in ['IBUF', 'IBUFDS']:
                if verilog.unquote(p['SLEW']) == '':
                    # Default is None.
                    slew = verilog.quote('SLOW')
                else:
                    slew = p['SLEW']

                assert slew == site_from_fasm['SLEW'], (
                    tile, site_key, p, site_from_fasm)

                assert 'DRIVES' not in p, p
                assert 'DRIVES' in site_from_fasm, (
                    tile, site, p['type'], site_from_fasm)

                if p['DRIVE'] is None:
                    assert None in site_from_fasm['DRIVES'], (
                        tile, site_key, p['DRIVE'], site_from_fasm['DRIVES'])
                elif p['DRIVE'] is '':
                    if None in site_from_fasm['DRIVES']:
                        # IOSTANDARD has not DRIVE setting, ignore
                        pass
                    else:
                        # Check that drive is at default
                        assert 'I12' in site_from_fasm['DRIVES'], (
                            tile, site_key, p['DRIVE'],
                            site_from_fasm['DRIVES'])
                else:
                    assert 'I{}'.format(
                        p['DRIVE']) in site_from_fasm['DRIVES'], (
                            tile, site_key, p['DRIVE'],
                            site_from_fasm['DRIVES'])

            count += 1

    return count


def scan_specimens():
    for root, dirs, files in os.walk('build'):
        if os.path.basename(root).startswith('specimen_'):
            print('Processing', os.path.basename(root))
            process_specimen(
                fasm_file=os.path.join(root, 'design.fasm'),
                params_json=os.path.join(root, 'params.json'))

    print('No errors found!')


def main():
    parser = argparse.ArgumentParser(description="Verify IOB FASM vs BELs.")

    parser.add_argument('--fasm')
    parser.add_argument('--params')

    args = parser.parse_args()

    if not args.fasm and not args.params:
        scan_specimens()
    else:
        count = process_specimen(fasm_file=args.fasm, params_json=args.params)
        print('No errors found in {} IO sites'.format(count))


if __name__ == "__main__":
    main()
