# Copyright lowRISC contributors.
# Licensed under the Apache License, Version 2.0, see LICENSE for details.
# SPDX-License-Identifier: Apache-2.0
import re
import logging as log
from collections import OrderedDict
from enum import Enum
from typing import Dict, List

from reggen.validate import check_keys
from reggen.ip_block import IpBlock

# For the reference
# val_types = {
#     'd': ["int", "integer (binary 0b, octal 0o, decimal, hex 0x)"],
#     'x': ["xint", "x for undefined otherwise int"],
#     'b': [
#         "bitrange", "bit number as decimal integer, \
#                     or bit-range as decimal integers msb:lsb"
#     ],
#     'l': ["list", "comma separated list enclosed in `[]`"],
#     'ln': ["name list", 'comma separated list enclosed in `[]` of '\
#            'one or more groups that have just name and dscr keys.'\
#            ' e.g. `{ name: "name", desc: "description"}`'],
#     'lnw': ["name list+", 'name list that optionally contains a width'],
#     'lp': ["parameter list", 'parameter list having default value optionally'],
#     'g': ["group", "comma separated group of key:value enclosed in `{}`"],
#     's': ["string", "string, typically short"],
#     't': ["text", "string, may be multi-line enclosed in `'''` "\
#           "may use `**bold**`, `*italic*` or `!!Reg` markup"],
#     'T': ["tuple", "tuple enclosed in ()"],
#     'pi': ["python int", "Native Python type int (generated)"],
#     'pb': ["python Bool", "Native Python type Bool (generated)"],
#     'pl': ["python list", "Native Python type list (generated)"],
#     'pe': ["python enum", "Native Python type enum (generated)"]
# }

# Required/optional field in top hjson
top_required = {
    'name': ['s', 'Top name'],
    'type': ['s', 'type of hjson. Shall be "top" always'],
    'clocks': ['g', 'group of clock properties'],
    'resets': ['l', 'list of resets'],
    'module': ['l', 'list of modules to instantiate'],
    'memory': ['l', 'list of memories. At least one memory '
                    'is needed to run the software'],
    'xbar': ['l', 'List of the xbar used in the top'],
    'rnd_cnst_seed': ['int', "Seed for random netlist constant computation"],
    'pinout': ['g', 'Pinout configuration'],
    'targets': ['l', ' Target configurations'],
    'pinmux': ['g', 'pinmux configuration'],
}

top_optional = {
    'alert_async': ['l', 'async alerts (generated)'],
    'alert': ['lnw', 'alerts (generated)'],
    'alert_module': [
        'l',
        'list of the modules that connects to alert_handler'
    ],
    'datawidth': ['pn', "default data width"],
    'exported_clks': ['g', 'clock signal routing rules'],
    'host': ['g', 'list of host-only components in the system'],
    'inter_module': ['g', 'define the signal connections between the modules'],
    'interrupt': ['lnw', 'interrupts (generated)'],
    'interrupt_module': ['l', 'list of the modules that connects to rv_plic'],
    'num_cores': ['pn', "number of computing units"],
    'power': ['g', 'power domains supported by the design'],
    'port': ['g', 'assign special attributes to specific ports']
}

top_added = {}

pinmux_required = {}
pinmux_optional = {
    'num_wkup_detect': [
        'd', 'Number of wakeup detectors'
    ],
    'wkup_cnt_width': [
        'd', 'Number of bits in wakeup detector counters'
    ],
    'signals': ['l', 'List of Dedicated IOs.'],
}
pinmux_added = {
    'ios': ['l', 'Full list of IO'],
}

pinmux_sig_required = {
    'instance': ['s', 'Module instance name'],
    'connection': ['s', 'Specification of connection type, '
                        'can be direct, manual or muxed'],
}
pinmux_sig_optional = {
    'port': ['s', 'Port name of module'],
    'pad': ['s', 'Pad name for direct connections'],
    'desc': ['s', 'Signal description'],
    'attr': ['s', 'Pad type for generating the correct attribute CSR']
}
pinmux_sig_added = {}

pinout_required = {
    'banks': ['l', 'List of IO power banks'],
    'pads': ['l', 'List of pads']
}
pinout_optional = {
}
pinout_added = {}

