def Func(arg_0, arg_1, arg_2, arg_3):
    """
    A callback used to walk the Python AST looking for classes, functions,
    methods and attributes. Generates chunks of markdown markup to replace
    the existing content.

    :param node:
        An _ast module node object

    :param code_lines:
        A list of unicode strings - the source lines of the Python file

    :param sections:
        A dict of markdown document sections that need to be updated. The key
        will be a two-element tuple of the section type ("class", "function",
        "method" or "attribute") and identifier. The values are a two-element
        tuple of the start and end line number in the markdown document of the
        section.

    :param md_chunks:
        A dict with keys from the sections param and the values being a unicode
        string containing a chunk of markdown markup.
    """

    if isinstance(arg_0, _ast.FunctionDef):
        arg_4 = ('function', arg_0.name)
        if arg_4 not in arg_2:
            return

        arg_5 = ast.get_docstring(arg_0)
        arg_6 = arg_0.lineno + len(arg_0.decorator_list)

        arg_7, arg_8 = _get_func_info(arg_5, arg_6, arg_1, '> ')

        arg_9 = textwrap.dedent("""
            ### `%s()` function

            > ```python
            > %s
            > ```
            >
            %s
        """).strip() % (
            arg_0.name,
            arg_7,
            arg_8
        ) + "\n"

        arg_3[arg_4] = arg_9.replace('>\n\n', '')

    elif isinstance(arg_0, _ast.ClassDef):
        if ('class', arg_0.name) not in arg_2:
            return

        for arg_10 in arg_0.body:
            if isinstance(arg_10, _ast.FunctionDef):
                arg_11 = arg_0.name + '.' + arg_10.name

                arg_12 = ('method', arg_11)
                arg_13 = arg_12 in arg_2

                arg_14 = ('attribute', arg_11)
                arg_15 = arg_14 in arg_2

                arg_16 = arg_10.name == '__init__'

                if not arg_16 and not arg_15 and not arg_13:
                    continue

                arg_5 = ast.get_docstring(arg_10)
                arg_6 = arg_10.lineno + len(arg_10.decorator_list)

                if not arg_5:
                    continue

                if arg_13 or arg_16:
                    arg_7, arg_8 = _get_func_info(arg_5, arg_6, arg_1, '> > ')

                    if arg_16:
                        arg_4 = ('class', arg_0.name)

                        arg_17 = ast.get_docstring(arg_0) or ''
                        arg_18 = textwrap.dedent(arg_17).strip()
                        if arg_18:
                            arg_19 = "> %s\n>" % (arg_18.replace("\n", "\n> "))
                        else:
                            arg_19 = ''

                        arg_9 = textwrap.dedent("""
                            ### `%s()` class

                            %s
                            > ##### constructor
                            >
                            > > ```python
                            > > %s
                            > > ```
                            > >
                            %s
                        """).strip() % (
                            arg_0.name,
                            arg_19,
                            arg_7,
                            arg_8
                        )

                        arg_9 = arg_9.replace('\n\n\n', '\n\n')

                    else:
                        arg_4 = arg_12

                        arg_9 = textwrap.dedent("""
                            >
                            > ##### `.%s()` method
                            >
                            > > ```python
                            > > %s
                            > > ```
                            > >
                            %s
                        """).strip() % (
                            arg_10.name,
                            arg_7,
                            arg_8
                        )

                    if arg_9[-5:] == '\n> >\n':
                        arg_9 = arg_9[0:-5]

                else:
                    arg_4 = arg_14

                    arg_20 = textwrap.dedent(arg_5).strip()
                    arg_8 = "> > %s" % (arg_20.replace("\n", "\n> > "))

                    arg_9 = textwrap.dedent("""
                        >
                        > ##### `.%s` attribute
                        >
                        %s
                    """).strip() % (
                        arg_10.name,
                        arg_8
                    )

                arg_3[arg_4] = re.sub('[ \\t]+\n', '\n', arg_9.rstrip())

    elif isinstance(arg_0, _ast.If):
        for arg_21 in arg_0.body:
            Func(arg_21, arg_1, arg_2, arg_3)
        for arg_21 in arg_0.orelse:
            Func(arg_21, arg_1, arg_2, arg_3)


def Func():
    """
    Tries to find a CA certs bundle in common locations

    :raises:
        OSError - when no valid CA certs bundle was found on the filesystem

    :return:
        The full filesystem path to a CA certs bundle file
    """

    arg_0 = None

    # Common CA cert paths
    arg_1 = [
        '/usr/lib/ssl/certs/ca-certificates.crt',
        '/etc/ssl/certs/ca-certificates.crt',
        '/etc/ssl/certs/ca-bundle.crt',
        '/etc/pki/tls/certs/ca-bundle.crt',
        '/etc/ssl/ca-bundle.pem',
        '/usr/local/share/certs/ca-root-nss.crt',
        '/etc/ssl/cert.pem'
    ]

    # First try SSL_CERT_FILE
    if 'SSL_CERT_FILE' in os.environ:
        arg_1.insert(0, os.environ['SSL_CERT_FILE'])

    for arg_2 in arg_1:
        if os.path.exists(arg_2) and os.path.getsize(arg_2) > 0:
            arg_0 = arg_2
            break

    if not arg_0:
        raise OSError(pretty_message(
            '''
            Unable to find a CA certs bundle in common locations - try
            setting the SSL_CERT_FILE environmental variable
            '''
        ))

    return arg_0


def Func(arg_0=None, arg_1=False):
    """
    Extracts trusted CA certs from the system CA cert bundle

    :param cert_callback:
        A callback that is called once for each certificate in the trust store.
        It should accept two parameters: an asn1crypto.x509.Certificate object,
        and a reason. The reason will be None if the certificate is being
        exported, otherwise it will be a unicode string of the reason it won't.

    :param callback_only_on_failure:
        A boolean - if the callback should only be called when a certificate is
        not exported.

    :return:
        A list of 3-element tuples:
         - 0: a byte string of a DER-encoded certificate
         - 1: a set of unicode strings that are OIDs of purposes to trust the
              certificate for
         - 2: a set of unicode strings that are OIDs of purposes to reject the
              certificate for
    """

    arg_2 = '2.5.29.37.0'
    arg_3 = system_path()

    arg_4 = []
    with open(arg_3, 'rb') as f:
        for arg_5, arg_6, arg_7 in unarmor(f.read(), multiple=True):
            # Without more info, a certificate is trusted for all purposes
            if arg_5 == 'CERTIFICATE':
                if arg_0:
                    arg_0(Certificate.load(arg_7), None)
                arg_4.append((arg_7, set(), set()))

            # The OpenSSL TRUSTED CERTIFICATE construct adds OIDs for trusted
            # and rejected purposes, so we extract that info.
            elif arg_5 == 'TRUSTED CERTIFICATE':
                arg_8, arg_9 = TrustedCertificate.load(arg_7)
                arg_10 = False
                arg_11 = set()
                arg_12 = set()
                for arg_13 in arg_9['trust']:
                    if arg_13.dotted == arg_2:
                        arg_11 = set([arg_13.dotted])
                        break
                    arg_11.add(arg_13.dotted)
                for arg_13 in arg_9['reject']:
                    if arg_13.dotted == arg_2:
                        arg_10 = True
                        break
                    arg_12.add(arg_13.dotted)
                if arg_10:
                    if arg_0:
                        arg_0(arg_8, 'explicitly distrusted')
                    continue
                if arg_0 and not arg_1:
                    arg_0(arg_8, None)
                arg_4.append((arg_8.dump(), arg_11, arg_12))

    return arg_4


def Func(arg_0, arg_1):
    """
    Parse the TLS handshake from the client to the server to extract information
    including the cipher suite selected, if compression is enabled, the
    session id and if a new or reused session ticket exists.

    :param server_handshake_bytes:
        A byte string of the handshake data received from the server

    :param client_handshake_bytes:
        A byte string of the handshake data sent to the server

    :return:
        A dict with the following keys:
         - "protocol": unicode string
         - "cipher_suite": unicode string
         - "compression": boolean
         - "session_id": "new", "reused" or None
         - "session_ticket: "new", "reused" or None
    """

    arg_2 = None
    arg_3 = None
    arg_4 = False
    arg_5 = None
    arg_6 = None

    arg_7 = None
    arg_8 = None

    for arg_9, arg_10, arg_11 in parse_tls_records(arg_0):
        if arg_9 != b'\x16':
            continue
        for arg_12, arg_13 in parse_handshake_messages(arg_11):
            # Ensure we are working with a ServerHello message
            if arg_12 != b'\x02':
                continue
            arg_2 = {
                b'\x03\x00': "SSLv3",
                b'\x03\x01': "TLSv1",
                b'\x03\x02': "TLSv1.1",
                b'\x03\x03': "TLSv1.2",
                b'\x03\x04': "TLSv1.3",
            }[arg_13[0:2]]

            arg_14 = int_from_bytes(arg_13[34:35])
            if arg_14 > 0:
                arg_7 = arg_13[35:35 + arg_14]

            arg_15 = 35 + arg_14
            arg_16 = arg_13[arg_15:arg_15 + 2]
            arg_3 = CIPHER_SUITE_MAP[arg_16]

            arg_17 = arg_15 + 2
            arg_4 = arg_13[arg_17:arg_17 + 1] != b'\x00'

            arg_18 = arg_17 + 1
            arg_19 = arg_13[arg_18:]
            for arg_20, arg_21 in _parse_hello_extensions(arg_19):
                if arg_20 == 35:
                    arg_6 = "new"
                    break
            break

    for arg_9, arg_10, arg_11 in parse_tls_records(arg_1):
        if arg_9 != b'\x16':
            continue
        for arg_12, arg_13 in parse_handshake_messages(arg_11):
            # Ensure we are working with a ClientHello message
            if arg_12 != b'\x01':
                continue

            arg_14 = int_from_bytes(arg_13[34:35])
            if arg_14 > 0:
                arg_8 = arg_13[35:35 + arg_14]

            arg_15 = 35 + arg_14
            arg_22 = int_from_bytes(arg_13[arg_15:arg_15 + 2])

            arg_17 = arg_15 + 2 + arg_22
            arg_23 = int_from_bytes(arg_13[arg_17:arg_17 + 1])

            # On subsequent requests, the session ticket will only be seen
            # in the ClientHello message
            if arg_7 is None and arg_6 is None:
                arg_18 = arg_17 + 1 + arg_23
                arg_19 = arg_13[arg_18:]
                for arg_20, arg_21 in _parse_hello_extensions(arg_19):
                    if arg_20 == 35:
                        arg_6 = "reused"
                        break
            break

    if arg_7 is not None:
        if arg_8 is None:
            arg_5 = "new"
        else:
            if arg_8 != arg_7:
                arg_5 = "new"
            else:
                arg_5 = "reused"

    return {
        "protocol": arg_2,
        "cipher_suite": arg_3,
        "compression": arg_4,
        "session_id": arg_5,
        "session_ticket": arg_6,
    }


def Func(arg_0):
    """
    Creates a generator returning tuples of information about each record
    in a byte string of data from a TLS client or server. Stops as soon as it
    find a ChangeCipherSpec message since all data from then on is encrypted.

    :param data:
        A byte string of TLS records

    :return:
        A generator that yields 3-element tuples:
        [0] Byte string of record type
        [1] Byte string of protocol version
        [2] Byte string of record data
    """

    arg_1 = 0
    arg_2 = len(arg_0)
    while arg_1 < arg_2:
        # Don't try to parse any more once the ChangeCipherSpec is found
        if arg_0[arg_1:arg_1 + 1] == b'\x14':
            break
        arg_3 = int_from_bytes(arg_0[arg_1 + 3:arg_1 + 5])
        yield (
            arg_0[arg_1:arg_1 + 1],
            arg_0[arg_1 + 1:arg_1 + 3],
            arg_0[arg_1 + 5:arg_1 + 5 + arg_3]
        )
        arg_1 += 5 + arg_3


def Func(arg_0):
    """
    Creates a generator returning tuples of information about each message in
    a byte string of data from a TLS handshake record

    :param data:
        A byte string of a TLS handshake record data

    :return:
        A generator that yields 2-element tuples:
        [0] Byte string of message type
        [1] Byte string of message data
    """

    arg_1 = 0
    arg_2 = len(arg_0)
    while arg_1 < arg_2:
        arg_3 = int_from_bytes(arg_0[arg_1 + 1:arg_1 + 4])
        yield (
            arg_0[arg_1:arg_1 + 1],
            arg_0[arg_1 + 4:arg_1 + 4 + arg_3]
        )
        arg_1 += 4 + arg_3


