#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Copyright (C) 2020  The SymbiFlow 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

"""
Generate MUX.

MUXes come in two types,
 1) Configurable via logic signals,
 2) Statically configured by PnR (called "routing") muxes.
"""

import argparse
import itertools
import lxml.etree as ET
import os
import sys

from .lib import mux as mux_lib
from .lib.argparse_extra import ActionStoreBool
from .lib.asserts import assert_eq

parser = argparse.ArgumentParser(
    description='Generate a MUX wrapper.',
    fromfile_prefix_chars='@',
    prefix_chars='-~'
)

parser.add_argument(
    '--verbose',
    '--no-verbose',
    action=ActionStoreBool,
    default=os.environ.get('V', '') == '1',
    help="Print lots of information about the generation."
)

parser.add_argument('--width', type=int, default=8, help="Width of the MUX.")

parser.add_argument(
    '--data-width', type=int, default=1, help="data width of the MUX."
)

parser.add_argument(
    '--type',
    choices=['logic', 'routing'],
    default='logic',
    help="Type of MUX."
)

parser.add_argument(
    '--split-inputs',
    action=ActionStoreBool,
    default=False,
    help="Split the inputs into separate signals"
)

parser.add_argument(
    '--split-selects',
    action=ActionStoreBool,
    default=False,
    help="Split the selects into separate signals"
)

parser.add_argument(
    '--name-mux', type=str, default='MUX', help="Name of the mux."
)

parser.add_argument(
    '--name-input',
    type=str,
    default='I',
    help="Name of the input values for the mux."
)

parser.name_inputs = parser.add_argument(
    '--name-inputs',
    type=str,
    default=None,
    help=  # noqa: E251
    "Comma deliminator list for the name of each input to the mux " + \
    "(implies --split-inputs)."
)

parser.add_argument(
    '--name-output',
    type=str,
    default='O',
    help="Name of the output value for the mux."
)

parser.add_argument(
    '--name-select',
    type=str,
    default='S',
    help="Name of the select parameter for the mux."
)

parser.name_selects = parser.add_argument(
    '--name-selects',
    type=str,
    default=None,
    help=  # noqa: E251
    "Comma deliminator list for the name of each select to the mux " +
    "(implies --split-selects)."
)

parser.add_argument(
    '--order',
    choices=[''.join(x) for x in itertools.permutations('ios')] +
    [''.join(x) for x in itertools.permutations('io')],
    default='iso',
    help=  # noqa: E251
    """Order of the arguments for the MUX.
(i - Inputs, o - Output, s - Select)"""
)

parser.add_argument(
    '--outdir',
    default=None,
    help="""Directory to output generated content too."""
)

parser.add_argument(
    '--outfilename',
    default=None,
    help="""Filename to output generated content too."""
)

parser.add_argument(
    '--comment', default=None, help="""Add some type of comment to the mux."""
)

parser.add_argument(
    '--num_pb', default=1, help="""Set the num_pb for the mux."""
)

parser.add_argument(
    '--subckt', default=None, help="""Override the subcircuit name."""
)


