# 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, Union

from reggen.validate import check_int
from reggen.inter_signal import InterSignal
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, xbar: OrderedDict):
    ports = [x for x in xbar["nodes"] if x["type"] in ["host", "device"]]
    for port in ports:
        if port["xbar"]:
            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_%s" % port["name"],
                                       rsp_m=port["name"],
                                       rsp_s="tl_%s" % xbar["name"])
            continue  # xbar port case

        # check if name exists in ["module", "memory"]
        ips = [
            x for x in topcfg["module"] + topcfg["memory"]
            if x["name"] == port["name"] and lib.is_inst(x)
        ]

        assert len(ips) <= 1

        if len(ips) == 0:
            # if not in module, memory, should be existed in top or ext field
            module_key = "{}.tl_{}".format(xbar["name"], port["name"])
            if module_key not in topcfg["inter_module"]["top"] + list(
                    topcfg["inter_module"]["external"].keys()):
                log.error("Inter-module key {} cannot be found in module, "
                          "memory, top, or external lists.".format(module_key))
            continue

        ip = ips[0]

        # Depending on whether ip came from reggen or topgen, it might be an
        # InterSignal object or it might be a dict. Extract the fields we need
        # so that the code below can treat it as a dict.
        isl = ip['inter_signal_list']
        if not isl or isinstance(isl[0], InterSignal):
            inter_signal_list = [signal.as_dict() for signal in isl]
        else:
            inter_signal_list = isl

        # get the port name
        def get_signame(act: str) -> OrderedDict:
            ims = [
                x for x in inter_signal_list
                if (x.get('package') == 'tlul_pkg' and
                    x['struct'] == 'tl' and
                    x['act'] == act)
            ]
            return ims

        if port["type"] == "device":
            ims = get_signame("rsp")
        else:  # host type
            ims = get_signame("req")

        assert len(ims) == 1
        sig_name = ims[0]["name"]

        add_intermodule_connection(obj=topcfg,
                                   req_m=port["name"],
                                   req_s=sig_name,
                                   rsp_m=xbar["name"],
                                   rsp_s="tl_%s" % port["name"])
        continue  # len() == 1


def autoconnect(topcfg: OrderedDict):
    """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, 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"]

    intermodule_instances = [x for x in instances if "inter_signal_list" in x]

    # Collect up all intermodule signals, operating in place on each of the
    # instances and converting back from an InterSignal object to a dict if
    # necessary.
    for x in intermodule_instances:
        new_isl = []
        for sig in x["inter_signal_list"]:
            if isinstance(sig, InterSignal):
                sig_dict = sig.as_dict()
            else:
                sig_dict = sig

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

        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
        if "top_signame" not in sig:
            sig["top_signame"] = sig_name

        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'),
                             ('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'),
                             ('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'),
                             ('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(obj: Union[InterSignal, OrderedDict],
                            prefix: str = "") -> Tuple[int, OrderedDict]:
    error = 0

    if isinstance(obj, InterSignal):
        sig = obj.as_dict()
    else:
        sig = obj

    # 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')
    }
    for pair in special_inst_names:
        if pair == (m, s):
            result = special_inst_names.get(pair)
            return [('top', result[0], 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: Union[InterSignal, 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: InterSignal, suffix: str = "") -> str:
    """return IP's port name

    e.g signame_o for requester req signal
    """
    if suffix == "":
        suffix_s = "_o" if obj['act'] == "req" else "_i"
    elif suffix == "req":
        suffix_s = "_o" if obj['act'] == "req" else "_i"
    else:
        suffix_s = "_o" if obj['act'] == "rsp" else "_i"

    return "{signame}{suffix}".format(signame=obj['name'], suffix=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
