# Copyright lowRISC contributors.
# Licensed under the Apache License, Version 2.0, see LICENSE for details.
# SPDX-License-Identifier: Apache-2.0

import logging as log
import re
from collections import OrderedDict
from enum import Enum
from typing import Dict, List, Tuple

from reggen.block import Block
from reggen.inter_signal import InterSignal
from reggen.validate import check_int
from topgen import lib

IM_TYPES = ['uni', 'req_rsp']
IM_ACTS = ['req', 'rsp', 'rcv']
IM_VALID_TYPEACT = {'uni': ['req', 'rcv'], 'req_rsp': ['req', 'rsp']}
IM_CONN_TYPE = ['1-to-1', '1-to-N', 'broadcast']


class ImType(Enum):
    Uni = 1
    ReqRsp = 2


class ImAct(Enum):
    Req = 1
    Rsp = 2
    Rcv = 3


class ImConn(Enum):
    OneToOne = 1  # req <-> {rsp,rcv} with same width
    OneToN = 2  # req width N <-> N x {rsp,rcv}s width 1
    Broadcast = 3  # req width 1 <-> N x rcvs width 1


def intersignal_format(req: Dict) -> str:
    """Determine the signal format of the inter-module connections

    @param[req] Request struct. It has instance name, package format
                and etc.
    """

    # TODO: Handle array signal
    result = "{req}_{struct}".format(req=req["inst_name"], struct=req["name"])

    # check signal length if exceeds 100

    # 7 : space + .
    # 3 : _{i|o}(
    # 6 : _{req|rsp}),
    req_length = 7 + len(req["name"]) + 3 + len(result) + 6

    if req_length > 100:
        logmsg = "signal {0} length cannot be greater than 100"
        log.warning(logmsg.format(result))
        log.warning("Please consider shorten the instance name")
    return result


def get_suffixes(ims: OrderedDict) -> (str, str):
    """Get suffixes of the struct.

    TL-UL struct uses `h2d`, `d2h` suffixes for req, rsp pair.
    """
    if ims["package"] == "tlul_pkg" and ims["struct"] == "tl":
        return ("_h2d", "_d2h")

    return ("_req", "_rsp")


def add_intermodule_connection(obj: OrderedDict, req_m: str, req_s: str,
                               rsp_m: str, rsp_s: str):
    """Add if doesn't exist the connection

    Add a connection into obj['inter_module']['connect'] dictionary if doesn't exist.

    Parameters:
        obj:   Top dictionary object
        req_m: Requester module name
        req_s: Requester signal name
        rsp_m: Responder module name
        rsp_s: Responder signal name

    Returns:
        No return type for this function
    """
    req_key = "{}.{}".format(req_m, req_s)
    rsp_key = "{}.{}".format(rsp_m, rsp_s)

    connect = obj["inter_module"]["connect"]
    if req_key in connect:
        # check if rsp has data
        if rsp_key in connect[req_key]:
            return
        req_key.append(rsp_key)
        return

    # req_key is not in connect:
    # check if rsp_key
    if rsp_key in connect:
        # check if rsp has data
        if req_key in connect[rsp_key]:
            return
        rsp_key.append(req_key)
        return

    # Add new key and connect
    connect[req_key] = [rsp_key]


