#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Copyright (C) 2017-2022  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():
    '''
    IOB18S: main IOB of a diff pair
    IOB18M: secondary IOB of a diff pair
    IOB18: not a diff pair. Relatively rare (at least in ROI...2 of them?)
    Focus on IOB18S 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)

        for site_name, site_type in gridinfo.sites.items():
            if site_type in ['IOB18S', 'IOB18M']:
                yield tile_name, site_name


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 use_oserdese2(p, luts, connects):

    p['oddr_mux_config'] = 'none'
    p['tddr_mux_config'] = 'none'

    p['DATA_RATE_OQ'] = verilog.quote(random.choice((
        'SDR',
        'DDR',
    )))

    p['DATA_RATE_TQ'] = verilog.quote(random.choice((
        'BUF',
        'SDR',
        'DDR',
    )))

    if verilog.unquote(p['DATA_RATE_OQ']) == 'SDR':
        data_widths = [2, 3, 4, 5, 6, 7, 8]
    else:
        data_widths = [4, 6, 8]

    p['DATA_WIDTH'] = random.choice(data_widths)

    if p['DATA_WIDTH'] == 4 and verilog.unquote(
            p['DATA_RATE_OQ']) == 'DDR' and verilog.unquote(
                p['DATA_RATE_TQ']) == 'DDR':
        tristate_width = 4
    else:
        tristate_width = 1
    p['SERDES_MODE'] = verilog.quote(random.choice(('MASTER', 'SLAVE')))

    p['TRISTATE_WIDTH'] = tristate_width
    p['OSERDES_MODE'] = verilog.quote(random.choice(('MASTER', 'SLAVE')))

    if p['io']:
        p['TFB'] = '.TFB(tfb_{site}),'.format(**p)
        p['TQ'] = '.TQ({twire}),'.format(**p)
        p['t1net'] = luts.get_next_output_net()
        p['t2net'] = luts.get_next_output_net()
        p['t3net'] = luts.get_next_output_net()
        p['t4net'] = luts.get_next_output_net()
        p['tcenet'] = luts.get_next_output_net()

        for idx in range(4):
            p['IS_T{}_INVERTED'.format(idx + 1)] = random.randint(0, 1)
    else:
        p['TFB'] = '.TFB(),'
        p['TQ'] = '.TQ(),'
        p['t1net'] = ''
        p['t2net'] = ''
        p['t3net'] = ''
        p['t4net'] = ''
        p['tcenet'] = ''

        for idx in range(4):
            p['IS_T{}_INVERTED'.format(idx + 1)] = 0

    p['SRVAL_OQ'] = random.randint(0, 1)
    p['SRVAL_TQ'] = random.randint(0, 1)
    p['INIT_OQ'] = random.randint(0, 1)
    p['INIT_TQ'] = random.randint(0, 1)

    for idx in range(8):
        p['IS_D{}_INVERTED'.format(idx + 1)] = random.randint(0, 1)

    p['IS_CLK_INVERTED'] = random.randint(0, 1)
    p['IS_CLKDIV_INVERTED'] = random.randint(0, 1)

    clk_connections = ''
    p['CLK_USED'] = random.randint(0, 1)
    p['CLKDIV_USED'] = random.randint(0, 1)
    if p['CLK_USED']:
        clk_connections += '''
        .CLK({}),'''.format(luts.get_next_output_net())
    if p['CLKDIV_USED']:
        clk_connections += '''
        .CLKDIV({}),'''.format(luts.get_next_output_net())

    print(
        '''
    (* KEEP, DONT_TOUCH, LOC = "{ologic_loc}" *)
    OSERDESE2 #(
        .SERDES_MODE({OSERDES_MODE}),
        .DATA_RATE_TQ({DATA_RATE_TQ}),
        .DATA_RATE_OQ({DATA_RATE_OQ}),
        .DATA_WIDTH({DATA_WIDTH}),
        .TRISTATE_WIDTH({TRISTATE_WIDTH}),
        .SRVAL_OQ({SRVAL_OQ}),
        .SRVAL_TQ({SRVAL_TQ}),
        .INIT_OQ({INIT_OQ}),
        .INIT_TQ({INIT_TQ}),
        .IS_T1_INVERTED({IS_T1_INVERTED}),
        .IS_T2_INVERTED({IS_T2_INVERTED}),
        .IS_T3_INVERTED({IS_T3_INVERTED}),
        .IS_T4_INVERTED({IS_T4_INVERTED}),
        .IS_D1_INVERTED({IS_D1_INVERTED}),
        .IS_D2_INVERTED({IS_D2_INVERTED}),
        .IS_D3_INVERTED({IS_D3_INVERTED}),
        .IS_D4_INVERTED({IS_D4_INVERTED}),
        .IS_D5_INVERTED({IS_D5_INVERTED}),
        .IS_D6_INVERTED({IS_D6_INVERTED}),
        .IS_D7_INVERTED({IS_D7_INVERTED}),
        .IS_D8_INVERTED({IS_D8_INVERTED}),
        .IS_CLK_INVERTED({IS_CLK_INVERTED}),
        .IS_CLKDIV_INVERTED({IS_CLKDIV_INVERTED})
    ) oserdese2_{site} (
        .OQ({owire}),
        {TFB}
        {TQ}
        {clk_connections}
        .D1({d1net}),
        .D2({d2net}),
        .D3({d3net}),
        .D4({d4net}),
        .D5({d5net}),
        .D6({d6net}),
        .D7({d7net}),
        .D8({d8net}),
        .OCE({ocenet}),
        .RST({rstnet}),
        .T1({t1net}),
        .T2({t2net}),
        .T3({t3net}),
        .T4({t4net}),
        .TCE({tcenet})
        );'''.format(
            clk_connections=clk_connections,
            rstnet=luts.get_next_output_net(),
            d1net=luts.get_next_output_net(),
            d2net=luts.get_next_output_net(),
            d3net=luts.get_next_output_net(),
            d4net=luts.get_next_output_net(),
            d5net=luts.get_next_output_net(),
            d6net=luts.get_next_output_net(),
            d7net=luts.get_next_output_net(),
            d8net=luts.get_next_output_net(),
            ocenet=luts.get_next_output_net(),
            ofb_wire=luts.get_next_input_net(),
            **p),
        file=connects)


def use_direct_and_oddr(p, luts, connects):
    p['oddr_mux_config'] = random.choice((
        'direct',
        'lut',
        'none',
    ))

    if p['io']:
        if p['oddr_mux_config'] != 'lut':
            p['tddr_mux_config'] = random.choice((
                'direct',
                'lut',
                'none',
            ))
        else:
            p['tddr_mux_config'] = random.choice((
                'lut',
                'none',
            ))
    else:
        p['tddr_mux_config'] = 'none'

    # toddr and oddr share the same clk
    if random.randint(0, 1):
        clknet = luts.get_next_output_net()
        p['IS_CLK_INVERTED'] = 0
    else:
        clknet = 'bufg_o'
        p['IS_CLK_INVERTED'] = random.randint(0, 1)

    if p['tddr_mux_config'] == 'direct':
        p['TINIT'] = random.randint(0, 1)
        p['TSRTYPE'] = verilog.quote(random.choice(('SYNC', 'ASYNC')))
        p['TDDR_CLK_EDGE'] = verilog.quote('OPPOSITE_EDGE')

        # Note: it seems that CLK_EDGE setting is ignored for TDDR
        p['TDDR_CLK_EDGE'] = verilog.quote(
            random.choice(('OPPOSITE_EDGE', 'SAME_EDGE')))

        p['t_sr_used'] = random.choice(('None', 'S', 'R'))
        if p['t_sr_used'] == 'None':
            p['t_srnet'] = ''
        elif p['t_sr_used'] == 'S':
            p['srnet'] = luts.get_next_output_net()
            p['t_srnet'] = '.S({}),\n'.format(p['srnet'])
        elif p['t_sr_used'] == 'R':
            p['srnet'] = luts.get_next_output_net()
            p['t_srnet'] = '.R({}),\n'.format(p['srnet'])

        print(
            '''
    (* KEEP, DONT_TOUCH, LOC = "{ologic_loc}" *)
    ODDR #(
        .INIT({TINIT}),
        .SRTYPE({TSRTYPE}),
        .DDR_CLK_EDGE({TDDR_CLK_EDGE}),
        .IS_C_INVERTED({IS_CLK_INVERTED})
    ) toddr_{site} (
        .C({cnet}),
        .D1({d1net}),
        .D2({d2net}),
        .CE({cenet}),
        {t_srnet}
        .Q(tddr_d_{site})
        );
        '''.format(
                cnet=clknet,
                d1net=luts.get_next_output_net(),
                d2net=luts.get_next_output_net(),
                cenet=luts.get_next_output_net(),
                **p),
            file=connects)

    if p['tddr_mux_config'] == 'direct':
        print(
            '''
    assign {twire} = tddr_d_{site};'''.format(**p, ),
            file=connects)
    elif p['tddr_mux_config'] == 'lut':
        print(
            '''
    assign {twire} = {lut};'''.format(lut=luts.get_next_output_net(), **p),
            file=connects)
        pass
    elif p['tddr_mux_config'] == 'none':
        pass
    else:
        assert False, p['tddr_mux_config']

    if p['oddr_mux_config'] == 'direct':
        p['QINIT'] = random.randint(0, 1)
        p['SRTYPE'] = verilog.quote(random.choice(('SYNC', 'ASYNC')))
        p['ODDR_CLK_EDGE'] = verilog.quote(
            random.choice((
                'OPPOSITE_EDGE',
                'SAME_EDGE',
            )))

        p['o_sr_used'] = random.choice(('None', 'S', 'R'))
        if p['o_sr_used'] == 'None':
            p['o_srnet'] = ''
        elif p['o_sr_used'] == 'S':
            if 'srnet' not in p:
                p['srnet'] = luts.get_next_output_net()
            p['o_srnet'] = '.S({}),\n'.format(p['srnet'])
        elif p['o_sr_used'] == 'R':
            if 'srnet' not in p:
                p['srnet'] = luts.get_next_output_net()
            p['o_srnet'] = '.R({}),\n'.format(p['srnet'])

        print(
            '''
    (* KEEP, DONT_TOUCH, LOC = "{ologic_loc}" *)
    ODDR #(
        .INIT({QINIT}),
        .SRTYPE({SRTYPE}),
        .DDR_CLK_EDGE({ODDR_CLK_EDGE}),
        .IS_C_INVERTED({IS_CLK_INVERTED})
    ) oddr_{site} (
        .C({cnet}),
        .D1({d1net}),
        .D2({d2net}),
        .CE({cenet}),
        {o_srnet}
        .Q(oddr_d_{site})
        );
        '''.format(
                cnet=clknet,
                d1net=luts.get_next_output_net(),
                d2net=luts.get_next_output_net(),
                cenet=luts.get_next_output_net(),
                **p),
            file=connects)

    if p['oddr_mux_config'] == 'direct':
        print(
            '''
    assign {owire} = oddr_d_{site};'''.format(**p, ),
            file=connects)
    elif p['oddr_mux_config'] == 'lut':
        print(
            '''
    assign {owire} = {lut};'''.format(lut=luts.get_next_output_net(), **p),
            file=connects)
        pass
    elif p['oddr_mux_config'] == 'none':
        pass
    else:
        assert False, p['oddr_mux_config']


def run():
    iostandards = [
        'LVCMOS12', 'LVCMOS15', 'LVCMOS18'
    ]
    iostandard = random.choice(iostandards)

    if iostandard in ['LVCMOS12']:
        drives = [2, 4, 6, 8]
    elif iostandard in ['LVCMOS15', 'LVCMOS18']:
        drives = [2, 4, 6, 8, 12, 16]
    else:
        assert False, "This should be unreachable"

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

    luts = lut_maker.LutMaker()

    connects = io.StringIO()

    tile_params = []
    params = []

    ndio = 0
    ndo = 0
    for idx, (tile, site) in enumerate(gen_sites()):
        if idx == 0:
            continue

        p = {}
        p['tile'] = tile
        p['site'] = site
        p['ilogic_loc'] = site.replace('IOB', 'ILOGIC')
        p['ologic_loc'] = site.replace('IOB', 'OLOGIC')
        p['IOSTANDARD'] = verilog.quote(iostandard)
        p['PULLTYPE'] = verilog.quote(random.choice(pulls))
        p['DRIVE'] = random.choice(drives)
        p['SLEW'] = verilog.quote(random.choice(slews))

        p['io'] = random.randint(0, 1)
        p['owire'] = 'do_buf[{}]'.format(idx - 1)

        if p['io']:
            p['pad_wire'] = 'dio[{}]'.format(ndio)
            ndio += 1

            p['iwire'] = 'di_buf[{}]'.format(idx - 1)
            p['twire'] = 't[{}]'.format(idx - 1)
        else:
            p['pad_wire'] = 'do[{}]'.format(ndo)
            ndo += 1

        params.append(p)
        tile_params.append(
            (
                tile, site, p['pad_wire'], iostandard, p['DRIVE'],
                verilog.unquote(p['SLEW']) if p['SLEW'] else None,
                verilog.unquote(p['PULLTYPE'])))

    write_params(tile_params)

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

module top(input clk, output wire [`N_DO-1:0] do, inout wire [`N_DIO-1:0] dio);
    wire [(`N_DIO+`N_DO)-1:0] di_buf;
    wire [(`N_DIO+`N_DO)-1:0] do_buf;
    wire [(`N_DIO+`N_DO)-1:0] t;
    '''.format(n_dio=ndio, n_do=ndo))

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

        wire bufg_o;
        (* KEEP, DONT_TOUCH *)
        BUFG (.O(bufg_o));
        ''')

    for p in params:
        if p['io']:
            print(
                '''
        wire oddr_d_{site};

        (* KEEP, DONT_TOUCH, LOC = "{site}" *)
        IOBUF #(
            .IOSTANDARD({IOSTANDARD})
        ) obuf_{site} (
            .IO({pad_wire}),
            .I({owire}),
            .O({iwire}),
            .T({twire})
            );
            '''.format(**p),
                file=connects)
        else:
            print(
                '''
        wire oddr_d_{site};

        (* KEEP, DONT_TOUCH, LOC = "{site}" *)
        OBUF #(
            .IOSTANDARD({IOSTANDARD})
        ) obuf_{site} (
            .O({pad_wire}),
            .I({owire})
            );
            '''.format(**p),
                file=connects)

        p['use_oserdese2'] = random.randint(0, 1)
        if p['use_oserdese2']:
            use_oserdese2(p, luts, connects)
        else:
            use_direct_and_oddr(p, luts, connects)

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

    print(connects.getvalue())

    print("endmodule")

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


if __name__ == '__main__':
    run()