pad_required = {
    'name': ['l', 'Pad name'],
    'type': ['s', 'Pad type'],
    'bank': ['s', 'IO power bank for the pad'],
    'connection': ['s', 'Specification of connection type, '
                        'can be direct, manual or muxed'],
}
pad_optional = {
    'desc': ['s', 'Pad description'],
}
pad_added = {}

target_required = {
    'name': ['s', 'Name of target'],
    'pinout': ['g', 'Target-specific pinout configuration'],
    'pinmux': ['g', 'Target-specific pinmux configuration']
}
target_optional = {
}
target_added = {}

target_pinmux_required = {
    'special_signals': ['l', 'List of special signals and the pad they are mapped to.'],
}
target_pinmux_optional = {}
target_pinmux_added = {}

target_pinout_required = {
    'remove_ports': ['l', 'List of port names to remove from the port list'],
    'remove_pads': ['l', 'List of pad names to remove and stub out'],
    'add_pads': ['l', 'List of manual pads to add'],
}
target_pinout_optional = {}
target_pinout_added = {}

straps_required = {
    'tap0': ['s', 'Name of tap0 pad'],
    'tap1': ['s', 'Name of tap1 pad'],
    'dft0': ['s', 'Name of dft0 pad'],
    'dft1': ['s', 'Name of dft1 pad'],
}
straps_optional = {}
straps_added = {}

straps_required = {
    'tap0': ['s', 'Name of tap0 pad'],
    'tap1': ['s', 'Name of tap1 pad'],
    'dft0': ['s', 'Name of dft0 pad'],
    'dft1': ['s', 'Name of dft1 pad'],
}
straps_optional = {}
straps_added = {}

special_sig_required = {
    'name': ['s', 'DIO name'],
    'pad': ['s', 'Pad name'],
}
special_sig_optional = {
    'desc': ['s', 'Description of signal connection'],
}
special_sig_added = {}

eflash_required = {
    'type': ['s', 'string indicating type of memory'],
    'banks': ['d', 'number of flash banks'],
    'pages_per_bank': ['d', 'number of data pages per flash bank'],
    'program_resolution': ['d', 'maximum number of flash words allowed to program'],
}

eflash_optional = {}

eflash_added = {}

module_required = {
    'name': ['s', 'name of the instance'],
    'type': ['s', 'comportable IP type'],
    'clock_srcs': ['g', 'dict with clock sources'],
    'clock_group': ['s', 'clock group'],
    'reset_connections': ['g', 'dict with reset sources'],
}

module_optional = {
    'domain': ['l', 'optional list of power domains, defaults to Domain0'],
    'clock_reset_export': ['l', 'optional list with prefixes for exported '
                                'clocks and resets at the chip level'],
    'attr': ['s', 'optional attribute indicating whether the IP is '
                  '"templated" or "reggen_only"'],
    'base_addr': ['s', 'hex start address of the peripheral '
                       '(if the IP has only a single TL-UL interface)'],
    'base_addrs': ['d', 'hex start addresses of the peripheral '
                        ' (if the IP has multiple TL-UL interfaces)'],
    'memory': ['g', 'optional dict with memory region attributes'],
    'param_decl': ['g', 'optional dict that allows to override instantiation parameters']
}

module_added = {
    'clock_connections': ['g', 'generated clock connections']
}

memory_required = {
    'label': ['s', 'region label for the linker script'],
    'swaccess': ['s', 'access attributes for the memory region (ro, rw)'],
    'exec': ['pb', 'executable region indication for the linker script'],
    'byte_write': ['pb', 'indicate whether the memory supports byte write accesses'],
}

memory_optional = {
    'size': ['d', 'memory region size in bytes for the linker script, '
                  'xbar and RTL parameterisations'],
    'config': ['d', 'Extra configuration for a particular memory'],
}

memory_added = {
}

reset_connection_required = {
    'name': ['s', 'name of the connecting reset'],
    'domain': ['s', 'connected domain'],
}

reset_connection_optional = {}
reset_connection_added = {}


# Supported PAD types.
# Needs to coincide with enum definition in prim_pad_wrapper_pkg.sv
class PadType(Enum):
    INPUT_STD = 'InputStd'
    BIDIR_STD = 'BidirStd'
    BIDIR_TOL = 'BidirTol'
    BIDIR_OD = 'BidirOd'
    ANALOG_IN0 = 'AnalogIn0'
    ANALOG_IN1 = 'AnalogIn1'


def is_valid_pad_type(obj):
    try:
        PadType(obj)
    except ValueError:
        return False
    return True