def autoconnect_xbar(topcfg: OrderedDict,
                     name_to_block: Dict[str, Block],
                     xbar: OrderedDict) -> None:
    # The crossbar is connecting to modules and memories in topcfg, plus
    # possible external connections. Make indices for the modules and memories
    # for quick lookup and add some assertions to make sure no name appears in
    # multiple places.
    name_to_module = {}
    for mod in topcfg['module']:
        assert mod['name'] not in name_to_module
        if lib.is_inst(mod):
            name_to_module[mod['name']] = mod

    name_to_memory = {}
    for mem in topcfg['memory']:
        assert mem['name'] not in name_to_memory
        if lib.is_inst(mem):
            name_to_memory[mem['name']] = mem

    # The names of modules and memories should be disjoint
    assert not (set(name_to_module.keys()) & set(name_to_memory.keys()))

    external_names = (set(topcfg['inter_module']['top']) |
                      set(topcfg["inter_module"]["external"].keys()))

    ports = [x for x in xbar["nodes"] if x["type"] in ["host", "device"]]
    for port in ports:
        # Here, we expect port_name to either be a single identifier (in which
        # case, it's taken as the name of some module or memory) to be a dotted
        # pair MOD.INAME where MOD is the name of some module and INAME is the
        # associated interface name.
        name_parts = port['name'].split('.', 1)
        port_base = name_parts[0]
        port_iname = name_parts[1] if len(name_parts) > 1 else None
        esc_name = port['name'].replace('.', '__')

        if port["xbar"]:
            if port_iname is not None:
                log.error('A crossbar connection may not '
                          'have a target of the form MOD.INAME (saw {!r})'
                          .format(port['name']))
                continue

            if port["type"] == "host":
                # Skip as device will add connection
                continue

            # Device port adds signal
            add_intermodule_connection(obj=topcfg,
                                       req_m=xbar["name"],
                                       req_s="tl_" + esc_name,
                                       rsp_m=esc_name,
                                       rsp_s="tl_" + xbar["name"])
            continue  # xbar port case

        port_mod = name_to_module.get(port_base)
        port_mem = name_to_memory.get(port_base)
        assert port_mod is None or port_mem is None

        if not (port_mod or port_mem):
            # if not in module, memory, should be existed in top or ext field
            module_key = "{}.tl_{}".format(xbar["name"], esc_name)
            if module_key not in external_names:
                log.error("Inter-module key {} cannot be found in module, "
                          "memory, top, or external lists.".format(module_key))

            continue

        if port_iname is not None and port_mem is not None:
            log.error('Cannot make connection for {!r}: the base of the name '
                      'points to a memory but memories do not support '
                      'interface names.'
                      .format(port['name']))

        is_host = port['type'] == 'host'

        # If the hit is a module, it originally came from reggen (via
        # merge.py's amend_ip() function). In this case, we should have a
        # BusInterfaces object as well as a list of InterSignal objects.
        #
        # If not, this is a memory that will just have a dictionary of inter
        # signals.
        if port_mod is not None:
            block = name_to_block[port_mod['type']]
            try:
                sig_name = block.bus_interfaces.find_port_name(is_host,
                                                               port_iname)
            except KeyError:
                log.error('Cannot make {} connection for {!r}: the base of '
                          'the target module has no matching bus interface.'
                          .format('host' if is_host else 'device',
                                  port['name']))
                continue
        else:
            inter_signal_list = port_mem['inter_signal_list']
            act = 'req' if is_host else 'rsp'
            matches = [
                x for x in inter_signal_list
                if (x.get('package') == 'tlul_pkg' and
                    x['struct'] == 'tl' and
                    x['act'] == act)
            ]
            if not matches:
                log.error('Cannot make {} connection for {!r}: the memory '
                          'has no signal with an action of {}.'
                          .format('host' if is_host else 'device',
                                  port['name'],
                                  act))
                continue

            assert len(matches) == 1
            sig_name = matches[0]['name']

        add_intermodule_connection(obj=topcfg,
                                   req_m=port_base,
                                   req_s=sig_name,
                                   rsp_m=xbar["name"],
                                   rsp_s="tl_" + esc_name)


def autoconnect(topcfg: OrderedDict, name_to_block: Dict[str, Block]):
    """Matching the connection based on the naming rule
    between {memory, module} <-> Xbar.
    """

    # Add xbar connection to the modules, memories
    for xbar in topcfg["xbar"]:
        autoconnect_xbar(topcfg, name_to_block, xbar)