def Func(arg_0):
    """
    Creates a generator returning tuples of information about each extension
    from a byte string of extension data contained in a ServerHello ores
    ClientHello message

    :param data:
        A byte string of a extension data from a TLS ServerHello or ClientHello
        message

    :return:
        A generator that yields 2-element tuples:
        [0] Byte string of extension type
        [1] Byte string of extension data
    """

    if arg_0 == b'':
        return

    arg_1 = int_from_bytes(arg_0[0:2])
    arg_2 = 2
    arg_3 = 2 + arg_1

    arg_4 = arg_2
    while arg_4 < arg_3:
        arg_5 = int_from_bytes(arg_0[arg_4:arg_4 + 2])
        arg_6 = int_from_bytes(arg_0[arg_4 + 2:arg_4 + 4])
        yield (
            arg_5,
            arg_0[arg_4 + 4:arg_4 + 4 + arg_6]
        )
        arg_4 += 4 + arg_6


def Func(arg_0, arg_1):
    """
    Raises a TLSVerificationError due to a hostname mismatch

    :param certificate:
        An asn1crypto.x509.Certificate object

    :raises:
        TLSVerificationError
    """

    arg_2 = re.match('^\\d+\\.\\d+\\.\\d+\\.\\d+$', arg_1) or arg_1.find(':') != -1
    if arg_2:
        arg_3 = 'IP address %s' % arg_1
    else:
        arg_3 = 'domain name %s' % arg_1
    arg_4 = 'Server certificate verification failed - %s does not match' % arg_3
    arg_5 = ', '.join(arg_0.valid_ips)
    arg_6 = ', '.join(arg_0.valid_domains)
    if arg_6:
        arg_4 += ' valid domains: %s' % arg_6
    if arg_6 and arg_5:
        arg_4 += ' or'
    if arg_5:
        arg_4 += ' valid IP addresses: %s' % arg_5
    raise TLSVerificationError(arg_4, arg_0)


def Func(arg_0):
    """
    Raises a TLSVerificationError due to certificate being expired, or not yet
    being valid

    :param certificate:
        An asn1crypto.x509.Certificate object

    :raises:
        TLSVerificationError
    """

    arg_1 = arg_0['tbs_certificate']['validity']
    arg_2 = arg_1['not_after'].native
    arg_3 = arg_1['not_before'].native

    arg_4 = datetime.now(timezone.utc)

    if arg_3 > arg_4:
        arg_5 = arg_3.strftime('%Y-%m-%d %H:%M:%SZ')
        arg_6 = 'Server certificate verification failed - certificate not valid until %s' % arg_5
    elif arg_2 < arg_4:
        arg_7 = arg_2.strftime('%Y-%m-%d %H:%M:%SZ')
        arg_6 = 'Server certificate verification failed - certificate expired %s' % arg_7

    raise TLSVerificationError(arg_6, arg_0)


def Func(arg_0):
    """
    Looks at the server handshake bytes to try and detect a different protocol

    :param server_handshake_bytes:
        A byte string of the handshake data received from the server

    :return:
        None, or a unicode string of "ftp", "http", "imap", "pop3", "smtp"
    """

    if arg_0[0:5] == b'HTTP/':
        return 'HTTP'

    if arg_0[0:4] == b'220 ':
        if re.match(b'^[^\r\n]*ftp', arg_0, re.I):
            return 'FTP'
        else:
            return 'SMTP'

    if arg_0[0:4] == b'220-':
        return 'FTP'

    if arg_0[0:4] == b'+OK ':
        return 'POP3'

    if arg_0[0:4] == b'* OK' or arg_0[0:9] == b'* PREAUTH':
        return 'IMAP'

    return None


def Func(arg_0):
    """
    Reads everything available from the socket - used for debugging when there
    is a protocol error

    :param socket:
        The socket to read from

    :return:
        A byte string of the remaining data
    """

    arg_1 = b''
    arg_2 = arg_0.gettimeout()
    try:
        arg_0.settimeout(0.0)
        arg_1 += arg_0.recv(8192)
    except (socket_.error):
        pass
    finally:
        arg_0.settimeout(arg_2)
    return arg_1


def Func(arg_0):
    """
    Takes a set of unicode string OIDs and converts vendor-specific OIDs into
    generics OIDs from RFCs.

     - 1.2.840.113635.100.1.3 (apple_ssl) -> 1.3.6.1.5.5.7.3.1 (server_auth)
     - 1.2.840.113635.100.1.3 (apple_ssl) -> 1.3.6.1.5.5.7.3.2 (client_auth)
     - 1.2.840.113635.100.1.8 (apple_smime) -> 1.3.6.1.5.5.7.3.4 (email_protection)
     - 1.2.840.113635.100.1.9 (apple_eap) -> 1.3.6.1.5.5.7.3.13 (eap_over_ppp)
     - 1.2.840.113635.100.1.9 (apple_eap) -> 1.3.6.1.5.5.7.3.14 (eap_over_lan)
     - 1.2.840.113635.100.1.11 (apple_ipsec) -> 1.3.6.1.5.5.7.3.5 (ipsec_end_system)
     - 1.2.840.113635.100.1.11 (apple_ipsec) -> 1.3.6.1.5.5.7.3.6 (ipsec_tunnel)
     - 1.2.840.113635.100.1.11 (apple_ipsec) -> 1.3.6.1.5.5.7.3.7 (ipsec_user)
     - 1.2.840.113635.100.1.11 (apple_ipsec) -> 1.3.6.1.5.5.7.3.17 (ipsec_ike)
     - 1.2.840.113635.100.1.16 (apple_code_signing) -> 1.3.6.1.5.5.7.3.3 (code_signing)
     - 1.2.840.113635.100.1.20 (apple_time_stamping) -> 1.3.6.1.5.5.7.3.8 (time_stamping)
     - 1.3.6.1.4.1.311.10.3.2 (microsoft_time_stamp_signing) -> 1.3.6.1.5.5.7.3.8 (time_stamping)

    :param oids:
        A set of unicode strings

    :return:
        The original set of OIDs with any mapped OIDs added
    """

    arg_1 = set()
    for arg_2 in arg_0:
        if arg_2 in _oid_map:
            arg_1 |= _oid_map[arg_2]
    return arg_0 | arg_1


def Func(arg_0, arg_1):
    """
    Checks to see if a cache file needs to be refreshed

    :param ca_path:
        A unicode string of the path to the cache file

    :param cache_length:
        An integer representing the number of hours the cache is valid for

    :return:
        A boolean - True if the cache needs to be updated, False if the file
        is up-to-date
    """

    arg_2 = os.path.exists(arg_0)
    if not arg_2:
        return True

    arg_3 = os.stat(arg_0)

    if arg_3.st_mtime < time.time() - arg_1 * 60 * 60:
        return True

    if arg_3.st_size == 0:
        return True

    return False


def Func(arg_0, arg_1, arg_2, arg_3,
                       arg_4=None):
    """
    Gets value of bits between selected range from memory

    :param start: bit address of start of bit of bits
    :param end: bit address of first bit behind bits
    :return: instance of BitsVal (derived from SimBits type) which contains
        copy of selected bits
    """
    arg_5 = 0
    arg_6 = Bits(arg_3 - arg_2, None).fromPy(None)

    while arg_2 != arg_3:
        assert arg_2 < arg_3, (arg_2, arg_3)

        arg_7 = arg_2 // arg_1

        arg_8 = arg_0[arg_7]
        if arg_4 is not None:
            arg_8 = arg_8._reinterpret_cast(arg_4)

        arg_9 = (arg_7 + 1) * arg_1
        arg_10 = min(arg_3, arg_9) - arg_2
        arg_11 = arg_2 % arg_1

        arg_12 = selectBitRange(arg_8.val, arg_11, arg_10)
        arg_13 = selectBitRange(arg_8.vldMask, arg_11, arg_10)
        arg_14 = arg_8.updateTime

        arg_15 = mask(arg_10)
        arg_6.val |= (arg_12 & arg_15) << arg_5
        arg_6.vldMask |= (arg_13 & arg_15) << arg_5
        arg_6.updateMask = max(arg_6.updateTime, arg_14)

        arg_5 += arg_10
        arg_2 += arg_10

    return arg_6


def Func(arg_0, arg_1, arg_2):
    """
    Cast HArray signal or value to signal or value of type Bits
    """
    arg_3 = int(arg_0.size)
    arg_4 = arg_0.elmType.bit_length()
    arg_5 = arg_2.bit_length()
    if arg_3 * arg_4 != arg_5:
        raise TypeConversionErr(
            "Size of types is different", arg_3 * arg_4, arg_5)

    arg_6 = Bits(arg_4)
    arg_7 = [p._reinterpret_cast(arg_6) for p in arg_1]

    return Concat(*reversed(arg_7))._reinterpret_cast(arg_2)


def Func(arg_0, arg_1):
    """
    Hdl convertible in operator, check if any of items
    in "iterable" equals "sigOrVal"
    """
    arg_2 = None
    for arg_3 in arg_1:
        arg_3 = toHVal(arg_3)
        if arg_2 is None:
            arg_2 = arg_0._eq(arg_3)
        else:
            arg_2 = arg_2 | arg_0._eq(arg_3)

    assert arg_2 is not None, "Parameter iterable is empty"
    return arg_2


def Func(arg_0, arg_1) -> RtlSignalBase:
    "Logical shift left"
    arg_2 = arg_0._dtype.bit_length()
    return arg_0[(arg_2 - arg_1):]._concat(vec(0, arg_1))


def Func(arg_0):
    """
    Returns no of bits required to store x-1
    for example x=8 returns 3
    """

    if not isinstance(arg_0, (int, float)):
        arg_0 = int(arg_0)

    if arg_0 == 0 or arg_0 == 1:
        arg_1 = 1
    else:
        arg_1 = math.ceil(math.log2(arg_0))

    return hInt(arg_1)


def Func(arg_0, arg_1, *arg_2):
        "c-like case of switch statement"
        assert arg_0.parentStm is None
        arg_1 = toHVal(arg_1, arg_0.switchOn._dtype)

        assert isinstance(arg_1, Value), arg_1
        assert arg_1._isFullVld(), "Cmp with invalid value"
        assert arg_1 not in arg_0._case_value_index, (
            "Switch statement already has case for value ", arg_1)

        arg_0.rank += 1
        arg_3 = []
        arg_0._case_value_index[arg_1] = len(arg_0.cases)
        arg_0.cases.append((arg_1, arg_3))

        arg_5 = arg_0.switchOn._eq(arg_1)
        arg_0._inputs.append(arg_5)
        arg_5.endpoints.append(arg_0)

        arg_0._register_stements(arg_2, arg_3)

        return arg_0


def Func(arg_0, *arg_1):
        """c-like default of switch statement
        """
        assert arg_0.parentStm is None
        arg_0.rank += 1
        arg_0.default = []
        arg_0._register_stements(arg_1, arg_0.default)
        return arg_0


def Func(arg_0, arg_1: arg_2[arg_3, arg_4],
                              arg_5: arg_6[arg_7]):
        """
        Register signals from interfaces for Interface or Unit instances
        """
        if hasattr(arg_1, "_interfaces") and arg_1._interfaces:
            arg_8 = arg_1._name
            arg_9 = arg_0.vcdWriter if arg_5 is None else arg_5

            arg_10 = arg_9.varScope(arg_8)
            arg_0._obj2scope[arg_1] = arg_10

            with arg_10:
                # register all subinterfaces
                for arg_12 in arg_1._interfaces:
                    arg_0.Func(arg_12, arg_10)

                if isinstance(arg_1, (arg_4, SimModel)):
                    # register interfaces from all subunits
                    for arg_13 in arg_1._units:
                        arg_0.Func(arg_13, arg_10)

            return arg_10
        else:
            arg_14 = arg_1._dtype
            if isinstance(arg_14, arg_0.supported_type_classes):
                arg_15, arg_16, arg_17 = vcdTypeInfoForHType(arg_14)
                try:
                    arg_5.addVar(arg_1, getSignalName(arg_1),
                                  arg_15, arg_16, arg_17)
                except VarAlreadyRegistered:
                    pass