class TargetType(Enum):
    MODULE = "module"
    XBAR = "xbar"


class Target:
    """Target class informs the checkers if we are validating a module or xbar
    """
    def __init__(self, target_type):
        # The type of this target
        self.target_type = target_type
        # The key to search against
        if target_type == TargetType.MODULE:
            self.key = "type"
        else:
            self.key = "name"


class Flash:
    """Flash class contains information regarding parameter defaults.
       For now, only expose banks / pages_per_bank for user configuration.
       For now, also enforce power of 2 requiremnt.
    """
    max_banks = 4
    max_pages_per_bank = 1024

    def __init__(self, mem, base_addr=0):
        self.base_addr = int(base_addr, 16)
        self.banks = mem.get('banks', 2)
        self.pages_per_bank = mem.get('pages_per_bank', 8)
        self.program_resolution = mem.get('program_resolution', 128)
        self.words_per_page = 256
        self.data_width = 64
        self.metadata_width = 12
        self.info_types = 3
        self.infos_per_bank = [10, 1, 2]
        self.word_bytes = int(self.data_width / 8)
        self.pgm_resolution_bytes = int(self.program_resolution * self.word_bytes)
        self.check_values()

        # populate size variable
        self.bytes_per_page = self.word_bytes * self.words_per_page
        self.bytes_per_bank = self.bytes_per_page * self.pages_per_bank
        self.total_bytes = self.bytes_per_bank * self.banks

        size_int = int(self.total_bytes)
        self.size = hex(size_int)
        self.end_addr = self.base_addr + size_int

    def is_pow2(self, n):
        return (n != 0) and (n & (n - 1) == 0)

    def check_values(self):
        pow2_check = (self.is_pow2(self.banks) and
                      self.is_pow2(self.pages_per_bank) and
                      self.is_pow2(self.program_resolution))
        limit_check = ((self.banks <= Flash.max_banks) and
                       (self.pages_per_bank <= Flash.max_pages_per_bank))

        if not pow2_check:
            raise ValueError('flash power of 2 check failed. A supplied parameter '
                             'is not power of 2')

        if not limit_check:
            raise ValueError('flash number of banks and pages per bank too large')

    def _asdict(self):
        return {
            'banks': self.banks,
            'pages_per_bank': self.pages_per_bank,
            'program_resolution': self.pgm_resolution_bytes,
            'bytes_per_page': self.bytes_per_page,
            'bytes_per_bank': self.bytes_per_bank,
            'size': self.size
        }


# Check to see if each module/xbar defined in top.hjson exists as ip/xbar.hjson
# Also check to make sure there are not multiple definitions of ip/xbar.hjson for each
# top level definition
# If it does, return a dictionary of instance names to index in ip/xbarobjs
def check_target(top, objs, tgtobj):
    error = 0
    idxs = OrderedDict()

    # Collect up counts of object names. We support entries of objs that are
    # either dicts (for top-levels) or IpBlock objects.
    name_indices = {}
    for idx, obj in enumerate(objs):
        if isinstance(obj, IpBlock):
            name = obj.name.lower()
        else:
            name = obj['name'].lower()

        log.info("%d Order is %s" % (idx, name))
        name_indices.setdefault(name, []).append(idx)

    tgt_type = tgtobj.target_type.value
    inst_key = tgtobj.key

    for cfg in top[tgt_type]:
        cfg_name = cfg['name'].lower()
        log.info("Checking target %s %s" % (tgt_type, cfg_name))

        indices = name_indices.get(cfg[inst_key], [])
        if not indices:
            log.error("Could not find %s.hjson" % cfg_name)
            error += 1
        elif len(indices) > 1:
            log.error("Duplicate %s.hjson" % cfg_name)
            error += 1
        else:
            idxs[cfg_name] = indices[0]

    log.info("Current state %s" % idxs)
    return error, idxs


def check_pad(top: Dict,
              pad: Dict,
              known_pad_names: Dict,
              valid_connections: List[str],
              prefix: str) -> int:
    error = 0
    error += check_keys(pad, pad_required, pad_optional,
                        pad_added, prefix)

    # check name uniqueness
    if pad['name'] in known_pad_names:
        log.warning('Pad name {} is not unique'.format(pad['name']))
        error += 1
    known_pad_names[pad['name']] = 1

    if not is_valid_pad_type(pad['type']):
        log.warning('Unkown pad type {}'.format(pad['type']))
        error += 1

    if pad['bank'] not in top['pinout']['banks']:
        log.warning('Unkown io power bank {}'.format(pad['bank']))
        error += 1

    if pad['connection'] not in valid_connections:
        log.warning('Connection type {} of pad {} is invalid'
                    .format(pad['connection'], pad['name']))
        error += 1

    return error