def elab_intermodule(topcfg: OrderedDict):
    """Check the connection of inter-module and categorize them

    In the top template, it uses updated inter_module fields to create
    connections between the modules (incl. memories). This function is to
    create and check the validity of the connections `inter_module` using IPs'
    `inter_signal_list`.
    """

    list_of_intersignals = []

    if "inter_signal" not in topcfg:
        topcfg["inter_signal"] = OrderedDict()

    # Gather the inter_signal_list
    instances = topcfg["module"] + topcfg["memory"] + topcfg["xbar"] + \
        topcfg["host"] + topcfg["port"]

    for x in instances:
        old_isl = x.get('inter_signal_list')
        if old_isl is None:
            continue

        new_isl = []
        for entry in old_isl:
            # Convert any InterSignal objects to the expected dictionary format.
            sig = (entry.as_dict()
                   if isinstance(entry, InterSignal)
                   else entry.copy())

            # Add instance name to the entry and add to list_of_intersignals
            sig["inst_name"] = x["name"]
            list_of_intersignals.append(sig)
            new_isl.append(sig)

        x['inter_signal_list'] = new_isl

    # Add field to the topcfg
    topcfg["inter_signal"]["signals"] = list_of_intersignals

    # TODO: Cross check Can be done here not in validate as ipobj is not
    # available in validate
    error = check_intermodule(topcfg, "Inter-module Check")
    assert error == 0, "Inter-module validation is failed cannot move forward."

    # intermodule
    definitions = []

    # Check the originator
    # As inter-module connection allow only 1:1, 1:N, or N:1, pick the most
    # common signals. If a requester connects to multiple responders/receivers,
    # the requester is main connector so that the definition becomes array.
    #
    # For example:
    #  inter_module: {
    #    'connect': {
    #      'pwr_mgr.pwrup': ['lc.pwrup', 'otp.pwrup']
    #    }
    #  }
    # The tool adds `struct [1:0] pwr_mgr_pwrup`
    # It doesn't matter whether `pwr_mgr.pwrup` is requester or responder.
    # If the key is responder type, then the connection is made in reverse,
    # such that `lc.pwrup --> pwr_mgr.pwrup[0]` and
    # `otp.pwrup --> pwr_mgr.pwrup[1]`

    uid = 0  # Unique connection ID across the top

    for req, rsps in topcfg["inter_module"]["connect"].items():
        log.info("{req} --> {rsps}".format(req=req, rsps=rsps))

        # Split index
        req_module, req_signal, req_index = filter_index(req)

        # get the module signal
        req_struct = find_intermodule_signal(list_of_intersignals, req_module,
                                             req_signal)

        # decide signal format based on the `key`
        sig_name = intersignal_format(req_struct)
        req_struct["top_signame"] = sig_name

        # Find package in req, rsps
        if "package" in req_struct:
            package = req_struct["package"]
        else:
            for rsp in rsps:
                rsp_module, rsp_signal, rsp_index = filter_index(rsp)
                rsp_struct = find_intermodule_signal(list_of_intersignals,
                                                     rsp_module, rsp_signal)
                if "package" in rsp_struct:
                    package = rsp_struct["package"]
                    break
            if not package:
                package = ""

        # Add to definition
        if req_struct["type"] == "req_rsp":
            req_suffix, rsp_suffix = get_suffixes(req_struct)
            # Add two definitions
            definitions.append(
                OrderedDict([('package', package),
                             ('struct', req_struct["struct"] + req_suffix),
                             ('signame', sig_name + "_req"),
                             ('width', req_struct["width"]),
                             ('type', req_struct["type"]),
                             ('end_idx', req_struct["end_idx"]),
                             ('act', req_struct["act"]),
                             ('suffix', "req"),
                             ('default', req_struct["default"])]))
            definitions.append(
                OrderedDict([('package', package),
                             ('struct', req_struct["struct"] + rsp_suffix),
                             ('signame', sig_name + "_rsp"),
                             ('width', req_struct["width"]),
                             ('type', req_struct["type"]),
                             ('end_idx', req_struct["end_idx"]),
                             ('act', req_struct["act"]),
                             ('suffix', "rsp"),
                             ('default', req_struct["default"])]))
        else:
            # unidirection
            definitions.append(
                OrderedDict([('package', package),
                             ('struct', req_struct["struct"]),
                             ('signame', sig_name),
                             ('width', req_struct["width"]),
                             ('type', req_struct["type"]),
                             ('end_idx', req_struct["end_idx"]),
                             ('act', req_struct["act"]),
                             ('suffix', ""),
                             ('default', req_struct["default"])]))

        req_struct["index"] = -1

        for i, rsp in enumerate(rsps):
            # Split index
            rsp_module, rsp_signal, rsp_index = filter_index(rsp)

            rsp_struct = find_intermodule_signal(list_of_intersignals,
                                                 rsp_module, rsp_signal)

            # determine the signal name

            rsp_struct["top_signame"] = sig_name
            if req_struct["type"] == "uni" and req_struct[
                    "top_type"] == "broadcast":
                rsp_struct["index"] = -1
            elif rsp_struct["width"] == req_struct["width"] and len(rsps) == 1:
                rsp_struct["index"] = -1
            else:
                rsp_struct["index"] = -1 if req_struct["width"] == 1 else i

            # Assume it is logic
            # req_rsp doesn't allow logic
            if req_struct["struct"] == "logic":
                assert req_struct[
                    "type"] != "req_rsp", "logic signal cannot have req_rsp type"

            # increase Unique ID
            uid += 1

    # TODO: Check unconnected port
    if "top" not in topcfg["inter_module"]:
        topcfg["inter_module"]["top"] = []

    for s in topcfg["inter_module"]["top"]:
        sig_m, sig_s, sig_i = filter_index(s)
        assert sig_i == -1, 'top net connection should not use bit index'
        sig = find_intermodule_signal(list_of_intersignals, sig_m, sig_s)
        sig_name = intersignal_format(sig)
        sig["top_signame"] = sig_name
        if "index" not in sig:
            sig["index"] = -1

        if sig["type"] == "req_rsp":
            req_suffix, rsp_suffix = get_suffixes(sig)
            # Add two definitions
            definitions.append(
                OrderedDict([('package', sig["package"]),
                             ('struct', sig["struct"] + req_suffix),
                             ('signame', sig_name + "_req"),
                             ('width', sig["width"]), ('type', sig["type"]),
                             ('end_idx', -1),
                             ('default', sig["default"])]))
            definitions.append(
                OrderedDict([('package', sig["package"]),
                             ('struct', sig["struct"] + rsp_suffix),
                             ('signame', sig_name + "_rsp"),
                             ('width', sig["width"]), ('type', sig["type"]),
                             ('end_idx', -1),
                             ('default', sig["default"])]))
        else:  # if sig["type"] == "uni":
            definitions.append(
                OrderedDict([('package', sig["package"]),
                             ('struct', sig["struct"]), ('signame', sig_name),
                             ('width', sig["width"]), ('type', sig["type"]),
                             ('end_idx', -1),
                             ('default', sig["default"])]))

    topcfg["inter_module"].setdefault('external', [])
    topcfg["inter_signal"].setdefault('external', [])

    for s, port in topcfg["inter_module"]["external"].items():
        sig_m, sig_s, sig_i = filter_index(s)
        assert sig_i == -1, 'top net connection should not use bit index'
        sig = find_intermodule_signal(list_of_intersignals, sig_m, sig_s)

        # To make netname `_o` or `_i`
        sig['external'] = True

        sig_name = port if port != "" else intersignal_format(sig)

        # if top signame already defined, then a previous connection category
        # is already connected to external pin.  Sig name is only used for
        # port definition
        conn_type = False
        if "top_signame" not in sig:
            sig["top_signame"] = sig_name
        else:
            conn_type = True

        if "index" not in sig:
            sig["index"] = -1

        # Add the port definition to top external ports
        index = sig["index"]
        netname = sig["top_signame"]
        if sig["type"] == "req_rsp":
            req_suffix, rsp_suffix = get_suffixes(sig)
            if sig["act"] == "req":
                req_sigsuffix, rsp_sigsuffix = ("_o", "_i")

            else:
                req_sigsuffix, rsp_sigsuffix = ("_i", "_o")

            topcfg["inter_signal"]["external"].append(
                OrderedDict([('package', sig["package"]),
                             ('struct', sig["struct"] + req_suffix),
                             ('signame', sig_name + "_req" + req_sigsuffix),
                             ('width', sig["width"]), ('type', sig["type"]),
                             ('default', sig["default"]),
                             ('direction',
                              'out' if sig['act'] == "req" else 'in'),
                             ('conn_type', conn_type),
                             ('index', index),
                             ('netname', netname + req_suffix)]))
            topcfg["inter_signal"]["external"].append(
                OrderedDict([('package', sig["package"]),
                             ('struct', sig["struct"] + rsp_suffix),
                             ('signame', sig_name + "_rsp" + rsp_sigsuffix),
                             ('width', sig["width"]), ('type', sig["type"]),
                             ('default', sig["default"]),
                             ('direction',
                              'in' if sig['act'] == "req" else 'out'),
                             ('conn_type', conn_type),
                             ('index', index),
                             ('netname', netname + rsp_suffix)]))
        else:  # uni
            if sig["act"] == "req":
                sigsuffix = "_o"
            else:
                sigsuffix = "_i"
            topcfg["inter_signal"]["external"].append(
                OrderedDict([('package', sig.get("package", "")),
                             ('struct', sig["struct"]),
                             ('signame', sig_name + sigsuffix),
                             ('width', sig["width"]), ('type', sig["type"]),
                             ('default', sig["default"]),
                             ('direction',
                              'out' if sig['act'] == "req" else 'in'),
                             ('conn_type', conn_type),
                             ('index', index),
                             ('netname', netname)]))

    for sig in topcfg["inter_signal"]["signals"]:
        # Check if it exist in definitions
        if "top_signame" in sig:
            continue

        # Set index to -1
        sig["index"] = -1

        # TODO: Handle the unconnected port rule

    if "definitions" not in topcfg["inter_signal"]:
        topcfg["inter_signal"]["definitions"] = definitions


