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

import logging as log
import re
from collections import OrderedDict

from .access import SWAccess, HWAccess, SWACCESS_PERMITTED
from .bits import Bits
from .field import Field
from .multi_register import MultiRegister
from .register import Register


# Routine that can be used for Hjson object_pairs_hook
# The baseline is dict(pairs) i.e. construct a dictonary from pairs
# The usual is OrderedDict(pairs) which is redundant in latest python
# Both of these silently allow repeated keys, which this version detects
def checking_dict(pairs):
    d = {}
    for x in pairs:
        if x[0] in d:
            repkey = 'Repeated' + x[0]
            log.warn("Repeated key " + x[0] + " added as " + repkey)
            d[repkey] = x[1]
        else:
            d[x[0]] = x[1]
    return d


# validating version of int(x, 0)
# returns int value, error flag
# if error flag is True value will be zero
def check_int(x, err_prefix, suppress_err_msg=False):
    if isinstance(x, int):
        return x, False
    if x[0] == '0' and len(x) > 2:
        if x[1] in 'bB':
            validch = '01'
        elif x[1] in 'oO':
            validch = '01234567'
        elif x[1] in 'xX':
            validch = '0123456789abcdefABCDEF'
        else:
            if not suppress_err_msg:
                log.error(err_prefix +
                          ": int must start digit, 0b, 0B, 0o, 0O, 0x or 0X")
            return 0, True
        for c in x[2:]:
            if c not in validch:
                if not suppress_err_msg:
                    log.error(err_prefix + ": Bad character " + c + " in " + x)
                return 0, True
    else:
        if not x.isdecimal():
            if not suppress_err_msg:
                log.error(err_prefix + ": Number not valid int " + x)
            return 0, True
    return int(x, 0), False


def check_bool(x, err_prefix):
    """check_bool checks if input 'x' is one of the list:
        "true", "false"

        It returns value as Bool type and Error condition.
    """
    if isinstance(x, bool):
        # if Bool returns as it is
        return x, False
    if not x.lower() in ["true", "false"]:
        log.error(err_prefix + ": Bad field value " + x)
        return False, True
    else:
        return (x.lower() == "true"), False


def check_ln(obj, x, withwidth, err_prefix):
    error = 0
    if not isinstance(obj[x], list):
        log.error(err_prefix + ' element ' + x + ' not a list')
        return 1
    for y in obj[x]:
        error += check_keys(y, ln_required, ln_optional if withwidth else {},
                            {}, err_prefix + ' element ' + x)
        if withwidth:
            if 'width' in y:
                w, err = check_int(y['width'], err_prefix + ' width in ' + x)
                if err:
                    error += 1
                    w = 1
            else:
                w = 1
            y['width'] = str(w)

    return error