def check_pinout(top: Dict, prefix: str) -> int:
    error = check_keys(top['pinout'], pinout_required, pinout_optional,
                       pinout_added, prefix + ' Pinout')

    known_names = {}
    for pad in top['pinout']['pads']:
        error += check_keys(pad, pad_required, pad_optional,
                            pad_added, prefix + ' Pinout')

        error += check_pad(top, pad, known_names,
                           ['direct', 'manual', 'muxed'],
                           prefix + ' Pad')

    return error


def check_pinmux(top: Dict, prefix: str) -> int:
    error = check_keys(top['pinmux'], pinmux_required, pinmux_optional,
                       pinmux_added, prefix + ' Pinmux')

    # This is used for the direct connection accounting below,
    # where we tick off already connected direct pads.
    known_direct_pads = {}
    direct_pad_attr = {}
    for pad in top['pinout']['pads']:
        if pad['connection'] == 'direct':
            known_direct_pads[pad['name']] = 1
            direct_pad_attr[pad['name']] = pad['type']

    # Note: the actual signal crosscheck is deferred until the merge stage,
    # since we have no idea at this point which IOs comportable IPs expose.
    for sig in top['pinmux']['signals']:
        error += check_keys(sig, pinmux_sig_required, pinmux_sig_optional,
                            pinmux_sig_added, prefix + ' Pinmux signal')

        if sig['connection'] not in ['direct', 'manual', 'muxed']:
            log.warning('Invalid connection type {}'.format(sig['connection']))
            error += 1

        # The pad needs to refer to a valid pad name in the pinout that is of
        # connection type "direct". We tick off all direct pads that have been
        # referenced in order to make sure there are no double connections
        # and unconnected direct pads.
        padname = sig.setdefault('pad', '')
        if padname != '':
            if padname in known_direct_pads:
                if known_direct_pads[padname] == 1:
                    known_direct_pads[padname] = 0
                    padattr = direct_pad_attr[padname]
                else:
                    log.warning('Warning, direct pad {} is already connected'
                                .format(padname))
                    error += 1
            else:
                log.warning('Unknown direct pad {}'.format(padname))
                error += 1

        # Check port naming scheme.
        port = sig.setdefault('port', '')
        pattern = r'^[a-zA-Z0-9_]*(\[[0-9]*\]){0,1}'
        matches = re.match(pattern, port)
        if matches is None:
            log.warning('Port name {} has wrong format'
                        .format(port))
            error += 1

        # Check that only direct connections have pad keys
        if sig['connection'] == 'direct':
            if sig.setdefault('attr', '') != '':
                log.warning('Direct connection of instance {} port {} '
                            'must not have an associated pad attribute field'
                            .format(sig['instance'],
                                    sig['port']))
                error += 1
            # Since the signal is directly connected, we can automatically infer
            # the pad type needed to instantiate the correct attribute CSR WARL
            # module inside the pinmux.
            sig['attr'] = padattr

            if padname == '':
                log.warning('Instance {} port {} connection is of direct type '
                            'and therefore must have an associated pad name.'
                            .format(sig['instance'],
                                    sig['port']))
                error += 1
            if port == '':
                log.warning('Instance {} port {} connection is of direct type '
                            'and therefore must have an associated port name.'
                            .format(sig['instance'],
                                    sig['port']))
                error += 1
        elif sig['connection'] == 'muxed':
            # Muxed signals do not have a corresponding pad and attribute CSR,
            # since they first go through the pinmux matrix.
            if sig.setdefault('attr', '') != '':
                log.warning('Muxed connection of instance {} port {} '
                            'must not have an associated pad attribute field'
                            .format(sig['instance'],
                                    sig['port']))
                error += 1
            if padname != '':
                log.warning('Muxed connection of instance {} port {} '
                            'must not have an associated pad'
                            .format(sig['instance'],
                                    sig['port']))
                error += 1
        elif sig['connection'] == 'manual':
            # This pad attr key is only allowed in the manual case,
            # as there is no way to infer the pad type automatically.
            sig.setdefault('attr', 'BidirStd')
            if padname != '':
                log.warning('Manual connection of instance {} port {} '
                            'must not have an associated pad'
                            .format(sig['instance'],
                                    sig['port']))
                error += 1

    # At this point, all direct pads should have been ticked off.
    for key, val in known_direct_pads.items():
        if val == 1:
            log.warning('Direct pad {} has not been connected'
                        .format(key))
            error += 1

    return error