def filter_index(signame: str) -> Tuple[str, str, int]:
    """If the signal has array indicator `[N]` then split and return name and
    array index. If not, array index is -1.

    param signame module.sig{[N]}

    result (module_name, signal_name, array_index)
    """
    m = re.match(r'(\w+)\.(\w+)(\[(\d+)\])*', signame)

    if not m:
        # Cannot match the pattern
        return "", "", -1

    if m.group(3):
        # array index is not None
        return m.group(1), m.group(2), m.group(4)

    return m.group(1), m.group(2), -1


def find_intermodule_signal(sig_list, m_name, s_name) -> Dict:
    """Return the intermodule signal structure
    """

    filtered = [
        x for x in sig_list if x["name"] == s_name and x["inst_name"] == m_name
    ]

    if len(filtered) == 1:
        return filtered[0]

    log.error("Found {num} entry/entries for {m_name}.{s_name}:".format(
        num=len(filtered), m_name=m_name, s_name=s_name))
    return None


# Validation
def check_intermodule_field(sig: OrderedDict,
                            prefix: str = "") -> Tuple[int, OrderedDict]:
    error = 0

    # type check
    if sig["type"] not in IM_TYPES:
        log.error("{prefix} Inter_signal {name} "
                  "type {type} is incorrect.".format(prefix=prefix,
                                                     name=sig["name"],
                                                     type=sig["type"]))
        error += 1

    if sig["act"] not in IM_ACTS:
        log.error("{prefix} Inter_signal {name} "
                  "act {act} is incorrect.".format(prefix=prefix,
                                                   name=sig["name"],
                                                   act=sig["act"]))
        error += 1

    # Check if type and act are matched
    if error == 0:
        if sig["act"] not in IM_VALID_TYPEACT[sig['type']]:
            log.error("{type} and {act} of {name} are not a valid pair."
                      "".format(type=sig['type'],
                                act=sig['act'],
                                name=sig['name']))
            error += 1
    # Check 'width' field
    width = 1
    if "width" not in sig:
        sig["width"] = 1
    elif not isinstance(sig["width"], int):
        width, err = check_int(sig["width"], sig["name"])
        if err:
            log.error("{prefix} Inter-module {inst}.{sig} 'width' "
                      "should be int type.".format(prefix=prefix,
                                                   inst=sig["inst_name"],
                                                   sig=sig["name"]))
            error += 1
        else:
            # convert to int value
            sig["width"] = width

    # Add empty string if no explicit default for dangling pins is given.
    # In that case, dangling pins of type struct will be tied to the default
    # parameter in the corresponding package, and dangling pins of type logic
    # will be tied off to '0.
    if "default" not in sig:
        sig["default"] = ""

    return error, sig