def check_lp(obj, x, err_prefix):
    error = 0
    if not isinstance(obj[x], list):
        log.error(err_prefix + ' element ' + x + ' not a list')
        return 1

    for y in obj[x]:
        error += check_keys(y, lp_required, lp_optional, {},
                            err_prefix + ' element ' + x)

        # If this is a random netlist constant, other attributes like local, default and expose
        # are automatically set. Throw an error if they already exist in the dict.
        randcount = int(y.setdefault('randcount', "0"))
        randtype = y.setdefault('randtype', "none")
        if randtype != "none":

            if randcount <= 0:
                log.error(err_prefix + ' randwith for parameter ' + y['name'] +
                          ' must be greater > 0.')
                return error + 1

            if randtype not in ['perm', 'data']:
                log.error(err_prefix + ' parameter ' + y['name'] +
                          ' has unknown randtype ' + randtype)
                return error + 1

            if y.get('type') is None:
                log.error(
                    err_prefix + ' parameter ' + y['name'] +
                    ' has undefined type. '
                    'It is required to define the type in the IP package.')
                return error + 1

            if not y.get('name').lower().startswith('rndcnst'):
                log.error(
                    err_prefix + ' parameter ' + y['name'] +
                    ' is defined as a compile-time '
                    'random netlist constant. The name must therefore start with RndCnst.'
                )
                return error + 1

            overrides = [('local', 'false'), ('default', ''),
                         ('expose', 'false')]

            for key, value in overrides:
                if y.setdefault(key, value) != value:
                    log.error(
                        err_prefix + ' ' + key + ' for parameter ' +
                        y['name'] +
                        ' must not be set since it will be defined automatically.'
                    )
                    return error + 1

        # TODO: Check if PascalCase or ALL_CAPS
        y.setdefault('type', 'int')

        y.setdefault('local', 'true')
        local, ierr = check_bool(y["local"], err_prefix + " local")
        if ierr:
            error += 1
            y["local"] = "true"

        y.setdefault('expose', 'false')
        local, ierr = check_bool(y["expose"], err_prefix + " expose")
        if ierr:
            error += 1
            y["expose"] = "false"

        if y["local"] == "true" and y["expose"] == "true":
            log.error(err_prefix + ' element ' + x + '["' + y["name"] + '"]' +
                      ' cannot be local and exposed to top level')
            return error + 1

        if "default" in y:
            if y["type"][:3] == "int":
                default, ierr = check_int(y["default"],
                                          err_prefix + " default")
                if ierr:
                    error += 1
                    y["default"] = "1"
        elif y["randtype"] != "none":
            # Don't make assumptions for exposed parameters. These must have
            # a default.
            if y["expose"] == "true":
                log.error(err_prefix + ' element ' + x + '["' + y["name"] +
                          '"]' + ' has no defined default value')
            elif y["type"][:3] == "int":
                y["default"] = "1"
            elif y["type"] == "string":
                y["default"] = ""
            else:
                log.error(err_prefix + ' element ' + x + '["' + y["name"] +
                          '"]' + ' type is not supported')
                return error + 1

    return error


def search_param(obj, key):
    """return the param object if found, else return non zero error
    """
    for p in obj:
        if p["name"] == key:
            return p, 0

    log.error("Param {} cannot be found".format(key))
    return None, 1


def check_keys(obj, required_keys, optional_keys, added_keys, err_prefix):
    error = 0
    for x in required_keys:
        if x not in obj:
            error += 1
            log.error(err_prefix + " missing required key " + x)
    for x in obj:
        type = None
        if x in required_keys:
            type = required_keys[x][0]
        elif x in optional_keys:
            type = optional_keys[x][0]
        elif x not in added_keys:
            log.warning(err_prefix + " contains extra key " + x)
        if type is not None:
            if type[:2] == 'ln':
                error += check_ln(obj, x, type == 'lnw', err_prefix)
            if type == 'lp':
                error += check_lp(obj, x, err_prefix)

    return error


# Only allow zero or one of the list of keys
def check_zero_one_key(obj, optone, err_prefix):
    error = 0
    seenopt = 0
    for x in obj:
        if (x in optone):
            seenopt += 1
    if (seenopt > 1) or ((seenopt == 1) and len(obj) > 1):
        log.error(err_prefix + " only allowed one option key: ")
        for x in obj:
            log.error(err_prefix + "   found: " + x)
            error += 1
    return error


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 `{}`"],
    'lg': [
        "list of group", "comma separated group of key:value enclosed in `{}`"
        " the second entry of the list is the sub group format"
    ],
    '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)"]
}