def check_implementation_targets(top: Dict, prefix: str) -> int:
    error = 0
    known_names = {}
    for target in top['targets']:
        error += check_keys(target, target_required, target_optional,
                            target_added, prefix + ' Targets')

        # check name uniqueness
        if target['name'] in known_names:
            log.warning('Target name {} is not unique'.format(target['name']))
            error += 1
        known_names[target['name']] = 1

        error += check_keys(target['pinmux'], target_pinmux_required, target_pinmux_optional,
                            target_pinmux_added, prefix + ' Target pinmux')

        error += check_keys(target['pinout'], target_pinout_required, target_pinout_optional,
                            target_pinout_added, prefix + ' Target pinout')

        # Check special pad signals
        known_entry_names = {}
        for entry in target['pinmux']['special_signals']:
            error += check_keys(entry, special_sig_required, special_sig_optional,
                                special_sig_added, prefix + ' Special signal')

            # check name uniqueness
            if entry['name'] in known_entry_names:
                log.warning('Special pad name {} is not unique'.format(entry['name']))
                error += 1
            known_entry_names[entry['name']] = 1

            # The pad key needs to refer to a valid pad name.
            is_muxed = False
            for pad in top['pinout']['pads']:
                if entry['pad'] == pad['name']:
                    is_muxed = pad['connection'] == 'muxed'
                    break
            else:
                log.warning('Unknown pad {}'.format(entry['pad']))
                error += 1

            if not is_muxed:
                # If this is not a muxed pad, we need to make sure this refers to
                # DIO that is NOT a manual pad.
                for sig in top['pinmux']['signals']:
                    if entry['pad'] == sig['pad']:
                        break
                else:
                    log.warning('Special pad {} cannot refer to a manual pad'.format(entry['pad']))
                    error += 1

        # Check ports to remove
        for entry in target['pinout']['remove_ports']:
            # The pad key needs to refer to a valid pad name.
            for pad in top['pinout']['pads'] + target['pinout']['add_pads']:
                if entry == pad['name']:
                    break
            else:
                log.warning('Unknown pad {}'.format(entry))
                error += 1

        # Check pads to remove and stub out
        for entry in target['pinout']['remove_pads']:
            # The pad key needs to refer to a valid pad name.
            for pad in top['pinout']['pads']:
                if entry == pad['name']:
                    break
            else:
                log.warning('Unknown pad {}'.format(entry))
                error += 1

        # Check pads to add
        known_pad_names = {}
        for pad in top['pinout']['pads']:
            known_pad_names.update({pad['name']: 1})

        for pad in target['pinout']['add_pads']:
            error += check_pad(top, pad, known_pad_names, ['manual'],
                               prefix + ' Additional Pad')

    return error


def check_clocks_resets(top, ipobjs, ip_idxs, xbarobjs, xbar_idxs):

    error = 0

    # there should only be one each of pwrmgr/clkmgr/rstmgr
    pwrmgrs = [m for m in top['module'] if m['type'] == 'pwrmgr']
    clkmgrs = [m for m in top['module'] if m['type'] == 'clkmgr']
    rstmgrs = [m for m in top['module'] if m['type'] == 'rstmgr']

    if len(pwrmgrs) == 1 * len(clkmgrs) == 1 * len(rstmgrs) != 1:
        log.error("Incorrect number of pwrmgr/clkmgr/rstmgr")
        error += 1

    # all defined clock/reset nets
    reset_nets = [reset['name'] for reset in top['resets']['nodes']]
    clock_srcs = list(top['clocks'].all_srcs.keys())

    # Check clock/reset port connection for all IPs
    for ipcfg in top['module']:
        ipcfg_name = ipcfg['name'].lower()
        log.info("Checking clock/resets for %s" % ipcfg_name)
        error += validate_reset(ipcfg, ipobjs[ip_idxs[ipcfg_name]], reset_nets)
        error += validate_clock(ipcfg, ipobjs[ip_idxs[ipcfg_name]], clock_srcs)

        if error:
            log.error("module clock/reset checking failed")
            break

    # Check clock/reset port connection for all xbars
    for xbarcfg in top['xbar']:
        xbarcfg_name = xbarcfg['name'].lower()
        log.info("Checking clock/resets for xbar %s" % xbarcfg_name)
        error += validate_reset(xbarcfg, xbarobjs[xbar_idxs[xbarcfg_name]],
                                reset_nets, "xbar")
        error += validate_clock(xbarcfg, xbarobjs[xbar_idxs[xbarcfg_name]],
                                clock_srcs, "xbar")

        if error:
            log.error("xbar clock/reset checking failed")
            break

    return error