def find_otherside_modules(topcfg: OrderedDict, m,
                           s) -> List[Tuple[str, str, str]]:
    """Find far-end port based on given module and signal name
    """
    # TODO: handle special cases
    special_inst_names = {
        ('main', 'tl_rom'): ('tl_adapter_rom', 'tl'),
        ('main', 'tl_ram_main'): ('tl_adapter_ram_main', 'tl'),
        ('main', 'tl_eflash'): ('tl_adapter_eflash', 'tl'),
        ('peri', 'tl_ram_ret_aon'): ('tl_adapter_ram_ret_aon', 'tl'),
        ('main', 'tl_corei'): ('rv_core_ibex', 'tl_i'),
        ('main', 'tl_cored'): ('rv_core_ibex', 'tl_d'),
        ('main', 'tl_dm_sba'): ('dm_top', 'tl_h'),
        ('main', 'tl_debug_mem'): ('dm_top', 'tl_d'),
        ('peri', 'tl_ast'): ('ast', 'tl')
    }
    special_result = special_inst_names.get((m, s))
    if special_result is not None:
        return [('top', special_result[0], special_result[1])]

    signame = "{}.{}".format(m, s)
    for req, rsps in topcfg["inter_module"]["connect"].items():
        if req.startswith(signame):
            # return rsps after splitting module instance name and the port
            result = []
            for rsp in rsps:
                rsp_m, rsp_s, rsp_i = filter_index(rsp)
                result.append(('connect', rsp_m, rsp_s))
            return result

        for rsp in rsps:
            if signame == rsp:
                req_m, req_s, req_i = filter_index(req)
                return [('connect', req_m, req_s)]

    # if reaches here, it means either the format is wrong, or floating port.
    log.error("`find_otherside_modules()`: "
              "No such signal {}.{} exists.".format(m, s))
    return []