def mux_gen(argv='Python function',
            width=8,
            data_width=1,
            datatype='logic',
            split_inputs=False,
            split_selects=False,
            name_mux='MUX',
            name_input='I',
            name_inputs=None,
            name_output='O',
            name_select='S',
            name_selects=None,
            order='iso',
            outdir=None,
            outfilename=None,
            comment=None,
            num_pb=1,
            subckt=None,
            verbose=False
            ):
    def output_block(name, s):
        if verbose:
            print()
            print(name, '-' * (75 - (len(name) + 1)))
            print(s, end="")
            if s[-1] != '\n':
                print()
            print('-' * 75)

    width_bits = mux_lib.clog2(width)

    def normpath(p, to=None):
        p = os.path.realpath(os.path.abspath(p))
        if to is None:
            return p
        return os.path.relpath(p, normpath(to))

    mypath = normpath(__file__)

    if not outdir:
        outdir = os.path.join(".", name_mux.lower())

    outdir = normpath(outdir)

    mydir = normpath(os.path.dirname(mypath), to=outdir)
    mux_dir = normpath(os.path.join(mydir, '..', 'vpr', 'muxes'), to=outdir)

    if data_width > 1 and not split_inputs:
        assert False, "data_width(%d) > 1 requires using split_inputs" % (
            data_width
        )

    name_input_default = 'I'
    name_inputs_default = None
    name_select_default = 'S'
    name_selects_default = None

    if name_inputs:
        assert_eq(name_input, name_input_default)
        name_input = None
        split_inputs = True

        names = name_inputs.split(',')
        assert len(names) == width, "%s input names, but %s needed." % (
            names, width
        )
        name_inputs = names
    elif split_inputs:
        name_inputs = [
            name_input + str(i) for i in range(width)
        ]
        name_inputs_default = name_inputs
        assert_eq(name_inputs_default, name_inputs)

    if name_selects:
        assert_eq(name_select, name_select_default)
        name_select = None
        split_selects = True

        names = name_selects.split(',')
        assert len(names) == width_bits, (
            "%s select names, but %s needed." % (names, width_bits)
        )
        name_selects = names
    elif split_selects:
        name_selects = [
            name_select + str(i) for i in range(width_bits)
        ]
        name_selects.default = name_selects
        assert_eq(name_selects_default, name_selects)

    os.makedirs(outdir, exist_ok=True)

    # Generated headers
    generated_with = """
Generated with %s
""" % mypath

    # XML Files can't have "--" in them, so instead we use ~~
    xml_comment = """
Generated with %s
""" % "\n".join(argv).replace('--', '~~')

    if not outfilename:
        outfilename = name_mux.lower()

    model_xml_filename = '%s.model.xml' % outfilename
    pbtype_xml_filename = '%s.pb_type.xml' % outfilename
    sim_filename = '%s.sim.v' % outfilename

    # ------------------------------------------------------------------------
    # Work out the port and their names
    # ------------------------------------------------------------------------

    port_names = []
    for i in order:
        if i == 'i':
            if split_inputs:
                port_names.extend(
                    mux_lib.ModulePort(
                        mux_lib.MuxPinType.INPUT, name_inputs[j], 1,
                        '[%i]' % j, data_width
                    ) for j in range(width)
                )
            else:
                # verilog range bounds are inclusive and convention is
                # [<width-1>:0]
                port_names.append(
                    mux_lib.ModulePort(
                        mux_lib.MuxPinType.INPUT, name_input, width,
                        '[%i:0]' % (width - 1)
                    )
                )
        elif i == 's':
            if split_selects:
                port_names.extend(
                    mux_lib.ModulePort(
                        mux_lib.MuxPinType.SELECT, name_selects[j], 1,
                        '[%i]' % j
                    ) for j in range(width_bits)
                )
            else:
                # verilog range bounds are inclusive and convention is
                # [<width-1>:0]
                assert name_select is not None
                port_names.append(
                    mux_lib.ModulePort(
                        mux_lib.MuxPinType.SELECT, name_select,
                        width_bits, '[%i:0]' % (width_bits - 1)
                    )
                )
        elif i == 'o':
            port_names.append(
                mux_lib.ModulePort(
                    mux_lib.MuxPinType.OUTPUT, name_output, 1, '',
                    data_width
                )
            )

    # ------------------------------------------------------------------------
    # Generate the techmap Verilog module
    # ------------------------------------------------------------------------
    techmap_filename = '%s.techmap.v' % outfilename
    techmap_pathname = os.path.join(outdir, techmap_filename)
    if datatype == 'routing':
        with open(techmap_pathname, "w") as f:
            module_args = []
            for port in port_names:
                if (datatype == 'routing' and
                        port.pin_type == mux_lib.MuxPinType.SELECT):
                    continue
                module_args.append(port.name)

            f.write("/* ")
            f.write("\n * ".join(generated_with.splitlines()))
            f.write("\n */\n\n")

            f.write(
                "module %s(%s);\n" %
                (name_mux.upper(), ", ".join(module_args))
            )
            f.write('\tparameter MODE = "";\n')

            modes = [
                port.name
                for port in port_names
                if port.pin_type in (mux_lib.MuxPinType.INPUT, )
            ]

            outputs = [
                port.name
                for port in port_names
                if port.pin_type in (mux_lib.MuxPinType.OUTPUT, )
            ]
            for port in port_names:
                if port.pin_type != mux_lib.MuxPinType.SELECT:
                    f.write(port.getDefinition())

            f.write('\tgenerate\n')
            for i, mode in enumerate(modes):
                f.write(
                    '\t\t%s ( MODE == "%s" )\n' %
                    (('if', 'else if')[i > 0], mode)
                )
                f.write('\t\tbegin\n')
                f.write('\t\t\tassign %s = %s;\n' % (outputs[0], mode))
                f.write('\t\tend\n')
            f.write('\t\telse\n')
            f.write('\t\tbegin\n')
            f.write('\t\t\twire _TECHMAP_FAIL_ = 1;\n')
            f.write('\t\tend\n')
            f.write("\tendgenerate\n")
            f.write("endmodule")

    # ------------------------------------------------------------------------
    # Generate the sim.v Verilog module
    # ------------------------------------------------------------------------
    sim_pathname = os.path.join(outdir, sim_filename)
    with open(sim_pathname, "w") as f:
        module_args = []
        for port in port_names:
            if (datatype == 'routing' and
                    port.pin_type == mux_lib.MuxPinType.SELECT):
                continue
            module_args.append(port.name)

        mux_class = {'logic': 'mux', 'routing': 'routing'}[datatype]

        f.write("/* ")
        f.write("\n * ".join(generated_with.splitlines()))
        f.write("\n */\n\n")
        f.write("`default_nettype none\n")
        f.write("\n")

        if datatype != 'routing':
            f.write(
                '`include "%s/%s/%smux%i/%smux%i.sim.v"\n' % (
                    mux_dir,
                    'logic',
                    '',
                    width,
                    '',
                    width,
                )
            )
        f.write("\n")
        f.write('(* CLASS="%s" *)\n' % mux_class)

        if datatype == 'routing':
            modes = [
                port.name
                for port in port_names
                if port.pin_type in (mux_lib.MuxPinType.INPUT, )
            ]
            outputs = [
                port.name
                for port in port_names
                if port.pin_type in (mux_lib.MuxPinType.OUTPUT, )
            ]
            assert len(
                outputs
            ) == 1, "FIXME: routing muxes should only have 1 output."
            f.write('(* MODES="%s" *)\n' % "; ".join(modes))

        f.write('(* whitebox *)\n')
        f.write(
            "module %s(%s);\n" %
            (name_mux.upper(), ", ".join(module_args))
        )
        previous_type = None
        for port in port_names:
            if previous_type != port.pin_type:
                f.write("\n")
                previous_type = port.pin_type
            if (datatype == 'routing' and
                    port.pin_type == mux_lib.MuxPinType.SELECT):
                f.write('\tparameter MODE = "";\n')
            else:
                f.write(port.getDefinition())

        f.write("\n")
        if data_width > 1:
            f.write('\tgenvar\tii;\n')
            f.write(
                '\tfor(ii=0; ii<%d; ii++) begin: bitmux\n' % (data_width)
            )

        if datatype == 'logic':
            f.write('\tMUX%s mux (\n' % width)
            for i in range(0, width):
                j = 0
                for port in port_names:
                    if port.pin_type != mux_lib.MuxPinType.INPUT:
                        continue
                    if j + port.width <= i:
                        j += port.width
                        continue
                    break

                if port.width == 1:
                    if data_width > 1:
                        f.write('\t\t.I%i(%s[ii]),\n' % (i, port.name))
                    else:
                        f.write('\t\t.I%i(%s),\n' % (i, port.name))
                else:
                    f.write('\t\t.I%i(%s[%i]),\n' % (i, port.name, i - j))

            for i in range(0, width_bits):
                j = 0
                for port in port_names:
                    if port.pin_type != mux_lib.MuxPinType.SELECT:
                        continue
                    if j + port.width < i:
                        j += port.width
                        continue
                    break

                if port.width == 1:
                    f.write('\t\t.S%i(%s),\n' % (i, port.name))
                else:
                    f.write('\t\t.S%i(%s[%i]),\n' % (i, port.name, i - j))

            for port in port_names:
                if port.pin_type != mux_lib.MuxPinType.OUTPUT:
                    continue
                break
            assert_eq(port.width, 1)
            if data_width > 1:
                f.write('\t\t.O(%s[ii])\n\t);\n' % port.name)
            else:
                f.write('\t\t.O(%s)\n\t);\n' % port.name)

        elif datatype == 'routing':
            f.write('\tgenerate\n')
            for i, mode in enumerate(modes):
                f.write(
                    '\t\t%s ( MODE == "%s" )\n' %
                    (('if', 'else if')[i > 0], mode)
                )
                f.write('\t\tbegin:SELECT_%s\n' % mode)
                f.write('\t\t\tassign %s = %s;\n' % (outputs[0], mode))
                f.write('\t\tend\n')
            f.write('\t\telse\n')
            f.write('\t\tbegin\n')
            f.write(
                ('\t\t\t//$error("%s: Invalid routing value %%s ' +
                    '(options are: %s)", MODE);\n')
                % (name_mux, ", ".join(modes))
            )
            f.write('\t\tend\n')
            f.write('\tendgenerate\n')

        if data_width > 1:
            f.write('end\n')

        f.write('endmodule\n')

    output_block(sim_filename, open(sim_pathname).read())

    if datatype == 'logic':
        subckt = subckt or name_mux
        assert subckt
    elif datatype == 'routing':
        assert subckt is None
        subckt = None

    # ------------------------------------------------------------------------
    # Generate the Model XML form.
    # ------------------------------------------------------------------------
    def xml_comment_indent(n, s):
        return ("\n" + " " * n).join(s.splitlines() + [""])

    if datatype == 'logic':
        models_xml = ET.Element('models')
        models_xml.append(ET.Comment(xml_comment_indent(4, xml_comment)))

        model_xml = ET.SubElement(models_xml, 'model', {'name': subckt})

        input_ports = ET.SubElement(model_xml, 'input_ports')
        output_ports = ET.SubElement(model_xml, 'output_ports')
        for port in port_names:
            if port.pin_type in (mux_lib.MuxPinType.INPUT,
                                 mux_lib.MuxPinType.SELECT):
                ET.SubElement(
                    input_ports, 'port', {
                        'name':
                            port.name,
                        'combinational_sink_ports':
                            ' '.join(
                                port.name for port in port_names if
                                port.pin_type in (mux_lib.MuxPinType.OUTPUT, )
                            ),
                    }
                )
            elif port.pin_type in (mux_lib.MuxPinType.OUTPUT, ):
                ET.SubElement(output_ports, 'port', {'name': port.name})

        models_str = ET.tostring(models_xml, pretty_print=True).decode('utf-8')
    else:
        models_str = "<models><!-- No models for routing elements.--></models>"

    output_block(model_xml_filename, models_str)
    with open(os.path.join(outdir, model_xml_filename), "w") as f:
        f.write(models_str)

    # ------------------------------------------------------------------------
    # Generate the pb_type XML form.
    # ------------------------------------------------------------------------

    pb_type_xml = mux_lib.pb_type_xml(
        mux_lib.MuxType[datatype.upper()],
        name_mux,
        port_names,
        subckt=subckt,
        num_pb=num_pb,
        comment=xml_comment_indent(4, xml_comment),
    )

    pb_type_str = ET.tostring(pb_type_xml, pretty_print=True).decode('utf-8')
    output_block(pbtype_xml_filename, pb_type_str)
    with open(os.path.join(outdir, pbtype_xml_filename), "w") as f:
        f.write(pb_type_str)

    print("Generated mux {} in {}".format(name_mux, outdir))


def main(argv):
    args = parser.parse_args()

    mux_gen(argv=argv,
            width=args.width,
            data_width=args.data_width,
            datatype=args.type,
            split_inputs=args.split_inputs,
            split_selects=args.split_selects,
            name_mux=args.name_mux,
            name_input=args.name_input,
            name_inputs=args.name_inputs,
            name_output=args.name_output,
            name_select=args.name_select,
            name_selects=args.name_selects,
            order=args.order,
            outdir=args.outdir,
            outfilename=args.outfilename,
            comment=args.comment,
            num_pb=args.num_pb,
            subckt=args.subckt,
            verbose=args.verbose,
            )


if __name__ == "__main__":
    sys.exit(main(sys.argv))