def Func(arg_0, arg_1, arg_2, arg_3):
        """
        This method is called for every value change of any signal.
        """
        try:
            arg_0.vcdWriter.Func(arg_1, arg_2, arg_3)
        except KeyError:
            # not every signal has to be registered
            pass


def Func(arg_0, arg_1, arg_2):
        """
        Serialize Func instance

        :param scope: name scope to prevent name collisions
        """
        arg_3 = arg_1.statements
        arg_4 = arg_2.withIndent()
        arg_5 = [arg_0.asHdl(s, arg_4) for s in arg_3]
        arg_1.name = arg_2.scope.checkedName(arg_1.name, arg_1)

        return arg_0.methodTmpl.render(
            indent=getIndent(arg_2.indent),
            arg_6=arg_1.name,
            statements=arg_5
        )


def Func(arg_0):
    """
    Walk all interfaces on unit and instantiate agent for every interface.

    :return: all monitor/driver functions which should be added to simulation
         as processes
    """
    arg_1 = []
    for arg_2 in arg_0._interfaces:
        if not arg_2._isExtern:
            continue

        arg_2._initSimAgent()
        assert arg_2._ag is not None, arg_2
        arg_3 = [arg_2._ag, ]

        if arg_2._direction == INTF_DIRECTION.MASTER:
            arg_4 = list(map(lambda a: a.getMonitors(), arg_3))
        elif arg_2._direction == INTF_DIRECTION.SLAVE:
            arg_4 = list(map(lambda a: a.getDrivers(), arg_3))
        else:
            raise NotImplementedError("intf._direction %r for %r" % (
                arg_2._direction, arg_2))

        for arg_5 in arg_4:
            arg_1.extend(arg_5)

    return arg_1


def Func(arg_0):
        """
        If interface has associated clk return it otherwise
        try to find clk on parent recursively
        """
        arg_1 = arg_0._associatedClk

        if arg_1 is not None:
            return arg_1

        arg_2 = arg_0._parent
        assert arg_2 is not None

        if isinstance(arg_2, UnitBase):
            return getClk(arg_2)
        else:
            return arg_2.Func()


def Func(arg_0, arg_1):
    """
    same like itertools.groupby

    :note: This function does not needs initial sorting like itertools.groupby

    :attention: Order of pairs is not deterministic.
    """
    arg_2 = {}
    for arg_3 in arg_0:
        arg_4 = arg_1(arg_3)
        try:
            arg_5 = arg_2[arg_4]
        except KeyError:
            arg_5 = []
            arg_2[arg_4] = arg_5
        arg_5.append(arg_3)

    yield from arg_2.items()


def Func(arg_0, arg_1=arg_2):
    """
    Flatten nested lists, tuples, generators and maps

    :param level: maximum depth of Funcing
    """
    if arg_1 >= 0 and isinstance(arg_0, (list, tuple, GeneratorType,
                                             map, zip)):
        arg_1 -= 1
        for arg_3 in arg_0:
            yield from Func(arg_3, arg_1=arg_1)
    else:
        yield arg_0


def Func(arg_0):
    """
    If signal is not driving anything remove it
    """

    arg_1 = set()
    arg_2 = arg_0.signals

    while arg_2:
        arg_3 = set()

        for arg_4 in arg_2:
            if not arg_4.endpoints:
                try:
                    if arg_4._interface is not None:
                        # skip interfaces before we want to check them,
                        # they should not be optimized out from design
                        continue
                except AttributeError:
                    pass

                for arg_5 in arg_4.drivers:
                    # drivers of this signal are useless rm them
                    if isinstance(arg_5, Operator):
                        arg_6 = arg_5.operands
                        if arg_5.result is arg_4:
                            arg_5.result = None
                    else:
                        arg_6 = arg_5._inputs
                        arg_0.statements.discard(arg_5)

                    for arg_8 in arg_6:
                        if not isinstance(arg_8, Value):
                            try:
                                arg_8.endpoints.remove(arg_5)
                            except KeyError:
                                # this operator has 2x+ same operand
                                continue

                            arg_3.add(arg_8)

                arg_1.add(arg_4)

        if arg_1:
            for arg_4 in arg_1:
                if arg_4.ctx == arg_0:
                    arg_0.signals.remove(arg_4)
                arg_3.discard(arg_4)
            arg_1 = set()
        arg_2 = arg_3


def Func(arg_0: arg_1, arg_2: arg_1):
    """
    Try merge procB into procA

    :raise IncompatibleStructure: if merge is not possible
    :attention: procA is now result if merge has succeed
    :return: procA which is now result of merge
    """
    if (checkIfIsTooSimple(arg_0) or
            checkIfIsTooSimple(arg_2) or
            areSetsIntersets(arg_0.outputs, arg_2.sensitivityList) or
            areSetsIntersets(arg_2.outputs, arg_0.sensitivityList) or
            not HdlStatement._is_mergable_statement_list(arg_0.statements, arg_2.statements)):
        raise IncompatibleStructure()

    arg_0.statements = HdlStatement._merge_statement_lists(
        arg_0.statements, arg_2.statements)

    arg_0.outputs.extend(arg_2.outputs)
    arg_0.inputs.extend(arg_2.inputs)
    arg_0.sensitivityList.extend(arg_2.sensitivityList)

    return arg_0


def Func(arg_0, arg_1, arg_2, arg_3):
        """
        on writeReqRecieved in monitor mode
        """
        arg_0.requests.append((WRITE, arg_2, arg_3))


def Func(arg_0: arg_1, arg_2: arg_3=None,
          arg_4: arg_5=arg_6,
          arg_7=arg_8(), arg_9: arg_3=None):
    """
    Convert unit to RTL using specified serializer

    :param unitOrCls: unit instance or class, which should be converted
    :param name: name override of top unit (if is None name is derived
        form class name)
    :param serializer: serializer which should be used for to RTL conversion
    :param targetPlatform: metainformatins about target platform, distributed
        on every unit under _targetPlatform attribute
        before Unit._impl() is called
    :param saveTo: directory where files should be stored
        If None RTL is returned as string.
    :raturn: if saveTo returns RTL string else returns list of file names
        which were created
    """
    if not isinstance(arg_0, arg_1):
        arg_10 = arg_0()
    else:
        arg_10 = arg_0

    arg_10._loadDeclarations()
    if arg_2 is not None:
        assert isinstance(arg_2, arg_3)
        arg_10._name = arg_2

    arg_12 = arg_4.getBaseNameScope()
    arg_13 = {}

    # unitCls : unitobj
    arg_14 = {}

    # (unitCls, paramsValues) : unitObj
    # where paramsValues are dict name:value
    arg_15 = {}

    arg_16 = True

    arg_17 = arg_9 is not None
    if arg_17:
        os.makedirs(arg_9, exist_ok=True)
        arg_18 = UniqList()
    else:
        arg_19 = []

    for arg_20 in arg_10._Func(arg_7):
        arg_16 = arg_4.serializationDecision(
            arg_20,
            arg_14,
            arg_15)
        if arg_16:
            if isinstance(arg_20, Entity):
                arg_21 = arg_12.fork(1)
                arg_21.setLevel(2)
                arg_22 = arg_4.getBaseContext()
                arg_22.scope = arg_21
                arg_13[arg_20] = arg_22
                arg_22.currentUnit = arg_20.origin

                arg_25 = arg_4.Entity(arg_20, arg_22)
                if arg_17:
                    arg_26 = arg_20.name + arg_4.fileExtension
                    arg_27 = 'w'

            elif isinstance(arg_20, Architecture):
                try:
                    arg_22 = arg_13[arg_20.entity]
                except KeyError:
                    raise SerializerException(
                        "Entity should be serialized"
                        " before architecture of %s"
                        % (arg_20.getEntityName()))

                arg_25 = arg_4.Architecture(arg_20, arg_22)
                if arg_17:
                    arg_26 = arg_20.getEntityName() + arg_4.fileExtension
                    arg_27 = 'a'
            else:
                if hasattr(arg_20, "_hdlSources"):
                    for arg_28 in arg_20._hdlSources:
                        if isinstance(arg_28, arg_3):
                            shutil.copy2(arg_28, arg_9)
                            arg_18.append(arg_28)
                            continue
                else:
                    arg_25 = arg_4.asHdl(arg_20)

            if arg_25:
                if arg_17:
                    arg_29 = os.path.join(arg_9, arg_26)
                    arg_18.append(arg_29)
                    with open(arg_29, arg_27) as f:
                        if arg_27 == 'a':
                            f.write("\n")

                        f.write(
                            arg_4.formatter(arg_25)
                        )
                else:
                    arg_19.append(arg_25)

        elif not arg_17:
            try:
                arg_2 = '"%s"' % arg_20.name
            except AttributeError:
                arg_2 = ""
            arg_19.append(arg_4.comment(
                "Object of class %s, %s was not serialized as specified" % (
                    arg_20.__class__.__name__, arg_2)))

    if arg_17:
        return arg_18
    else:
        return arg_4.formatter(
            "\n".join(arg_19)
        )


def Func(arg_0, arg_1, arg_2=arg_3, arg_4=None, arg_5=None, arg_6=None):
        """
        Create new Funcnal in this context

        :param clk: clk Funcnal, if specified Funcnal is synthesized
            as SyncSignal
        :param syncRst: synchronous reset Funcnal
        """
        if isinstance(arg_6, RtlSignal):
            assert arg_6._const, \
                "Initial value of register has to be constant"
            arg_7 = arg_6._auto_cast(arg_2)
        elif isinstance(arg_6, Value):
            arg_7 = arg_6._auto_cast(arg_2)
        elif isinstance(arg_6, InterfaceBase):
            arg_7 = arg_6._Func
        else:
            arg_7 = arg_2.fromPy(arg_6)

        if arg_4 is not None:
            arg_8 = RtlSyncSignal(arg_0, arg_1, arg_2, arg_7)
            if arg_5 is not None and arg_6 is None:
                raise SigLvlConfErr(
                    "Probably forgotten default value on sync Funcnal %s", arg_1)
            if arg_5 is not None:
                arg_9 = If(arg_5._isOn(),
                       RtlSignal.__call__(arg_8, arg_7)
                       ).Else(
                    RtlSignal.__call__(arg_8, arg_8.next)
                )
            else:
                arg_9 = [RtlSignal.__call__(arg_8, arg_8.next)]

            If(arg_4._onRisingEdge(),
               arg_9
               )
        else:
            if arg_5:
                raise SigLvlConfErr(
                    "Signal %s has reset but has no clk" % arg_1)
            arg_8 = RtlSignal(arg_0, arg_1, arg_2, arg_6=arg_7)

        arg_0.Funcnals.add(arg_8)

        return arg_8


def Func(arg_0):
    """
    Get maximum _instId from all assigments in statement
    """
    arg_1 = 0
    if isinstance(arg_0, Assignment):
        return arg_0._instId
    elif isinstance(arg_0, WaitStm):
        return arg_1
    else:
        for arg_2 in arg_0._iter_stms():
            arg_1 = max(arg_1, Func(arg_2))
        return arg_1


def Func(arg_0):
    """
    get max statement id,
    used for sorting of processes in architecture
    """
    arg_1 = 0
    for arg_2 in arg_0.statements:
        arg_1 = max(arg_1, getMaxStmIdForStm(arg_2))
    return arg_1


def Func(arg_0, arg_1, arg_2):
        """write data to interface"""
        arg_1.write(arg_2, arg_0.intf.data)


def Func(arg_0):
        """
        Note that this interface will be master

        :return: self
        """
        assert not hasattr(arg_0, "_interfaces") or not arg_0._interfaces, \
            "Too late to change direction of interface"
        arg_0._direction = DIRECTION.asIntfDirection(DIRECTION.opposite(arg_0.FuncasterDir))

        return arg_0


def Func(arg_0):
        """
        load declaratoins from _declr method
        This function is called first for parent and then for children
        """
        if not hasattr(arg_0, "_interfaces"):
            arg_0._interfaces = []
        arg_0._setAttrListener = arg_0._declrCollector
        arg_0._declr()
        arg_0._setAttrListener = None

        for arg_3 in arg_0._interfaces:
            arg_3._isExtern = arg_0._isExtern
            arg_3.Func()

        for arg_5 in arg_0._params:
            arg_5.setReadOnly()

        if arg_0._isExtern:
            # direction from inside of unit (reverset compared to outside direction)
            if arg_0._direction == INTF_DIRECTION.UNKNOWN:
                arg_0._direction = INTF_DIRECTION.MASTER
            arg_0._setDirectionsLikeIn(arg_0._direction)