def check_intermodule(topcfg: Dict, prefix: str) -> int:
    if "inter_module" not in topcfg:
        return 0

    total_error = 0

    for req, rsps in topcfg["inter_module"]["connect"].items():
        error = 0
        # checking the key, value are in correct format
        # Allowed format
        #   1. module.signal
        #   2. module.signal[index] // Remember array is not yet supported
        #                           // But allow in format checker
        #
        # Example:
        #   inter_module: {
        #     'connect': {
        #       'flash_ctrl.flash': ['eflash.flash_ctrl'],
        #       'life_cycle.provision': ['debug_tap.dbg_en', 'dft_ctrl.en'],
        #       'otp.pwr_hold': ['pwrmgr.peri[0]'],
        #       'flash_ctrl.pwr_hold': ['pwrmgr.peri[1]'],
        #     }
        #   }
        #
        # If length of value list is > 1, then key should be array (width need to match)
        # If key is format #2, then length of value list shall be 1
        # If one of the value is format #2, then the key should be 1 bit width and
        # entries of value list should be 1
        req_m, req_s, req_i = filter_index(req)

        if req_s == "":
            log.error(
                "Cannot parse the inter-module signal key '{req}'".format(
                    req=req))
            error += 1

        # Check rsps signal format is list
        if not isinstance(rsps, list):
            log.error("Value of key '{req}' should be a list".format(req=req))
            error += 1
            continue

        req_struct = find_intermodule_signal(topcfg["inter_signal"]["signals"],
                                             req_m, req_s)

        err, req_struct = check_intermodule_field(req_struct)
        error += err

        if req_i != -1 and len(rsps) != 1:
            # Array format should have one entry
            log.error(
                "If key {req} has index, only one entry is allowed.".format(
                    req=req))
            error += 1

        total_width = 0
        widths = []

        # Check rsp format
        for i, rsp in enumerate(rsps):
            rsp_m, rsp_s, rsp_i = filter_index(rsp)
            if rsp_s == "":
                log.error(
                    "Cannot parse the inter-module signal key '{req}->{rsp}'".
                    format(req=req, rsp=rsp))
                error += 1

            rsp_struct = find_intermodule_signal(
                topcfg["inter_signal"]["signals"], rsp_m, rsp_s)

            err, rsp_struct = check_intermodule_field(rsp_struct)
            error += err

            total_width += rsp_struct["width"]
            widths.append(rsp_struct["width"])

            # Type check
            if "package" not in rsp_struct:
                rsp_struct["package"] = req_struct.get("package", "")
            elif req_struct["package"] != rsp_struct["package"]:
                log.error(
                    "Inter-module package should be matched: "
                    "{req}->{rsp} exp({expected}), actual({actual})".format(
                        req=req_struct["name"],
                        rsp=rsp_struct["name"],
                        expected=req_struct["package"],
                        actual=rsp_struct["package"]))
                error += 1
            if req_struct["type"] != rsp_struct["type"]:
                log.error(
                    "Inter-module type should be matched: "
                    "{req}->{rsp} exp({expected}), actual({actual})".format(
                        req=req_struct["name"],
                        rsp=rsp_struct["name"],
                        expected=req_struct["type"],
                        actual=rsp_struct["type"]))
                error += 1

            # If len(rsps) is 1, then the width should be matched to req
            if req_struct["width"] != 1:
                if rsp_struct["width"] not in [1, req_struct["width"]]:
                    log.error(
                        "If req {req} is an array, "
                        "rsp {rsp} shall be non-array or array with same width"
                        .format(req=req, rsp=rsp))
                    error += 1

                elif rsp_i != -1:
                    # If rsp has index, req should be width 1
                    log.error(
                        "If rsp {rsp} has an array index, only one-to-one map is allowed."
                        .format(rsp=rsp))
                    error += 1

        # Determine if broadcast or one-to-N
        log.debug("Handling inter-sig {} {}".format(req_struct['name'], total_width))
        req_struct["end_idx"] = -1
        if req_struct["width"] > 1 or len(rsps) != 1:
            # If req width is same to the every width of rsps ==> broadcast
            if len(rsps) * [req_struct["width"]] == widths:
                log.debug("broadcast type")
                req_struct["top_type"] = "broadcast"

            # If req width is same as total width of rsps ==> one-to-N
            elif req_struct["width"] == total_width:
                log.debug("one-to-N type")
                req_struct["top_type"] = "one-to-N"

            # one-to-N connection is not fully populated
            elif req_struct["width"] > total_width:
                log.debug("partial one-to-N type")
                req_struct["top_type"] = "partial-one-to-N"
                req_struct["end_idx"] = len(rsps)

            # If not, error
            else:
                log.error("'uni' type connection {req} should be either "
                          "OneToN or Broadcast".format(req=req))
                error += 1

        elif req_struct["type"] == "uni":
            # one-to-one connection
            req_struct["top_type"] = "broadcast"

        # If req is array, it is not allowed to have partial connections.
        # Doing for loop again here: Make code separate from other checker
        # for easier maintenance
        total_error += error

        if error != 0:
            # Skip the check
            continue

    for item in topcfg["inter_module"]["top"] + list(
            topcfg["inter_module"]["external"].keys()):
        sig_m, sig_s, sig_i = filter_index(item)
        if sig_i != -1:
            log.error("{item} cannot have index".format(item=item))
            total_error += 1

        sig_struct = find_intermodule_signal(topcfg["inter_signal"]["signals"],
                                             sig_m, sig_s)
        err, sig_struct = check_intermodule_field(sig_struct)
        total_error += err

    return total_error