# Toplevel keys
top_required = {
    'name': ['s', "name of the component"],
    'clock_primary': ['s', "name of the primary clock"],
    'bus_device': ['s', "name of the bus interface for the device"],
    'registers':
    ['l', "list of register definition groups and "
     "offset control groups"]
}
top_optional = {
    'alert_list': ['lnw', "list of peripheral alerts"],
    'available_inout_list': ['lnw', "list of available peripheral inouts"],
    'available_input_list': ['lnw', "list of available peripheral inputs"],
    'available_output_list': ['lnw', "list of available peripheral outputs"],
    'bus_host': ['s', "name of the bus interface as host"],
    'hier_path': [
        None,
        'additional hierarchy path before the reg block instance'
    ],
    'interrupt_list': ['lnw', "list of peripheral interrupts"],
    'inter_signal_list': ['l', "list of inter-module signals"],
    'no_auto_alert_regs': [
        's', "Set to true to suppress automatic "
        "generation of alert test registers. "
        "Defaults to true if no alert_list is present. "
        "Otherwise this defaults to false. "
    ],
    'no_auto_intr_regs': [
        's', "Set to true to suppress automatic "
        "generation of interrupt registers. "
        "Defaults to true if no interrupt_list is present. "
        "Otherwise this defaults to false. "
    ],
    'other_clock_list': ['l', "list of other chip clocks needed"],
    'other_reset_list': ['l', "list of other resets"],
    'param_list': ['lp', "list of parameters of the IP"],
    'regwidth': ['d', "width of registers in bits (default 32)"],
    'reset_primary': ['s', "primary reset used by the module"],
    'reset_request_list': ['l', 'list of signals requesting reset'],
    'scan': ['pb', 'Indicates the module have `scanmode_i`'],
    'scan_reset': ['pb', 'Indicates the module have `test_rst_ni`'],
    'SPDX-License-Identifier': [
        's', "License ientifier (if using pure json) "
        "Only use this if unable to put this "
        "information in a comment at the top of the "
        "file."
    ],
    'wakeup_list': ['lnw', "list of peripheral wakeups"]
}
top_added = {
    'genrnames': ['pl', "list of register names"],
    'genautoregs': ['pb', "Registers were generated from config info"],
    'genwennames': ['pl', "list of registers used as write enables"],
    'gennextoffset': ['pi', "offset next register would use"],
    'gensize': [
        'pi', "address space size needed for registers. "
        "Generated by tool as next power of 2."
    ]
}

# ln type has list of groups with only name and description
# (was called "subunit" in cfg_validate)
ln_required = {
    'name': ['s', "name of the item"],
    'desc': ['s', "description of the item"],
}
ln_optional = {
    'width': ['d', "bit width of the item (if not 1)"],
}

# lp type
lp_required = {
    'name': ['s', "name of the item"],
}
lp_optional = {
    'desc': ['s', "description of the item"],
    'type': ['s', "item type. int by default"],
    'default': ['s', "item default value"],
    'local': ['pb', "to be localparam"],
    'expose': ['pb', "to be exposed to top"],
    'randcount':
    ['s', "number of bits to randomize in the parameter. 0 by default."],
    'randtype': ['s', "type of randomization to perform. none by default"],
}

# Registers list may have embedded keys
list_optone = {
    'reserved': ['d', "number of registers to reserve space for"],
    'skipto': ['d', "set next register offset to value"],
    'window': [
        'g', "group defining an address range "
        "for something other than standard registers"
    ],
    'multireg':
    ['g', "group defining registers generated "
     "from a base instance."]
}

# Register keys
reg_added = {
    'genresval': ['pi', "reset value generated from resval and fields"],
    'genresmask': ['pi', "mask of bits with valid reset value (not x)"],
    'genbitsused': ['pi', "mask of bits defined in the register"],
    'genoffset': ['pi', "offset address of the register"],
    'gendvrights': ['s', "SW Rights used in UVM reg class"]
}

# Window keys
window_required = {
    'name': ['s', "Name of the window"],
    'desc': ['t', "description of the window"],
    'items': ['d', "size in fieldaccess width words of the window"],
    'swaccess': ['s', "software access permitted"],
}

# TODO potential for additional optional to give more type info?
# eg sram-hw-port: "none", "sync", "async"
window_optional = {
    'byte-write': [
        's', "True if byte writes are supported. "
        "Defaults to false if not present."
    ],
    'validbits': [
        'd', "Number of valid data bits within "
        "regwidth sized word. "
        "Defaults to regwidth. If "
        "smaller than the regwidth then in each "
        "word of the window bits "
        "[regwidth-1:validbits] are unused and "
        "bits [validbits-1:0] are valid."
    ],
    'unusual': [
        's', "True if window has unusual parameters "
        "(set to prevent Unusual: errors)."
        "Defaults to false if not present."
    ]
}

