#!/usr/bin/env python3
"""
Convert a Verilog simulation model to a VPR `model.xml`

The following Verilog attributes are considered on ports:
    - `(* CLOCK *)` : force a given port to be a clock

    - `(* ASSOC_CLOCK="RDCLK" *)` : force a port's associated clock to a given value

The following Verilog attributes are considered on modules:
    - `(* MODEL_NAME="model" *)` : override the name used for <model> and for
    ".subckt name" in the BLIF model. Mostly intended for use with w.py, when several
    different pb_types implement the same model.

    - `(* CLASS="lut|routing|mux|flipflop|mem" *)` : specify the class of an given
    instance. A model will not be generated for the `lut`, `routing` or `flipflop`
    class.
"""
import argparse
import os
import re
import sys

import lxml.etree as ET

import yosys.run
from yosys.json import YosysJSON

from lib import xmlinc


def is_clock_assoc(infiles, module, clk, port, direction):
    """Checks if a specific port is associated with a clk clock

    Returns a boolean value
    -------
    is_clock_assoc: bool
    """
    clock_assoc_signals = yosys.run.get_clock_assoc_signals(
        infiles, module, clk
    )

    if direction == "input":
        assoc_outputs = yosys.run.get_related_output_for_input(
            infiles, module, port
        )
        for out in assoc_outputs:
            if out in clock_assoc_signals:
                return True
    elif direction == "output":
        if port in clock_assoc_signals:
            return True
    else:
        assert False, "Bidirectional ports are not supported yet"

    return False


def is_registered_path(tmod, pin, pout):
    """Checks if a i/o path is sequential. If that is the case
    no combinational_sink_port is needed

    Returns a boolean value
    """

    for cell, ctype in tmod.all_cells:
        if ctype != "$dff":
            continue

        if tmod.port_conns(pin) == tmod.cell_conn_list(
                cell, "D") and tmod.port_conns(pout) == tmod.cell_conn_list(
                    cell, "Q"):
            return True

    return False


parser = argparse.ArgumentParser(description=__doc__.strip())
parser.add_argument(
    'infiles',
    metavar='input.v',
    type=str,
    nargs='+',
    help="""\
One or more Verilog input files, that will be passed to Yosys internally.
They should be enough to generate a flattened representation of the model,
so that paths through the model can be determined.
"""
)
parser.add_argument(
    '--top',
    help="""\
Top level module, will usually be automatically determined from the file name
%.sim.v
"""
)
parser.add_argument(
    '--includes',
    help="""\
Comma separate list of include directories.
""",
    default=""
)
parser.add_argument('-o', help="""\
Output filename, default 'model.xml'
""")

args = parser.parse_args()
iname = os.path.basename(args.infiles[0])

outfile = "model.xml"
if "o" in args and args.o is not None:
    outfile = args.o

if args.includes:
    for include in args.includes.split(','):
        yosys.run.add_include(include)

aig_json = yosys.run.vlog_to_json(args.infiles, flatten=True, aig=True)

top = None
if args.top is not None:
    top = args.top.upper()
else:
    yj = YosysJSON(aig_json)
    if yj.top is not None:
        top = yj.top
    else:
        wm = re.match(r"([A-Za-z0-9_]+)\.sim\.v", iname)
        if wm:
            top = wm.group(1).upper()
        else:
            print(
                """\
ERROR file name not of format %.sim.v ({}), cannot detect top level.
Manually specify the top level module using --top"""
            ).format(iname)
            sys.exit(1)

assert top is not None
yj = YosysJSON(aig_json, top)
if top is None:
    print(
        """\
ERROR: more than one module in design, cannot detect top level.
Manually specify the top level module using --top"""
    )
    sys.exit(1)

tmod = yj.top_module
models_xml = ET.Element("models", nsmap={'xi': xmlinc.xi_url})

inc_re = re.compile(r'^\s*`include\s+"([^"]+)"')

deps_files = set()
# XML dependencies need to correspond 1:1 with Verilog includes, so we have
# to do this manually rather than using Yosys
with open(args.infiles[0], 'r') as f:
    for line in f:
        im = inc_re.match(line)
        if not im:
            continue
        deps_files.add(im.group(1))

if len(deps_files) > 0:
    # Has dependencies, not a leaf model
    for df in sorted(deps_files):
        abs_base = os.path.dirname(os.path.abspath(args.infiles[0]))
        abs_dep = os.path.normpath(os.path.join(abs_base, df))
        module_path = os.path.dirname(abs_dep)
        module_basename = os.path.basename(abs_dep)
        wm = re.match(r"([A-Za-z0-9_]+)\.sim\.v", module_basename)
        if wm:
            model_path = "{}/{}.model.xml".format(
                module_path,
                wm.group(1).lower()
            )
        else:
            assert False, "included Verilog file name {} does not follow pattern %%.sim.v".format(
                module_basename
            )
        xmlinc.include_xml(
            parent=models_xml,
            href=model_path,
            outfile=outfile,
            xptr="xpointer(models/child::node())"
        )
else:
    # Is a leaf model
    topname = tmod.attr("MODEL_NAME", top)
    assert topname == topname.upper(
    ), "Leaf model names should be all uppercase!"
    modclass = tmod.attr("CLASS", "")

    if modclass not in ("lut", "routing", "flipflop"):
        model_xml = ET.SubElement(
            models_xml, "model", {'name': topname}
        )
        ports = tmod.ports

        inports_xml = ET.SubElement(model_xml, "input_ports")
        outports_xml = ET.SubElement(model_xml, "output_ports")

        clocks = yosys.run.list_clocks(args.infiles, top)

        for name, width, bits, iodir in ports:
            attrs = dict(name=name)
            sinks = yosys.run.get_combinational_sinks(args.infiles, top, name)

            # Removes comb sinks if path from in to out goes through a dff
            for sink in sinks:
                if is_registered_path(tmod, name, sink):
                    sinks.remove(sink)

            # FIXME: Check if ignoring clock for "combination_sink_ports" is a
            # valid thing to do.
            if name in clocks or "clk" in name.lower():
                attrs["is_clock"] = "1"
            else:
                clks = list()
                if len(sinks) > 0 and iodir == "input":
                    attrs["combinational_sink_ports"] = " ".join(sinks)
                for clk in clocks:
                    if is_clock_assoc(args.infiles, top, clk, name, iodir):
                        clks.append(clk)
                    if clks:
                        attrs["clock"] = " ".join(clks)
            if iodir == "input":
                ET.SubElement(inports_xml, "port", attrs)
            elif iodir == "output":
                ET.SubElement(outports_xml, "port", attrs)
            else:
                assert False, "bidirectional ports not permitted in VPR models"

if len(models_xml) == 0:
    models_xml.insert(0, ET.Comment("this file is intentionally left blank"))

f = open(outfile, 'w')
f.write(ET.tostring(models_xml, pretty_print=True).decode('utf-8'))
f.close()
print("Generated {} from {}".format(outfile, iname))