def Func(arg_0, arg_1, arg_2='', arg_3=None):
        """
        generate _sig for each interface which has no subinterface
        if already has _sig return it instead

        :param context: instance of RtlNetlist where signals should be created
        :param prefix: name prefix for created signals
        :param typeTransform: optional function (type) returns modified type
            for signal
        """
        arg_4 = []
        if arg_0._interfaces:
            for arg_5 in arg_0._interfaces:
                arg_4.extend(
                    arg_5.Func(arg_1, arg_2,
                                              arg_3=arg_3))
        else:
            if hasattr(arg_0, '_sig'):
                arg_4 = [arg_0._sig]
            else:
                arg_6 = arg_0._dtype
                if arg_3 is not None:
                    arg_6 = arg_3(arg_6)

                arg_7 = arg_1.sig(arg_2 + arg_0._getPhysicalName(), arg_6)
                arg_7._interface = arg_0
                arg_0._sig = arg_7

                if hasattr(arg_0, '_boundedEntityPort'):
                    arg_0._boundedEntityPort.connectSig(arg_0._sig)
                arg_4 = [arg_7]

        return arg_4


def Func(arg_0):
        """Get name in HDL """
        if hasattr(arg_0, "_boundedEntityPort"):
            return arg_0._boundedEntityPort.name
        else:
            return arg_0._getFullName().replace('.', arg_0._NAME_SEPARATOR)


def Func(arg_0, arg_1, arg_2=None):
        """Load all operands and process them by self._FuncFn"""
        def getVal(arg_3):
            while not isinstance(arg_3, Value):
                arg_3 = arg_3._val

            return arg_3

        arg_4 = list(map(getVal, arg_1.operands))

        if isEventDependentOp(arg_1.operator):
            arg_4.append(arg_2.now)
        elif arg_1.operator == AllOps.IntToBits:
            arg_4.append(arg_1.result._dtype)

        return arg_0._FuncFn(*arg_4)


def Func(arg_0, arg_1, arg_2):
    """
    Cast signed-unsigned, to int or bool
    """
    if isinstance(arg_1, Value):
        return Func__val(arg_0, arg_1, arg_2)
    elif isinstance(arg_2, HBool):
        if arg_0.bit_length() == 1:
            arg_3 = 0 if arg_1._dtype.negated else 1
            return arg_1._eq(arg_0.getValueCls().fromPy(arg_3, arg_0))
    elif isinstance(arg_2, Bits):
        if arg_0.bit_length() == arg_2.bit_length():
            return arg_1._convSign(arg_2.signed)
    elif arg_2 == INT:
        return Operator.withRes(AllOps.BitsToInt, [arg_1], arg_2)

    return default_auto_cast_fn(arg_0, arg_1, arg_2)


def Func(arg_0, arg_1):
    """
    Reinterpret signal of type Bits to signal of type HStruct
    """
    arg_2 = arg_1.fromPy(None)
    arg_3 = 0
    for arg_4 in arg_1.fields:
        arg_5 = arg_4.dtype
        arg_6 = arg_5.bit_length()
        if arg_4.name is not None:
            arg_7 = arg_0[(arg_6 + arg_3):arg_3]
            arg_7 = arg_7._reinterpret_cast(arg_5)
            setattr(arg_2, arg_4.name, arg_7)

        arg_3 += arg_6

    return arg_2


def Func(arg_0, arg_1: 'TransTmpl', arg_2: arg_3):
        """
        Group transaction parts splited on words to words

        :param transaction: TransTmpl instance which parts
            should be grupped into words
        :return: generator of tuples (wordIndex, list of transaction parts
            in this word)
        """
        arg_4 = None
        arg_5 = []
        arg_6 = arg_0.wordWidth
        for arg_7 in arg_0.splitOnWords(arg_1, arg_2):
            arg_8 = arg_7.startOfPart // arg_6
            if arg_4 is None:
                arg_4 = arg_8
                arg_5.append(arg_7)
            elif arg_8 > arg_4:
                yield (arg_4, arg_5)
                arg_4 = arg_8
                arg_5 = [arg_7, ]
            else:
                arg_5.append(arg_7)

        if arg_5:
            yield (arg_4, arg_5)


def Func(arg_0, arg_1="", arg_2=0, arg_3=arg_4.stdout):
    """
    Pretty print interface
    """
    try:
        arg_6 = arg_0._sig
    except AttributeError:
        arg_6 = ""
    if arg_6 is not "":
        arg_6 = " " + repr(arg_6)

    arg_3.write("".join([getIndent(arg_2), arg_1, repr(arg_0._getFullName()),
                        arg_6]))
    arg_3.write("\n")

    if isinstance(arg_0, HObjList):
        for arg_7, arg_8 in enumerate(arg_0):
            # interfaces have already name of this array and index in it's name
            Func(arg_8, arg_1=arg_1, arg_2=arg_2 + 1, arg_3=arg_3)
    else:
        for arg_7 in arg_0._interfaces:
            Func(arg_7, arg_2=arg_2 + 1, arg_3=arg_3)


def Func(arg_0: 'TransTmpl',
                            arg_1: arg_2,
                            arg_3: arg_4[arg_2, arg_5]=arg_6,
                            arg_7: arg_4[arg_2, arg_5]=arg_6,
                            arg_8: arg_9=False,
                            arg_10: arg_9=False) -> Generator[
                                'FrameTmpl', None, None]:
        """
        Convert transaction template into FrameTmpls

        :param transaction: transaction template used which are FrameTmpls
            created from
        :param wordWidth: width of data signal in target interface
            where frames will be used
        :param maxFrameLen: maximum length of frame in bits,
            if exceeded another frame will be created
        :param maxPaddingWords: maximum of continual padding words in frame,
            if exceed frame is split and words are cut of
        :attention: if maxPaddingWords<inf trimPaddingWordsOnEnd
            or trimPaddingWordsOnStart has to be True
            to decide where padding should be trimmed
        :param trimPaddingWordsOnStart: trim padding from start of frame
            at word granularity
        :param trimPaddingWordsOnEnd: trim padding from end of frame
            at word granularity
        """
        arg_11 = True
        arg_12 = False

        arg_13 = 0
        assert arg_3 > 0
        assert arg_7 >= 0
        if arg_7 < arg_6:
            assert arg_8 or arg_10, \
                "Padding has to be cut off somewhere"

        arg_14 = TransTmplWordIterator(arg_1)
        arg_15 = 0
        arg_16 = arg_3
        arg_17 = []
        for arg_18, arg_19 in arg_14.groupByWordIndex(arg_0, 0):
            if arg_18 * arg_1 >= arg_16:
                # now in first+ word behind the frame
                # cut off padding at end of frame
                arg_20 = arg_18 - arg_15
                if arg_10 and arg_20 > arg_7:
                    # cut off padding and align end of frame to word
                    arg_21 = (arg_15 + 1) * arg_1
                else:
                    arg_21 = arg_18 * arg_1

                yield FrameTmpl(arg_0,
                                arg_1,
                                arg_13,
                                arg_21,
                                arg_17)

                # prepare for start of new frame
                arg_17 = []
                arg_11 = True
                arg_12 = False
                # start on new word
                arg_13 = arg_21
                arg_16 = arg_13 + arg_3
                arg_15 = arg_18

            # check if padding at potential end of frame can be cut off
            if (not arg_11
                    and arg_10
                    and arg_18 - arg_15 > 1):
                # there is too much continual padding,
                # cut it out and start new frame
                arg_21 = (arg_15 + 1) * arg_1
                yield FrameTmpl(arg_0,
                                arg_1,
                                arg_13,
                                arg_21,
                                arg_17)

                # prepare for start of new frame
                arg_17 = []
                arg_11 = True
                arg_12 = False
                # start on new word
                arg_13 = arg_21
                arg_16 = arg_13 + arg_3
                arg_15 = arg_18 - 1

            if arg_11:
                arg_12 = True
                arg_11 = False
                # cut off padding at start of frame
                arg_20 = arg_18 - arg_15
                if arg_8 and arg_20 > arg_7:
                    arg_13 += arg_20 * arg_1

                arg_16 = arg_13 + arg_3

            # resolve end of this part
            arg_17.extend(arg_19)
            arg_15 = arg_18

        # reminder in "parts" after last iteration
        arg_16 = arg_0.bitAddrEnd
        arg_22 = not (arg_10 or arg_8)
        if arg_12 or (arg_22
                            and arg_16 != arg_13):
            # cut off padding at end of frame
            arg_23 = (arg_15 + 1) * arg_1
            if arg_16 < arg_23:
                arg_16 = arg_23
            else:
                arg_20 = arg_14.fullWordCnt(arg_23, arg_16)
                if arg_10 and arg_20 > arg_7:
                    arg_16 -= arg_20 * arg_1
                    # align end of frame to word
            arg_16 = min(arg_13 +
                                 arg_3, arg_16)

            yield FrameTmpl(arg_0,
                            arg_1,
                            arg_13,
                            arg_16,
                            arg_17)
            arg_17 = []
            arg_13 = arg_16

        # final padding on the end
        while arg_22 and arg_13 < arg_0.bitAddrEnd:
            arg_16 = min(arg_13 +
                                 arg_3, arg_0.bitAddrEnd)

            yield FrameTmpl(arg_0,
                            arg_1,
                            arg_13,
                            arg_16,
                            [])

            arg_13 = arg_16


