#!/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 json
import io
import os
import random
random.seed(int(os.getenv("SEED"), 16))
from prjxray import util
from prjxray import lut_maker
from prjxray import verilog
from prjxray.db import Database


def gen_sites():
    '''
    IOB33S: main IOB of a diff pair
    IOB33M: secondary IOB of a diff pair
    IOB33: not a diff pair. Relatively rare (at least in ROI...2 of them?)
    Focus on IOB33S to start
    '''
    db = Database(util.get_db_root(), util.get_part())
    grid = db.grid()
    for tile_name in sorted(grid.tiles()):
        loc = grid.loc_of_tilename(tile_name)
        gridinfo = grid.gridinfo_at_loc(loc)

        sites = {}
        for site_name, site_type in gridinfo.sites.items():
            if site_type in ['IOB33S', 'IOB33M']:
                sites[site_type] = site_name

        if sites:
            yield tile_name, sites


def write_params(params):
    pinstr = 'tile,site,pin,iostandard,drive,slew\n'
    for vals in params:
        pinstr += ','.join(map(str, vals)) + '\n'

    open('params.csv', 'w').write(pinstr)


def run():
    tile_types = ['IBUF', 'OBUF', 'IOBUF_INTERMDISABLE', None, None]

    i_idx = 0
    o_idx = 0
    io_idx = 0

    iostandards = [
        'LVCMOS12',
        'LVCMOS15',
        'LVCMOS18',
        'LVCMOS25',
        'LVCMOS33',
        'LVTTL',
        'SSTL135',
        'SSTL15',
        'LVDS_25',
        'TMDS_33',
    ]

    diff_map = {
        "SSTL135": ["DIFF_SSTL135"],
        "SSTL15": ["DIFF_SSTL15"],
    }

    only_diff_map = {
        "LVDS_25": ["LVDS_25"],
        "TMDS_33": ["TMDS_33"],
    }

    IN_TERM_ALLOWED = [
        'SSTL15',
        'SSTL15_R',
        'SSTL18',
        'SSTL18_R',
        'SSTL135',
        'SSTL135_R',
        'HSTL_I'
        'HSTL_I_18'
        'HSTL_II',
        'HSTL_II_18',
    ]

    slews = ['FAST', 'SLOW']
    pulls = ["NONE", "KEEPER", "PULLDOWN", "PULLUP"]

    luts = lut_maker.LutMaker()

    connects = io.StringIO()

    tile_params = []
    params = {
        "tiles": [],
        'INTERNAL_VREF': {},
    }

    with open(os.path.join(os.getenv('FUZDIR'), 'build', 'iobanks.txt')) as f:
        iobanks = set()
        iob_sites = dict()
        for l in f:
            fields = l.split(',')
            iob_site = fields[0]
            iobank = fields[1].rstrip()

            iobanks.add(iobank)
            iob_sites[iob_site] = iobank

    params['iobanks'] = iobanks

    iostandard_map = dict()
    for iobank in iobanks:
        iostandard = random.choice(iostandards)
        if iostandard in ['SSTL135', 'SSTL15']:
            params['INTERNAL_VREF'][iobank] = random.choice(
                (
                    .600,
                    .675,
                    .75,
                    .90,
                ))

        iostandard_map[iobank] = iostandard

    params['iobanks'] = list(iobanks)

    any_idelay = False
    for tile, sites in gen_sites():
        iostandard = None

        site_bels = {}
        for site_type, site_name in sites.items():
            iobank = iob_sites[site_name]
            iostandard = iostandard_map[iobank]

            if iostandard in ['LVTTL', 'LVCMOS18']:
                drives = [4, 8, 12, 16, 24]
            elif iostandard in ['LVCMOS12']:
                drives = [4, 8, 12]
            elif iostandard in ['SSTL135', 'SSTL15', 'LVDS_25', 'TMDS_33']:
                drives = None
            else:
                drives = [4, 8, 12, 16]

            if site_type.endswith('M'):
                if iostandard in diff_map:
                    site_bels[site_type] = random.choice(
                        tile_types + ['IBUFDS', 'OBUFDS', 'OBUFTDS'])
                elif iostandard in only_diff_map:
                    site_bels[site_type] = random.choice(
                        ['IBUFDS', 'OBUFDS', 'OBUFTDS', None, None])
                else:
                    site_bels[site_type] = random.choice(tile_types)
                is_m_diff = site_bels[site_type] is not None and site_bels[
                    site_type].endswith('DS')
            else:
                site_bels[site_type] = random.choice(tile_types)

        if is_m_diff or iostandard in only_diff_map:
            site_bels['IOB33S'] = None

        for site_type, site in sites.items():
            p = {}
            p['tile'] = tile
            p['site'] = site
            p['type'] = site_bels[site_type]

            if p['type'] is not None and p['type'].endswith('DS'):
                if iostandard in diff_map:
                    iostandard_site = random.choice(diff_map[iostandard])
                elif iostandard in only_diff_map:
                    iostandard_site = random.choice(only_diff_map[iostandard])
                p['pair_site'] = sites['IOB33S']
            else:
                iostandard_site = iostandard

            p['IOSTANDARD'] = verilog.quote(iostandard_site)
            p['PULLTYPE'] = verilog.quote(random.choice(pulls))

            if p['type'] is None:
                p['pad_wire'] = None
            elif p['type'] == 'IBUF':
                p['pad_wire'] = 'di[{}]'.format(i_idx)
                p['IDELAY_ONLY'] = random.randint(0, 1)
                if not p['IDELAY_ONLY']:
                    p['owire'] = luts.get_next_input_net()
                else:
                    any_idelay = True
                    p['owire'] = 'idelay_{site}'.format(**p)

                p['DRIVE'] = None
                p['SLEW'] = None
                p['IBUF_LOW_PWR'] = random.randint(0, 1)

                if iostandard in IN_TERM_ALLOWED:
                    p['IN_TERM'] = random.choice(
                        (
                            'NONE',
                            'UNTUNED_SPLIT_40',
                            'UNTUNED_SPLIT_50',
                            'UNTUNED_SPLIT_60',
                        ))

                i_idx += 1
            elif p['type'] == 'IBUFDS':
                p['pad_wire'] = 'di[{}]'.format(i_idx)
                i_idx += 1
                p['bpad_wire'] = 'di[{}]'.format(i_idx)
                i_idx += 1

                p['IDELAY_ONLY'] = random.randint(0, 1)
                p['DIFF_TERM'] = random.randint(0, 1)
                if not p['IDELAY_ONLY']:
                    p['owire'] = luts.get_next_input_net()
                else:
                    any_idelay = True
                    p['owire'] = 'idelay_{site}'.format(**p)

                p['DRIVE'] = None
                p['SLEW'] = None
                p['IBUF_LOW_PWR'] = random.randint(0, 1)

            elif p['type'] == 'OBUF':
                p['pad_wire'] = 'do[{}]'.format(o_idx)
                p['iwire'] = luts.get_next_output_net()
                if drives is not None:
                    p['DRIVE'] = random.choice(drives)
                else:
                    p['DRIVE'] = None
                p['SLEW'] = verilog.quote(random.choice(slews))

                o_idx += 1
            elif p['type'] == 'OBUFDS':
                p['pad_wire'] = 'do[{}]'.format(o_idx)
                o_idx += 1
                p['bpad_wire'] = 'do[{}]'.format(o_idx)
                o_idx += 1
                p['iwire'] = luts.get_next_output_net()
                if drives is not None:
                    p['DRIVE'] = random.choice(drives)
                else:
                    p['DRIVE'] = None
                p['SLEW'] = verilog.quote(random.choice(slews))
            elif p['type'] == 'OBUFTDS':
                p['pad_wire'] = 'do[{}]'.format(o_idx)
                o_idx += 1
                p['bpad_wire'] = 'do[{}]'.format(o_idx)
                o_idx += 1
                p['tristate_wire'] = random.choice(
                    ('0', luts.get_next_output_net()))
                p['iwire'] = luts.get_next_output_net()
                if drives is not None:
                    p['DRIVE'] = random.choice(drives)
                else:
                    p['DRIVE'] = None
                p['SLEW'] = verilog.quote(random.choice(slews))
            elif p['type'] == 'IOBUF_INTERMDISABLE':
                p['pad_wire'] = 'dio[{}]'.format(io_idx)
                p['iwire'] = luts.get_next_output_net()
                p['owire'] = luts.get_next_input_net()
                if drives is not None:
                    p['DRIVE'] = random.choice(drives)
                else:
                    p['DRIVE'] = None
                p['SLEW'] = verilog.quote(random.choice(slews))
                p['tristate_wire'] = random.choice(
                    ('0', luts.get_next_output_net()))
                p['ibufdisable_wire'] = random.choice(
                    ('0', luts.get_next_output_net()))
                p['intermdisable_wire'] = random.choice(
                    ('0', luts.get_next_output_net()))
                io_idx += 1

            if 'DRIVE' in p:
                if p['DRIVE'] is not None:
                    p['DRIVE_STR'] = '.DRIVE({}),'.format(p['DRIVE'])
                else:
                    p['DRIVE_STR'] = ''

            if 'SLEW' in p:
                p['SLEW_STR'] = ''
                if iostandard in only_diff_map:
                    p['SLEW'] = None
                elif p['DRIVE'] is not None:
                    p['SLEW_STR'] = '.SLEW({}),'.format(p['SLEW'])

            if p['type'] is not None:
                tile_params.append(
                    (
                        tile,
                        site,
                        p['pad_wire'],
                        iostandard_site,
                        p['DRIVE'],
                        verilog.unquote(p['SLEW']) if p['SLEW'] else None,
                        verilog.unquote(p['PULLTYPE']),
                        p['IN_TERM'] if 'IN_TERM' in p else None,
                    ))
            params['tiles'].append(p)

    write_params(tile_params)

    with open('iobank_vref.csv', 'w') as f:
        for iobank, vref in params['INTERNAL_VREF'].items():
            f.write('{},{}\n'.format(iobank, vref))

    print(
        '''
`define N_DI {n_di}
`define N_DO {n_do}
`define N_DIO {n_dio}

module top(input wire [`N_DI-1:0] di, output wire [`N_DO-1:0] do, inout wire [`N_DIO-1:0] dio);
    '''.format(n_di=i_idx, n_do=o_idx, n_dio=io_idx))

    if any_idelay:
        print('''
        (* KEEP, DONT_TOUCH *)
        IDELAYCTRL();''')

    # Always output a LUT6 to make placer happy.
    print('''
        (* KEEP, DONT_TOUCH *)
        LUT6 dummy_lut();''')

    for p in params['tiles']:
        if p['type'] is None:
            continue
        elif p['type'] == 'IBUF':
            print(
                '''
        wire idelay_{site};

        (* KEEP, DONT_TOUCH *)
        IBUF #(
            .IBUF_LOW_PWR({IBUF_LOW_PWR}),
            .IOSTANDARD({IOSTANDARD})
        ) ibuf_{site} (
            .I({pad_wire}),
            .O({owire})
            );'''.format(**p),
                file=connects)
            if p['IDELAY_ONLY']:
                print(
                    """
        (* KEEP, DONT_TOUCH *)
        IDELAYE2 idelay_site_{site} (
            .IDATAIN(idelay_{site})
            );""".format(**p),
                    file=connects)

        elif p['type'] == 'IBUFDS':
            print(
                '''
        wire idelay_{site};

        (* KEEP, DONT_TOUCH *)
        IBUFDS #(
            .IBUF_LOW_PWR({IBUF_LOW_PWR}),
            .DIFF_TERM({DIFF_TERM}),
            .IOSTANDARD({IOSTANDARD})
        ) ibuf_{site} (
            .I({pad_wire}),
            .IB({bpad_wire}),
            .O({owire})
            );'''.format(**p),
                file=connects)
            if p['IDELAY_ONLY']:
                print(
                    """
        (* KEEP, DONT_TOUCH *)
        IDELAYE2 idelay_site_{site} (
            .IDATAIN(idelay_{site})
            );""".format(**p),
                    file=connects)

        elif p['type'] == 'OBUF':
            print(
                '''
        (* KEEP, DONT_TOUCH *)
        OBUF #(
            {DRIVE_STR}
            {SLEW_STR}
            .IOSTANDARD({IOSTANDARD})
        ) obuf_{site} (
            .O({pad_wire}),
            .I({iwire})
            );'''.format(**p),
                file=connects)
        elif p['type'] == 'OBUFDS':
            print(
                '''
        (* KEEP, DONT_TOUCH *)
        OBUFDS #(
            {DRIVE_STR}
            {SLEW_STR}
            .IOSTANDARD({IOSTANDARD})
        ) obufds_{site} (
            .O({pad_wire}),
            .OB({bpad_wire}),
            .I({iwire})
            );'''.format(**p),
                file=connects)
        elif p['type'] == 'OBUFTDS':
            print(
                '''
        (* KEEP, DONT_TOUCH *)
        OBUFTDS #(
            {DRIVE_STR}
            {SLEW_STR}
            .IOSTANDARD({IOSTANDARD})
        ) obufds_{site} (
            .O({pad_wire}),
            .OB({bpad_wire}),
            .T({tristate_wire}),
            .I({iwire})
            );'''.format(**p),
                file=connects)
        elif p['type'] == 'IOBUF_INTERMDISABLE':
            print(
                '''
        (* KEEP, DONT_TOUCH *)
        IOBUF_INTERMDISABLE #(
            {DRIVE_STR}
            {SLEW_STR}
            .IOSTANDARD({IOSTANDARD})
        ) ibuf_{site} (
            .IO({pad_wire}),
            .I({iwire}),
            .O({owire}),
            .T({tristate_wire}),
            .IBUFDISABLE({ibufdisable_wire}),
            .INTERMDISABLE({intermdisable_wire})
            );'''.format(**p),
                file=connects)

    for l in luts.create_wires_and_luts():
        print(l)

    print(connects.getvalue())

    print("endmodule")

    with open('params.json', 'w') as f:
        json.dump(params, f, indent=2)


if __name__ == '__main__':
    run()