# Template functions
def im_defname(obj: OrderedDict) -> str:
    """return definition struct name

    e.g. flash_ctrl::flash_req_t
    """
    if obj["package"] == "":
        # should be logic
        return "logic"

    return "{package}::{struct}_t".format(package=obj["package"],
                                          struct=obj["struct"])


def im_netname(sig: OrderedDict,
               suffix: str = "", default_name=False) -> str:
    """return top signal name with index

    It also adds suffix for external signal.

    The default name input forces function to return default name, even if object
    has a connection.
    """

    # Basic check and add missing fields
    err, obj = check_intermodule_field(sig)
    assert not err

    # Floating signals
    # TODO: Find smarter way to assign default?
    if "top_signame" not in obj or default_name:
        if obj["act"] == "req" and suffix == "req":
            return ""
        if obj["act"] == "rsp" and suffix == "rsp":
            return ""
        if obj["act"] == "req" and suffix == "rsp":
            # custom default has been specified
            if obj["default"]:
                return obj["default"]
            if obj["package"] == "tlul_pkg" and obj["struct"] == "tl":
                return "{package}::{struct}_D2H_DEFAULT".format(
                    package=obj["package"], struct=obj["struct"].upper())
            return "{package}::{struct}_RSP_DEFAULT".format(
                package=obj["package"], struct=obj["struct"].upper())
        if obj["act"] == "rsp" and suffix == "req":
            # custom default has been specified
            if obj["default"]:
                return obj["default"]
            if obj.get("package") == "tlul_pkg" and obj["struct"] == "tl":
                return "{package}::{struct}_H2D_DEFAULT".format(
                    package=obj["package"], struct=obj["struct"].upper())
            return "{package}::{struct}_REQ_DEFAULT".format(
                package=obj.get("package", ''), struct=obj["struct"].upper())
        if obj["act"] == "rcv" and suffix == "" and obj["struct"] == "logic":
            # custom default has been specified
            if obj["default"]:
                return obj["default"]
            return "'0"
        if obj["act"] == "rcv" and suffix == "":
            # custom default has been specified
            if obj["default"]:
                return obj["default"]
            return "{package}::{struct}_DEFAULT".format(
                package=obj["package"], struct=obj["struct"].upper())

        return ""

    # Connected signals
    assert suffix in ["", "req", "rsp"]

    suffix_s = "_{suffix}".format(suffix=suffix) if suffix != "" else suffix

    # External signal handling
    if "external" in obj and obj["external"]:
        pairs = {
            # act , suffix: additional suffix
            ("req", "req"): "_o",
            ("req", "rsp"): "_i",
            ("rsp", "req"): "_i",
            ("rsp", "rsp"): "_o",
            ("req", ""): "_o",
            ("rcv", ""): "_i"
        }
        suffix_s += pairs[(obj['act'], suffix)]

    return "{top_signame}{suffix}{index}".format(
        top_signame=obj["top_signame"],
        suffix=suffix_s,
        index=lib.index(obj["index"]))