# Checks the following
# For each defined reset connection in top*.hjson, there exists a defined port at the destination
# and defined reset net
# There are the same number of defined connections as there are ports
def validate_reset(top, inst, reset_nets, prefix=""):
    # Gather inst port list
    error = 0

    # Handle either an IpBlock (generated by reggen) or an OrderedDict
    # (generated by topgen for a crossbar)
    if isinstance(inst, IpBlock):
        name = inst.name
        reset_signals = inst.clocking.reset_signals()
    else:
        name = inst['name']
        reset_signals = ([inst.get('reset_primary', 'rst_ni')] +
                         inst.get('other_reset_list', []))

    log.info("%s %s resets are %s" %
             (prefix, name, reset_signals))

    # Check if reset connections are properly formatted
    # There are two options
    # The reset connection for a particular port must be a str
    # The reset connection for a paritcular port must be a dict
    # If value is a string, the module can only have ONE domain
    # If value is a dict, it must have the keys name / domain, and the
    # value of domain must match that defined for the module.
    for port, reset in top["reset_connections"].items():
        if isinstance(reset, str):
            top["reset_connections"][port] = {}
            top["reset_connections"][port]['name'] = reset

            if len(top["domain"]) > 1:
                raise ValueError(f"{top['name']} reset connection {reset} "
                                 "has no assigned domain")
            else:
                top["reset_connections"][port]['domain'] = top["domain"][0]

        if isinstance(reset, dict):
            error += check_keys(reset,
                                reset_connection_required,
                                reset_connection_optional,
                                reset_connection_added,
                                'dict structure for reset connections')

            if reset['domain'] not in top["domain"]:
                error += 1
                log.error(f"domain {reset['domain']} defined for reset {reset['name']} "
                          f"is not a domain of {top['name']}")

    # Check if the reset connections are fully populated
    if len(top['reset_connections']) != len(reset_signals):
        error += 1
        log.error("%s %s mismatched number of reset ports and nets" %
                  (prefix, name))

    missing_port = [
        port for port in top['reset_connections'].keys()
        if port not in reset_signals
    ]

    if missing_port:
        error += 1
        log.error("%s %s Following reset ports do not exist:" %
                  (prefix, name))
        [log.error("%s" % port) for port in missing_port]

    missing_net = [
        net['name'] for net in top['reset_connections'].values()
        if net['name'] not in reset_nets
    ]

    if missing_net:
        error += 1
        log.error("%s %s Following reset nets do not exist:" %
                  (prefix, name))
        [log.error("%s" % net) for net in missing_net]

    return error


# Checks the following
# For each defined clock_src in top*.hjson, there exists a defined port at the destination
# and defined clock source
# There are the same number of defined connections as there are ports
def validate_clock(top, inst, clock_srcs, prefix=""):
    # Gather inst port list
    error = 0

    # Handle either an IpBlock (generated by reggen) or an OrderedDict
    # (generated by topgen for a crossbar)
    if isinstance(inst, IpBlock):
        name = inst.name
        clock_signals = inst.clocking.clock_signals(False)
    else:
        name = inst['name']
        clock_signals = ([inst.get('clock_primary', 'rst_ni')] +
                         inst.get('other_clock_list', []))

    if len(top['clock_srcs']) != len(clock_signals):
        error += 1
        log.error("%s %s mismatched number of clock ports and nets" %
                  (prefix, name))

    missing_port = [
        port for port in top['clock_srcs'].keys()
        if port not in clock_signals
    ]

    if missing_port:
        error += 1
        log.error("%s %s Following clock ports do not exist:" %
                  (prefix, name))
        [log.error("%s" % port) for port in missing_port]

    missing_net = []
    for port, net in top['clock_srcs'].items():
        net_name = net['clock'] if isinstance(net, Dict) else net

        if net_name not in clock_srcs:
            missing_net.append(net)

    if missing_net:
        error += 1
        log.error("%s %s Following clock nets do not exist:" %
                  (prefix, name))
        [log.error("%s" % net) for net in missing_net]

    return error