window_added = {
    'genbyte-write': ['pb', "generated boolean for byte-write"],
    'genvalidbits': ['pi', "valid data width"],
    'genoffset':
    ['pi', "base offset address of the window (aligned for size)"],
    'genswaccess': ['pe', "Software access (gen enum)"],
    'genswwraccess': ['pe', "Software write access (gen enum)"],
    'genswrdaccess': ['pe', "Software read access (gen enum)"]
}

# Field keys
# special case in the code, no name and no desc if only field
field_added = {
    'genrsvdenum': ['pb', "enum did not cover every possible value"],
    'genresval': [
        'pi', "resval for field constructed by the tool. "
        "Will be set to 0 for x."
    ],
    'genresvalx': ['pb', "Indicates if resval is x"],
    'genswaccess': ['pe', "Software access (generated enum)"],
    'genswwraccess': ['pe', "Software write access (generated enum)"],
    'genswrdaccess': ['pe', "Software read access (generated enum)"],
    'genhwaccess': ['pe', "Hardware access (generated Enum)"],
    'genhwqe': ['pb', "Hardware qualifier enable signal needed"],
    'genhwre': ['pb', "Hardware read enable signal needed"],
    'bitinfo': ['T', "tuple (bitfield_mask, field width, lsb)"]
}

key_use = {'r': "required", 'o': "optional", 'a': "added by tool"}


# if not int, check in param_list
def resolve_value(entry, param_list):
    val, not_int = check_int(entry, "", True)
    err = 0

    if not_int:
        param, err = search_param(param_list, entry)
        val = param['default']
        if param['local'] != "true":
            log.warning(
                "It is recommended to define {} as localparam,"
                " since it should not be changed in the design".format(entry))

    return int(val), err


def _upd_gennames(regs, offset, register):
    genrnames = regs['genrnames']
    rname = register.name.lower()
    err = 0
    if rname in genrnames:
        log.error('Duplicate register name {!r} at offset {:#x}.'
                  .format(offset, rname))
        err = 1
    genrnames.append(rname)
    genwennames = regs['genwennames']
    if register.regwen is not None and register.regwen not in genwennames:
        genwennames.append(register.regwen)

    return err


def make_intr_alert_reg(regs, name, offset, swaccess, hwaccess, desc):
    if name == 'ALERT_TEST':
        signal_list = regs['alert_list']
    else:
        signal_list = regs['interrupt_list']
    # these names will be converted into test registers
    testreg_names = ['INTR_TEST', 'ALERT_TEST']

    swaccess_obj = SWAccess('make_intr_alert_reg()', swaccess)
    hwaccess_obj = HWAccess('make_intr_alert_reg()', hwaccess)

    fields = []
    cur_bit = 0
    for (field_idx, bit) in enumerate(signal_list):
        w = 1
        if 'width' in bit and bit['width'] != '1':
            w = int(bit['width'], 0)
            field_bits = Bits(cur_bit + w - 1, cur_bit)
        else:
            field_bits = Bits(cur_bit, cur_bit)
        cur_bit += w

        field_name = bit['name']
        if name == 'INTR_ENABLE':
            field_desc = ('Enable interrupt when {}!!INTR_STATE.{} is set.'
                          .format('corresponding bit in ' if w > 1 else '',
                                  field_name))
        elif name == 'INTR_TEST':
            field_desc = ('Write 1 to force {}!!INTR_STATE.{} to 1.'
                          .format('corresponding bit in ' if w > 1 else '',
                                  field_name))
        elif name == 'ALERT_TEST':
            field_desc = 'Write 1 to trigger one alert event of this kind.'
        else:
            field_desc = bit['desc']

        # Put the automatically generated information back into
        # `interrupt_list`, so that it can be used to generate C preprocessor
        # definitions if needed.
        signal_list[field_idx]['bits'] = field_bits.as_str()
        signal_list[field_idx]['bitinfo'] = (field_bits.bitmask(),
                                             field_bits.width(),
                                             field_bits.lsb)

        fields.append(Field(field_name,
                            field_desc,
                            bit.get('tags', []),
                            swaccess_obj,
                            hwaccess_obj,
                            hwqe=name in testreg_names,
                            hwre=False,
                            bits=field_bits,
                            resval=0,
                            enum=None))

    hwext = 'true' if name in testreg_names else 'false'
    if name == 'INTR_TEST':
        # intr_test csr is WO which - it reads back 0s
        reg_tags = ["excl:CsrNonInitTests:CsrExclWrite"]
    elif name == 'INTR_STATE':
        # intr_state csr is affected by writes to other csrs - skip write-check
        reg_tags = ["excl:CsrNonInitTests:CsrExclWriteCheck"]
    else:
        reg_tags = []

    bool_hwext = hwext.lower() == 'true'

    reg = Register(offset,
                   name,
                   desc,
                   swaccess_obj,
                   hwaccess_obj,
                   hwext=bool_hwext,
                   hwqe=bool_hwext,
                   hwre=False,
                   regwen=None,
                   tags=reg_tags,
                   resval=None,
                   shadowed=False,
                   fields=fields,
                   update_err_alert=None,
                   storage_err_alert=None)
    _upd_gennames(regs, offset, reg)
    return reg