def im_portname(obj: OrderedDict, suffix: str = "") -> str:
    """return IP's port name

    e.g signame_o for requester req signal
    """
    act = obj['act']
    name = obj['name']

    if suffix == "":
        suffix_s = "_o" if act == "req" else "_i"
    elif suffix == "req":
        suffix_s = "_o" if act == "req" else "_i"
    else:
        suffix_s = "_o" if act == "rsp" else "_i"

    return name + suffix_s


def get_dangling_im_def(objs: OrderedDict) -> str:
    """return partial inter-module definitions

    Dangling intermodule connections happen when a one-to-N assignment
    is not fully populated.

    This can result in two types of dangling:
    - outgoing requests not used
    - incoming responses not driven

    The determination of which category we fall into follows similar rules
    as those used by im_netname.

    When the direction of the net is the same as the active direction of the
    the connecting module, it is "unused".

    When the direction of the net is opposite of the active direction of the
    the connecting module, it is "undriven".

    As an example, edn is defined as "rsp" of a "req_rsp" pair. It is also used
    as the "active" module in inter-module connection. If there are not enough
    connecting modules, the 'req' line is undriven, while the 'rsp' line is
    unused.

    """
    unused_def = [obj for obj in objs if obj['end_idx'] > 0 and
                  obj['act'] == obj['suffix']]

    undriven_def = [obj for obj in objs if obj['end_idx'] > 0 and
                    (obj['act'] == 'req' and obj['suffix'] == 'rsp' or
                     obj['act'] == 'rsp' and obj['suffix'] == 'req')]

    return unused_def, undriven_def
