# 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.ip_block import IpBlock
from reggen.inter_signal import InterSignal
from reggen.validate import check_int
from topgen import lib

IM_TYPES = ['uni', 'req_rsp', 'io']
IM_ACTS = ['req', 'rsp', 'rcv', 'none']
IM_VALID_TYPEACT = {'uni': ['req', 'rcv'], 'req_rsp': ['req', 'rsp'], 'io': ['none']}
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) -> Tuple[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, IpBlock],
                     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']

        if is_host:
            add_intermodule_connection(obj=topcfg,
                                       req_m=xbar["name"],
                                       req_s="tl_" + esc_name,
                                       rsp_m=port_base,
                                       rsp_s=sig_name)
        else:
            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, IpBlock]):
    """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 _get_default_name(sig, suffix):
    """Generate default for a net if one does not already exist.
    """

    # The else case covers the scenario where neither package nor default is provided.
    # Specifically, the interface is 'logic' and has no default value.
    # In this situation, just return 0's
    if sig['default']:
        return sig['default']
    elif sig['package']:
        return "{}::{}_DEFAULT".format(sig['package'], (sig["struct"] + suffix).upper())
    else:
        return "'0"


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["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)
            req_default = _get_default_name(req_struct, req_suffix)
            rsp_default = _get_default_name(req_struct, rsp_suffix)

            # based on the active direction of the req_struct, one of the directions does not
            # need a default since it will be an output
            if (req_struct["act"] == 'req'):
                req_default = ''
            else:
                rsp_default = ''

            # 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_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', rsp_default)]))
        else:
            # unidirection
            default = _get_default_name(req_struct, "")
            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', 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)]))
        elif sig["type"] == "io":
            sigsuffix = "_io"
            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', "inout"),
                             ('conn_type', conn_type),
                             ('index', index),
                             ('netname', netname)]))
        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"] = ""

    if "package" not in sig:
        sig["package"] = ""

    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 = {
        ('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 no package was declared, it is declared with an empty string
            if not rsp_struct["package"]:
                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


def get_direction(sig):
    if sig["direction"] == "in":
        return "input "
    elif sig["direction"] == "out":
        return "output"
    elif sig["direction"] == "inout":
        return "inout "


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

    e.g. flash_ctrl::flash_req_t
    """
    if obj["type"] == "io":
        # io type, don't declare anything
        return ""

    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())
            # default is used for dangling ports in definitions.
            # the struct name already has `_req` suffix
            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", "io"]

    # io types have no role
    if suffix == "io":
        suffix_s = ""
    else:
        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",
            ("none", "io"): "_io"
        }
        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"
    elif suffix == "io":
        suffix_s = "_io"
    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