def make_intr_regs(regs, offset, addrsep, fullwidth):
    iregs = []
    intrs = regs['interrupt_list']
    num_intrs = sum([int(x.get('width', '1'), 0) for x in intrs])
    if num_intrs > fullwidth:
        log.error('More than ' + str(fullwidth) + ' interrupts in list')
        return iregs, 1

    new_reg = make_intr_alert_reg(regs, 'INTR_STATE', offset, 'rw1c', 'hrw',
                                  'Interrupt State Register')
    iregs.append(new_reg)
    new_reg = make_intr_alert_reg(regs, 'INTR_ENABLE', offset + addrsep, 'rw',
                                  'hro', 'Interrupt Enable Register')
    iregs.append(new_reg)
    new_reg = make_intr_alert_reg(regs, 'INTR_TEST', offset + 2 * addrsep,
                                  'wo', 'hro', 'Interrupt Test Register')
    iregs.append(new_reg)
    return iregs, 0


def make_alert_regs(regs, offset, addrsep, fullwidth):
    alert_regs = []
    alerts = regs['alert_list']
    num_alerts = sum([int(x.get('width', '1'), 0) for x in alerts])
    if num_alerts > fullwidth:
        log.error('More than ' + str(fullwidth) + ' alerts in list')
        return alert_regs, 1

    new_reg = make_intr_alert_reg(regs, 'ALERT_TEST', offset, 'wo', 'hro',
                                  'Alert Test Register')
    alert_regs.append(new_reg)
    return alert_regs, 0