def check_flash(top):

    for mem in top['memory']:
        if mem['type'] == "eflash":

            raise ValueError('top level flash memory definition not supported. Please use '
                             'the flash embedded inside flash_ctrl instead.  If there is a '
                             'need for top level flash memory, please file an issue.')


def check_power_domains(top):

    # check that the default domain is valid
    if top['power']['default'] not in top['power']['domains']:
        raise ValueError(f"Default power domain {top['power']['default']} is "
                         "not a valid domain")

    # Check that each module, xbar, memory has a power domain defined.
    # If not, give it a default.
    # If there is one defined, check that it is a valid definition
    for end_point in top['module'] + top['memory'] + top['xbar']:
        if 'domain' not in end_point:
            end_point['domain'] = [top['power']['default']]

        for d in end_point['domain']:
            if d not in top['power']['domains']:
                raise ValueError(f"{end_point['name']} defined invalid domain {d}")


def check_modules(top, prefix):
    error = 0
    for m in top['module']:
        modname = m.get("name", "unnamed module")
        error += check_keys(m, module_required, module_optional, module_added,
                            prefix + " " + modname)

        # these fields are mutually exclusive
        if 'base_addr' in m and 'base_addrs' in m:
            log.error("{} {} a module cannot define both the 'base_addr' "
                      "and 'base_addrs' keys at the same time"
                      .format(prefix, modname))
            error += 1

        if 'base_addrs' in m and 'memory' in m:
            for intf, value in m['memory'].items():
                error += check_keys(value, memory_required,
                                    memory_optional, memory_added,
                                    prefix + " " + modname + " " + intf)

                # if size is not declared, there must be extra config to determine it
                if 'size' not in value and 'config' not in value:
                    raise ValueError(f'{m["name"]} memory declaration has neither size '
                                     'nor extra configuration.  Unable to determine '
                                     'memory size')

                if 'size' not in value:
                    mem_type = value['config'].get('type', "")

                    if mem_type == "flash":
                        check_keys(value['config'], eflash_required, eflash_optional,
                                   eflash_added, "Eflash")
                        flash = Flash(value['config'], m['base_addrs'][intf])
                        value['size'] = flash.size
                        value['config'] = flash
                    else:
                        raise ValueError(f'{m["name"]} memory config declaration does not have '
                                         'a valid type')

                # make sure the memory regions correspond to the TL-UL interfaces
                if intf not in m['base_addrs']:
                    log.error("{} {} memory region {} does not "
                              "correspond to any of the defined "
                              "TL-UL interfaces".format(prefix, modname, intf))
                    error += 1
                # make sure the linker region access attribute is valid
                attr = value.get('swaccess', 'unknown attribute')
                if attr not in ['ro', 'rw']:
                    log.error('{} {} swaccess attribute {} of memory region {} '
                              'is not valid'.format(prefix, modname, attr, intf))
                    error += 1
    return error


def validate_top(top, ipobjs, xbarobjs):
    # return as it is for now
    error = check_keys(top, top_required, top_optional, top_added, "top")

    if error != 0:
        log.error("Top HJSON has top level errors. Aborting")
        return top, error

    component = top['name']

    # Check module instantiations
    error += check_modules(top, component)

    # MODULE  check
    err, ip_idxs = check_target(top, ipobjs, Target(TargetType.MODULE))
    error += err

    # XBAR check
    err, xbar_idxs = check_target(top, xbarobjs, Target(TargetType.XBAR))
    error += err

    # MEMORY check
    check_flash(top)

    # Power domain check
    check_power_domains(top)

    # Clock / Reset check
    error += check_clocks_resets(top, ipobjs, ip_idxs, xbarobjs, xbar_idxs)

    # RV_PLIC check

    # Pinout, pinmux and target checks
    # Note that these checks must happen in this order, as
    # the pinmux and target configs depend on the pinout.
    error += check_pinout(top, component)
    error += check_pinmux(top, component)
    error += check_implementation_targets(top, component)

    return top, error