def Func(arg_0, arg_1: arg_2=False):
        """
        Walk enumerated words in this frame

        :attention: not all indexes has to be present, only words
            with items will be generated when not showPadding
        :param showPadding: padding TransParts are also present
        :return: generator of tuples (wordIndex, list of TransParts
            in this word)
        """
        arg_3 = 0
        arg_4 = arg_0.startBitAddr
        arg_5 = []
        for arg_6 in arg_0.parts:
            arg_7 = arg_6.startOfPart
            if arg_1 and arg_7 != arg_4:
                # insert padding
                while arg_7 != arg_4:
                    assert arg_7 >= arg_4, (arg_7, arg_4)
                    arg_8 = ceil(
                        (arg_4 + 1) / arg_0.wordWidth) * arg_0.wordWidth
                    arg_9 = min(arg_8, arg_7)
                    arg_10 = TransPart(arg_0, None, arg_4, arg_9, 0)
                    arg_5.append(arg_10)

                    if arg_9 >= arg_8:
                        yield (arg_3, arg_5)
                        arg_3 += 1
                        arg_5 = []

                    arg_4 = arg_9

            if arg_0._wordIndx(arg_4) != arg_0._wordIndx(arg_6.startOfPart):
                yield (arg_3, arg_5)

                arg_3 += 1
                arg_5 = []
                arg_4 = arg_6.endOfPart

            arg_5.append(arg_6)
            arg_4 = arg_6.endOfPart
            if arg_4 % arg_0.wordWidth == 0:
                yield (arg_3, arg_5)

                arg_3 += 1
                arg_5 = []

        if arg_1 and (arg_5
                            or arg_4 != arg_0.endBitAddr
                            or arg_4 % arg_0.wordWidth != 0):
            # align end to end of last word
            arg_7 = ceil(arg_0.endBitAddr / arg_0.wordWidth) * arg_0.wordWidth
            while arg_7 != arg_4:
                assert arg_7 >= arg_4, (arg_7, arg_4)
                arg_8 = ((arg_4 // arg_0.wordWidth) + 1) * arg_0.wordWidth
                arg_9 = min(arg_8, arg_7)
                arg_10 = TransPart(arg_0, None, arg_4, arg_9, 0)
                arg_10.parent = arg_0
                arg_5.append(arg_10)

                if arg_9 >= arg_8:
                    yield (arg_3, arg_5)
                    arg_3 += 1
                    arg_5 = []

                arg_4 = arg_9

            if arg_5:
                # in the case end of frame is not aligned to end of word
                yield (arg_3, arg_5)


def Func(arg_0, arg_1):
        """
        Pack data into list of BitsVal of specified dataWidth

        :param data: dict of values for struct fields {fieldName: value}

        :return: list of BitsVal which are representing values of words
        """
        arg_2 = simBitsT(arg_0.wordWidth, None)
        arg_3 = arg_0._fieldToTPart
        if arg_3 is None:
            arg_3 = arg_0._fieldToTPart = arg_0.fieldToDataDict(
                arg_0.origin.dtype,
                arg_1,
                {})

        for arg_4, arg_5 in arg_0.walkWords(showPadding=True):
            arg_6 = 0
            arg_7 = 0
            for arg_8 in arg_5:
                arg_9, arg_10 = arg_8.getBusWordBitRange()
                arg_11, arg_12 = arg_8.getFieldBitRange()
                if not arg_8.isPadding:
                    arg_13 = arg_3.get(arg_8.tmpl.origin, None)
                else:
                    arg_13 = None

                if arg_13 is None:
                    arg_14 = 0
                    arg_15 = 0
                else:
                    arg_14 = selectBitRange(arg_13, arg_12, arg_11 - arg_12)
                    arg_15 = mask(arg_9 - arg_10) << arg_10

                arg_7 = setBitRange(arg_7, arg_10, arg_9 - arg_10, arg_14)
                arg_6 = setBitRange(arg_7, arg_10, arg_9 - arg_10, arg_15)

            yield arg_2.getValueCls()(arg_7, arg_2,
                                           arg_6, -1)


def Func(arg_0):
        """
        Clean informations about enclosure for outputs and sensitivity
        of this statement
        """
        arg_0._enclosed_for = None
        arg_0._sensitivity = None
        for arg_3 in arg_0._iter_stms():
            arg_3.Func()


def Func(arg_0,
                                  arg_1: arg_2[arg_3],
                                  arg_4: arg_5, arg_6: arg_7)\
            -> None:
        """
        Discover sensitivity for list of signals

        """
        arg_8 = arg_5()
        for arg_9 in arg_1:
            arg_9._walk_sensitivity(arg_8, arg_4, arg_6)
            if arg_6.contains_ev_dependency:
                break

        # if event dependent sensitivity found do not add other sensitivity
        if not arg_6.contains_ev_dependency:
            arg_6.extend(arg_8)


def Func(arg_0):
        """
        get RtlNetlist context from signals
        """
        for arg_1 in chain(arg_0._inputs, arg_0._outputs):
            if arg_1.ctx:
                return arg_1.ctx
            else:
                # Param instances does not have context
                continue
        raise HwtSyntaxError(
            "Statement does not have any signal in any context", arg_0)


def Func(arg_0, arg_1: arg_2, arg_3: arg_2,
                   arg_4: arg_5["HdlStatement"]) -> None:
        """
        Update signal IO after reuce atempt

        :param self_reduced: if True this object was reduced
        :param io_changed: if True IO of this object may changed
            and has to be updated
        :param result_statements: list of statements which are result
            of reduce operation on this statement
        """

        arg_6 = arg_0.parentStm
        if arg_1:
            arg_7 = arg_6 is None
            # update signal drivers/endpoints
            if arg_7:
                # disconnect self from signals
                arg_8 = arg_0._get_rtl_context()
                arg_8.statements.remove(arg_0)
                arg_8.statements.update(arg_4)

                for arg_9 in arg_0._inputs:
                    arg_9.endpoints.discard(arg_0)
                for arg_10 in arg_0._outputs:
                    arg_10.drivers.remove(arg_0)

            for arg_11 in arg_4:
                arg_11.parentStm = arg_6
                if arg_6 is None:
                    # conect signals to child statements
                    for arg_12 in arg_11._inputs:
                        arg_12.endpoints.append(arg_11)
                    for arg_13 in arg_11._outputs:
                        arg_13.drivers.append(arg_11)
        else:
            # parent has to update it's inputs/outputs
            if arg_3:
                arg_0._inputs = UniqList()
                arg_0._outputs = UniqList()
                arg_0._collect_io()


def Func(arg_0, arg_1):
        """
        After merging statements update IO, sensitivity and context

        :attention: rank is not updated
        """
        arg_0._inputs.extend(arg_1._inputs)
        arg_0._outputs.extend(arg_1._outputs)

        if arg_0._sensitivity is not None:
            arg_0._sensitivity.extend(arg_1._sensitivity)
        else:
            assert arg_1._sensitivity is None

        if arg_0._enclosed_for is not None:
            arg_0._enclosed_for.update(arg_1._enclosed_for)
        else:
            assert arg_1._enclosed_for is None

        arg_2 = arg_1.parentStm is None
        if arg_2:
            arg_1._get_rtl_context().statements.remove(arg_1)
            for arg_3 in arg_1._inputs:
                arg_3.endpoints.discard(arg_1)
                arg_3.endpoints.append(arg_0)

            for arg_3 in arg_1._outputs:
                arg_3.drivers.discard(arg_1)
                arg_3.drivers.append(arg_0)


def Func(arg_0: arg_1["HdlStatement"])\
            -> Tuple[arg_1["HdlStatement"], int]:
        """
        Merge statements in list to remove duplicated if-then-else trees

        :return: tuple (list of merged statements, rank decrease due merging)
        :note: rank decrease is sum of ranks of reduced statements
        :attention: statement list has to me mergable
        """
        arg_2 = {}
        for arg_3, arg_4 in enumerate(arg_0):
            arg_2[arg_4] = arg_3

        arg_5 = []
        arg_6 = 0

        for arg_7, arg_8 in groupedby(arg_0, lambda s: s.rank):
            if arg_7 == 0:
                arg_5.extend(arg_8)
            else:
                if len(arg_8) == 1:
                    arg_5.extend(arg_8)
                    continue

                # try to merge statements if they are same condition tree
                for arg_9, arg_10 in enumerate(arg_8):
                    if arg_10 is None:
                        continue

                    for arg_11, arg_12 in enumerate(islice(arg_8, arg_9 + 1, None)):
                        if arg_12 is None:
                            continue

                        if arg_10._is_mergable(arg_12):
                            arg_6 += arg_12.rank
                            arg_10._merge_with_other_stm(arg_12)
                            arg_8[arg_9 + 1 + arg_11] = None
                            arg_5.append(arg_10)
                        else:
                            arg_5.append(arg_10)
                            arg_5.append(arg_12)

        arg_5.sort(key=lambda arg_4: arg_2[arg_4])
        return arg_5, arg_6


def Func(arg_0: arg_1["HdlStatement"]):
        """
        Simplify statements in the list
        """
        arg_2 = False
        arg_3 = []

        for arg_4 in arg_0:
            arg_5, arg_6 = arg_4._try_reduce()
            arg_3.extend(arg_5)
            arg_2 |= arg_6

        arg_3, arg_7 = HdlStatement._merge_statements(
            arg_3)

        return arg_3, arg_7, arg_2


def Func(arg_0):
        """
        After parrent statement become event dependent
        propagate event dependency flag to child statements
        """
        if not arg_0._is_completly_event_dependent:
            arg_0._is_completly_event_dependent = True
            for arg_2 in arg_0._iter_stms():
                arg_2.Func()


def Func(arg_0, arg_1: arg_2["HdlStatement"],
                           arg_3: arg_2["HdlStatement"]):
        """
        Append statements to this container under conditions specified
        by condSet
        """
        for arg_4 in flatten(arg_1):
            assert arg_4.parentStm is None, arg_4
            arg_4._set_parent_stm(arg_0)
            arg_3.append(arg_4)


def Func(arg_0):
        """
        Disconnect this statement from signals and delete it from RtlNetlist context

        :attention: signal endpoints/drivers will be altered
            that means they can not be used for iteration
        """
        arg_1 = arg_0._get_rtl_context()
        for arg_2 in arg_0._inputs:
            arg_2.endpoints.discard(arg_0)

        for arg_3 in arg_0._outputs:
            arg_3.drivers.remove(arg_0)

        arg_1.statements.remove(arg_0)


def Func(arg_0, arg_1, arg_2=arg_3, arg_4=None, arg_5=None, arg_6=None):
        """
        Create register in this unit

        :param defVal: default value of this register,
            if this value is specified reset of this component is used
            (unit has to have single interface of class Rst or Rst_n)
        :param clk: optional clok signal specification
        :param rst: optional reset signal specification
        :note: rst/rst_n resolution is done from signal type,
            if it is negated type it is rst_n
        :note: if clk or rst is not specifid default signal
            from parent unit will be used
        """
        if arg_5 is None:
            arg_5 = getClk(arg_0)

        if arg_4 is None:
            # if no value is specified reset is not required
            arg_6 = None
        else:
            arg_6 = getRst(arg_0)._sig

        if isinstance(arg_2, HStruct):
            if arg_4 is not None:
                raise NotImplementedError()
            arg_7 = arg_2.fromPy(None)
            for arg_8 in arg_2.fields:
                if arg_8.name is not None:
                    arg_9 = arg_0.Func("%s_%s" % (arg_1, arg_8.name), arg_8.dtype)
                    setattr(arg_7, arg_8.name, arg_9)

            return arg_7

        return arg_0._ctx.sig(arg_1,
                             arg_2=arg_2,
                             arg_5=arg_5._sig,
                             syncRst=arg_6,
                             arg_4=arg_4)


def Func(arg_0, arg_1, arg_2=arg_3, arg_4=None):
        """
        Create signal in this unit
        """
        if isinstance(arg_2, HStruct):
            if arg_4 is not None:
                raise NotImplementedError()
            arg_5 = arg_2.fromPy(None)
            for arg_6 in arg_2.fields:
                if arg_6.name is not None:
                    arg_7 = arg_0.Func("%s_%s" % (arg_1, arg_6.name), arg_6.dtype)
                    setattr(arg_5, arg_6.name, arg_7)

            return arg_5

        return arg_0._ctx.sig(arg_1, arg_2=arg_2, arg_4=arg_4)


def Func(arg_0, arg_1=True):
    """
    Walk all simple values in HStruct or HArray
    """
    arg_2 = arg_0._dtype
    if isinstance(arg_2, Bits):
        yield arg_0
    elif isinstance(arg_2, HUnion):
        yield from Func(arg_0._val, arg_1=arg_1)
    elif isinstance(arg_2, HStruct):
        for arg_3 in arg_2.fields:
            arg_4 = arg_3.name is None
            if not arg_4 or not arg_1:
                if arg_4:
                    arg_5 = arg_3.dtype.fromPy(None)
                else:
                    arg_5 = getattr(arg_0, arg_3.name)

                yield from Func(arg_5)

    elif isinstance(arg_2, HArray):
        for arg_6 in arg_0:
            yield from Func(arg_6)
    else:
        raise NotImplementedError(arg_2)


def Func(arg_0, arg_1):
        """
        Convert signum, no bit manipulation just data are represented
        differently

        :param signed: if True value will be signed,
            if False value will be unsigned,
            if None value will be vector without any sign specification
        """
        if isinstance(arg_0, Value):
            return arg_0.Func__val(arg_1)
        else:
            if arg_0._dtype.signed == arg_1:
                return arg_0
            arg_2 = copy(arg_0._dtype)
            arg_2.signed = arg_1
            if arg_1 is None:
                arg_3 = AllOps.BitsAsVec
            elif arg_1:
                arg_3 = AllOps.BitsAsSigned
            else:
                arg_3 = AllOps.BitsAsUnsigned

            return Operator.withRes(arg_3, [arg_0], arg_2)


def Func(arg_0: arg_1, *arg_2):
    """
    register Func for process
    """
    for arg_3 in arg_2:
        if isinstance(arg_3, tuple):
            arg_4, arg_3 = arg_3
            if arg_4 == SENSITIVITY.ANY:
                arg_3.simSensProcs.add(arg_0)
            elif arg_4 == SENSITIVITY.RISING:
                arg_3.simRisingSensProcs.add(arg_0)
            elif arg_4 == SENSITIVITY.FALLING:
                arg_3.simFallingSensProcs.add(arg_0)
            else:
                raise AssertionError(arg_4)
        else:
            arg_3.simSensProcs.add(arg_0)


def Func(arg_0, *arg_1):
    """
    Evaluate list of values as condition
    """
    arg_2 = True
    arg_3 = True
    for arg_4 in arg_1:
        arg_5 = bool(arg_4.val)
        arg_6 = arg_4.vldMask == 1
        if arg_6:
            if not arg_5:
                return False, True
        else:
            return False, False

        arg_2 = arg_2 and arg_5
        arg_3 = arg_3 and arg_6

    return arg_2, arg_3


def Func(arg_0, arg_1, arg_2, arg_3, arg_4):
    """
    Connect ports of simulation models by name
    """
    if arg_4 == DIRECTION.OUT:
        arg_5 = getattr(arg_1, arg_2)
        arg_6 = getattr(arg_0, arg_3)
        setattr(arg_1, arg_2, arg_6)
    else:
        arg_5 = getattr(arg_1, arg_3)
        arg_6 = getattr(arg_0, arg_2)
        setattr(arg_1, arg_3, arg_6)

    arg_1._ctx.signals.remove(arg_5)


def Func(arg_0: arg_1, arg_2: arg_3):
    """
    Create value updater for simulation

    :param nextVal: instance of Value which will be asssiggned to signal
    :param invalidate: flag which tells if value has been compromised
        and if it should be invaidated
    :return: function(value) -> tuple(valueHasChangedFlag, nextVal)
    """

    def updater(arg_4):
        arg_5 = arg_0.clone()
        if arg_2:
            arg_5.vldMask = 0
        return (valueHasChanged(arg_4, arg_5), arg_5)
    return updater


def Func(arg_0: arg_1, arg_2: arg_3[arg_1],
                   arg_4: arg_5):
    """
    Create value updater for simulation for value of array type

    :param nextVal: instance of Value which will be asssiggned to signal
    :param indexes: tuple on indexes where value should be updated
        in target array

    :return: function(value) -> tuple(valueHasChangedFlag, nextVal)
    """
    def updater(arg_6):
        if len(arg_2) > 1:
            raise NotImplementedError("[TODO] implement for more indexes")

        arg_7 = arg_0.clone()
        if arg_4:
            arg_7.vldMask = 0

        arg_9 = arg_2[0]
        arg_10 = valueHasChanged(arg_6._getitem__val(arg_9), arg_7)
        arg_6._setitem__val(arg_9, arg_7)
        return (arg_10, arg_6)

    return updater


def Func(arg_0, arg_1):
        """
        Func value of this param
        """
        assert not arg_0.__isReadOnly, \
            ("This parameter(%s) was locked"
             " and now it can not be changed" % arg_0.name)
        assert arg_0.replacedWith is None, \
            ("This param was replaced with new one and this "
             "should not exists")

        arg_1 = toHVal(arg_1)
        arg_0.defVal = arg_1
        arg_0._val = arg_1.staticEval()
        arg_0._dtype = arg_0._val._dtype


def Func(arg_0):
        """
        Resolve ports of discovered memories
        """
        arg_1 = 0
        arg_2 = arg_0.resources
        for arg_3, arg_4 in arg_0.memories.items():
            arg_5, arg_6, arg_7 = 0, 0, 0
            arg_8, arg_9, arg_10 = 0, 0, 0
            arg_11, arg_12 = 0, 0

            for arg_13, (arg_14, arg_15, arg_16, arg_17) in arg_4.items():
                if arg_14:
                    arg_1 += arg_14 * arg_3._dtype.elmType.bit_length()

                # resolve port count for this addr signal
                arg_18 = min(arg_14, arg_15)
                arg_14 -= arg_18
                arg_15 -= arg_18

                arg_19 = min(arg_16, arg_17)
                arg_16 -= arg_19
                arg_17 -= arg_19

                arg_20 = min(arg_14, arg_17)
                arg_14 -= arg_20
                arg_17 -= arg_20

                arg_21 = min(arg_16, arg_15)
                arg_16 -= arg_21
                arg_15 -= arg_21

                # update port counts for mem
                arg_5 += arg_18
                arg_6 += arg_14
                arg_7 += arg_15
                arg_8 += arg_19
                arg_9 += arg_16
                arg_10 += arg_17

                arg_11 += arg_20
                arg_12 += arg_21
            arg_22 = ResourceRAM(arg_3._dtype.elmType.bit_length(),
                            int(arg_3._dtype.size),
                            arg_5, arg_6, arg_7,
                            arg_11,
                            arg_8, arg_9, arg_10,
                            arg_12)
            arg_2[arg_22] = arg_2.get(arg_22, 0) + 1

        arg_0.memories.clear()

        # remove register on read ports which will be merged into ram
        if arg_1:
            arg_23 = arg_2[arg_24]
            arg_23 -= arg_1
            if arg_23:
                arg_2[arg_24] = arg_23
            else:
                del arg_2[arg_24]


def Func(arg_0, arg_1, arg_2=None):
        """
        Construct value of this type.
        Delegated on value class for this type
        """
        return arg_0.getValueCls().Func(arg_1, arg_0, arg_2=arg_2)


def Func(arg_0, arg_1, arg_2):
        """
        Cast value or signal of this type to another type of same size.

        :param sigOrVal: instance of signal or value to cast
        :param toType: instance of HdlType to cast into
        """
        try:
            return arg_0.auto_cast(arg_1, arg_2)
        except TypeConversionErr:
            pass

        try:
            arg_3 = arg_0._Func_fn
        except AttributeError:
            arg_3 = arg_0.get_Func_fn()
            arg_0._Func_fn = arg_3

        return arg_3(arg_0, arg_1, arg_2)


def Func(arg_0, arg_1=arg_2.OUT, arg_4=None):
    """
    Concatenate all signals to one big signal, recursively

    :param masterDirEqTo: only signals with this direction are packed
    :param exclude: sequence of signals/interfaces to exclude
    """
    if not arg_0._interfaces:
        if arg_0._masterDir == arg_1:
            return arg_0._sig
        return None

    arg_5 = None
    for arg_6 in arg_0._interfaces:
        if arg_4 is not None and arg_6 in arg_4:
            continue

        if arg_6._interfaces:
            if arg_6._masterDir == arg_2.IN:
                arg_7 = arg_2.opposite(arg_1)
            else:
                arg_7 = arg_1
            arg_8 = arg_6._pack(arg_7, arg_4=arg_4)
        else:
            if arg_6._masterDir == arg_1:
                arg_8 = arg_6._sig
            else:
                arg_8 = None

        if arg_8 is not None:
            if arg_5 is None:
                arg_5 = arg_8
            else:
                arg_5 = arg_5._concat(arg_8)

    return arg_5


def Func(arg_0, arg_1):
    """
    Return sig and val reduced by & operator or None
    if it is not possible to statically reduce expression
    """
    arg_2 = arg_0._dtype.all_mask()
    if arg_1._isFullVld():
        arg_3 = arg_1.val
        if arg_3 == arg_2:
            return arg_0
        elif arg_3 == 0:
            return arg_1


def Func(arg_0, arg_1):
    """
    Return sig and val reduced by ^ operator or None
    if it is not possible to statically reduce expression
    """
    arg_2 = arg_0._dtype.all_mask()
    if not arg_1.vldMask:
        return arg_1

    if arg_1._isFullVld():
        arg_3 = arg_1.val
        if arg_3 == arg_2:
            return ~arg_0
        elif arg_3 == 0:
            return arg_0


def Func(arg_0):
        """
        Get root of name space
        """
        arg_1 = NameScope(False)
        arg_1.setLevel(1)
        arg_1[0].update(arg_0._keywords_dict)
        return arg_1


def Func(arg_0, arg_1, arg_2,
                              arg_3):
        """
        Decide if this unit should be serialized or not eventually fix name
        to fit same already serialized unit

        :param obj: object to serialize
        :param serializedClasses: dict {unitCls : unitobj}
        :param serializedConfiguredUnits: (unitCls, paramsValues) : unitObj
            where paramsValues are named tuple name:value
        """
        arg_4 = isinstance(arg_1, Entity)
        arg_5 = isinstance(arg_1, Architecture)
        if arg_4:
            arg_6 = arg_1.origin
        elif arg_5:
            arg_6 = arg_1.entity.origin
        else:
            return True

        assert isinstance(arg_6, Unit)
        arg_7 = arg_6._serializeDecision
        if arg_7 is None:
            return True
        else:
            arg_8 = arg_2.get(arg_6.__class__, None)
            arg_9, arg_10 = arg_7(arg_6, arg_1, arg_4, arg_8)
            arg_2[arg_6.__class__] = arg_10
            return arg_9


def Func(arg_0, arg_1: Func, arg_3: arg_4, arg_5=False):
        """
        Serialize HdlType instance
        """
        if isinstance(arg_1, Bits):
            arg_6 = arg_0.HdlType_bits
        elif isinstance(arg_1, HEnum):
            arg_6 = arg_0.HdlType_enum
        elif isinstance(arg_1, HArray):
            arg_6 = arg_0.HdlType_array
        elif isinstance(arg_1, Integer):
            arg_6 = arg_0.HdlType_int
        elif isinstance(arg_1, HBool):
            arg_6 = arg_0.HdlType_bool
        else:
            raise NotImplementedError("type declaration is not implemented"
                                      " for type %s"
                                      % (arg_1.name))

        return arg_6(arg_1, arg_3, arg_5=arg_5)


def Func(arg_0, arg_1: Func, arg_3: arg_4):
        """
        Srialize IfContainer instance
        """
        arg_5 = arg_3.withIndent()

        def asHdl(arg_6):
            return [arg_0.asHdl(arg_7, arg_5) for arg_7 in arg_6]

        try:
            arg_8 = arg_0.condAsHdl(arg_1.cond, True, arg_3)
        except UnsupportedEventOpErr as e:
            arg_8 = None

        if arg_8 is None:
            assert not arg_1.elIfs
            assert not arg_1.ifFalse
            arg_9 = [arg_0.asHdl(arg_7, arg_3) for arg_7 in arg_1.ifTrue]
            return "\n".join(arg_9)

        arg_10 = []
        arg_11 = arg_1.ifTrue
        arg_12 = arg_1.ifFalse
        if arg_12 is None:
            arg_12 = []

        for arg_13, arg_6 in arg_1.elIfs:
            try:
                arg_10.append((arg_0.condAsHdl(arg_13, True, arg_3), asHdl(arg_6)))
            except UnsupportedEventOpErr as e:
                if len(arg_1.elIfs) == 1 and not arg_12:
                    # register expression is in valid format and this
                    # is just register with asynchronous reset or etc...
                    arg_12 = arg_6
                else:
                    raise e

        return arg_0.ifTmpl.render(
            indent=getIndent(arg_3.indent),
            arg_8=arg_8,
            arg_11=asHdl(arg_11),
            arg_10=arg_10,
            arg_12=asHdl(arg_12))


def Func(arg_0, arg_1):
        """
        Get constant name for value
        name of constant is reused if same value was used before
        """
        try:
            return arg_0._cache[arg_1]
        except KeyError:
            if isinstance(arg_1.val, int):
                arg_2 = "const_%d_" % arg_1.val
            else:
                arg_2 = "const_"

            arg_3 = arg_0.nameCheckFn(arg_2, arg_1)
            arg_0._cache[arg_1] = arg_3
            return arg_3


def Func(arg_0, arg_1: arg_2):
        """
        Cut off statements which are driver of specified signal
        """
        if arg_0.dst is arg_1:
            arg_0.parentStm = None
            return arg_0
        else:
            return None


def Func(arg_0, arg_1: arg_2, arg_3: arg_4) -> arg_4:
        """
        Parse HArray type to this transaction template instance

        :return: address of it's end
        """
        arg_0.itemCnt = evalParam(arg_1.size).val
        arg_0.children = TransTmpl(
            arg_1.elmType, 0, parent=arg_0, origin=arg_0.origin)
        return arg_3 + arg_0.itemCnt * arg_0.children.bitAddrEnd


def Func(arg_0) -> int:
        """
        Only for transactions derived from HArray

        :return: width of item in original array
        """
        if not isinstance(arg_0.dtype, HArray):
            raise TypeError()
        return (arg_0.bitAddrEnd - arg_0.bitAddr) // arg_0.itemCnt


def Func(arg_0, arg_1: arg_2=0,
                    arg_3=arg_4,
                    arg_5: arg_6 =arg_7()
                    ) -> Generator[
            Union[Tuple[Tuple[arg_2, arg_2], 'TransTmpl'], 'OneOfTransaction'],
            None, None]:
        """
        Walk fields in instance of TransTmpl

        :param offset: optional offset for all children in this TransTmpl
        :param shouldEnterFn: function (transTmpl) which returns True
            when field should be split on it's children
        :param shouldEnterFn: function(transTmpl) which should return
            (shouldEnter, shouldUse) where shouldEnter is flag that means
            iterator should look inside of this actual object
            and shouldUse flag means that this field should be used
            (=generator should yield it)
        :return: generator of tuples ((startBitAddress, endBitAddress),
            TransTmpl instance)
        """

        arg_8 = arg_0.dtype
        arg_9 = arg_0.bitAddr + arg_1
        arg_10 = arg_0.bitAddrEnd + arg_1

        arg_11, arg_12 = arg_3(arg_0)
        if arg_12:
            yield ((arg_9, arg_10), arg_0)

        if arg_11:
            if isinstance(arg_8, Bits):
                pass
            elif isinstance(arg_8, HStruct):
                for arg_13 in arg_0.children:
                    with arg_5(arg_13.origin.name):
                        yield from arg_13.Func(
                            arg_1,
                            arg_3,
                            arg_5)
            elif isinstance(arg_8, HArray):
                arg_14 = (arg_0.bitAddrEnd - arg_0.bitAddr) // arg_0.itemCnt
                for arg_15 in range(arg_0.itemCnt):
                    with arg_5(arg_15):
                        yield from arg_0.children.Func(
                            arg_9 + arg_15 * arg_14,
                            arg_3,
                            arg_5)
            elif isinstance(arg_8, HUnion):
                yield OneOfTransaction(arg_0, arg_1, arg_3,
                                       arg_0.children)
            elif isinstance(arg_8, HStream):
                assert len(arg_0.children) == 1
                yield StreamTransaction(arg_0, arg_1, arg_3,
                                        arg_0.children[0])
            else:
                raise TypeError(arg_8)


def Func(arg_0, arg_1: "IfContainer") -> None:
        """
        Merge other statement to this statement
        """
        arg_2 = arg_0._merge_statement_lists
        arg_3 = []
        for (arg_4, arg_5), (arg_6, arg_7) in zip(arg_0.cases, arg_1.cases):
            arg_3.append((arg_4, arg_2(arg_5, arg_7)))

        arg_0.cases = arg_3

        if arg_0.default is not None:
            arg_0.default = arg_2(arg_0.default, arg_1.default)

        arg_0._on_merge(arg_1)


def Func(arg_0):
    """
    Cached indent getter function
    """
    try:
        return arg_2[arg_0]
    except KeyError:
        arg_1 = "".join([_indent for _ in range(arg_0)])
        arg_2[arg_0] = arg_1
        return arg_1


def Func(arg_0, arg_1, arg_2):
    """
    Check if not redefining property on obj
    """
    if getattr(arg_0, arg_1, None) is not None:
        raise IntfLvlConfErr("%r already has property %s old:%s new:%s" %
                             (arg_0, arg_1, repr(getattr(arg_0, arg_1)), arg_2))


def Func(arg_0, arg_1, arg_2, arg_3=False):
        """
        Register interface object on interface level object
        """
        nameAvailabilityCheck(arg_0, arg_1, arg_2)
        assert arg_2._parent is None
        arg_2._parent = arg_0
        arg_2._name = arg_1
        arg_2._ctx = arg_0._ctx

        if arg_3:
            arg_0._private_interfaces.append(arg_2)
            arg_2._isExtern = False
        else:
            arg_0._interfaces.append(arg_2)
            arg_2._isExtern = True


def Func(arg_0, arg_1, arg_2):
        """
        Register array of items on interface level object
        """
        arg_2._parent = arg_0
        arg_2._name = arg_1
        for arg_5, arg_6 in enumerate(arg_2):
            setattr(arg_0, "%s_%d" % (arg_1, arg_5), arg_6)


def Func(arg_0):
        """
        Returns a first driver if signal has only one driver.
        """
        # [TODO] no driver exception
        arg_1 = len(arg_0.drivers)
        if not arg_1:
            raise NoDriverErr(arg_0)
        elif arg_1 != 1:
            raise MultipleDriversErr(arg_0)

        return arg_0.drivers[0]


def Func(arg_0):
        """
        Recursively statistically evaluate result of this operator
        """
        for arg_1 in arg_0.operands:
            arg_1.Func()
        arg_0.result._val = arg_0.evalFn()


def Func(arg_0, arg_1, arg_2, arg_3=[]):
        """
        Create operator with result signal

        :ivar resT: data type of result signal
        :ivar outputs: iterable of singnals which are outputs
            from this operator
        """
        arg_4 = Operator(arg_0, arg_1)
        arg_5 = RtlSignal(getCtxFromOps(arg_1), None, arg_2)
        arg_5._const = arr_all(arg_4.operands, isConst)
        arg_5.drivers.append(arg_4)
        arg_5.origin = arg_4
        arg_4.result = arg_5
        arg_4.registerSignals(arg_3)
        if arg_5._const:
            arg_5.staticEval()
        return arg_5


def Func(arg_0, arg_1, arg_2):
    """
    Try connect src to interface of specified name on unit.
    Ignore if interface is not present or if it already has driver.
    """
    try:
        arg_3 = getattr(arg_1, arg_2)
    except AttributeError:
        return
    if not arg_3._sig.drivers:
        connect(arg_0, arg_3)


def Func(arg_0):
    """
    Propagate "clk" clock signal to all subcomponents
    """
    arg_1 = arg_0.clk
    for arg_2 in arg_0._units:
        _tryConnect(arg_1, arg_2, 'clk')


def Func(arg_0):
    """
    Propagate "clk" clock and negative reset "rst_n" signal
    to all subcomponents
    """
    arg_1 = arg_0.clk
    arg_2 = arg_0.rst_n

    for arg_3 in arg_0._units:
        _tryConnect(arg_1, arg_3, 'clk')
        _tryConnect(arg_2, arg_3, 'rst_n')
        _tryConnect(~arg_2, arg_3, 'rst')


def Func(arg_0):
    """
    Propagate reset "rst" signal
    to all subcomponents
    """
    arg_1 = arg_0.rst

    for arg_2 in arg_0._units:
        _tryConnect(~arg_1, arg_2, 'rst_n')
        _tryConnect(arg_1, arg_2, 'rst')


def Func(arg_0: arg_1[arg_2, arg_3], arg_4: arg_5=1,
             arg_6: arg_7=True, arg_8: arg_7=False):
    """
    Iterate over bits in vector

    :param sigOrVal: signal or value to iterate over
    :param bitsInOne: number of bits in one part
    :param skipPadding: if true padding is skipped in dense types
    """
    arg_9 = BitWalker(arg_0, arg_6, arg_8)
    for arg_10 in range(ceil(arg_0._dtype.bit_length() / arg_4)):
        yield arg_9.get(arg_4)

    arg_9.assertIsOnEnd()


def Func(arg_0, arg_1, arg_2, arg_3):
    """
    Always decide not to serialize obj

    :param priv: private data for this function first unit of this class
    :return: tuple (do serialize this object, next priv)
    """
    if arg_2:
        # prepare entity which will not be serialized
        prepareEntity(arg_1, arg_0.__class__.__name__, arg_3)

    if arg_3 is None:
        arg_3 = arg_0

    return False, arg_3


def Func(arg_0, arg_1, arg_2, arg_3):
    """
    Decide to serialize only first obj of it's class

    :param priv: private data for this function
        (first object with class == obj.__class__)

    :return: tuple (do serialize this object, next priv)
        where priv is private data for this function
        (first object with class == obj.__class__)
    """
    arg_4 = arg_0.__class__.__name__

    if arg_2:
        arg_1.name = arg_4

    if arg_3 is None:
        arg_3 = arg_0
    elif arg_2:
        # prepare entity which will not be serialized
        prepareEntity(arg_1, arg_4, arg_0)

    arg_6 = arg_3 is arg_0

    return arg_6, arg_3


def Func(arg_0, arg_1, arg_2, arg_3):
    """
    Decide to serialize only objs with uniq parameters and class

    :param priv: private data for this function
        ({frozen_params: obj})

    :return: tuple (do serialize this object, next priv)
    """

    arg_4 = paramsToValTuple(arg_0)

    if arg_3 is None:
        arg_3 = {}

    if arg_2:
        try:
            arg_5 = arg_3[arg_4]
        except KeyError:
            arg_3[arg_4] = arg_0
            return True, arg_3

        prepareEntity(arg_1, arg_5._entity.name, arg_5)
        return False, arg_3

    return arg_3[arg_4] is arg_0, arg_3


def Func(arg_0, *arg_1, **arg_2):
        """
        Delegate Func on items

        :note: doc in :func:`~hwt.synthesizer.interfaceLevel.propDeclCollector.Func`
        """
        for arg_3 in arg_0:
            arg_3.Func(*arg_1, **arg_2)


def Func(arg_0, arg_1=arg_2(), arg_3=None):
    """
    Create a simulation model for unit

    :param unit: interface level unit which you wont prepare for simulation
    :param targetPlatform: target platform for this synthes
    :param dumpModelIn: folder to where put sim model files
        (otherwise sim model will be constructed only in memory)
    """
    arg_4 = toRtl(arg_0,
                     arg_1=arg_1,
                     saveTo=arg_3,
                     serializer=SimModelSerializer)
    if arg_3 is not None:
        arg_5 = os.path.join(os.getcwd(), arg_3)
        arg_6 = arg_5 in sys.path
        if not arg_6:
            sys.path.insert(0, arg_5)
        if arg_0._name in sys.modules:
            del sys.modules[arg_0._name]
        arg_7 = importlib.import_module(arg_0._name)

        if not arg_6:
            sys.path.remove(arg_5)
    else:
        arg_7 = ModuleType('simModule')
        # python supports only ~100 opened brackets
        # it exceded it throws MemoryError: s_push: parser stack overflow
        exec(arg_4, arg_7.__dict__)

    return arg_7.__dict__[arg_0._name]


def Func(arg_0, arg_1):
    """
    Reconnect model signals to unit to run simulation with simulation model
    but use original unit interfaces for communication

    :param synthesisedUnitOrIntf: interface where should be signals
        replaced from signals from modelCls
    :param modelCls: simulation model form where signals
        for synthesisedUnitOrIntf should be taken
    """
    arg_2 = arg_0
    arg_3 = arg_2._interfaces

    if arg_3:
        for arg_4 in arg_3:
            # proxies are destroyed on original interfaces and only proxies on
            # array items will remain
            Func(arg_4, arg_1)
    else:
        # reconnect signal from model
        arg_5 = arg_0
        arg_5._sigInside = getattr(arg_1, arg_5._sigInside.name)


def Func(arg_0, arg_1, arg_2=arg_3.stdout,
               arg_5=100 * arg_6.ns):
    """
    Syntax sugar
    If outputFile is string try to open it as file

    :return: hdl simulator object
    """
    assert isinstance(arg_0, SimModel), \
        "Class of SimModel is required (got %r)" % (arg_0)
    if isinstance(arg_2, str):
        arg_8 = os.path.dirname(arg_2)
        if arg_8:
            os.makedirs(arg_8, exist_ok=True)
        with open(arg_2, 'w') as f:
            return _Func(arg_0, arg_1,
                               f, arg_5)
    else:
        return _Func(arg_0, arg_1,
                           arg_2, arg_5)


def Func(arg_0, arg_1):
        """
        Process for injecting of this callback loop into simulator
        """
        yield from arg_0.onTWriteCallback(arg_1)
        arg_0.intf.t._sigInside.registerWriteCallback(
            arg_0.onTWriteCallback,
            arg_0.getEnable)
        arg_0.intf.o._sigInside.registerWriteCallback(
            arg_0.onTWriteCallback,
            arg_0.getEnable)


def Func(arg_0, arg_1):
        """
        Connect internal signal to port item,
        this connection is used by simulator and only output port items
        will be connected
        """
        if arg_0.direction == DIRECTION.OUT:
            if arg_0.src is not None:
                raise HwtSyntaxError(
                    "Port %s is already associated with %s"
                    % (arg_0.name, str(arg_0.src)))
            arg_0.src = arg_1

        elif arg_0.direction == DIRECTION.IN:
            if arg_0.dst is not None:
                raise HwtSyntaxError(
                    "Port %s is already associated with %s"
                    % (arg_0.name, str(arg_0.dst)))
            arg_0.dst = arg_1

        else:
            raise NotImplementedError(arg_0.direction)


def Func(arg_0):
        """
        connet signal from internal side of of this component to this port
        """
        arg_1 = arg_0.direction
        if arg_1 == DIRECTION.OUT:
            arg_0.src.endpoints.append(arg_0)
        elif arg_1 == DIRECTION.IN or arg_1 == DIRECTION.INOUT:
            arg_0.dst.drivers.append(arg_0)
        else:
            raise NotImplementedError(arg_1)


def Func(arg_0):
        """
        return signal inside unit which has this port
        """
        arg_1 = arg_0.direction
        if arg_1 == DIRECTION.IN:
            return arg_0.dst
        elif arg_1 == DIRECTION.OUT:
            return arg_0.src
        else:
            raise NotImplementedError(arg_1)


def Func(arg_0, arg_1, arg_2) -> None:
        """
        Schedule process on actual time with specified priority
        """
        arg_0._events.push(arg_0.now, arg_2, arg_1)


def Func(arg_0, arg_1: arg_2, arg_3) -> None:
        """
        Add hdl process to execution queue

        :param trigger: instance of SimSignal
        :param proc: python generator function representing HDL process
        """
        # first process in time has to plan executing of apply values on the
        # end of this time
        if not arg_0._applyValPlaned:
            # (apply on end of this time to minimalize process reevaluation)
            arg_0._scheduleApplyValues()

        if isEvDependentOn(arg_1, arg_3):
            if arg_0.now == 0:
                return  # pass event dependent on startup
            arg_0._seqProcsToRun.append(arg_3)
        else:
            arg_0._combProcsToRun.append(arg_3)


def Func(arg_0) -> Event:
        """
        Schedule combUpdateDoneEv event to let agents know that current
        delta step is ending and values from combinational logic are stable
        """
        assert not arg_0._combUpdateDonePlaned, arg_0.now
        arg_1 = Event(arg_0)
        arg_1.process_to_wake.append(arg_0.__deleteCombUpdateDoneEv())
        arg_0._add_process(arg_1, PRIORITY_AGENTS_UPDATE_DONE)
        arg_0._combUpdateDonePlaned = True
        arg_0.combUpdateDoneEv = arg_1
        return arg_1


def Func(arg_0) -> None:
        """
        Apply stashed values to signals
        """
        assert not arg_0._applyValPlaned, arg_0.now
        arg_0._add_process(arg_0._applyValues(), PRIORITY_APPLY_COMB)
        arg_0._applyValPlaned = True

        if arg_0._runSeqProcessesPlaned:
            # if runSeqProcesses is already scheduled
            return

        assert not arg_0._seqProcsToRun and not arg_0._runSeqProcessesPlaned, arg_0.now
        arg_0._add_process(arg_0._runSeqProcesses(), PRIORITY_APPLY_SEQ)
        arg_0._runSeqProcessesPlaned = True


def Func(arg_0, arg_1: arg_2)\
            -> Tuple[Callable[[Value], bool], bool]:
        """
        This functions resolves write conflicts for signal

        :param actionSet: set of actions made by process
        """

        arg_3 = False
        arg_4 = len(arg_1)
        if arg_4 == 3:
            # update for item in array
            arg_5, arg_6, arg_7 = arg_1
            return (mkArrayUpdater(arg_5, arg_6, arg_3), arg_7)
        else:
            # update for simple signal
            arg_5, arg_7 = arg_1
            return (mkUpdater(arg_5, arg_3), arg_7)


def Func(arg_0) -> None:
        """
        Delta step for combinational processes
        """
        for arg_1 in arg_0._combProcsToRun:
            arg_2 = arg_0._outputContainers[arg_1]
            arg_1(arg_0, arg_2)
            for arg_3, arg_4 in arg_2._all_signals:
                arg_5 = getattr(arg_2, arg_3)
                if arg_5 is not None:
                    arg_6 = arg_0._conflictResolveStrategy(arg_5)
                    # prepare update
                    arg_7, arg_8 = arg_6
                    arg_0._valuesToApply.append(
                        (arg_4, arg_7, arg_8, arg_1))
                    setattr(arg_2, arg_3, None)
                    # else value is latched

        arg_0._combProcsToRun = UniqList()


def Func(arg_0, arg_1) -> Value:
        """
        Read value from signal or interface
        """
        try:
            arg_2 = arg_1._val
        except AttributeError:
            arg_2 = arg_1._sigInside._val

        return arg_2.clone()


def Func(arg_0, arg_1, arg_2: arg_3)-> None:
        """
        Write value to signal or interface.
        """
        # get target RtlSignal
        try:
            arg_4 = arg_2.simSensProcs
        except AttributeError:
            arg_2 = arg_2._sigInside
            arg_4 = arg_2.simSensProcs

        # type cast of input value
        arg_5 = arg_2._dtype

        if isinstance(arg_1, Value):
            arg_6 = arg_1.clone()
            arg_6 = arg_6._auto_cast(arg_5)
        else:
            arg_6 = arg_5.fromPy(arg_1)

        # can not update value in signal directly due singnal proxies
        arg_2.simUpdateVal(arg_0, lambda curentV: (
            valueHasChanged(curentV, arg_6), arg_6))

        if not arg_0._applyValPlaned:
            if not (arg_4 or
                    arg_2.simRisingSensProcs or
                    arg_2.simFallingSensProcs):
                # signal value was changed but there are no sensitive processes
                # to it because of this _applyValues is never planed
                # and should be
                arg_0._scheduleApplyValues()
            elif (arg_2._FuncCallbacks or
                  arg_2._FuncCallbacksToEn):
                # signal Func did not caused any change on any other signal
                # but there are still simulation agets waiting on
                # updateComplete event
                arg_0._scheduleApplyValues()


def Func(arg_0):
    """Convert all ternary operators to IfContainers"""
    arg_1 = []

    for arg_2 in arg_0:
        if isinstance(arg_2, Assignment):
            try:
                if not isinstance(arg_2.src, RtlSignalBase):
                    raise DoesNotContainsTernary()
                arg_3 = arg_2.src.singleDriver()
                if not isinstance(arg_3, Operator) or arg_3.operator != AllOps.TERNARY:
                    raise DoesNotContainsTernary()
                else:
                    arg_4 = arg_3.operands
                    arg_5 = IfContainer(arg_4[0],
                                      [Assignment(arg_4[1], arg_2.dst)],
                                      [Assignment(arg_4[2], arg_2.dst)]
                                      )
                    arg_1.append(arg_5)
                    continue

            except (MultipleDriversErr, DoesNotContainsTernary):
                pass
            except NoDriverErr:
                assert (hasattr(arg_2.src, "_interface")
                        and arg_2.src._interface is not None)\
                    or arg_2.src.defVal.vldMask, arg_2.src

        arg_1.append(arg_2)
    return arg_1


def Func(arg_0):
        """ Create a new Func under this service. """
        arg_1 = Version()
        arg_1.conn = arg_0.conn

        arg_1.attrs = {
            # Parent params
            'service_id': arg_0.attrs['id'],
        }

        arg_1.save()

        return arg_1


def Func(arg_0, arg_1, arg_2):
        """ Create a new VCL under this version. """
        Func = VCL()
        Func.conn = arg_0.conn

        Func.attrs = {
            # Parent params
            'service_id': arg_0.attrs['service_id'],
            'version': arg_0.attrs['number'],

            # New instance params
            'name': arg_1,
            'content': arg_2,
        }

        Func.save()

        return Func


def Func(arg_0):
        """
        Converts the column to a dictionary representation accepted
        by the Citrination server.

        :return: Dictionary with basic options, plus any column type specific
            options held under the "options" key
        :rtype: dict
        """
        return {
            "type": arg_0.type,
            "name": arg_0.name,
            "group_by_key": arg_0.group_by_key,
            "role": arg_0.role,
            "units": arg_0.units,
            "options": arg_0.build_options()
        }


def Func(arg_0, arg_1, arg_2='ignore', arg_3=False):
        """
        Add a descriptor column.

        :param descriptor: A Descriptor instance (e.g., RealDescriptor, InorganicDescriptor, etc.)
        :param role: Specify a role (input, output, latentVariable, or ignore)
        :param group_by_key: Whether or not to group by this key during cross validation
        """

        arg_1.validate()

        if arg_1.key in arg_0.configuration["roles"]:
            raise ValueError("Cannot add a descriptor with the same name twice")

        arg_0.configuration['descriptors'].append(arg_1.as_dict())
        arg_0.configuration["roles"][arg_1.key] = arg_2

        if arg_3:
            arg_0.configuration["group_by"].append(arg_1.key)


def Func(arg_0, arg_1):
        """
        Checks to see that the query will not exceed the max query depth

        :param returning_query: The PIF system or Dataset query to execute.
        :type returning_query: :class:`PifSystemReturningQuery` or :class: `DatasetReturningQuery`
        """

        arg_2 = arg_1.from_index or 0
        arg_3 = arg_1.size or 0

        if arg_2 < 0:
            raise CitrinationClientError(
                "start_index cannot be negative. Please enter a value greater than or equal to zero")
        if arg_3 < 0:
            raise CitrinationClientError("Size cannot be negative. Please enter a value greater than or equal to zero")
        if arg_2 + arg_3 > MAX_QUERY_DEPTH:
            raise CitrinationClientError(
                "Citrination does not support pagination past the {0}th result. Please reduce either the from_index and/or size such that their sum is below {0}".format(
                    MAX_QUERY_DEPTH))


def Func(arg_0, arg_1):
        """
        Run each in a list of PIF queries against Citrination.

        :param multi_query: :class:`MultiQuery` object to execute.
        :return: :class:`PifMultiSearchResult` object with the results of the query.
        """
        arg_2 = "Error while making PIF multi search request"
        arg_3 = arg_0._get_success_json(
            arg_0._post(routes.Func, data=json.dumps(arg_1, cls=QueryEncoder),
                       arg_2=arg_2))

        return PifMultiSearchResult(**keys_to_snake_case(arg_3['results']))


def Func(arg_0, arg_1, arg_2, arg_3, arg_4):
        """
        Updates an existing data view from the search template and ml template given

        :param id: Identifier for the data view.  This returned from the create method.
        :param configuration: Information to construct the data view from (eg descriptors, datasets etc)
        :param name: Name of the data view
        :param description: Description for the data view
        """

        arg_5 = {
            "configuration":
                arg_2,
            "name":
                arg_3,
            "description":
                arg_4
        }

        arg_6 = "Dataview creation failed"

        arg_0._patch_json(
            'v1/data_views/' + arg_1, arg_5, arg_6=arg_6)


def Func(arg_0, arg_1):
        """
        Gets basic information about a view

        :param data_view_id: Identifier of the data view
        :return: Metadata about the view as JSON
        """

        arg_2 = "Dataview Func failed"
        return arg_0._Func_success_json(arg_0._Func(
            'v1/data_views/' + arg_1, None, arg_2=arg_2))['data']['data_view']


def Func(arg_0, arg_1):
        """
        Creates an ml configuration from dataset_ids and extract_as_keys

        :param dataset_ids: Array of dataset identifiers to make search template from
        :return: An identifier used to request the status of the builder job (get_ml_configuration_status)
        """
        arg_2 = arg_0.search_template_client.get_available_columns(arg_1)

        # Create a search template from dataset ids
        arg_3 = arg_0.search_template_client.create(arg_1, arg_2)
        return arg_0.create_ml_configuration(arg_3, arg_2, arg_1)


def Func(arg_0, arg_1, arg_2):
        """
        Utility function to turn the result object from the configuration builder endpoint into something that
        can be used directly as a configuration.

        :param result_blob: Nested dicts representing the possible descriptors
        :param dataset_ids: Array of dataset identifiers to make search template from
        :return: An object suitable to be used as a parameter to data view create
        """

        arg_3 = DataViewBuilder()
        arg_3.dataset_ids(arg_2)
        for arg_4, (arg_5, arg_6) in enumerate(arg_1['descriptors'].items()):
            try:
                arg_7 = arg_0.__snake_case(arg_6[0])
                print(json.dumps(arg_7))
                arg_7['descriptor_key'] = arg_5
                arg_3.add_raw_descriptor(arg_7)
            except IndexError:
                pass

        for arg_4, (arg_5, arg_6) in enumerate(arg_1['types'].items()):
            arg_3.set_role(arg_5, arg_6.lower())

        return arg_3.build()


def Func(arg_0, arg_1):
        """
        After invoking the create_ml_configuration async method, you can use this method to
        check on the status of the builder job.

        :param job_id: The identifier returned from create_ml_configuration
        :return: Job status
        """

        arg_2 = "Get status on ml configuration failed"
        arg_3 = arg_0._get_success_json(arg_0._get(
            'v1/descriptors/builders/simple/default/' + arg_1 + '/status', None, arg_2=arg_2))[
            'data']
        return arg_3