def validate_window(win, offset, regwidth, top):
    error = 0

    if 'name' not in win:
        name = "Window at +" + hex(offset)
    else:
        name = win['name']
        if name.lower() in top['genrnames']:
            error += 1
            log.error("Window at +" + hex(offset) + " duplicate name " + name)
        else:
            top['genrnames'].append(name.lower())

    error += check_keys(win, window_required, window_optional, window_added,
                        name)

    # if there was an error before this then can't trust anything!
    if error > 0:
        log.debug(name + "@" + hex(offset) + " " + str(error) +
                  " top level errors. Window will be ignored.")
        return error, offset

    # optional flags
    unusual = 'unusual' in win and win['unusual'].lower() == "true"
    win['genbyte-write'] = ('byte-write' in win and
                            win['byte-write'].lower() == "true")

    if 'validbits' in win:
        wid, err = check_int(win['validbits'], name + " validbits")
        if err:
            error += err
            wid = regwidth
        if wid > regwidth:
            error += 1
            log.error(name + ": validbits " + str(wid) +
                      " is greater than regwidth (" + str(regwidth) + ").")
            wid = regwidth
        win['genvalidbits'] = wid
    else:
        win['genvalidbits'] = regwidth

    param, err = resolve_value(win['items'], top['param_list'])
    error += err

    winitems, err = check_int(param, name + " items")

    if err:
        error += err
        winitems = 4

    win['items'] = str(winitems)

    # convert items to bytes
    winsize = winitems * (regwidth // 8)
    # if size is not a power of two, po2_size is next po2 larger
    po2_size = 1 << (winsize.bit_length() - 1)
    if winsize != po2_size:
        # the -1 above was wrong if not a power of two
        po2_size = po2_size << 1
        if not unusual:
            log.warn(name + ": Unusual: Size " + str(winitems) +
                     " is not a power of 2.")

    # Align to ensure base address of first item in window has
    # all zeros in the low bits
    if (offset & (po2_size - 1)) != 0:
        genoff = (offset | (po2_size - 1)) + 1
    else:
        genoff = offset
    nextoff = genoff + winsize
    win['genoffset'] = genoff

    swaccess = win['swaccess']
    if swaccess not in SWACCESS_PERMITTED:
        log.warn(name + ": Bad window swaccess value " + swaccess)
        swaccess = "wo"
    swacc_info = SWACCESS_PERMITTED[swaccess]
    win['genswaccess'] = swacc_info[1]
    win['genswwraccess'] = swacc_info[2]
    win['genswrdaccess'] = swacc_info[3]
    if not swacc_info[4] and not unusual:
        log.warn(name + ": Unusual: access type for a window " + swaccess)

    return error, nextoff


""" Check that terms specified for regwen exist

Regwen are all assumed to be individual registers.
"""


def check_wen_regs(regs):
    error = 0

    # Construct a map from register name to a tuple (resval, swaccess, hwaccess)
    name_to_reg_data = {}
    for x in regs['registers']:
        if isinstance(x, Register):
            x_regs = [x]
        elif isinstance(x, MultiRegister):
            x_regs = x.regs
        else:
            x_regs = []

        for reg in x_regs:
            assert isinstance(reg, Register)
            reg_data = (reg.resval, reg.swaccess, reg.hwaccess)
            name_to_reg_data[reg.name.lower()] = reg_data

    # check for reset value
    # both w1c and w0c are acceptable, ro is also acceptable when hwaccess is wo (hw managed regwen)
    for x in regs['genwennames']:

        # check the REGWEN naming convention
        if re.fullmatch(r'(.+_)*REGWEN(_[0-9]+)?', x) is None:
            error += 1
            log.error("Regwen name %s must have the suffix '_REGWEN'" % x)

        target = x.lower()
        log.debug("check_wen_regs::Searching for %s" % target)

        reg_data = name_to_reg_data.get(target)
        if reg_data is None:
            error += 1
            log.error("Could not find register name matching %s" % target)
            continue

        resval, swaccess, hwaccess = reg_data

        # If the REGWEN bit is SW controlled, enfore that this bit defaults to 1.
        # If this bit is read-only by SW and hence hardware controlled, we do
        # not enforce this requirement.
        if swaccess.key != "ro" and not resval:
            error += 1
            log.error(x + " used as regwen fails requirement to default " +
                      "to 1")

        # either the regwen is software managed (must be rw0c)
        # or it is completely hw managed (sw=r0 and hw=wo)
        sw_regwen = 0
        hw_regwen = 0

        if swaccess.key in ["rw0c"]:
            sw_regwen += 1

        if swaccess.key == "ro" and hwaccess.key == "hwo":
            hw_regwen += 1

        if (sw_regwen + hw_regwen) == 0:
            error += 1
            log.error(
                "{x} used as regwen fails requirement to be "
                "swaccess=W0C or swaccess=RO and hwaccess=HWO".format(x=x))

    return error


def validate(regs, **kwargs):
    if "params" in kwargs:
        params = kwargs["params"]
    else:
        params = []

    if 'name' not in regs:
        log.error("Component has no name. Aborting.")
        return 1

    component = regs['name']

    regs.setdefault('param_list', [])

    error = check_keys(regs, top_required, top_optional, top_added, component)
    if (error > 0):
        log.error("Component has top level errors. Aborting.")
        return error
    regs['genrnames'] = []
    regs['genwennames'] = []
    error = 0

    if 'regwidth' in regs:
        fullwidth, ierr = check_int(regs['regwidth'], "regwidth")
        if ierr:
            fullwidth = 32
            error += 1
    else:
        fullwidth = 32
        log.warning('regwidth not specified, assuming 32.')
    regs['regwidth'] = str(fullwidth)

    if ((fullwidth % 8) != 0):
        addrsep = (fullwidth // 8) + 1
        log.warning("regwidth is not a multiple of 8 bits!")
    else:
        addrsep = fullwidth // 8

    offset = 0
    autoregs = []

    # auto header generation would go here and update autoregs

    if 'no_auto_intr_regs' in regs:
        no_auto_intr, err = check_bool(regs['no_auto_intr_regs'],
                                       'no_auto_intr_regs')
        if err:
            error += 1
    else:
        if 'interrupt_list' not in regs:
            no_auto_intr = True
        else:
            no_auto_intr = False

    if 'no_auto_alert_regs' in regs:
        no_auto_alerts, err = check_bool(regs['no_auto_alert_regs'],
                                         'no_auto_alert_regs')
        if err:
            error += 1
    else:
        if 'alert_list' not in regs:
            no_auto_alerts = True
        else:
            no_auto_alerts = False

    if 'interrupt_list' in regs and 'genautoregs' not in regs and not no_auto_intr:
        iregs, err = make_intr_regs(regs, offset, addrsep, fullwidth)
        error += err
        autoregs.extend(iregs)
        offset += addrsep * len(iregs)

    # Generate a NumAlerts parameter for provided alert_list.
    if regs.setdefault('alert_list', []):
        # Generate alert test registers.
        if 'genautoregs' not in regs and not no_auto_alerts:
            aregs, err = make_alert_regs(regs, offset, addrsep, fullwidth)
            error += err
            autoregs.extend(aregs)
            offset += addrsep * len(aregs)

        num_alerts = 0
        for alert in regs['alert_list']:
            alert_width = int(alert.get('width', '1'), 0)
            num_alerts += alert_width
            if alert_width > 1:
                log.warning(
                    "{}: Consider naming each alert individually instead of "
                    "declaring an alert signal with width > 1.".format(
                        alert['name']))

            # check alert naming scheme
            if alert['name'] == "":
                log.error("{}: Alert name cannot be empty".format(alert['name']))
                error += 1
            prefix = alert['name'].split('_')
            if prefix[0] not in ['recov', 'fatal']:
                log.error(
                    "{}: Alerts must be prefixed with either 'recov_' or "
                    "'fatal_'.".format(alert['name']))
                error += 1

        if num_alerts != 0:
            param = ''
            for p in regs['param_list']:
                if p['name'] == 'NumAlerts':
                    param = p
            if param:
                # We already have an NumAlerts parameter.
                if (param['type'] != 'int' or
                        param['default'] != str(num_alerts) or
                        param['local'] != 'true'):
                    log.error(
                        'Conflicting definition of NumAlerts parameter found.')
                    error += 1
            else:
                # Generate the NumAlerts parameter.
                regs['param_list'].append({
                    'name': 'NumAlerts',
                    'type': 'int',
                    'default': str(num_alerts),
                    'desc': 'Number of alerts',
                    'local': 'true',
                    'expose': 'false',
                })

    # Change default param value if exists.
    #   Assumed param list is already validated in above `check_keys` function
    if "param_list" in regs and len(regs["param_list"]) != 0:
        for p in params:
            if p == '':
                continue

            tokens = p.split('=')
            if len(tokens) != 2:
                error += 1
                log.error("Parameter format isn't correct. {}".format(p))
            key, value = tokens[0], tokens[1]
            param, err = search_param(regs["param_list"], key)
            if err != 0:
                error += err
                continue

            value, err = check_int(
                value, component + " param[{}]".format(param["name"]))
            if err != 0:
                error += err
                continue

            param["default"] = value

    if "scan" in regs:
        scan, err = check_bool(regs["scan"], component + " scan")
    else:
        regs["scan"] = "false"

    vld_regs = []
    for x in regs['registers']:
        ck_err = check_zero_one_key(x, list_optone, "At " + hex(offset))
        if ck_err != 0:
            error += ck_err
            continue

        if 'reserved' in x:
            nreserved, ierr = check_int(x['reserved'],
                                        "Reserved at " + hex(offset))
            if ierr:
                error += 1
            else:
                offset = offset + (addrsep * nreserved)

            vld_regs.append(x)
            continue

        if 'skipto' in x:
            skipto, ierr = check_int(x['skipto'], "skipto at " + hex(offset))
            if ierr:
                error += 1
            elif (skipto < offset):
                log.error("{skipto " + x['skipto'] + "} at " + hex(offset) +
                          " evaluates as " + hex(skipto) +
                          " which would move backwards")
                error += 1
            elif (skipto % addrsep) != 0:
                log.error("{skipto " + x['skipto'] + "} at " + hex(offset) +
                          " evaluates as " + hex(skipto) +
                          " which is not a multiple of the register size " +
                          str(addrsep))
                error += 1
            else:
                offset = skipto

            vld_regs.append(x)
            continue

        if 'window' in x:
            err, offset = validate_window(x['window'], offset, fullwidth, regs)
            error += err
            vld_regs.append(x)
            continue

        if 'multireg' in x:
            try:
                multi_reg = MultiRegister(offset, addrsep, fullwidth,
                                          regs.get('param_list', []),
                                          x['multireg'])
                vld_regs.append(multi_reg)
                for reg in multi_reg.regs:
                    error += _upd_gennames(regs, offset, reg)
                offset += addrsep * len(multi_reg.regs)
            except ValueError as err:
                log.error('Error in multireg at offset {:#x}: {}'
                          .format(offset, err))
                error += 1
            continue

        try:
            reg = Register.from_raw(fullwidth, offset,
                                    regs.get('param_list', []),
                                    x)
            vld_regs.append(reg)
            error += _upd_gennames(regs, offset, reg)
        except ValueError as err:
            log.error('Error in register at offset {:#x}: {}'
                      .format(offset, err))
            error += 1
        offset += addrsep

    regs['registers'] = vld_regs

    regs['gennextoffset'] = offset
    # make the right thing happen if now exactly on power of 2
    if offset > 0:
        offset -= 1
    regs['gensize'] = 1 << offset.bit_length()

    error += check_wen_regs(regs)

    if autoregs:
        # auto generated registers go at the front
        autoregs.extend(regs['registers'])
        regs['registers'] = autoregs
        regs['genautoregs'] = True

    log.debug("Validated, size = " + hex(regs['gensize']) + " errors=" +
              str(error) + " names are " + str(regs['genrnames']))
    if (error > 0):
        log.error("Register description had " + str(error) + " error" +
                  "s" if error > 1 else "")

    regs.setdefault('inter_signal_list', [])
    regs.setdefault('bus_device', '')
    regs.setdefault('bus_host', '')

    if regs["bus_device"] == "tlul":
        # Add to inter_module_signal
        port_name = "tl" if regs["bus_host"] in ["none", ""] else "tl_d"

        regs["inter_signal_list"].append(
            OrderedDict([('struct', 'tl'), ('package', 'tlul_pkg'),
                         ('type', 'req_rsp'), ('act', 'rsp'),
                         ('name', port_name)]))

    if regs['bus_host'] == "tlul":
        port_name = "tl" if regs["bus_host"] in ["none", ""] else "tl_h"

        regs["inter_signal_list"].append(
            OrderedDict([('struct', 'tl'), ('package', 'tlul_pkg'),
                         ('type', 'req_rsp'), ('act', 'req'),
                         ('name', port_name)]))
    return error
